如何实现Highcharts堆叠柱状图:以系列最大值为柱高合并数据
Highcharts堆叠柱状图自定义实现:以类别最大值为柱高,合并小值显示
需求说明
要实现特殊的堆叠柱状图效果:每个类别下的柱子高度取该类别所有系列的最大值,而非默认的堆叠求和。举例:
- Arsenal的系列值为14和3,柱子高度保持14,将3合并显示在该柱内,Y轴最大值不超过各系列最大值
- Liverpool的系列值为6、8、1,柱子高度取最大值8,无需堆叠求和
此前尝试的示例仅单个类别(Manchester)生效,其他类别如Arsenal的低数值堆叠被隐藏,要求所有堆叠颜色都能正常显示。
解决方案
通过预处理数据结合Highcharts的stacking: 'normal'配置实现:
- 遍历每个类别,找出该类别下所有系列的最大值
- 对每个系列的数据进行调整:若当前值与已累加值之和超过类别最大值,则将当前值设为「最大值 - 已累加值」,确保柱子总高度等于最大值,同时所有系列的颜色都能在柱内展示
- 动态计算Y轴最大值为所有系列的最大值,避免Y轴高度冗余
代码示例
Highcharts.chart('container', { chart: { type: 'column' }, title: { text: '自定义堆叠柱状图(以类别最大值为柱高)' }, xAxis: { categories: ['Arsenal', 'Liverpool', 'Manchester'] }, yAxis: { min: 0, title: { text: '数值' }, // 动态计算Y轴最大值为所有数据点的最大值 max: function() { let maxVal = 0; this.series.forEach(series => { series.data.forEach(point => { if (point.y > maxVal) maxVal = point.y; }); }); return maxVal; } }, tooltip: { headerFormat: '<b>{point.x}</b><br/>', pointFormat: '{series.name}: {point.y}' }, plotOptions: { column: { stacking: 'normal' } }, series: (function() { // 原始数据集 const rawData = [ {name: '红牌', data: [14, 6, 2]}, {name: '黄牌', data: [3, 8, 10]}, {name: '点球', data: [0, 1, 0]} ]; const processedData = []; const categoryNum = rawData[0].data.length; // 逐个处理每个类别的数据 for (let i = 0; i < categoryNum; i++) { // 找出当前类别的最大值 let categoryMax = 0; rawData.forEach(series => { if (series.data[i] > categoryMax) categoryMax = series.data[i]; }); let accumulated = 0; rawData.forEach(series => { // 初始化处理后的系列 if (!processedData.some(s => s.name === series.name)) { processedData.push({name: series.name, data: []}); } const targetSeries = processedData.find(s => s.name === series.name); let currentVal = series.data[i]; // 调整当前值,确保累加后不超过类别最大值 if (accumulated + currentVal > categoryMax) { currentVal = categoryMax - accumulated; } targetSeries.data.push(currentVal); accumulated += currentVal; }); } return processedData; })() });
效果说明
处理后每个类别的柱子高度严格等于该类别下的最大值,所有系列的颜色都能在柱内正常显示,不会出现小数值被隐藏的情况;Y轴最大值自动适配所有数据中的最大值,保证图表展示紧凑合理。
内容的提问来源于stack exchange,提问作者Sahil Vig
相关产品推荐
相关产品推荐

