BulletChart 子弹图
单值进度条 + 目标线 + 质量带,比 Gauge 更适合"对比目标"语义。
基础用法
数据通过 props 传入,纯 SVG 渲染,无第三方图表库依赖。
配色取自 --viz-1..8 token,色盲友好。
背景 视口
收入
留存率
<script setup lang="ts">
import { CfBulletChart } from '@chufix-design/vue';
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 12px; max-width: 360px;">
<CfBulletChart label="收入" :value="780" :target="900" :max="1200" :bands="[{upTo: 400, tone: 'error'}, {upTo: 700, tone: 'warning'}, {upTo: 1200, tone: 'success'}]" />
<CfBulletChart label="留存率" :value="62" :target="70" :max="100" :bands="[{upTo: 40, tone: 'error'}, {upTo: 70, tone: 'warning'}, {upTo: 100, tone: 'success'}]" />
</div>
</template> <script setup>
import { CfBulletChart } from '@chufix-design/vue';
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 12px; max-width: 360px;">
<CfBulletChart label="收入" :value="780" :target="900" :max="1200" :bands="[{upTo: 400, tone: 'error'}, {upTo: 700, tone: 'warning'}, {upTo: 1200, tone: 'success'}]" />
<CfBulletChart label="留存率" :value="62" :target="70" :max="100" :bands="[{upTo: 40, tone: 'error'}, {upTo: 70, tone: 'warning'}, {upTo: 100, tone: 'success'}]" />
</div>
</template> import { CfBulletChart } from '@chufix-design/react';
export default function Demo() {
return (
<>
<div style={{ display: "flex", flexDirection: "column", gap: 12, maxWidth: 360 }}>
<CfBulletChart label="收入" value={780} target={900} max={1200} bands={[{upTo: 400, tone: 'error'}, {upTo: 700, tone: 'warning'}, {upTo: 1200, tone: 'success'}]} />
<CfBulletChart label="留存率" value={62} target={70} max={100} bands={[{upTo: 40, tone: 'error'}, {upTo: 70, tone: 'warning'}, {upTo: 100, tone: 'success'}]} />
</div>
</>
);
} import { CfBulletChart } from '@chufix-design/react';
export default function Demo() {
return (
<>
<div style={{ display: "flex", flexDirection: "column", gap: 12, maxWidth: 360 }}>
<CfBulletChart label="收入" value={780} target={900} max={1200} bands={[{upTo: 400, tone: 'error'}, {upTo: 700, tone: 'warning'}, {upTo: 1200, tone: 'success'}]} />
<CfBulletChart label="留存率" value={62} target={70} max={100} bands={[{upTo: 40, tone: 'error'}, {upTo: 70, tone: 'warning'}, {upTo: 100, tone: 'success'}]} />
</div>
</>
);
} 质量带 + 超过目标
bands 三段染色 + target 垂直线,超过目标时 value 条会延伸过 target。
背景 视口
无质量带
3 段质量带
超过目标
<script setup lang="ts">
import { CfBulletChart } from '@chufix-design/vue';
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 12px; max-width: 360px;">
<CfBulletChart label="无质量带" :value="65" :target="80" :max="100" />
<CfBulletChart
label="3 段质量带"
:value="65"
:target="80"
:max="100"
:bands="[{upTo: 40, tone: 'error'}, {upTo: 75, tone: 'warning'}, {upTo: 100, tone: 'success'}]"
/>
<CfBulletChart
label="超过目标"
:value="92"
:target="80"
:max="100"
:bands="[{upTo: 50, tone: 'error'}, {upTo: 80, tone: 'warning'}, {upTo: 100, tone: 'success'}]"
/>
</div>
</template> <script setup>
import { CfBulletChart } from '@chufix-design/vue';
</script>
<template>
<div style="display: flex; flex-direction: column; gap: 12px; max-width: 360px;">
<CfBulletChart label="无质量带" :value="65" :target="80" :max="100" />
<CfBulletChart
label="3 段质量带"
:value="65"
:target="80"
:max="100"
:bands="[{upTo: 40, tone: 'error'}, {upTo: 75, tone: 'warning'}, {upTo: 100, tone: 'success'}]"
/>
<CfBulletChart
label="超过目标"
:value="92"
:target="80"
:max="100"
:bands="[{upTo: 50, tone: 'error'}, {upTo: 80, tone: 'warning'}, {upTo: 100, tone: 'success'}]"
/>
</div>
</template> import { CfBulletChart } from '@chufix-design/react';
export default function Demo() {
return (
<>
<div style={{ display: "flex", flexDirection: "column", gap: 12, maxWidth: 360 }}>
<CfBulletChart label="无质量带" value={65} target={80} max={100} />
<CfBulletChart label="3 段质量带" value={65} target={80} max={100} bands={[{upTo: 40, tone: 'error'}, {upTo: 75, tone: 'warning'}, {upTo: 100, tone: 'success'}]} />
<CfBulletChart label="超过目标" value={92} target={80} max={100} bands={[{upTo: 50, tone: 'error'}, {upTo: 80, tone: 'warning'}, {upTo: 100, tone: 'success'}]} />
</div>
</>
);
} import { CfBulletChart } from '@chufix-design/react';
export default function Demo() {
return (
<>
<div style={{ display: "flex", flexDirection: "column", gap: 12, maxWidth: 360 }}>
<CfBulletChart label="无质量带" value={65} target={80} max={100} />
<CfBulletChart label="3 段质量带" value={65} target={80} max={100} bands={[{upTo: 40, tone: 'error'}, {upTo: 75, tone: 'warning'}, {upTo: 100, tone: 'success'}]} />
<CfBulletChart label="超过目标" value={92} target={80} max={100} bands={[{upTo: 50, tone: 'error'}, {upTo: 80, tone: 'warning'}, {upTo: 100, tone: 'success'}]} />
</div>
</>
);
} API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | number | — | 当前值 |
target | number | — | 目标值(垂直线) |
max | number | — | 最大值 |
bands | { upTo: number; tone?: 'error' | 'warning' | 'success' }[] | [] | 质量带;从左到右染色,配合 upTo 累计 |
label | string | — | 左侧标签 |
width | number | 480 | SVG 宽度 |
height | number | 32 | SVG 高度 |
ariaLabel | string | — | 透传给根 <svg> 的 aria-label |
Events
| Vue 事件 | React 回调 | 载荷类型 | 说明 |
|---|---|---|---|
click | onClick | BulletChartInteractionPayload | 点击 bullet 区域 |
item-enter | onItemEnter | BulletChartInteractionPayload | 鼠标进入 bullet 区域 |
item-leave | onItemLeave | BulletChartInteractionPayload | 鼠标离开 bullet 区域 |
类型
interface BulletChartInteractionPayload {
value: number;
target: number;
max: number;
nativeEvent?: PointerEvent | MouseEvent;
}
反馈与讨论
BulletChart 子弹图 的讨论