EvilDr
EvilDr

Reputation: 9632

Array item lost when converting from array to Google Visualization DataTable

I am calling an API that returns valid JSON data. Google Visualization charts require that data is bound to charts from JavaScript arrays, not JSON arrays (or arrays of arrays). Therefore using an answer I found elsewhere, I have achieved this.

It works perfectly when the JSON string contains multiple items, but for a single JSON (non-array) string, some of the data gets lost in translation.

The main part of the code is:

var data = JSON.parse('{"Total Users":206,"Active Users":137,"Archived Users":69}');
var arrayOfArrays = []; 
var colHead = [];

for (key in data) {
    colHead.push(key);
}
arrayOfArrays.push(colHead);
var gglRow = [];
for (key in data) {
   if (data.hasOwnProperty(key)) {
       gglRow.push(data[key]);
   }
}
arrayOfArrays.push(gglRow);
var googleDt = new google.visualization.arrayToDataTable(arrayOfArrays, false);
var chart = new google.visualization.ColumnChart(document.getElementById('MyChart'));
var options = {title: 'Test', width: 500, height: 300 };
chart.draw(googleDt, options);

JSFiddle here

When the chart is rendered however, one item is always missing:

Result

I've tried multiple data sources, and one item is always missing. A console log of arrayOfArrays.toString() shows all the data is there. I can't figure out whether the issue lies with my array code, or with the chart binding...

Solution

With thanks to @WhiteHat, the solution was to re-write the iteration code that created the Google DataTable, so that it had a 2-column format. Rendering as a table rather than a chart made the issue obvious.

Old (incorrect) format:

enter image description here

New iteration code:

arrayOfArrays.push(["Data", "Value"]);
for (key in data) {
    if (data.hasOwnProperty(key)) {
        arrayOfArrays.push([key, data[key]]);
    }
}

Result (as table - also displays well as chart):

enter image description here

Upvotes: 1

Views: 357

Answers (1)

WhiteHat
WhiteHat

Reputation: 61222

check the data format for a ColumnChart...

Column 0 is used for the x-axis,
the rest for the y-axis, unless a role is specified

as such, when converting the example json,
"Total Users" becomes the x-axis,
and the remaining columns are plotted as...

x=206, y=137
x=206, y=69

adding another key for the x-axis resolves this issue,
see following working snippet...

google.charts.load('current', {packages:['corechart']});
google.charts.setOnLoadCallback(drawChart);

function drawChart() {
  var data = JSON.parse('{"Users": "Users", "Total Users":206,"Active Users":137,"Archived Users":69}');
  var arrayOfArrays = [];
  var colHead = [];

  for (key in data) {
      colHead.push(key);
  }
  arrayOfArrays.push(colHead);
  var gglRow = [];
  for (key in data) {
     if (data.hasOwnProperty(key)) {
         gglRow.push(data[key]);
     }
  }
  arrayOfArrays.push(gglRow);
  var googleDt = google.visualization.arrayToDataTable(arrayOfArrays);
  var chart = new google.visualization.ColumnChart(document.getElementById('MyChart'));
  var options = {title: 'Test', width: 500, height: 300 };
  chart.draw(googleDt, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="MyChart"></div>


note: arrayToDataTable is a static method, new keyword not required...

var googleDt = google.visualization.arrayToDataTable(arrayOfArrays);

EDIT

google.charts.load('current', {packages:['table']});
google.charts.setOnLoadCallback(drawChart);

function drawChart() {
  var data0 = google.visualization.arrayToDataTable([
    ['Total Users', 30],  // <-- first row
    ['Active Users', 54],
    ['Archived Users', 80],
  ], true);  // <-- first row is data = true

  var chart0 = new google.visualization.Table(document.getElementById('chart_div0'));
  chart0.draw(data0);

  var data1 = google.visualization.arrayToDataTable([
    ['Group', 'Value'],  // <-- first row
    ['Total Users', 30],
    ['Active Users', 54],
    ['Archived Users', 80],
  ], false);  // <-- first row is column headings = false

  var chart1 = new google.visualization.Table(document.getElementById('chart_div1'));
  chart1.draw(data1);
}
div {
  margin-bottom: 12px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div0"></div>
<div id="chart_div1"></div>

Upvotes: 1

Related Questions