
在数据可视化中,展示一个值距离某个目标还有多远是一种常见的需求。传统的柱状图可能只显示当前值,但如果能同时在一个柱状图中直观地看到“已完成”和“还需完成”两部分,将大大提升图表的信息传达效率。本教程将详细介绍如何使用强大的 chart.js 库来实现这种带有目标完成度指示的堆叠柱状图。
我们的目标是创建一个堆叠柱状图,其中:
例如,假设我们的目标是 60。如果当前值是 40,图表应显示 40 的蓝色部分和 20 的红色部分。如果当前值是 60 或 70,则只显示 60 或 70 的蓝色部分,不显示红色部分。
在深入实现之前,我们先回顾一个基本的 Chart.js 柱状图结构。通常,我们需要一个 <canvas> 元素作为图表的容器,并通过 JavaScript 初始化 Chart 实例,传入数据和配置。
<div style="width: 500px;height: 300px"> <canvas id="mychart"></canvas> </div>
(function() {
const ctx = document.getElementById("mychart");
const datas = {
labels: ['通过', '失败', '进行中'],
datasets: [{
label: '数据',
data: [10, 5, 80],
backgroundColor: [
"green",
"red",
"yellow"
],
}, ]
};
const chr = new Chart(ctx, {
data: datas,
type: 'bar'
});
})();上述代码展示了一个简单的柱状图,但它并未实现我们所需的目标完成度可视化功能。
要实现目标完成度堆叠柱状图,关键在于数据预处理。我们需要在将数据传递给 Chart.js 之前,计算出每个数据点距离目标的剩余量,并将其作为一个独立的 dataset 添加到图表中。
假设我们的目标值是 60。对于原始数据集中的每个数据点 currentValue:
这个计算可以通过 Array.prototype.map() 方法高效完成。
const targetValue = 60; // 定义目标值
const originalData = datas.datasets[0].data; // 获取原始数据
const remainingData = originalData.map(currentValue => {
return currentValue >= targetValue ? 0 : targetValue - currentValue;
});计算出 remainingData 后,我们需要将其作为一个新的 dataset 添加到 datas.datasets 数组中。这个新的数据集将代表“距离目标量”的部分,并应使用一个醒目的颜色,例如红色。
datas.datasets.push({
label: '距离目标', // 新数据集的标签
backgroundColor: 'red', // 剩余量的颜色
data: remainingData // 剩余量数据
});Chart.js 在处理多个 type: 'bar' 的 dataset 时,默认会将其堆叠起来,除非显式设置 options.scales.x.stacked: false 或 options.scales.y.stacked: false。这正是我们想要的效果。
将上述逻辑整合到 Chart.js 的初始化代码中:
<!DOCTYPE html>
<html>
<head>
<title>Chart.js 目标完成度堆叠柱状图</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
body { font-family: sans-serif; margin: 0; padding: 20px; background-color: #f4f7f6; }
.chart-container {
width: 80%; /* 调整图表容器宽度 */
max-width: 800px; /* 最大宽度限制 */
height: 400px; /* 调整图表容器高度 */
margin: 20px auto;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
padding: 20px;
box-sizing: border-box;
}
h1 { text-align: center; color: #333; margin-bottom: 30px; }
</style>
</head>
<body>
<h1>Chart.js 目标完成度堆叠柱状图示例</h1>
<div class="chart-container">
<canvas id="mychart"></canvas>
</div>
<script>
(function() {
const ctx = document.getElementById("mychart");
const targetValue = 60; // 定义目标值
const datas = {
labels: ['任务A', '任务B', '任务C', '任务D', '任务E'],
datasets: [{
label: '当前进度',
data: [10, 65, 40, 60, 25], // 示例数据:任务B已超目标,任务D刚好达到目标
backgroundColor: [
"rgba(54, 162, 235, 0.8)", // 蓝色
"rgba(54, 162, 235, 0.8)",
"rgba(54, 162, 235, 0.8)",
"rgba(54, 162, 235, 0.8)",
"rgba(54, 162, 235, 0.8)"
],
}]
};
// 计算距离目标的剩余量
const remainingData = datas.datasets[0].data.map(currentValue => {
return currentValue >= targetValue ? 0 : targetValue - currentValue;
});
// 添加表示剩余量的新数据集
datas.datasets.push({
label: '距离目标',
backgroundColor: 'rgba(255, 99, 132, 0.8)', // 红色
data: remainingData
});
const chr = new Chart(ctx, {
data: datas,
type: 'bar',
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
title: {
display: true,
text: '任务进度与目标达成度',
font: {
size: 18,
weight: 'bold'
},
color: '#333'
},
legend: {
position: 'top',
labels: {
font: {
size: 14
}
}
},
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.dataset.label === '当前进度') {
label += context.raw;
} else { // 距离目标
if (context.raw > 0) {
label += context.raw;
} else {
label += '目标已达成';
}
}
return label;
}
}
}
},
scales: {
x: {
stacked: true, // 确保X轴堆叠
title: {
display: true,
text: '任务',
font: {
size: 16
},
color: '#555'
},
ticks: {
font: {
size: 12
}
}
},
y: {
stacked: true, // 确保Y轴堆叠
beginAtZero: true,
// 动态设置Y轴最大值,确保目标值可见且图表不过高
max: Math.max(targetValue, ...datas.datasets[0].data) + 10,
title: {
display: true,
text: '进度值',
font: {
size: 16
},
color: '#555'
},
ticks: {
font: {
size: 12
}以上就是使用 Chart.js 构建目标完成度堆叠柱状图的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号