You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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();
            });
        }
    }]
};

关键说明

  1. 自定义插件通过afterDraw钩子在图表绘制完成后执行,避免覆盖原有柱形绘制
  2. 遍历每个x轴分组,累加对应索引下所有数据集的数值得到总计
  3. 利用轴的getPixelForValue方法精准定位文本位置,确保在柱组顶部中心
  4. 复用原有数值格式化逻辑,保持文本样式统一

内容的提问来源于stack exchange,提问作者Darth Scitus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:42:46