如何在Chart.js堆叠柱状图中同时显示数据标签与总和
解决Chart.js堆叠柱状图同时显示单个数据标签与总和的问题
没问题,我来帮你搞定这个需求!你已经有了计算总和的totalizer插件,只需要调整chartjs-plugin-datalabels的配置,就能让单个数据标签和总和同时显示出来。核心思路是区分普通数据集和顶层数据集的标签显示逻辑:普通数据集显示单个数值,顶层数据集既显示自身数值,又显示该堆叠柱子的总和(或者把总和放在柱子顶部)。
修改后的完整代码
<script> const totalizer = { id: 'totalizer', beforeUpdate: chart => { let totals = {} let utmost = 0 chart.data.datasets.forEach((dataset, datasetIndex) => { if (chart.isDatasetVisible(datasetIndex)) { utmost = datasetIndex dataset.data.forEach((value, index) => { totals[index] = (totals[index] || 0) + value }) } }) chart.$totalizer = { totals: totals, utmost: utmost } } } new Chart('chart', { type: 'bar', data: { labels: ["Note par thème du répondant", "Note par thème sectorielle", "Note par thème générale"], datasets: [{ label: 'Thème 1', data: [12, 19, 3], backgroundColor: 'rgba(255, 206, 86)' }, { label: 'Thème 2', data: [3,8,1], backgroundColor: 'rgba(54, 162, 235)' }, { label: 'Thème 3', data: [ 5, 2, 3], backgroundColor: 'rgba(255, 255, 132)' },{ label: 'Thème 4', data: [ 5, 2, 3], backgroundColor: 'rgba(255, 99, 255)' },{ label: 'Thème 5', data: [ 5, 2, 3], backgroundColor: 'rgba(100, 250, 132)' },{ label: 'Thème 6', data: [ 5, 2, 3], backgroundColor: 'rgba(89, 99, 132)' },{ label: 'Thème 7', data: [ 5, 2, 3], backgroundColor: 'rgba(255, 0, 132)' },{ label: 'Thème 8', data: [ 5, 2, 3], backgroundColor: 'rgba(0, 150, 255)' },{ label: 'Thème 9', data: [ 5, 2, 3], backgroundColor: 'rgba(100, 100, 100)' },{ label: 'Thème 10', data: [ 10, 4, 7], backgroundColor: 'rgba(255, 255, 0)' }] }, options: { title :{ display :true, text : "Mon titre" }, scales: { yAxes: [{ stacked: true, ticks: { beginAtZero: true, suggestedMax: 100 } }], xAxes: [{ stacked: true }] }, plugins: { datalabels: { // 自定义格式化函数:区分普通数据集和顶层数据集 formatter: (value, ctx) => { const total = ctx.chart.$totalizer.totals[ctx.dataIndex]; // 如果是顶层数据集,返回单个值 + 总和(用换行区分) if (ctx.datasetIndex === ctx.chart.$totalizer.utmost) { return `${value}\nTotal: ${total.toLocaleString('fr-FR')}`; } // 普通数据集只返回单个值 return value; }, // 控制标签位置:普通数据集居中,顶层数据集靠上显示总和 align: (ctx) => { return ctx.datasetIndex === ctx.chart.$totalizer.utmost ? 'end' : 'center'; }, anchor: (ctx) => { return ctx.datasetIndex === ctx.chart.$totalizer.utmost ? 'end' : 'center'; }, // 所有可见数据集都显示标签 display: (ctx) => { return chart.isDatasetVisible(ctx.datasetIndex); }, // 可选:调整标签样式,让总和更突出 color: (ctx) => { return ctx.datasetIndex === ctx.chart.$totalizer.utmost ? '#000' : '#fff'; } } } }, plugins: [totalizer] }); </script>
关键修改说明
格式化函数区分逻辑:
- 当当前数据集是顶层(
ctx.datasetIndex === ctx.chart.$totalizer.utmost)时,返回单个数值加上总和(用换行\n分隔,让总和在单独一行) - 普通数据集只返回自身的数值
- 当当前数据集是顶层(
标签显示与位置调整:
- 修改
display配置,让所有可见的数据集都显示标签,而不是只显示顶层 - 通过
align和anchor动态调整标签位置:普通数据集的标签居中显示在柱子内部,顶层数据集的标签靠上(柱子顶部)显示,方便区分单个值和总和 - 可选:通过
color配置让顶层标签的颜色更突出(比如黑色,普通标签用白色)
- 修改
保留原有totalizer插件:
- 你的
totalizer插件逻辑完全不需要改动,它依然负责计算每个堆叠柱子的总和,供datalabels插件调用
- 你的
这样修改后,你的堆叠柱状图就能同时显示每个分块的单个数据标签,以及每个柱子顶部的总和啦!
内容的提问来源于stack exchange,提问作者B. Chaudron
相关产品推荐
相关产品推荐

