Google Charts调用addRows()后渲染空图表问题求助
问题分析与解决方案
你的问题核心出在异步操作的执行顺序错误上,导致绘制图表时数据还没准备好,所以图表显示为空。具体来说:
$.getJSON是异步请求,它会在后台默默获取数据,而主线程会继续执行后面的代码(包括chart.draw)- 你在
n还没被赋值(还是空数组)的时候就调用了n.forEach添加数据行,这一步根本没往chartData里加任何内容 - 最后绘制图表时,
chartData只有列定义,没有数据行,自然显示空图表
正确的实现思路
你必须把填充DataTable和绘制图表的逻辑,放到异步请求完成后的回调函数里,确保只有当数据完全处理好(包括过滤、去重、计算平均值)后,才触发图表相关操作。
修改后的完整代码
// 加载必要的Google Charts库 google.charts.load("visualization", "1", {'packages':["corechart"]}); google.charts.load('current', {'packages':['bar']}); function plot1() { var url = "你的本地JSON数据接口地址"; // 请补全你的实际接口地址 // 处理数据并绘制图表的回调函数 function addData(data) { var dataPoints = []; var n = []; // 从接口数据中提取原始站点和延误数据 for (var i = 0; i < data.length; i++) { for (var j = 0; j < data[i].delays.length; j++) { dataPoints.push({ x: data[i].delays[j].Station, y: data[i].delays[j].Arrival }); } } // 过滤掉"无信息"的无效数据 const invalidValues = ["no information"]; dataPoints = dataPoints.filter(item => !invalidValues.includes(item.y)); // 去重站点并计算平均延误时间 const stationMap = new Map(); dataPoints.forEach(({ x, y }) => { const [totalDelay, count] = stationMap.get(x) ?? [null, 0]; stationMap.set(x, [(totalDelay ?? 0) + parseInt(y), count + 1]); }); // 转换为最终需要的数组格式 n = [...stationMap].map(([station, stats]) => ({ x: station, y: stats[0] / stats[1] })); console.log(n); // 初始化DataTable并填充处理好的数据 var chartData = new google.visualization.DataTable(); chartData.addColumn('string', 'Station'); chartData.addColumn('number', 'Arrival'); n.forEach(row => { chartData.addRow([row.x, row.y]); }); // 图表配置项 var options = { width: 700, legend: { position: 'none' }, chart: { title: 'Verteilung der Verspätungen bei Ankunft (in Sekunden)'}, axes: { x: { 0: { side: 'top', label: 'Stationen'} // 顶部X轴 } }, bar: { groupWidth: "90%" } }; // 绘制图表 var chart = new google.charts.Bar(document.getElementById('plot1')); chart.draw(chartData, google.charts.Bar.convertOptions(options)); } // 发起异步请求,数据返回后执行处理逻辑 $.getJSON(url, addData); }; google.charts.setOnLoadCallback(plot1);
关键修改说明
- 调整代码时序:把
chartData初始化、数据填充、图表绘制全部移到addData函数内部,确保这些操作在数据处理完成后才执行 - 避免空数组遍历:现在
n是在数据处理完成后才生成的,遍历的时候已经有有效数据,不会再做无用功 - 异步逻辑闭环:所有依赖异步数据的操作都放在回调函数里,彻底解决时序问题
另外提个小建议:你的HTML里重复引入了两个版本的jQuery,建议只保留一个最新版本,避免潜在的冲突问题。
内容的提问来源于stack exchange,提问作者sppokky
相关产品推荐
相关产品推荐

