基于Highcharts与Angular实现动态柱状图,绑定对象数据可视化
问题描述
我有如下JSON响应数据:
{ "dates": [ "2023-05-01", "2023-05-02", "2023-05-03", "2023-05-04", "2023-05-05" ], "values": [ {}, {}, { "Apple": 454, "SIM-Free, Model A19211 6.5-inch Super": 191, "Samsung's new variant which goes beyond": 3 }, { "OPPO F19 is officially announced on April": 4980, "Huawei’s re-badged P30 Pro New Edition": 41424, "MacBook Pro 2021 with mini-LED display": 2535, "Basic Data": 293, "Samsung Galaxy Book S (2020)": 1181, "Style and speed. Stand out on HD video calls": 378 }, {} ] }
我需要实现柱状图:X轴显示所有日期,Y轴绑定对象数据(空对象对应日期显示0,非空对象的每个键值对对应一个数据系列)。当前编写的Angular代码无法正确绑定数据,请帮忙修正数据绑定逻辑:
public createChart(container, options, chartName = null) { const chartOptions = this.getOptions(); const chartData = []; options.forEach((data) => { const chartDataObject = { name: [], data: [], color: '', fillColor: {} }; chartDataObject.name = Object.keys(data.values) .filter((key) => Object.keys(data.values[key]).length !== 0) // Filter out empty objects .map((key) => key); // Extract the names chartDataObject.data = Object.values(data.values) .filter((value) => Object.keys(value).length !== 0) // Filter out empty objects .map((value) => (value ? Object.values(value)[0] : 0)); // Extract the names chartDataObject.color = data.color; chartDataObject.fillColor = { linearGradient: [0, 0, 0, 150], stops: [ [0, data.color], [1, Highcharts.color(data.color).setOpacity(0).get('rgba')] ] }; chartOptions.xAxis.categories = data.dates; console.log(chartDataObject); chartData.push(chartDataObject); }); chartOptions.series = chartData; const element = document.createElement('div'); container.appendChild(element); chartOptions.chart['renderTo'] = element; this.chart = new Highcharts.Chart(chartOptions); return this.chart; }
修正方案
原代码的核心问题是错误地按日期索引处理数据,没有按商品系列组织数据。正确逻辑是先收集所有商品名称,为每个商品生成独立系列,再遍历日期匹配对应数值(无数据则填0)。
修正后的完整代码:
public createChart(container, options, chartName = null) { const chartOptions = this.getOptions(); const chartData = []; options.forEach((data) => { const { dates, values } = data; // 收集所有唯一商品名称 const allProducts = new Set<string>(); values.forEach(item => { Object.keys(item).forEach(product => allProducts.add(product)); }); // 为每个商品生成系列数据 allProducts.forEach((productName, index) => { // 复用Highcharts内置颜色循环分配 const baseColor = Highcharts.getOptions().colors[index % Highcharts.getOptions().colors.length]; // 遍历每个日期,匹配当前商品的数值,无数据则填0 const seriesData = dates.map((_, dateIdx) => values[dateIdx][productName] || 0); chartData.push({ name: productName, data: seriesData, color: baseColor, fillColor: { linearGradient: [0, 0, 0, 150], stops: [ [0, baseColor], [1, Highcharts.color(baseColor).setOpacity(0).get('rgba')] ] } }); }); // X轴绑定所有日期 chartOptions.xAxis.categories = dates; }); chartOptions.series = chartData; const element = document.createElement('div'); container.appendChild(element); chartOptions.chart['renderTo'] = element; this.chart = new Highcharts.Chart(chartOptions); return this.chart; }
关键修正点
- 数据结构重组:从按日期整理改为按商品系列整理,每个商品对应一个独立系列,符合多系列柱状图的展示逻辑。
- 空值处理:遍历日期时,若当前日期无对应商品数据,直接填充0,保证每个系列的data数组长度与X轴日期数量一致。
- 颜色优化:利用Highcharts内置颜色循环分配系列颜色,无需手动指定。
- 逻辑简化:移除原代码中错误的过滤逻辑,保留所有日期和商品数据,确保图表完整性。
内容的提问来源于stack exchange,提问作者Lane T
相关产品推荐
相关产品推荐

