Google Chart loads extremely small when included in jQuery-based tabs
Asked Answered
C

5

11

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.

Clarethaclaretta answered 2/9, 2013 at 0:59 Comment(2)
sample code or jsfiddle ?Pemberton
Updated to include the API properly: jsfiddle.net/23Vju/4Clarethaclaretta
P
6

change chart options to set the width and height as you need

var options = {
          title: 'Company Performance'
          ,width:900
          ,height:500
        };
Pemberton answered 2/9, 2013 at 2:8 Comment(2)
So I looked at this and nearly responded, "I already tried that to no effect," but thought to give it another shot anyway. Apparently the first time I didn't apply this properly, because this resolved the issue entirely. I'm looking at it now and I'm comparing a chart with the problem against one without it, and it looks like this took care of it. I'm almost angry at myself, but thank you.Clarethaclaretta
Even doing that, you will still probably see rendering errors in some browsers. See my answer.Rid
R
9

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
});
Rid answered 2/9, 2013 at 4:6 Comment(1)
I had this problem while rendering the charts inside a Backbone.js CollectionView. The suggested answer (setting the height and width in the options) caused the charts to be the right size, but the labels still rendered incorrectly (using Chrome, they were jammed together even though the chart had plenty of room). This answer gave me the direction I needed to render the chart after the collection item was fully rendered on the page.Tullis
P
6

change chart options to set the width and height as you need

var options = {
          title: 'Company Performance'
          ,width:900
          ,height:500
        };
Pemberton answered 2/9, 2013 at 2:8 Comment(2)
So I looked at this and nearly responded, "I already tried that to no effect," but thought to give it another shot anyway. Apparently the first time I didn't apply this properly, because this resolved the issue entirely. I'm looking at it now and I'm comparing a chart with the problem against one without it, and it looks like this took care of it. I'm almost angry at myself, but thank you.Clarethaclaretta
Even doing that, you will still probably see rendering errors in some browsers. See my answer.Rid
U
0

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.

Uniparous answered 18/8, 2015 at 19:33 Comment(0)
S
0

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.

Scharaga answered 8/12, 2017 at 19:33 Comment(0)
F
0

I solved this by, leaving off the bootstrap class in the element holding the chart, and then after chart had been loaded, then apply the bootstrap class.

For example lets say we want to setup a collapsible with the chart in it:

    <a href="#div-id" data-toggle="collapse">
        Expand
    </a>
    <div id="div-id" class="future-collapse">
       <div id="some-chart"></div>
    </div>

And then in your script:

/**
 *  Callback function E.G. google.charts.setOnLoadCallback(drawChart);
 */
function drawChart(){
   // Drawing the charts
   draw_some_chart();
   // Applying the collapse class to our elements with the future-collapse class
   $('.future-collapse').attr('class', 'collapse');
}

function draw_some_chart(){
    // Draw your charts
}
Frobisher answered 23/7, 2019 at 21:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.