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

如何在Chart.js堆叠柱状图的每个柱子顶部显示总和(同时保留柱内数据标签)

如何在Chart.js堆叠柱状图的每个柱子顶部显示总和(同时保留柱内数据标签)

当然可以实现这个需求啦!我们可以通过给Chart.js添加一个自定义插件,配合你已经在用的chartjs-plugin-datalabels,就能同时保留柱内的分段数据标签,还在每个堆叠柱的顶部显示总和数值。

下面是修改后的完整代码,我会在关键部分做说明:

<head>
    <title>ChartJS Stacked Bar Chart Example</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels"></script>
</head>

<body>
    <h1 style="color:green;">
        GeeksforGeeks
    </h1>
    
    <h3>Chart JS Stacked Chart </h3>
    
    <div>
        <canvas id="stackedChartID"></canvas>
    </div>

    <script>
        // 自定义插件:用于在堆叠柱顶部绘制总和
        const sumLabelPlugin = {
            id: 'sumLabel',
            afterDraw: (chart) => {
                const { ctx, data, scales } = chart;
                const xScale = scales.x;
                const yScale = scales.y;
                
                // 遍历每个x轴类别(每个柱子)
                data.labels.forEach((label, index) => {
                    // 计算当前柱子的所有分段数据总和
                    let total = 0;
                    data.datasets.forEach(dataset => {
                        total += dataset.data[index] || 0;
                    });
                    
                    // 获取柱子顶部的坐标位置,往上偏移10px避免贴太近
                    const xPos = xScale.getPixelForValue(index) + xScale.width / 2;
                    const yPos = yScale.getPixelForValue(total) - 10;
                    
                    // 绘制总和文本
                    ctx.save();
                    ctx.font = '12px Arial';
                    ctx.fillStyle = '#333';
                    ctx.textAlign = 'center';
                    ctx.fillText(total, xPos, yPos);
                    ctx.restore();
                });
            }
        };

        // Get the drawing context on the canvas
        var ctx = document.getElementById("stackedChartID").getContext('2d');
        var myChart = new Chart(ctx, {
            // 同时启用自定义插件和datalabels插件
            plugins: [ChartDataLabels, sumLabelPlugin],
            type: 'bar',
            data: {
                labels: ["bike", "car", "scooter", "truck", "auto", "Bus"],
                datasets: [{
                    label: 'worst',
                    backgroundColor: "blue",
                    data: [17, 16, 4, 11, 8, 9],
                    datalabels: {
                      align: "center",
                      anchor: "center",
                      font:{
                        size: "10px",
                      },
                      padding: "0px",
                      color: "#000",
                    },
                }, {
                    label: 'Okay',
                    backgroundColor: "green",
                    data: [14, 2, 10, 6, 12, 16],
                    datalabels: {
                      align: "center",
                      anchor: "center",
                      font:{
                        size: "10px",
                      },
                      padding: "0px",
                      color: "#000",
                    },
                }, {
                    label: 'bad',
                    backgroundColor: "red",
                    data: [2, 21, 13, 3, 24, 7],
                    datalabels: {
                      align: "center",
                      anchor: "center",
                      font:{
                        size: "10px",
                      },
                      padding: "0px",
                      color: "#000",
                    },
                }],
            },
            options: {
                plugins: {
                    title: {
                        display: true,
                        text: 'Stacked Bar chart for pollution status'
                    },
                    // 确保datalabels正常启用
                    datalabels: {
                        display: true
                    }
                },
                scales: {
                    x: {
                        stacked: true,
                    },
                    y: {
                        stacked: true
                    }
                }
            }
        });
    </script>
</body>

</html>

关键部分说明:

  1. 自定义sumLabelPlugin插件:

    • 用afterDraw钩子在图表绘制完成后计算总和:遍历每个x轴类别,把对应位置的所有数据集数值相加得到堆叠总和。
    • 通过Chart.js的scalesAPI获取精准坐标,让总和文本刚好显示在柱子正上方(往上偏移10px是为了避免和柱子顶部贴得太近,你可以根据视觉需求调整这个值)。
  2. 插件共存配置:

    • 在plugins数组中同时加入ChartDataLabels和自定义插件,确保两者都能正常工作。
    • 保留了你原本的datalabels分段配置,所以柱内的17、14、2这类标签会继续显示,和顶部的总和互不干扰。

这样修改后,你就能看到比如"Bike"柱子顶部显示33(17+14+2的总和),同时柱子里的分段标签也完整保留,完全符合你的需求~

备注:内容来源于stack exchange,提问作者HelloWorld1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 13:54:32