redraw google charts on hidden bootstrap tab pane

前端 未结 2 759
轮回少年
轮回少年 2021-02-10 02:55

I am using google scatter chart in my web app and it loads on document ready. I recently did some restructuring and trying to divide the page content in different bootstrap tabs

相关标签:
2条回答
  • 2021-02-10 03:08

    Drawing charts inside hidden divs (which is usually what tab interfaces are implemented as) breaks the dimension detection algorithms in the Visualization API, which is why the chart draws oddly when drawn in any tab other than the tab open at the start.

    You can load the API only once; subsequent calls to google.load for the Visualization API will be ignored, which is why your "shown.bs.tab" event handler does not do what you want.

    Since delaying the tab initialization until after the charts draw is not really a viable option with Bootstrap, I would suggest replacing this code:

    google.load("visualization", "1", {packages: ["corechart"]});
    
    $("a[href='#engagement-graph']").on('shown.bs.tab', function (e) {
        google.load('visualization', '1', {
            packages: ['corechart'],
            callback: drawChart
        });
    });
    

    with this:

    function init () {
        if (/* boolean expression teting if chart tab is open */) {
            drawChart();
        }
        else {
            $("a[href='#engagement-graph']").one('shown.bs.tab', drawChart);
        }
    }
    
    google.load("visualization", "1", {packages: ["corechart"], callback: init});
    

    This should draw the chart if its container tab is open, and create a one-time event handler that draws the chart the first time the tab is opened if the tab is not open.

    You need to put this code inside the setGraphData function to avoid a race condition with your data loading, and so the drawChart function will be in scope. Also, remove these lines:

    if (google) {
        drawChart()
    } else {
        google.setOnLoadCallback(drawChart)
    }
    

    The google object exists as soon as the script tag for the jsapi loads, which will be before this code is executed, so you will always trigger the drawChart function here. Having the google object available, however, does not mean that the Visualization API is loaded.

    0 讨论(0)
  • 2021-02-10 03:12

    Just incase other people are looking for a simpler solution.

    An alternative is to implement the following:

    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
        var ev = document.createEvent('Event');
        ev.initEvent('resize', true, true);
        window.dispatchEvent(ev);
      });
    

    This will cause the chart to re-draw as if the browser was resized.

    0 讨论(0)
提交回复
热议问题