Chaps I have an interesting and odd problem. Today I had the brilliant(??) idea of using google
chart
for a site I am building. It is all nice and dandy till I placed the graph inside a hidden container,
planning to add some jquery and slide the graph down when somebody clicks a link. The functionality works,
in that the graph does actually slide down but the size of it shrunk to almost half of it. Feeling completely lost after having tried to increase the width of a few of the container created by the google script, I had a
look online and found something that perhaps explains what the problem is:
http://stackoverflow.com/questions/8577366/using-hide-and-show-with-google-visualization/8600892#8600892
In essence, when the graph is places in a hidden container, it doesn't work(!!). Now they do provide some
sort of fix, but I have failed to implement it (they say to use the call the function that draws the graph as
a callback function to the one that unhides the element, if I have understood correctly.)

Here is some html code and css to describe the issue (but you can see the problem online here if you click on 'pulse' and compare the size of that graph to the one under exercise which at the moment for demonstration purposes resides in a block container - no hiding occurs).
This is the html exerpt where you have the empty divs that the google script populates with the graphs:

<p><strong><a href="javascript:void(0)" class="accordion">Pulse</a></strong></p>
            <!-- <div class="hiddenDiv"> -->
            <div id="pulse" class="pulse"></div>
            <!-- </div> -->
            <p><strong><a href="javascript:void(0)" class="accordion">Exercise</a></strong></p>
            <div id="exercise" class="exercise"></div>

This is instead the css, you can see that the div containing the 'pulse' is hidden and will be then revealed using jquery:

.pulse, .exercise, .weight{
    width:900px;
/*  height:500px; */

}
.mainContainer{
    border:1px solid red;
    width:90%;
    margin:0 auto;
}
.heading{
    border:1px solid blue;
}
.hiddenDiv{
    border:1px solid red;
/*  width:100px;
    height:50px; */
    display:none;
}
.pulse{display:none;}

I am using this script - in an external file:

$(document).ready(function(){
    $(".accordion").click(function(){
        var theClass = $(this).parent().parent().next().attr('class');
        console.log("class is " + theClass);
        $(this).parent().parent().next().slideToggle();
    });
});

and google uses its own script for the graph (this in an internal script):

<script type="text/javascript">
      google.load("visualization", "1", {packages:["corechart"]});
      google.setOnLoadCallback(drawChart);
      function drawChart() {
        var data = google.visualization.arrayToDataTable([
          ['Day', 'Pulse'],
          ['26/03',  75],
          ['27/03',  71],
          ['15/04',  73],
          ['22/05',  64],
          ['26/03',  75],
          ['27/03',  71],
          ['15/04',  73],
          ['22/05',  64],
          ['26/03',  75],
          ['27/03',  71],
          ['15/04',  73],
          ['22/05',  64],
          ['30/05',  75]
        ]);

        var options = {
          title: 'Pulse'
        };

        var chart = new google.visualization.LineChart(document.getElementById('pulse'));
        chart.draw(data, options);
      }
    </script>

So how do I make sure that I call drawChart() as a callback function of my slideToggle() and not as part of google.setOnLoadCallback(drawChart);?
I mean the callback shouldn't be too challenging, I believe I can change my function to this:

$(document).ready(function(){
    $(".accordion").click(function(){
        var theClass = $(this).parent().parent().next().attr('class');
        console.log("class is " + theClass);
        $(this).parent().parent().next().slideToggle(function(){
            drawChart();
        });
    });
});

but how do I remove the drawChart() from inside the google script without making a mess? Can anybody give me a hand with this I am really stuck...

Dani AI

Generated

The chart is tiny because the Google Visualization API measures the container when it’s first drawn; if that container is display:none the measured size is effectively zero and the chart renders at a small default size. The simplest, robust fix is to draw (or redraw) the chart only after the container becomes visible, and to pass an explicit width when necessary.

A practical pattern:

  • let the Google API load but don’t force it to draw immediately;
  • keep your chart data/options accessible (or build them when needed);
  • on accordion click, run the draw logic in the slideToggle callback and mark the panel as “drawn” so you don’t recreate it every time.

Example (structure-only; keep your DataTable creation inside drawPanelChart so you don’t duplicate the data already in thread):

// called once when Google API is ready
function googleReady() { window.gvReady = true; }

(function($){
  var drawn = {};
  $('.accordion').on('click', function(){
    var $panel = $(this).closest('p').next(); // safer traversal than multiple parents
    $panel.slideToggle(300, function(){
      if (!$panel.is(':visible')) return;
      var id = $panel.attr('id');
      if (drawn[id]) return;
      // build DataTable/options inside this function (or refer to a prebuilt object)
      drawPanelChart($panel); // create chart for this panel and call chart.draw(...)
      drawn[id] = true;
    });
  });
})(jQuery);

Alternatives & tips

  • If you must preload the chart, temporarily show the container off-screen to let the chart measure (set position:absolute; visibility:hidden; display:block), draw, then restore—hacky but works.
  • Instead of relying on automatic sizing, pass width: $panel.width() in chart options so the chart uses the actual container width.
  • Add a debounced window resize handler to redraw charts for responsive layouts.
  • If you keep google.setOnLoadCallback(drawChart), either (a) make drawChart skip drawing hidden panels, storing chart data for later, or (b) replace it with a minimal ready-flag and draw on reveal as above.

As suggested, calling draw a second time will overwrite the small chart correctly, but drawing only after visibility (and caching a “drawn” flag) keeps behavior predictable and avoids extra work.

Recommended Answers

All 2 Replies

how do I remove the drawChart() from inside the google script

Are you sure this is necessary? Even though it gets drawn, wouldn't the second call to the draw just overwrite the graph correctly?

Hi pritaeas, no I am not sure it is necessary, but I was just going with what I have read in one of those links, so I thought maybe that will help. The thing is, I have posted this in the web design because personally I am fairly sure it is a CSS problem rather than a script, although this problem with the graph being displayed smaller inside a hidden element seems to be documented somewhere in one of the links. The only way around at present is not to hide the element containing the graphs, but it seems a bit lame. ANy other idea?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.