Histogram 直方图
分箱直方图,每个 bin 一个柱。
基础用法
数据通过 props 传入,纯 SVG 渲染,无第三方图表库依赖。
配色取自 --viz-1..8 token,色盲友好。
背景 视口
<script setup lang="ts">
import { CfHistogram } from '@chufix-design/vue';
const bins = [
{ label: '0-50', count: 4 },
{ label: '50-100', count: 8 },
{ label: '100-200', count: 16 },
{ label: '200-500', count: 28 },
{ label: '500-1k', count: 22 },
{ label: '1k-2k', count: 12 },
{ label: '2k-5k', count: 5 },
{ label: '5k+', count: 1 },
];
</script>
<template>
<CfHistogram :bins="bins" />
</template> <script setup>
import { CfHistogram } from '@chufix-design/vue';
const bins = [
{ label: '0-50', count: 4 },
{ label: '50-100', count: 8 },
{ label: '100-200', count: 16 },
{ label: '200-500', count: 28 },
{ label: '500-1k', count: 22 },
{ label: '1k-2k', count: 12 },
{ label: '2k-5k', count: 5 },
{ label: '5k+', count: 1 },
];
</script>
<template>
<CfHistogram :bins="bins" />
</template> import { CfHistogram } from '@chufix-design/react';
export default function Demo() {
const bins = [
{ label: '0-50', count: 4 },
{ label: '50-100', count: 8 },
{ label: '100-200', count: 16 },
{ label: '200-500', count: 28 },
{ label: '500-1k', count: 22 },
{ label: '1k-2k', count: 12 },
{ label: '2k-5k', count: 5 },
{ label: '5k+', count: 1 },
];
return (
<>
<CfHistogram bins={bins} />
</>
);
} import { CfHistogram } from '@chufix-design/react';
export default function Demo() {
const bins = [
{ label: '0-50', count: 4 },
{ label: '50-100', count: 8 },
{ label: '100-200', count: 16 },
{ label: '200-500', count: 28 },
{ label: '500-1k', count: 22 },
{ label: '1k-2k', count: 12 },
{ label: '2k-5k', count: 5 },
{ label: '5k+', count: 1 },
];
return (
<>
<CfHistogram bins={bins} />
</>
);
} 两种典型分布
正态分布 / 长尾分布对比 — 长尾时建议用对数刻度的 bin label。
背景 视口
正态分布
长尾分布
<script setup lang="ts">
import { CfHistogram } from '@chufix-design/vue';
const normal = [
{ label: '40-60', count: 2 },
{ label: '60-80', count: 8 },
{ label: '80-100', count: 18 },
{ label: '100-120', count: 32 },
{ label: '120-140', count: 24 },
{ label: '140-160', count: 12 },
{ label: '160-180', count: 4 },
];
const skewed = [
{ label: '0-100', count: 38 },
{ label: '100-200', count: 22 },
{ label: '200-400', count: 14 },
{ label: '400-800', count: 8 },
{ label: '800-1.6k', count: 4 },
{ label: '1.6k+', count: 2 },
];
</script>
<template>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
<div>
<div style="font-size: 11px; color: var(--fg-3); margin-bottom: 4px;">正态分布</div>
<CfHistogram :bins="normal" :height="160" :color-index="0" />
</div>
<div>
<div style="font-size: 11px; color: var(--fg-3); margin-bottom: 4px;">长尾分布</div>
<CfHistogram :bins="skewed" :height="160" :color-index="3" />
</div>
</div>
</template> <script setup>
import { CfHistogram } from '@chufix-design/vue';
const normal = [
{ label: '40-60', count: 2 },
{ label: '60-80', count: 8 },
{ label: '80-100', count: 18 },
{ label: '100-120', count: 32 },
{ label: '120-140', count: 24 },
{ label: '140-160', count: 12 },
{ label: '160-180', count: 4 },
];
const skewed = [
{ label: '0-100', count: 38 },
{ label: '100-200', count: 22 },
{ label: '200-400', count: 14 },
{ label: '400-800', count: 8 },
{ label: '800-1.6k', count: 4 },
{ label: '1.6k+', count: 2 },
];
</script>
<template>
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 16px;">
<div>
<div style="font-size: 11px; color: var(--fg-3); margin-bottom: 4px;">正态分布</div>
<CfHistogram :bins="normal" :height="160" :color-index="0" />
</div>
<div>
<div style="font-size: 11px; color: var(--fg-3); margin-bottom: 4px;">长尾分布</div>
<CfHistogram :bins="skewed" :height="160" :color-index="3" />
</div>
</div>
</template> import { CfHistogram } from '@chufix-design/react';
export default function Demo() {
const normal = [
{ label: '40-60', count: 2 },
{ label: '60-80', count: 8 },
{ label: '80-100', count: 18 },
{ label: '100-120', count: 32 },
{ label: '120-140', count: 24 },
{ label: '140-160', count: 12 },
{ label: '160-180', count: 4 },
];
const skewed = [
{ label: '0-100', count: 38 },
{ label: '100-200', count: 22 },
{ label: '200-400', count: 14 },
{ label: '400-800', count: 8 },
{ label: '800-1.6k', count: 4 },
{ label: '1.6k+', count: 2 },
];
return (
<>
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
<div>
<div style={{ fontSize: 11, color: "var(--fg-3)", marginBottom: 4 }}>正态分布</div>
<CfHistogram bins={normal} height={160} colorIndex={0} />
</div>
<div>
<div style={{ fontSize: 11, color: "var(--fg-3)", marginBottom: 4 }}>长尾分布</div>
<CfHistogram bins={skewed} height={160} colorIndex={3} />
</div>
</div>
</>
);
} import { CfHistogram } from '@chufix-design/react';
export default function Demo() {
const normal = [
{ label: '40-60', count: 2 },
{ label: '60-80', count: 8 },
{ label: '80-100', count: 18 },
{ label: '100-120', count: 32 },
{ label: '120-140', count: 24 },
{ label: '140-160', count: 12 },
{ label: '160-180', count: 4 },
];
const skewed = [
{ label: '0-100', count: 38 },
{ label: '100-200', count: 22 },
{ label: '200-400', count: 14 },
{ label: '400-800', count: 8 },
{ label: '800-1.6k', count: 4 },
{ label: '1.6k+', count: 2 },
];
return (
<>
<div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 16 }}>
<div>
<div style={{ fontSize: 11, color: "var(--fg-3)", marginBottom: 4 }}>正态分布</div>
<CfHistogram bins={normal} height={160} colorIndex={0} />
</div>
<div>
<div style={{ fontSize: 11, color: "var(--fg-3)", marginBottom: 4 }}>长尾分布</div>
<CfHistogram bins={skewed} height={160} colorIndex={3} />
</div>
</div>
</>
);
} API
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
bins | HistogramBin[] | — | { label, count }[] 分箱数据 |
width | number | 480 | SVG 宽度 |
height | number | 200 | SVG 高度 |
colorIndex | 0..7 | 0 | 柱体颜色(--viz-1..8) |
showLabels | boolean | true | bin label 显示开关 |
showTooltip | boolean | true | 启用 hover tooltip |
tooltipFormatter | (payload: HistogramInteractionPayload) => string | — | 完整 tooltip HTML 自渲染 |
ariaLabel | string | — | 透传给根 <svg> 的 aria-label |
Events
| Vue 事件 | React 回调 | 载荷类型 | 说明 |
|---|---|---|---|
item-enter | onItemEnter | HistogramInteractionPayload | 鼠标进入某 bin 时触发 |
item-leave | onItemLeave | HistogramInteractionPayload | 鼠标离开时触发 |
类型
interface HistogramInteractionPayload {
label: string;
count: number;
dataIndex: number;
nativeEvent?: MouseEvent;
}
反馈与讨论
Histogram 直方图 的讨论