I am using Google's line chart almost exactly as the demo - only the data has changed - inside of this jQuery tab plugin with no modification. Maybe 50% of the time, the chart will load at 400x200 even though it has been specified to load at 700x250. The containing div will have the proper width and height, but the chart as rendered by the API will load inside of that at 400x200.
I suspect this is because the tabs aren't being displayed when the API tries to render. Because of that, it tries to render in something it considers null and therefore forces itself into the smallest default resolution.
My thought is that if the display of the chart can be delayed until the appropriate tab is clicked, it would resolve the problem. Sadly, I have no idea how to do that, and my research hasn't been fruitful. The closest I could find is this thread, but I didn't find any real answers there.
I'd appreciate any advice if you have any, and I'd be glad to follow up with more information if necessary.
change chart options to set the width and height as you need
var options = {
title: 'Company Performance'
,width:900
,height:500
};
Rendering charts in a hidden div (which is what the non-selected tabs of a tab UI most likely are) messes with the Visualization API's ability to detect dimensions, so you want to do one of two things: either render all charts before instantiating tabs, or (as you've caught on to) bind event listeners to draw the charts when a tab is first opened. Setting the height and width in the chart's options is insufficient to solve the problem in all browsers.
I scanned over the easytabs documentation, and it looks like you should be able to do something like this:
// draw chart(s) in your default open tab
// track which tabs you've drawn charts in
var chartsDrawn = {
tab1: true,
tab2: false,
tab3: false
// etc
};
$('#tab-container').bind('easytabs:after', function (e) {
if (e.tab == 'tab-2' && !chartsDrawn.tab2) {
// draw chart(s) in tab 2
chartsDrawn.tab2 = true;
}
else if (e.tab == 'tab-3' && !chartsDrawn.tab3) {
// draw chart(s) in tab 3
chartsDrawn.tab3 = true;
}
// etc
});
This is how I solved using angular-bootstrap https://angular-ui.github.io/bootstrap/
<div class="google-chart" google-chart chart="chartObject1" on-ready="displayGoogleCharts()"></div>
<tab heading="Past Week" select="googleChartSizeFix()">
googleChartSizeFix = function() {
$('svg').parent().css({ opacity:"0" });
$(window).resize();
};
displayGoogleCharts = function() {
$('svg').parent().css({ opacity:"1" });
};
Each time a Tab is selected (the function googleChartSizeFix is triggered) the Google Chart is set to transparent (opacity = 0, so it does not disappear by the use of hide(), but keeps its size since its content is transparent) followed by the window resize is triggered, this forces Google Chart to fit the div that contains it, by the use of width 100% and height 100%:
"options": {
"chartArea": {
"width":'100%',
"height":'100%'
}
}
and finally once the Google Chart is ready (after resize) the displayGoogleCharts function is triggered and the opacity of the google chart is reset to 1, so the content is visible once again.
I stumbled across this "feature" of Bootstrap tabs. When cut-and-pasting multiple tabs in my HTML, I accidentally left the <div class=" tab-pane active"> in the "active" state for all the tabs. The result was that the content for all the tabs displayed sequentially in the first tab, but went away as you switched tabs.
My solution to the hidden tabs is to define them as active and then remove the "active" class from the div after I call chart.draw.
<div class="tab-pane active" id="myid" role="tabpanel">
<script type="text/javascript">
// all the chart stuff
chart.draw(data, options);
$('#myid').removeClass('active');
</script>
</div>
I see that jQuery tabs also use the "active" class. Perhaps this trick will work there too.