简体   繁体   中英

Drawing multiple Google Charts on a single page?

Basically my JavaScript receives data like this: year = {month1, ...., month12} . Each month stores data for 3 graphs. month1 = {graph1_data,..., graph3_data}

I wish to draw charts for all of them using Google Charts. So that makes it 12 * 3 = 36 charts. I have written the following code logic. But it fails to work.

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);
    });
}  

It draws 3 charts for month12 . Now why does this happen? Does this mean I must call setOnLoadCallback 36 times? Isn't there any alternative way?

Edit It looks like once Google Chart API is loaded, the callbacks in all the setOnLoadCallback s is called once. Which probably explains why I get only one graph, since at the time of execution of the function, the loop would have stopped at month12 .

So I finally figured out what is going wrong here.

You are only registering a callback with the Google Charts API, not actually calling it in your for(month in year) loop. The callback is called (as you can guess) when relevant resources have finished loading and the Charts API can start drawing. Unfortunately your globally defined var month is now equal to month12 . This is the state after your for loop completes:

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

As you can imagine, now when the callbacks, they are each called only once, with month = year.month12 . Hence the three graphs, all with month12 data.

So how do you fix this? Here's how:

  1. Initialise three callbacks only once . No need to keep them anonymous.

     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 } 
  2. Iterate over all the months inside each callback, and create a new Chart instance for each month. Also draw it.

     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); } } 
  3. Profit?

You might also want to store each Chart instance in a array or dictionary style object. That way you can later make changes to your plots, instead of having to regenerate and replace them.


OLD ANSWER: This happens because you draw the chart for graph_1 in the same HTML element for each month. So the chart for graph_1[month2] overwrites the chart for graph_1[month1] . Since graph_1[month12] is the last data to be processed, you get the chart for month12 . Likewise occurs for graph_2 and graph_3 .

What you can try is appending a new svg or vml element to your HTML document every time the plotting callback is called. This can be done from within the callback itself. That way you get a new chart for every month for every graph.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM