RidgePlot 密度脊图
多组密度曲线垂直堆叠。
基础用法
数据通过 props 传入,纯 SVG 渲染,无第三方图表库依赖。
配色取自 --viz-1..8 token,色盲友好。
背景
<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> <script setup>
import { CfRidgePlot } from '@chufix-design/vue';
function bell(center, 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 ... /> <CfRidgePlot ... /> 多峰分布
把多个 bell 叠加可得到双峰分布,常见于跨季节、跨用户群的二次集中点。
背景
<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> <script setup>
import { CfRidgePlot } from '@chufix-design/vue';
function bell(center, 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} /> <CfRidgePlot rows={rows} overlap={0.5} /> API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
rows | RidgeRow[] | — | { label, density: number[], colorIndex? }[] |
overlap | 0..1 | 0.6 | 行间重叠比例 |
反馈与讨论
RidgePlot 密度脊图 的讨论