Why Google charts' width not working when change display from none to block?

Viewed 1702

I create a Google charts' with width=100%:

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load("current", {packages:['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
  var data = google.visualization.arrayToDataTable([
    ["test", "val", { role: "style" } ],
    ["test", 21.45, "color: red"]
  ]);
  var options = {
          height: '300px',
          width: '100%'
          };
  var view = new google.visualization.DataView(data);
  var chart = new google.visualization.ColumnChart(document.getElementById("columnchart_values"));
  chart.draw(view,options);
  }
</script>
<div id="columnchart_values"></div>

Then, I create the same charts with display=none beginning. and shows chart after click:

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
  google.charts.load("current", {packages:['corechart']});
  google.charts.setOnLoadCallback(drawChart);
  function drawChart() {
    var data = google.visualization.arrayToDataTable([
  ["test", "val", { role: "style" } ],
  ["test", 21.45, "color: red"]
    ]);
    var options = {
          width: '100%'
          };
    var view = new google.visualization.DataView(data);
    var chart = new google.visualization.ColumnChart(document.getElementById("columnchart"));
    chart.draw(view,options);
    }
  function test() {
  document.getElementById("columnchart").style.display = "block";
  }
</script>
<div onclick="javascript:test()"> click me </div>
<div id="columnchart" style="width: 100%; height: 300px; display:none;"></div>

But it seems in the second method, Google charts' width style not working and only show the default width. Can anyone helps me? Thank you very much!

4 Answers

JavaScript cannot calculate the width while the block have display: none;

So as the script cannot calculate the width, it takes default 400px width.

To fix this issue you have several options:

1) do not use display: none, but use: opacity: 0 or visibility: hidden

2) draw the chart when the block becomes visible (display: block), so the calculation will be possible.

If you call draw graph just before displaying the element, then it works good. It is because, the graph is actually drawn, when the block is already having display: block, since the graph is drawn asynchronously, using the callback.

<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
function drawGraph() {

  google.charts.load("current", {packages:['corechart']});
  google.charts.setOnLoadCallback(drawChart);
  function drawChart() {
    var data = google.visualization.arrayToDataTable([
  ["test", "val", { role: "style" } ],
  ["test", 21.45, "color: red"]
    ]);
    var options = {
          width: '100%'
          };
    var view = new google.visualization.DataView(data);
    var chart = new google.visualization.ColumnChart(document.getElementById("columnchart"));
    chart.draw(view,options);
    }
}
  function test() {
  drawGraph();
  document.getElementById("columnchart").style.display = "block";
  }
</script>
<div onclick="javascript:test()"> click me </div>
<div id="columnchart" style="width: 100%; height: 300px; display:none;"></div>

Redraw the chart with the options after changing the display to block;

Do the same on the window's resize event, if you wish to.

"use strict";
console.clear();

{
  let data, options, view, chart;
  
  google.charts.load("current", {
    packages: ['corechart']
  });
  google.charts.setOnLoadCallback(drawChart);

  function drawChart() {
    data = google.visualization.arrayToDataTable([
      ["test", "val", {
        role: "style"
      }],
      ["test", 21.45, "color: red"]
    ]);
    options = {
      width: '100%'
    };
    view = new google.visualization.DataView(data);
    chart = new google.visualization.ColumnChart(document.getElementById("columnchart"));
    chart.draw(view, options);
  }

  function test() {
    document.getElementById("columnchart").style.display = "block";
    chart.draw(view, options);
  }
  
  document.getElementById('open-chart').addEventListener('click', test);
  window.addEventListener('resize', test)
}
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

<div id="open-chart" onclick="test()"> click me </div>
<div id="columnchart" style="width: 100%; height: 300px; display:none;"></div>

The width of your div #columnchart is 100% i.e full viewport but as you can see the graph is not of full width i.e because the chart created by google is of fixed width If you debug you will see this enter image description here

you can see the width is 400px

// Set chart options

    var options = {'title':'How Much Pizza I Ate Last Night',
                     'width':400,
                     'height':300};
chart.draw('', options);

Try something like checking the length of data and then assign 0 values before and after the .addrow function if the data has only one row because usually groupWidth doesn reflect if chart has only one column. See below:

 if (yourdatatable.length == 1) {
        data.addRow(['', 0, '#fa1150', '']);       
    }
    for (i = 1; i < yourdatatable.length; i++) {
        data.addRow([yourdatatable[i]['Name'], yourdatatable[i]['Percentage'], 
        '#fa1150', yourdatatable[i]['Percentage'].toString()]);       
    }
    if (yourdatatable.length == 1) {
        data.addRow(['', 0, '#fa1150', '']);       
    }
Related