开发预览 更新于 2026-05-10

RidgePlot 密度脊图

多组密度曲线垂直堆叠。

基础用法

数据通过 props 传入,纯 SVG 渲染,无第三方图表库依赖。 配色取自 --viz-1..8 token,色盲友好。

背景
2024 Q12024 Q22024 Q32024 Q4
<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

属性类型默认值说明
rowsRidgeRow[]{ label, density: number[], colorIndex? }[]
overlap0..10.6行间重叠比例

反馈与讨论

RidgePlot 密度脊图 的讨论

0
0 / 600
一键发送
正在加载评论...