How can I draw two material charts with the Google Charts API without one being empty?

℡╲_俬逩灬. 提交于 2019-12-24 05:13:09

问题


I'm trying to draw two charts using the Google Charts API. I set up my HTML like this:

<div id="page_views" data-title="{{ report['page_views']['title'] }}" data-labels="{{ report['page_views']['labels'] }}" data-rows="{{ report['page_views']['rows'] }}"></div>
<div id="event_views" data-title="{{ report['event_views']['title'] }}" data-labels="{{ report['event_views']['labels'] }}" data-rows="{{ report['event_views']['rows'] }}"></div>

where the data attributes are filled during template rendering. I then use the following javascript to attempt to draw my charts:

google.load('visualization', '1.0', {packages: ['line']});
google.setOnLoadCallback(drawCharts);

function drawPageViews() {
    var data = new google.visualization.DataTable();
    var page_views = document.getElementById("page_views");
    var labels = eval(page_views.dataset.labels);
    data.addColumn('number', "Day");
    for(var i = 0; i < labels.length; i++) {
        data.addColumn('number', labels[i]);
    }

    var rows = eval(page_views.dataset.rows);
    data.addRows(rows);

    var options = {
        chart: {
            title: page_views.dataset.title
        },
        width: 900,
        height: 500
    };

    var chart = new google.charts.Line(document.getElementById('page_views'));
    chart.draw(data, options);
}

function drawEventViews() {
    var data = new google.visualization.DataTable();
    var event_views = document.getElementById("event_views");
    var labels = eval(event_views.dataset.labels);
    data.addColumn('number', "Day");
    for(var i = 0; i < labels.length; i++) {
        data.addColumn('number', labels[i]);
    }

    var rows = eval(event_views.dataset.rows);
    data.addRows(rows);

    var options = {
        chart: {
            title: event_views.dataset.title
        },
        width: 900,
        height: 500
    };

    var chart = new google.charts.Line(document.getElementById('event_views'));
    chart.draw(data, options);
}

function drawCharts() {
    drawPageViews();
    drawEventViews();
}

The result that I get is that one of the charts is drawn while the other contains an SVG with an empty tag and nothing else inside. Which chart gets drawn is random. Commenting out either draw function makes the other single chart draw as expected.

It seems like there must be some sort of shared global state or variable but it looks to me like everything is defined in the different draw functions. When I look up similar questions people offer solutions which look very much like what I'm doing. What am I missing?


回答1:


It seems this behavior is related with draw function, in particular it occurs once multiple charts is rendered on the page.

According to the documentation:

The draw() method is asynchronous: that is, it returns immediately, but the instance that it returns might not be immediately available.

For rendering multiple charts on the page you could consider the following approach: render the next chart once the previous one is rendered, this is where ready event comes to the rescue.

Having said that the solution would be to replace:

function drawCharts() {
  drawPageViews();
  drawEventViews();
}

with

function drawCharts() {
    drawPageViews(function(){
       drawEventViews();
    });
}

where

function drawPageViews(chartReady) {
    //...
    var chart = new google.charts.Line(document.getElementById('page_views'));
    if (typeof chartReady !== 'undefined') google.visualization.events.addOneTimeListener(chart, 'ready', chartReady);
    chart.draw(data, options);
}

and

function drawEventViews(chartReady) {
    //...
    var chart = new google.charts.Line(document.getElementById('event_views'));
    if (typeof chartReady !== 'undefined') google.visualization.events.addOneTimeListener(chart, 'ready', chartReady);
    chart.draw(data, options);
}

Working example

google.load('visualization', '1.0', { packages: ['line'] });
google.setOnLoadCallback(drawCharts);

function drawPageViews(chartReady) {
    var data = new google.visualization.DataTable();
    var page_views = document.getElementById("page_views");
    var labels = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

    data.addColumn('string', 'Day');
    data.addColumn('number', 'PageViews');

   
    var rows = new Array();
    for (var i = 0; i < labels.length; i++) {
        rows.push([labels[i], getRandomInt(0, 100)]);
    }
    data.addRows(rows);


    var options = {
        chart: {
            title: 'Page views'
        },
        width: 900,
        height: 500
    };

    var chart = new google.charts.Line(document.getElementById('page_views'));
    if(typeof chartReady !== 'undefined') google.visualization.events.addOneTimeListener(chart, 'ready', chartReady);
    chart.draw(data, options);
}

function drawEventViews(chartReady) {
    var data = new google.visualization.DataTable();
    var event_views = document.getElementById("event_views");
   
    var labels = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];

    data.addColumn('string', 'Day');
    data.addColumn('number', 'EventViews');
    var rows = new Array();
    for (var i = 0; i < labels.length; i++) {
        rows.push([labels[i], getRandomInt(0, 100)]);
    }
    data.addRows(rows);

    var options = {
        chart: {
            title: 'Event views'
        },
        width: 900,
        height: 500
    };

    var chart = new google.charts.Line(document.getElementById('event_views'));
    if(typeof chartReady !== 'undefined') google.visualization.events.addOneTimeListener(chart, 'ready', chartReady);
    chart.draw(data, options);
}

function drawCharts() {
    drawPageViews(function(){
        drawEventViews();
    });
}


function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
<script type="text/javascript" src="https://www.google.com/jsapi"></script> 
<div id="page_views"></div>
<div id="event_views"></div>


来源:https://stackoverflow.com/questions/32998932/how-can-i-draw-two-material-charts-with-the-google-charts-api-without-one-being

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!