ChartJS柱状图需求:Y轴固定100%,实现占比而非堆叠显示
Chart.js 非堆叠比例柱状图实现方案
问题说明
现有代码实现了堆叠柱状图,将Correct与Total堆叠显示,Y轴最大值设为100%。需求调整为:保持Y轴固定显示0-100%,每个Band的Correct数据以占对应Total的比例形式显示(如Band1正确占比80%,则对应Bar高度为80%),而非原有的堆叠显示逻辑。
解决方案
原代码的问题在于同时使用了Total数据集(固定100%)和堆叠配置,导致图表逻辑不符合需求。以下提供两种符合需求的实现方案:
方案一:仅显示Correct占比柱状图
直接移除Total数据集,仅展示每个Band的Correct占比,Y轴保持0-100%范围:
const data = [{"band_1_correct":"16","band_1_total":"20","band_2_correct":"15","band_2_total":"20","band_3_correct":"12","band_3_total":"20","band_4_correct":"15","band_4_total":"21","band_5_correct":"13","band_5_total":"19","band_6_correct":"0","band_6_total":"0"}]; var correctCounts = []; var difficultyLevels = []; var difficultyData = data[0]; // 遍历生成标签和Correct占比数据 for (var i = 1; i <= 6; i++) { var levelKey = 'band_' + i; difficultyLevels.push('Band ' + i); var correctCount = parseInt(difficultyData[levelKey + '_correct']); var totalCount = parseInt(difficultyData[levelKey + '_total']); if (totalCount === 0) { correctCounts.push(0); } else { var correctPercentage = (correctCount / totalCount) * 100; correctCounts.push(correctPercentage.toFixed(2)); } } // 初始化图表 var ctx = document.getElementById('barChart1').getContext('2d'); var barChart = new Chart(ctx, { type: 'bar', data: { labels: difficultyLevels, datasets: [ { label: 'Correct Percentage', data: correctCounts, backgroundColor: 'rgba(54, 162, 235, 0.7)', } ] }, options: { scales: { x: { beginAtZero: true }, y: { beginAtZero: true, max: 100, ticks: { callback: function(value) { return value + '%'; // Y轴刻度显示百分比符号 } } } }, plugins: { tooltip: { callbacks: { label: function (context) { var label = context.dataset.label || ''; var value = context.parsed.y || 0; return label + ': ' + value + '%'; } } } } } });
方案二:显示完整100%柱状图(Correct+Incorrect分块)
如果需要直观展示每个Band的完整占比构成(Correct和错误部分组成100%的Bar),可以计算错误占比,将两个数据集堆叠为一个完整的Bar:
const data = [{"band_1_correct":"16","band_1_total":"20","band_2_correct":"15","band_2_total":"20","band_3_correct":"12","band_3_total":"20","band_4_correct":"15","band_4_total":"21","band_5_correct":"13","band_5_total":"19","band_6_correct":"0","band_6_total":"0"}]; var correctCounts = []; var incorrectCounts = []; var difficultyLevels = []; var difficultyData = data[0]; // 遍历生成标签、Correct占比和错误占比数据 for (var i = 1; i <= 6; i++) { var levelKey = 'band_' + i; difficultyLevels.push('Band ' + i); var correctCount = parseInt(difficultyData[levelKey + '_correct']); var totalCount = parseInt(difficultyData[levelKey + '_total']); if (totalCount === 0) { correctCounts.push(0); incorrectCounts.push(0); } else { var correctPercentage = (correctCount / totalCount) * 100; var incorrectPercentage = 100 - correctPercentage; correctCounts.push(correctPercentage.toFixed(2)); incorrectCounts.push(incorrectPercentage.toFixed(2)); } } // 初始化图表 var ctx = document.getElementById('barChart1').getContext('2d'); var barChart = new Chart(ctx, { type: 'bar', data: { labels: difficultyLevels, datasets: [ { label: 'Correct', data: correctCounts, backgroundColor: 'rgba(54, 162, 235, 0.7)', stack: 'band' // 同一stack实现单Bar内部分块堆叠 }, { label: 'Incorrect', data: incorrectCounts, backgroundColor: 'rgba(255, 99, 132, 0.3)', stack: 'band' } ] }, options: { scales: { x: { beginAtZero: true }, y: { beginAtZero: true, max: 100, stacked: true, // 开启Y轴堆叠,保证单Bar总高度为100% ticks: { callback: function(value) { return value + '%'; } } } }, plugins: { tooltip: { callbacks: { label: function (context) { var label = context.dataset.label || ''; var value = context.parsed.y || 0; return label + ': ' + value + '%'; } } } } } });
原代码问题解析
原代码中设置stacked: false无效,是因为同时存在Correct和Total两个数据集,Total的数值固定为100,关闭堆叠后两个数据集的Bar会并排显示,而非实现“Correct占Total比例”的效果。通过移除冗余的Total数据集,或替换为错误占比数据集,即可实现需求。
内容的提问来源于stack exchange,提问作者Micho
相关产品推荐
相关产品推荐

