Thursday, January 24, 2013

Stacked column charts with Google charts (compared to gnuplot)

Some time ago I had written about stacked histograms in gnuplot.

Today I wanted to see how to achieve the same result with Google charts.

For the purpose of this first exercise I was using the client side only and didn't worry about where the data should or could come from (in gnuplot data came from a file, naturally) but I put them directly into the JavaScript code.

So first take a look at the result.

As you can see the charts are pretty similar to gnuplot. There is currently one caveat in Google charts where you can't have multiline titles so it's displayed as one line.


So here is the JavaScript code.
The code is a slight modification of the Google charts column chart example and of course the calculation of the percentages for the second chart is the only piece where some real additional work is required.
I left all settings at their defaults (like colours, fonts etc.) except for the obvious y-axis title and height, chart title, thickness of chart border (in order to get a nice box) and the most important isStacked setting.

<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
  google.load("visualization", "1", {packages:["corechart"]});
 
  var dataSet = [
        ['year', 'foo', 'bar', 'rest'],
        ['1900', 20, 10, 20],
        ['2000', 20, 30, 10],
        ['2100', 20, 10, 10]
        ];

  // The first chart

  google.setOnLoadCallback(drawChart1); 
  function drawChart1() {
    var data = google.visualization.arrayToDataTable( dataSet );

    var options = {
      title: 'Stacked histogram\nTotals',
      vAxis: {title: 'total', maxValue: 100},  // sets the maximum value
      backgroundColor: {strokeWidth: 2 },  // to draw a nice box all around the chart
      isStacked: 'true'                    //  = rowstacked in gnuplot
    };

    var chart = new google.visualization.ColumnChart(document.getElementById('chart_div1'));
    chart.draw(data, options);
  }

  // The second chart

  var dataSet2    = dataSet;
  google.setOnLoadCallback(drawChart2);
  function drawChart2() {
    // Calculate the percentages
    var sum = new Array();
    for(row=1; row<dataSet.length; row++) {
      sum[row]        = 0;
      for(col=1; col<dataSet[row].length; col++) {
        sum[row]        += dataSet[row][col];
      }
      for(col=1; col<dataSet[row].length; col++) {
        dataSet2[row][col]      = 100*dataSet[row][col]/sum[row];
      }
    }

    var data = google.visualization.arrayToDataTable(dataSet2);

    var options = {
      title: 'Stacked histogram\n% Totals',
      vAxis: {title: 'total', maxValue: 100},  // sets the maximum value
      backgroundColor: {strokeWidth: 2 },  // to draw a nice box all around the chart
      isStacked: 'true'                    //  = rowstacked in gnuplot
    };

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

<div style="display: table;">
  <div style="display: table-row">
    <div id="chart_div1" style="width: 300px; height: 300px; display: table-cell;"></div>
    <div id="chart_div2" style="width: 300px; height: 300px; display: table-cell;"></div>
  </div>
</div>

Not having worked with Google charts before I did develop this in a couple of hours which shows that Google charts work well and can be learned pretty fast given that you have an idea about charts and its terminology.

Why Google termed their axes horizontal and vertical rather than using the mathematical standards x and y is the secret of their product team though.

There is some discussion whether and how to use Google charts (data privacy etc.) since it seems that data are sent to and processed by Google servers (or servers of other chart type providers) but that is beyond the scope of this blog.

The next step will be to look into the server side piece of Google charts i.e. writing a data provider.

5 comments:

  1. Thanks for this. It is odd however that google charts does not support this directly. Their pie chart will do the percent conversion for you automatically (and even display the percentage). It obviously needs to do that as a pie chart is by nature 100%.

    So I expect there must be some kind of trick to get a stacked 100% bar chart as well, but I have not seen it yet...

    ReplyDelete
  2. Hi, I have created the above chart in my local server and I need the data should be automatically server for the chart.

    My data display like this in the code:

    var dataSet = [
    ['Month', '1st Floor', '2nd Floor', '3rd Floor', '4th Floor', '5th Floor', '6th Floor', '7th Floor'],
    ['A Block', 1, 1, 1, 1, 1, 1, 1],
    ];

    How can I achieve this from mysql database.

    ReplyDelete
    Replies
    1. This is where the data should inject in my script from the database. I need here the data should automatically come from the database. Please help me on this.

      var dataSet = [
      ['Date','1st Floor', '2nd Floor', '3rd Floor', '4th Floor', '5th Floor', '6th Floor', '7th Floor', 'Tarrace Floor'],
      ['A Block', 1, 1, 1, 0, 0, 0, 0, 0],
      ['B Block', 1, 1, 1, 1, 1, 1, 1, 1],
      ['C Block', 1, 1, 1, 1, 1, 1, 1, 1],
      ['D Block', 1, 1, 1, 1, 1, 1, 1, 1],
      ['E Block', 1, 1, 0, 0, 0, 0, 0, 0],
      ['F Block', 1, 1, 0, 0, 0, 0, 0, 0],
      ];

      Once 1 floor completed the stcked chart automatically go up by 1. Output you can see in the URL http://www.onnetsourcing.com/vivera/chart.html

      Delete
  3. Please tell me how to take this data from database.
    var dataSet = [
    ['year', 'foo', 'bar', 'rest'],
    ['1900', 20, 10, 20],
    ['2000', 20, 30, 10],
    ['2100', 20, 10, 10]
    ];

    ReplyDelete