3
votes

I have a column called someNumber which contains nulls and zeros. When applying google.visualization.data.group to this column I cannot get the zero to come through to the table, only the null.

The documentation for both .min and .max indicates nulls are ignored but I can't seem to return anything but the null.

How can I get the zero to come through to my table?

Thank you experts!

Working Example:

// Load the Visualization API and the corechart package.
google.charts.load('current', {
  'packages': ['corechart', 'table', 'gauge', 'controls']
});

// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(gChart0);

function gChart0() {
  drawChart();
};

function drawChart() {

  var result = [{
    "calendarWeek": "2017-W30",
    "clnCount": 1,
    "someNumber": null //NOTE THIS IS SET TO NULL
  }, {
    "calendarWeek": "2017-W30",
    "clnCount": 3,
    "someNumber": 0 //NOTE THIS IS SET TO ZERO
  }];

  //Create DataTable
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Calendar Week');
  data.addColumn('number', 'Count');
  data.addColumn('number', 'Some Number');
  
  var dataArray = [];
  $.each(result, function(i, obj) {
    dataArray.push([
      obj.calendarWeek,
      obj.clnCount,
      obj.someNumber
    ]);
  });
  data.addRows(dataArray);

  //grouping 
  var groupView = google.visualization.data.group(data,
    [{
      column: 0,
      type: 'string'
    }],
    [{
        column: 1,
        aggregation: google.visualization.data.sum,
        type: 'number'
      },
      {
        column: 2,
        aggregation: google.visualization.data.min,
        type: 'number'
      }
    ]);

  //Options
  var options = {};

  // Instantiate and draw chart, passing in options.
  var chart = new google.visualization.Table(document.getElementById('chart_div'));
  chart.draw(groupView, options);

} //END  function drawChart()
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>

<div id="chart_div"></div>
2

2 Answers

3
votes

you can provide your own custom aggregation functions.
the aggregation function should accept an array of values as the only argument.

in the custom sum function, we replace null with zero

function customSum(values) {
  var sum = 0;
  values.forEach(function (value) {
    sum += value || 0;
  });
  return sum;
}

in the custom min function, Math.min will return zero when both values are null

function customMin(values) {
  var min = null;
  values.forEach(function (value) {
    min = Math.min(value, min);
  });
  return min;
}

see following working snippet...

google.charts.load('current', {
  'packages': ['corechart', 'table', 'gauge', 'controls']
});

// Set a callback to run when the Google Visualization API is loaded.
google.charts.setOnLoadCallback(gChart0);

function gChart0() {
  drawChart();
};

function drawChart() {

  var result = [{
    "calendarWeek": "2017-W30",
    "clnCount": 1,
    "someNumber": null //NOTE THIS IS SET TO NULL
  }, {
    "calendarWeek": "2017-W30",
    "clnCount": 3,
    "someNumber": 0 //NOTE THIS IS SET TO ZERO
  }];

  //Create DataTable
  var data = new google.visualization.DataTable();
  data.addColumn('string', 'Calendar Week');
  data.addColumn('number', 'Count');
  data.addColumn('number', 'Some Number');

  var dataArray = [];
  $.each(result, function(i, obj) {
    dataArray.push([
      obj.calendarWeek,
      obj.clnCount,
      obj.someNumber
    ]);
  });
  data.addRows(dataArray);

  //grouping
  var groupView = google.visualization.data.group(data,
    [{
      column: 0,
      type: 'string'
    }],
    [{
        column: 1,
        aggregation: customSum,
        type: 'number'
      },
      {
        column: 2,
        aggregation: customMin,
        type: 'number'
      }
    ]);

  function customSum(values) {
    var sum = 0;
    values.forEach(function (value) {
      sum += value || 0;
    });
    return sum;
  }

  function customMin(values) {
    var min = null;
    values.forEach(function (value) {
      min = Math.min(value, min);
    });
    return min;
  }

  //Options
  var options = {};

  // Instantiate and draw chart, passing in options.
  var chart = new google.visualization.Table(document.getElementById('chart_div'));
  chart.draw(groupView, options);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
0
votes

Tested a max version and it also works. Here's the code to share:

function customMax(values) {
    var max = null;
    values.forEach(function (value) {
        max = Math.max(value, max);
    });
    return max;
}