
本文介绍如何利用 chart.js 实现带“目标缺口”可视化效果的堆叠柱状图:底部显示当前实际值(蓝色),顶部叠加红色柱体表示距目标值60的差额;若已达或超过目标,则红色部分高度为0。
本文介绍如何利用 chart.js 实现带“目标缺口”可视化效果的堆叠柱状图:底部显示当前实际值(蓝色),顶部叠加红色柱体表示距目标值60的差额;若已达或超过目标,则红色部分高度为0。
在 Chart.js 中,原生不支持直接绘制“目标线+缺口填充”的混合逻辑,但可通过数据预处理实现等效效果——关键在于将单一系列拆分为两个堆叠子系列:基础值(当前完成量) 和 缺口值(60 − 当前值,若为负则取0)。
以下是一个完整、可运行的实现方案:
<div style="width: 500px; height: 300px;">
<canvas id="mychart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script><script>
(function() {
const ctx = document.getElementById("mychart").getContext('2d');
// 原始业务数据(如各状态下的完成数量)
const rawValues = [10, 5, 80]; // Passed, Failed, In Progress
const target = 60;
// 计算堆叠所需两组数据:
// - dataset1: 当前值(蓝色,上限截断至 target,避免红蓝重叠溢出)
// - dataset2: 缺口值(红色,仅当 < target 时为正数)
const currentData = rawValues.map(val => Math.min(val, target));
const gapData = rawValues.map(val => (val >= target ? 0 : target - val));
const chartData = {
labels: ['Passed', 'Failed', 'In Progress'],
datasets: [
{
label: 'Current Progress',
data: currentData,
backgroundColor: 'rgba(54, 162, 235, 0.8)', // 蓝色
stack: 'progress'
},
{
label: 'Remaining to Target (60)',
data: gapData,
backgroundColor: 'rgba(255, 99, 132, 0.9)', // 红色
stack: 'progress'
}
]
};
new Chart(ctx, {
type: 'bar',
data: chartData,
options: {
responsive: true,
scales: {
y: {
beginAtZero: true,
max: 70, // 留出顶部空间,便于观察红色缺口
ticks: {
stepSize: 10
}
},
x: {
grid: {
offset: true
}
}
},
plugins: {
legend: {
position: 'top',
},
tooltip: {
callbacks: {
label: function(context) {
const label = context.dataset.label || '';
const value = context.parsed.y;
return `${label}: ${value}`;
}
}
}
}
}
});
})();
</script>
✅ 核心要点说明:
- 使用
stack: 'progress'启用堆叠模式,确保蓝+红柱自然叠加; -
currentData对原始值做Math.min(val, target)处理,防止超目标值导致红色部分反向显示; -
gapData严格按val ≥ 60 ? 0 : 60 − val计算,保证缺口逻辑准确; - 推荐设置
y.max > target(如70),使红色缺口清晰可见; - 若需突出目标线,可配合
plugins.annotation添加水平参考线(需额外引入chartjs-plugin-annotation)。
⚠️ 注意事项:
- 不要省略
stack属性,否则将变为并列柱而非堆叠; - 颜色建议使用带透明度的
rgba(),提升视觉层次; - 数据更新时需重新计算
currentData和gapData,不可复用原始数组。
通过该方法,你不仅能精准表达“已完成 vs 待完成”的对比关系,还能保持图表语义清晰、交互友好,适用于 KPI 追踪、测试覆盖率、任务进度等典型业务场景。











