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

Histogram 直方图

分箱直方图,每个 bin 一个柱。

基础用法

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

背景 视口
0-5050-100100-200200-500500-1k1k-2k2k-5k5k+
src/App.vue
<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。

背景 视口
正态分布
40-6060-8080-100100-120120-140140-160160-180
长尾分布
0-100100-200200-400400-800800-1.6k1.6k+
src/App.vue
<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

属性类型默认值说明
binsHistogramBin[]{ label, count }[] 分箱数据
widthnumber480SVG 宽度
heightnumber200SVG 高度
colorIndex0..70柱体颜色(--viz-1..8
showLabelsbooleantruebin label 显示开关
showTooltipbooleantrue启用 hover tooltip
tooltipFormatter(payload: HistogramInteractionPayload) => string完整 tooltip HTML 自渲染
ariaLabelstring透传给根 <svg>aria-label

Events

Vue 事件React 回调载荷类型说明
item-enteronItemEnterHistogramInteractionPayload鼠标进入某 bin 时触发
item-leaveonItemLeaveHistogramInteractionPayload鼠标离开时触发

类型

interface HistogramInteractionPayload {
  label: string;
  count: number;
  dataIndex: number;
  nativeEvent?: MouseEvent;
}

反馈与讨论

Histogram 直方图 的讨论

0
0 / 600
正在加载评论...