Google 当数据 Table 是全局数据时图表不工作

Google Charts not Working When Data Table is Global

我正在为我的网站开发一个小型 HTML 应用程序,它可以进行一些模拟并将其绘制成图表(使用 Google 图表)。所有数据都将源自页面上的 JavaScript 代码(即我不是要从数据库或类似的东西中提取数据)。出于这个原因,我想从其他函数访问数据 table,以便在新模拟 运行.

时更新数据

我 运行 正在关注的是,如果我在 drawChart() 函数内部构建数据 table(和数据视图),一切正常。请参阅 this jsfiddle 或以下代码:

//Google charts stuff
google.charts.load('current', { 'packages': ['line', 'corechart'] });
google.charts.setOnLoadCallback(drawChart);

function drawChart() {
            var forceChartDiv = document.getElementById('force_chart_div');

            var sim_data = new google.visualization.DataTable();
            sim_data.addColumn('number', 'Elapsed Time (sec)');
            sim_data.addColumn('number', "Total Force");
            sim_data.addColumn('number', "M1 Force(Each)");

            sim_data.addRows([
                [0.0, -.5, 5.7],
                [0.1, .4, 8.7],
                [0.2, .5, 12]
            ]);

            var forceDataView = new google.visualization.DataView(sim_data);
            forceDataView.setColumns([0, 1, 2]);

            var forceChartOptions = {
                chart: {title: 'Simulation Results: Force'},
                width: 900,
                height: 500,
                series: {
                    // Gives each series an axis name that matches the Y-axis below.
                    0: { axis: 'Total' },
                    1: { axis: 'Individual' }
                },
                axes: {
                    // Adds labels to each axis; they don't have to match the axis names.
                    y: {
                        Total: { label: 'Total Force (Newtons)'},
                        Individual: { label: 'Per-Motor Force (Newtons)'}
                    }
                }
            };

            var forceChart = new google.charts.Line(forceChartDiv);   
            forceChart.draw(forceDataView, google.charts.Line.convertOptions(forceChartOptions));
        }

但是如果我将创建数据 table 和数据视图的代码移到函数范围之外,它就不起作用了。请参阅 this jsfiddle 或以下代码:

var sim_data;
var forceDataView;

//Google charts stuff
google.charts.load('current', { 'packages': ['line', 'corechart'] });

sim_data = new google.visualization.DataTable();
sim_data.addColumn('number', 'Elapsed Time (sec)');
sim_data.addColumn('number', "Total Force");
sim_data.addColumn('number', "M1 Force(Each)");

sim_data.addRows([
                [0.0, -0.5, 5.7],
                [0.1, 0.4, 8.7],
                [0.2, 0.5, 12]
                    ]);

forceDataView = new google.visualization.DataView(sim_data);
forceDataView.setColumns([0, 1, 2]);

google.charts.setOnLoadCallback(drawChart);

function drawChart() {
            var forceChartDiv = document.getElementById('force_chart_div');

            var forceChartOptions = {
                chart: {title: 'Simulation Results: Force'},
                width: 900,
                height: 500,
                series: {
                    // Gives each series an axis name that matches the Y-axis below.
                    0: { axis: 'Total' },
                    1: { axis: 'Individual' }
                },
                axes: {
                    // Adds labels to each axis; they don't have to match the axis names.
                    y: {
                        Total: { label: 'Total Force (Newtons)'},
                        Individual: { label: 'Per-Motor Force (Newtons)'}
                    }
                }
            };

            var forceChart = new google.charts.Line(forceChartDiv);   
            forceChart.draw(forceDataView, google.charts.Line.convertOptions(forceChartOptions));
        }

这两个示例都使用以下 HTML:

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<div id="force_chart_div"></div>

我觉得可能跟回调函数的执行顺序有关系。但是将它放在代码中的不同位置似乎并没有改变任何东西。在我的完整项目中,我什至添加了一个调用 drawChart() 函数的按钮只是为了检查,但这也没有帮助。

根据调用回调函数的位置,我会收到红色 "Data Table is not Defined" 警报,显示图表在网页上的位置。这几乎告诉了我我已经怀疑的事情,但我不知道如何解决。任何帮助,将不胜感激。顺便说一句,我是一个 JS 菜鸟,所以对我放轻松。

你的直觉是正确的,你必须等待回调完成,
在使用 google.visualizationgoogle.charts 命名空间之前。

它与时间有关,而不是代码的放置。

我们可以使用加载语句 returns 的承诺,而不是使用回调语句。

如以下代码片段所示...

var sim_data;
var forceDataView;

//Google charts stuff
google.charts.load('current', {
    packages: ['line', 'corechart']
}).then(function () {
    sim_data = new google.visualization.DataTable();
    sim_data.addColumn('number', 'Elapsed Time (sec)');
    sim_data.addColumn('number', "Total Force");
    sim_data.addColumn('number', "M1 Force(Each)");

    sim_data.addRows([
                    [0.0, -0.5, 5.7],
                    [0.1, 0.4, 8.7],
                    [0.2, 0.5, 12]
                        ]);

    forceDataView = new google.visualization.DataView(sim_data);
    forceDataView.setColumns([0, 1, 2]);
});

function drawChart() {
    var forceChartDiv = document.getElementById('force_chart_div');

    var forceChartOptions = {
        chart: {title: 'Simulation Results: Force'},
        width: 900,
        height: 500,
        series: {
            // Gives each series an axis name that matches the Y-axis below.
            0: { axis: 'Total' },
            1: { axis: 'Individual' }
        },
        axes: {
            // Adds labels to each axis; they don't have to match the axis names.
            y: {
                Total: { label: 'Total Force (Newtons)'},
                Individual: { label: 'Per-Motor Force (Newtons)'}
            }
        }
    };

    var forceChart = new google.charts.Line(forceChartDiv);   
    forceChart.draw(forceDataView, google.charts.Line.convertOptions(forceChartOptions));
}