随机出现:"TypeError: google.visualization.DataTable不是构造函数"

4
我正在网页上画几个图表,但是控制台随机出现以下错误:
TypeError: google.visualization.DataTable is not a constructor

我尝试只显示一个图表来缩小问题范围,但仍然经常出现错误消息并且没有绘制任何图表,约50%的时间。当没有出现错误时,图表会正确绘制。
我已阅读多个论坛和此文档,但我看不出哪里有问题。我的代码基本上与所提到的文档相同,除了我的函数在setOnLoadCallback之前声明,否则它们将变成undefined
以下是我(简化后)的一些代码:
MyPage.php:
<!DOCTYPE html>
<html>
  <head>
    // loading CSS
   </head>
     <body>
        <p>My page content...</p>
           <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
           <script src="https://www.gstatic.com/charts/loader.js"></script>
           <script src="/js/home.js" type="text/javascript"></script>
           // loading more scripts (moment.js, query.countdown.js, bootstrap.js...)
    </body>
</html>

在 home.js 中:
$(document).ready(function(){
  if (window.location.href == 'XXXXXController') {  

    // This chart draws a dual axis chart showing revenues and expenses
    function drawRevenuesExpenses() {
        var jsonData = $.ajax({
            type: "POST",
            url: "/draw_dual_lineChart",
            data: "someParameters",
            dataType:"json"
            }).done(function (jsonData) {          
                // Create our data table out of JSON data loaded from server.
                var data_chart = new google.visualization.DataTable(jsonData[0]['data']);
                // Set chart's options
                var options = jsonData[1]['options'];
                // Instantiate and draw the chart
                var chart = new google.visualization.LineChart(document.getElementById('dual_chart_revenues_expenses')); 
                chart.draw(data_chart, options);
            });
    }

    // This chart draws the resort's affluence (number of tourists per day)
    function drawAffluence() {
        var jsonData = $.ajax({
            type: "POST",
            url: "/draw_single_lineChart",
            data: "someParameters",
            dataType:"json"
            }).done(function (jsonData) {          
                // Create our data table out of JSON data loaded from server.
                var data_chart = new google.visualization.DataTable(jsonData[0]['data']);
                // Set chart's options
                var options = jsonData[1]['options'];
                // Instantiate and draw the chart
                var chart = new google.visualization.LineChart(document.getElementById('single_chart_affluence')); 
                chart.draw(data_chart, options);
            });
    }

    google.charts.load('current', {'packages':['corechart']});
    google.charts.setOnLoadCallback(drawRevenuesExpenses);
    //google.charts.setOnLoadCallback(drawAffluence);
  }
}
2个回答

5
文档已经相当陈旧了...
不建议使用多个setOnLoadCallback语句。
实际上,您可以直接将回调放在加载语句中。
您可以依赖回调来知道页面何时准备好了,无需使用$(document).ready。
尝试按照以下设置,在任何其他内容之前加载谷歌...
google.charts.load('current', {
  callback: drawCharts,
  packages: ['corechart']
});

function drawCharts() {
  if (window.location.href == 'XXXXXController') {
      $.ajax({
          type: "POST",
          url: "/draw_dual_lineChart",
          data: "someParameters",
          dataType:"json"
      }).done(function (jsonData) {
          // Create our data table out of JSON data loaded from server.
          var data_chart = new google.visualization.DataTable(jsonData[0]['data']);
          // Set chart's options
          var options = jsonData[1]['options'];
          // Instantiate and draw the chart
          var chart = new google.visualization.LineChart(document.getElementById('dual_chart_revenues_expenses'));
          chart.draw(data_chart, options);
      });

      $.ajax({
          type: "POST",
          url: "/draw_single_lineChart",
          data: "someParameters",
          dataType:"json"
      }).done(function (jsonData) {
          // Create our data table out of JSON data loaded from server.
          var data_chart = new google.visualization.DataTable(jsonData[0]['data']);
          // Set chart's options
          var options = jsonData[1]['options'];
          // Instantiate and draw the chart
          var chart = new google.visualization.LineChart(document.getElementById('single_chart_affluence'));
          chart.draw(data_chart, options);
      });
    }
  }
}

我按照你的建议重构了代码:将其移出了 $(document).ready,删除了所有的 setOnLoadCallback 并直接在 load 语句中加载 drawCharts,但是我仍然遇到了同样的问题。有两件事需要提一下:我需要在 drawCharts 函数之后放置 load 语句,否则它会变成未定义;而且简单的 F5 刷新总是触发错误。当我刷新缓存(在 Firefox 中按 CTRL+R)时,图表就能正常显示。我怀疑是加载文件/模块时出了问题... - remyremy
这已经在页面底部了,还有一些其他的<script>。我猜如果我在它们之间加载一些其他文件也没关系?或者Google的文件必须是最后一个加载的吗?我已经编辑了我的问题并附上了页面布局。 - remyremy
奇怪...现在只有在Firefox的Firebug控制台打开时才能重现这个问题...当Firebug关闭或在另一个浏览器(Chrome,IE11)中时,它可以正常工作。无论如何,感谢您的帮助,我的代码看起来更加清晰了。 - remyremy
如果你在一个脚本中引用了一个函数,但是这个函数直到后面的脚本才被定义,那么它还没有被定义。 - dlaliberte

3

除了需要在使用之前加载表格图表外,WhiteHat的所有内容都是正确的。像这样:

    google.charts.load("current", {
        packages : [ "corechart","table" ]
    });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接