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
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.
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.