Google图表报错:Uncaught (in promise) Error: Column header row must be an array 求助
问题排查:Google图表报错「Column header row must be an array」
问题场景
从地区列表选择选项时,onchange事件触发showAgeDistributionGraph方法,调用后台接口获取数据后执行drawChart函数绘制图表,此时抛出错误:Uncaught (in promise) Error: Column header row must be an array。
代码现状
前端触发方法
showAgeDistributionGraph: function() { let e = document.getElementById("TxtAgeGroup"); let txtAgeGroup = e.options[e.selectedIndex].value; let url = 'backend/core/loadCasesByAgeGroup.php'; var jsonData = $.ajax({ url: url, data: { ds: txtAgeGroup }, dataType: 'json', }).done(function(jsonData) { google.charts.load('current', { packages: ['corechart'] }).then(function () { drawChart(jsonData);}) }); google.charts.load('current', { packages: ['corechart'] }).then(function () { drawChart(jsonData); }); }
图表绘制函数
function drawChart(jsonData){ var data = google.visualization.arrayToDataTable([ jsonData ], false); console.log(jsonData); var options = { title: '按年龄组统计病例', width: 900, height: 400, bar: {groupWidth: "80%"}, legend: { position: "bottom" }, }; var chart = new google.visualization.ColumnChart(document.getElementById('chartContainer')); chart.draw(data, options); }
后端PHP代码
// 统计图表逻辑 public function districtPopulationGraph($ds) { $sql = "call `new_CasesAgeDistributionChart`(?);"; $stmt = $this->connect()->prepare($sql); $stmt->execute([$ds]); if ($stmt->rowCount()>0) { $data[] = ["年龄","客户总数"]; while ($record = $stmt->fetch()) { // 更新统计数据 $data[] = ["GroupA",$record['16-17']]; $data[] = ["GroupB",$record['18-29']]; $data[] = ["GroupC",$record['30-49']]; $data[] = ["GroupD",$record['50-64']]; $data[] = ["GroupE",$record['65+']]; } $data_for_chart = json_encode($data, JSON_NUMERIC_CHECK); return $data_for_chart; } }
后端返回数据格式
[["年龄","客户总数"],["GroupA","24"],["GroupB","251"],["GroupC","576"],["GroupD","407"],["GroupE","659"]]
错误原因
- 数据嵌套错误:
drawChart函数中调用google.visualization.arrayToDataTable时,错误地将本身已是二维数组的jsonData再套一层数组,导致传入结构变为[[[表头],[数据行1],...]],图表无法识别最外层的嵌套,判定表头行非数组类型,触发报错。 - 冗余代码导致的时序问题:
showAgeDistributionGraph中done回调外的google.charts.load调用会在AJAX请求完成前执行,此时jsonData还未获取到有效数据,也会引发异常。
修复方案
1. 修正图表绘制函数的数据传入
直接将jsonData传给arrayToDataTable,移除多余的外层数组嵌套:
function drawChart(jsonData){ // 直接传入jsonData,无需额外嵌套数组 var data = google.visualization.arrayToDataTable(jsonData, false); console.log(jsonData); var options = { title: '按年龄组统计病例', width: 900, height: 400, bar: {groupWidth: "80%"}, legend: { position: "bottom" }, }; var chart = new google.visualization.ColumnChart(document.getElementById('chartContainer')); chart.draw(data, options); }
2. 清理前端触发方法的冗余代码
移除done回调外的google.charts.load调用,确保仅在AJAX获取到数据后再加载图表库并绘制:
showAgeDistributionGraph: function() { let e = document.getElementById("TxtAgeGroup"); let txtAgeGroup = e.options[e.selectedIndex].value; let url = 'backend/core/loadCasesByAgeGroup.php'; $.ajax({ url: url, data: { ds: txtAgeGroup }, dataType: 'json', }).done(function(jsonData) { // 仅在获取数据后加载图表库并绘制 google.charts.load('current', { packages: ['corechart'] }).then(function () { drawChart(jsonData); }); }); }
3. 可选:后端优化数值类型
当前返回的数值为字符串格式,可强制转为整数类型,避免图表渲染时的类型问题:
$data[] = ["GroupA", (int)$record['16-17']]; $data[] = ["GroupB", (int)$record['18-29']]; $data[] = ["GroupC", (int)$record['30-49']]; $data[] = ["GroupD", (int)$record['50-64']]; $data[] = ["GroupE", (int)$record['65+']];
内容的提问来源于stack exchange,提问作者user3448324
相关产品推荐
相关产品推荐

