如何将指定JSON数据渲染为含子分类的双柱Highcharts柱状图
解决Highcharts实现双主分类柱状图的问题
看起来你遇到的核心问题是原始数据结构和Highcharts的配置不匹配——你的JSON把每个子分类都作为独立系列,且所有系列的x轴只有一个National类别,所以图表会渲染出9个分散的柱子,而不是你想要的2个主分类组。
下面我会给出两种符合你需求的实现方案,你可以根据实际视觉偏好选择:
方案1:堆叠柱状图(2个主柱,每个主柱包含子分类堆叠)
这种方案会把同一主分类下的子分类数据堆叠成一个主柱,既能看到每个主分类的总计,也能清晰看到子分类的构成。
代码实现
// 你的原始数据 const rawData = [{ "name": "scategories 1-1", "color": "#1E4585", "data": [ { "y": 40, "total": 40, "data": "1", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 2-1", "color": "#600AB5", "data": [ { "y": 40, "total": 40, "data": "2", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 3-1", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 1-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 2-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 3-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 4-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 5-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 6-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }]; // 转换数据:将子分类按主分类分组,绑定到对应的x轴类别 const series = []; // 处理主分类1的3个子分类 rawData.slice(0, 3).forEach(item => { series.push({ name: item.name, color: item.color, data: [item.data[0].y, null], // 仅在第一个x轴点(主分类1)填充数据 stack: '主分类1' // 指定堆叠组 }); }); // 处理主分类2的6个子分类 rawData.slice(3).forEach(item => { series.push({ name: item.name, color: item.color, data: [null, item.data[0].y], // 仅在第二个x轴点(主分类2)填充数据 stack: '主分类2' }); }); // 初始化Highcharts图表 Highcharts.chart('container', { chart: { type: 'column' }, title: { text: '主分类堆叠柱状图' }, xAxis: { categories: ['主分类1', '主分类2'], title: { text: '主分类' } }, yAxis: { min: 0, title: { text: '数值' }, stackLabels: { enabled: true, style: { fontWeight: 'bold', color: 'gray' } } }, tooltip: { headerFormat: '<b>{point.x}</b><br/>', pointFormat: '{series.name}: {point.y}<br/>总计: {point.stackTotal}' }, plotOptions: { column: { stacking: 'normal', dataLabels: { enabled: true, color: 'white' } } }, series: series });
方案2:分组柱状图(每个主分类下排列子分类柱子)
如果你希望每个主分类下的子分类是并排显示的柱子,而不是堆叠,可以用这个方案:
代码实现
// 你的原始数据 const rawData = [{ "name": "scategories 1-1", "color": "#1E4585", "data": [ { "y": 40, "total": 40, "data": "1", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 2-1", "color": "#600AB5", "data": [ { "y": 40, "total": 40, "data": "2", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 3-1", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 1-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 2-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 3-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 4-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 5-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }, { "name": "scategories 6-2", "color": "#0DB9D0", "data": [ { "y": 20, "total": 20, "data": "3", "name": "National", "drilldown": "3", "next": "level2" } ] }]; // 转换数据结构 const series = []; // 主分类1的子系列 rawData.slice(0, 3).forEach(item => { series.push({ name: item.name, color: item.color, data: [item.data[0].y] }); }); // 主分类2的子系列 rawData.slice(3).forEach(item => { series.push({ name: item.name, color: item.color, data: [null, item.data[0].y] }); }); // 初始化图表 Highcharts.chart('container', { chart: { type: 'column' }, title: { text: '主分类分组柱状图' }, xAxis: { categories: ['主分类1', '主分类2'], title: { text: '主分类' } }, yAxis: { min: 0, title: { text: '数值' } }, tooltip: { headerFormat: '<b>{point.x}</b><br/>', pointFormat: '{series.name}: {point.y}' }, plotOptions: { column: { grouping: true, borderWidth: 0 } }, series: series });
关键说明
你的原始数据问题在于:每个子分类都是独立系列,且所有系列的x轴类别只有National,导致Highcharts渲染出9个单独的柱子。解决的核心是重新映射数据,将子分类和对应的主分类x轴类别绑定,同时通过stack配置(堆叠方案)或默认分组(分组方案)来实现你要的“2个主柱包含子分类”的效果。
内容的提问来源于stack exchange,提问作者riyan193
相关产品推荐
相关产品推荐

