首页 文章

在一个页面上绘制多个Google Charts?

提问于
浏览
0

基本上我的JavaScript接收这样的数据: year = {month1, ...., month12} . 每个月存储3个图表的数据 . month1 = {graph1_data,..., graph3_data}

我希望使用Google Charts为所有人绘制图表 . 这样就可以得到12 * 3 = 36个图表 . 我编写了以下代码逻辑 . 但它无法奏效 .

for ( month in year )
{
    google.charts.setOnLoadCallback(function(){
           // draw graph1
            var data = new google.visualization.DataTable();
            // code
            // code
            // data.addColumn()
            // data.addColumn()
            data.addRows(data_table);
            var options = {title: month, height:100};
            var chart = new google.visualization.ColumnChart(
    document.querySelector('#'+month+' .graph1'));
            chart.draw(data, options);
    });

    google.charts.setOnLoadCallback(function(){
           // draw graph2
            google.charts.setOnLoadCallback(function(){

            var data = new google.visualization.DataTable();
            // code
            // code
            // data.addColumn()
            // data.addColumn()
            data.addRows(data_table);
            var options = {title: month, height:100};
            var chart = new google.visualization.ColumnChart(
    document.querySelector('#'+month+' .graph2'));
            chart.draw(data, options);
    });

    google.charts.setOnLoadCallback(function(){
           // draw graph3
           google.charts.setOnLoadCallback(function(){

            var data = new google.visualization.DataTable();
            // code
            // code
            // data.addColumn()
            // data.addColumn()
            data.addRows(data_table);
            var options = {title: month, height:100};
            var chart = new google.visualization.ColumnChart(
    document.querySelector('#'+month+' .graph3));
            chart.draw(data, options);
    });
}

它为 month12 绘制了3个图表 . 现在为什么会这样?这是否意味着我必须拨打 setOnLoadCallback 36次?有没有其他替代方式?

Edit 看起来加载Google Chart API后,所有 setOnLoadCallback 中的回调都会被调用一次 . 这可能解释了为什么我只得到一个图,因为在执行该函数时,循环将停止在 month12 .

1 回答

  • 0

    所以我终于弄清楚这里出了什么问题 .

    您只是使用Google Charts API注册回调,而不是在 for(month in year) 循环中实际调用它 . 当相关资源加载完毕并且Charts API可以开始绘制时,调用回调(正如您所猜测的那样) . 不幸的是,全局定义的var month 现在等于 month12 . 这是for循环完成后的状态:

    month = year.month12;
    callback_for_graph_1 = <anonymous function 1>
    callback_for_graph_2 = <anonymous function 2>
    callback_for_graph_3 = <anonymous function 3>
    

    可以想象,现在当回调时,它们每次只被调用一次,使用 month = year.month12 . 因此这三个图都是 month12 数据 .

    那你怎么解决这个问题呢?这是如何做:

    • 仅初始化三个回调 once . 不需要匿名 .
    google.charts.setOnLoadCallback(callbackForGraph1);
    google.charts.setOnLoadCallback(callbackForGraph2);
    google.charts.setOnLoadCallback(callbackForGraph3);
    
    function callbackForGraph1 {
    // do your thing
    }
    function callbackForGraph2 {
    // do your thing
    }
    function callbackForGraph3 {
    // do your thing
    }
    
    • 迭代每个回调中的所有月份,并为每个月创建一个新的 Chart 实例 . 也画它 .
    function callbackForGraph1() {
      for(month in year) {
        // draw graph1
        var data = new google.visualization.DataTable();
        // code
        // code
        // data.addColumn()
        // data.addColumn()
        data.addRows(data_table);
        var options = {title: month, height:100};
        // this is your Chart instance ->
        var chart = new google.visualization.ColumnChart(document.querySelector('#'+month+' .graph1'));
        // draw it!
        chart.draw(data, options);
      }
    }
    
    • 利润?

    您可能还希望将每个 Chart 实例存储在数组或字典样式对象中 . 这样您以后可以更改您的图,而不必重新生成和替换它们 .


    OLD ANSWER: 这是因为您在每个月的同一HTML元素中绘制 graph_1 的图表 . 因此 graph_1[month2] 的图表会覆盖 graph_1[month1] 的图表 . 由于 graph_1[month12] 是要处理的最后一个数据,因此您将获得 month12 的图表 . 同样适用于 graph_2graph_3 .

    每次调用绘图回调时,您可以尝试将新的 svgvml 元素附加到HTML document . 这可以在回调本身内完成 . 这样,您每个月都可以获得每个图表的新图表 .

相关问题