如何在Chart.js堆叠柱状图顶部添加总计数值?
在Chart.js堆叠柱状图顶部添加总计数值的实现方案
我需要在Chart.js的堆叠柱状图顶部添加总计数值,目前已完成图表基础配置(代码如下),图表效果接近需求但缺少顶部总计。
当前图表配置代码:
const dailySalesConfig = { type: 'bar', data: dailySalesData, options: { plugins: { datalabels: { color: 'white', formatter: function(value, context) { return `$${value.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}M`; } }, legend: { position: 'bottom' } }, responsive: false, scales: { x: { stacked: true, grid: { display: false } }, y: { stacked: true, ticks: { display:false }, grid: { display:false } } } } };
目标效果:
当前效果:
实现方案
通过Chart.js自定义插件的afterDraw钩子,计算每组堆叠柱的数值总和,再将总计文本绘制到对应柱组的顶部中心位置,具体修改后的完整配置如下:
const dailySalesConfig = { type: 'bar', data: dailySalesData, options: { plugins: { datalabels: { color: 'white', formatter: function(value, context) { return `$${value.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}M`; } }, legend: { position: 'bottom' }, // 自定义总计文本配置 totalLabel: { color: '#333', formatter: (total) => `$${total.replace(/\B(?=(\d{3})+(?!\d))/g, ",")}M` } }, responsive: false, scales: { x: { stacked: true, grid: { display: false } }, y: { stacked: true, ticks: { display:false }, grid: { display:false } } } }, // 自定义插件:绘制顶部总计 plugins: [{ id: 'totalLabel', afterDraw: (chart) => { const { ctx, data, scales } = chart; const xScale = scales.x; const yScale = scales.y; // 遍历每个x轴分组,计算并绘制总计 data.labels.forEach((_, index) => { let total = 0; // 累加当前组所有数据集的数值 data.datasets.forEach(dataset => { total += dataset.data[index] || 0; }); // 定位文本坐标:柱组中心x,柱顶上方15px的y位置 const xPos = xScale.getPixelForValue(index) + xScale.width / data.labels.length / 2; const yPos = yScale.getPixelForValue(total) - 15; // 绘制格式化后的总计文本 ctx.save(); ctx.font = '14px Arial'; ctx.fillStyle = chart.options.plugins.totalLabel.color; ctx.textAlign = 'center'; ctx.fillText(chart.options.plugins.totalLabel.formatter(total.toString()), xPos, yPos); ctx.restore(); }); } }] };
关键说明
- 自定义插件通过
afterDraw钩子在图表绘制完成后执行,避免覆盖原有柱形绘制 - 遍历每个x轴分组,累加对应索引下所有数据集的数值得到总计
- 利用轴的
getPixelForValue方法精准定位文本位置,确保在柱组顶部中心 - 复用原有数值格式化逻辑,保持文本样式统一
内容的提问来源于stack exchange,提问作者Darth Scitus
相关产品推荐
相关产品推荐

