Ridge plot
Vertically stacked density curves across multiple groups.
Basic usage
Data is passed via props and rendered as pure SVG, with no third-party charting dependency.
Colors are drawn from the --viz-1..8 tokens and are colorblind-friendly.
背景
<script setup lang="ts">
import { CfRidgePlot } from '@chufix-design/vue';
function bell(center: number, n = 30) {
return Array.from({ length: n }, (_, i) => {
const x = (i - center) / 4;
return Math.exp(-x * x);
});
}
const rows = [
{ label: '2024 Q1', density: bell(8) },
{ label: '2024 Q2', density: bell(12) },
{ label: '2024 Q3', density: bell(15) },
{ label: '2024 Q4', density: bell(20) },
];
</script>
<template>
<CfRidgePlot :rows="rows" />
</template> <CfRidgePlot ... /> Multimodal distributions
Stacking multiple bells produces bimodal distributions, common when crossing seasons or user cohorts with secondary peaks.
背景
<script setup lang="ts">
import { CfRidgePlot } from '@chufix-design/vue';
function bell(center: number, n = 30, height = 1) {
return Array.from({ length: n }, (_, i) => {
const x = (i - center) / 4;
return Math.exp(-x * x) * height;
});
}
function combine(...waves: number[][]) {
const out = new Array(waves[0].length).fill(0);
for (const w of waves) for (let i = 0; i < w.length; i++) out[i] += w[i];
return out;
}
const rows = [
{ label: '春', density: combine(bell(8, 30, 1), bell(20, 30, 0.4)) },
{ label: '夏', density: combine(bell(15, 30, 1.2)) },
{ label: '秋', density: combine(bell(10, 30, 0.6), bell(22, 30, 1.0)) },
{ label: '冬', density: combine(bell(5, 30, 0.8), bell(25, 30, 0.6)) },
];
</script>
<template>
<CfRidgePlot :rows="rows" :height="220" :overlap="0.5" />
</template>
<CfRidgePlot rows={rows} overlap={0.5} /> API
| Prop | Type | Default | Description |
|---|---|---|---|
rows | RidgeRow[] | — | { label, density: number[], colorIndex? }[] |
overlap | 0..1 | 0.6 | Inter-row overlap ratio |
反馈与讨论
Ridge plot · Discussion