1

In google charts, you can create a diffChart which will give you a nice representation of data by showing 1 series of data in front of the other, like so

Diff Chart

Problem is i need to do this with more then 2 series, i would like to do it with up to 4, stacking each item in front of each other. Is this possible using google charts?? I do not care if i have to use different google charts to accomplish this, but i need the 4 series in front of each other, NOT side by side

Here is an example plunkr, but it only compares the 2 first data sets

http://jsfiddle.net/Gillardo/nv8kb58y/5/

function drawChart() {
    var oldData = google.visualization.arrayToDataTable([
      ['Name', 'Popularity'],
      ['Cesar', 250],
      ['Rachel', 4200],
      ['Patrick', 2900],
      ['Eric', 8200]
    ]);

    var newData = google.visualization.arrayToDataTable([
      ['Name', 'Popularity'],
      ['Cesar', 370],
      ['Rachel', 600],
      ['Patrick', 700],
      ['Eric', 1500]
    ]);

    var thirdData = google.visualization.arrayToDataTable([
      ['Name', 'Popularity'],
      ['Cesar', 100],
      ['Rachel', 100],
      ['Patrick', 100],
      ['Eric', 100]
    ]);

    var colChartDiff = new google.visualization.ColumnChart(document.getElementById('chart_div'));
    var options = { legend: { position: 'top' } };
    var diffData = colChartDiff.computeDiff(oldData, newData);
    var diffData2 = colChartDiff.computeDiff(diffData, thirdData);
    colChartDiff.draw(diffData, options);

    console.log(diffData2);
  }

google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
Gillardo
  • 9,518
  • 18
  • 73
  • 141

1 Answers1

1

the computeDiff method will only evaluate two data sets

one option would be to stack multiple charts on top of each other,
although it will require some manipulation...

position all the chart containers at the same coordinates
use separate chart options to change the color and size of the bars
set specific vAxis.viewWindow on all charts
remove repeated labels (x-axis in data, ticks on y-axis, etc...)

see following working snippets...

Example with 3

google.charts.load('current', {
  packages: ['bar', 'controls', 'corechart']
}).then(function () {
  var data0 = google.visualization.arrayToDataTable([
    ['Name', 'Popularity 0'],
    ['Cesar', 250],
    ['Rachel', 4200],
    ['Patrick', 2900],
    ['Eric', 8200]
  ]);

  var data1 = google.visualization.arrayToDataTable([
    ['Name', 'Popularity 1'],
    ['', 370],
    ['', 600],
    ['', 700],
    ['', 1500]
  ]);

  var data2 = google.visualization.arrayToDataTable([
    ['Name', 'Popularity 2'],
    ['', 1370],
    ['', 1600],
    ['', 1700],
    ['', 500]
  ]);

  var options0 = {
    backgroundColor: 'transparent',
    colors: ['red'],
    height: 400,
    legend: {
      position: 'top'
    },
    vAxis: {
      viewWindow: {
        min: 0,
        max: 10000
      }
    },
    width: 600
  };

  var options1 = {
    backgroundColor: 'transparent',
    bar: {
      groupWidth: 40
    },
    colors: ['blue'],
    height: 400,
    legend: {
      position: 'top',
      alignment: 'center'
    },
    vAxis: {
      ticks: [{v: 0, f: ''}],
      viewWindow: {
        min: 0,
        max: 10000
      }
    },
    width: 600
  };

  var options2 = {
    backgroundColor: 'transparent',
    bar: {
      groupWidth: 20
    },
    colors: ['green'],
    height: 400,
    legend: {
      position: 'top',
      alignment: 'end'
    },
    vAxis: {
      ticks: [{v: 0, f: ''}],
      viewWindow: {
        min: 0,
        max: 10000
      }
    },
    width: 600
  };

  var colChart0 = new google.visualization.ColumnChart(document.getElementById('chart_div_0'));
  var colChart1 = new google.visualization.ColumnChart(document.getElementById('chart_div_1'));
  var colChart2 = new google.visualization.ColumnChart(document.getElementById('chart_div_2'));

  colChart0.draw(data0, options0);
  colChart1.draw(data1, options1);
  colChart2.draw(data2, options2);
});
.chart {
  position: absolute;
  left: 0px;
  top: 0px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="chart" id="chart_div_0"></div>
<div class="chart" id="chart_div_1"></div>
<div class="chart" id="chart_div_2"></div>

Example with 4

google.charts.load('current', {
  packages: ['corechart']
}).then(function () {
  var data0 = google.visualization.arrayToDataTable([
    ['Name', 'Popularity 0'],
    ['Cesar', 250],
    ['Rachel', 4200],
    ['Patrick', 2900],
    ['Eric', 8200]
  ]);

  var data1 = google.visualization.arrayToDataTable([
    ['Name', 'Popularity 1'],
    ['', 370],
    ['', 600],
    ['', 700],
    ['', 1500]
  ]);

  var data2 = google.visualization.arrayToDataTable([
    ['Name', 'Popularity 2'],
    ['', 1370],
    ['', 1600],
    ['', 1700],
    ['', 500]
  ]);

  var data3 = google.visualization.arrayToDataTable([
    ['Name', 'Popularity 3'],
    ['', 1070],
    ['', 1200],
    ['', 1000],
    ['', 900]
  ]);

  var chartColors = ['#f44336', '#9c27b0', '#2196f3', '#4caf50'];

  var options0 = {
    backgroundColor: 'transparent',
    colors: [chartColors[0]],
    height: 400,
    legend: {
      position: 'top',
      alignment: 'center'
    },
    vAxis: {
      viewWindow: {
        min: 0,
        max: 10000
      }
    },
    width: 600
  };

  var options1 = {
    backgroundColor: 'transparent',
    bar: {
      groupWidth: 40
    },
    colors: [chartColors[1]],
    height: 400,
    legend: {
      position: 'top',
      alignment: 'center'
    },
    vAxis: {
      ticks: [{v: 0, f: ''}],
      viewWindow: {
        min: 0,
        max: 10000
      }
    },
    width: 600
  };

  var options2 = {
    backgroundColor: 'transparent',
    bar: {
      groupWidth: 20
    },
    colors: [chartColors[2]],
    height: 400,
    legend: {
      position: 'top',
      alignment: 'center'
    },
    vAxis: {
      ticks: [{v: 0, f: ''}],
      viewWindow: {
        min: 0,
        max: 10000
      }
    },
    width: 600
  };

  var options3 = {
    backgroundColor: 'transparent',
    bar: {
      groupWidth: 10
    },
    colors: [chartColors[3]],
    height: 400,
    legend: {
      position: 'top',
      alignment: 'center'
    },
    vAxis: {
      ticks: [{v: 0, f: ''}],
      viewWindow: {
        min: 0,
        max: 10000
      }
    },
    width: 600
  };

  var colChart0 = new google.visualization.ColumnChart(document.getElementById('chart_div_0'));
  var colChart1 = new google.visualization.ColumnChart(document.getElementById('chart_div_1'));
  var colChart2 = new google.visualization.ColumnChart(document.getElementById('chart_div_2'));
  var colChart3 = new google.visualization.ColumnChart(document.getElementById('chart_div_3'));

  google.visualization.events.addListener(colChart0, 'ready', function () {
    adjustLegend(colChart0);
  });
  google.visualization.events.addListener(colChart1, 'ready', function () {
    adjustLegend(colChart1);
  });
  google.visualization.events.addListener(colChart2, 'ready', function () {
    adjustLegend(colChart2);
  });
  google.visualization.events.addListener(colChart3, 'ready', function () {
    adjustLegend(colChart3);
  });

  colChart0.draw(data0, options0);
  colChart1.draw(data1, options1);
  colChart2.draw(data2, options2);
  colChart3.draw(data3, options3);

  function adjustLegend(chart, index) {
    var chartContainer;
    var chartId;
    var chartLabels;
    var chartLayout = chart.getChartLayoutInterface();
    var chartBounds = chartLayout.getChartAreaBoundingBox();
    var labelBounds = chartLayout.getBoundingBox('legendentry#0');
    var legendMarkers;
    var offsetX;
    var offsetY;

    switch (chart) {
      case colChart0:
        chartId = 'chart_div_0';
        offsetX = labelBounds.width * -1;
        offsetY = labelBounds.height * -1;
        break;

      case colChart1:
        chartId = 'chart_div_1';
        offsetX = labelBounds.width;
        offsetY = labelBounds.height * -1;
        break;

      case colChart2:
        chartId = 'chart_div_2';
        offsetX = labelBounds.width * -1;
        offsetY = labelBounds.height;
        break;

      case colChart3:
        chartId = 'chart_div_3';
        offsetX = labelBounds.width;
        offsetY = labelBounds.height;
        break;
    }

    chartContainer = document.getElementById(chartId);

    chartLabels = chartContainer.getElementsByTagName('text');
    Array.prototype.forEach.call(chartLabels, function(label) {
      if (label.getAttribute('text-anchor') === 'start') {
        label.setAttribute('x', parseFloat(label.getAttribute('x')) + offsetX);
        label.setAttribute('y', parseFloat(label.getAttribute('y')) + offsetY);
      }
    });

    legendMarkers = chartContainer.getElementsByTagName('rect');
    Array.prototype.forEach.call(legendMarkers, function(rect) {
      if ((chartColors.indexOf(rect.getAttribute('fill')) > -1) && (parseFloat(rect.getAttribute('y')) < chartBounds.top)) {
        rect.setAttribute('x', parseFloat(rect.getAttribute('x')) + offsetX);
        rect.setAttribute('y', parseFloat(rect.getAttribute('y')) + offsetY);
        //console.log(chartId, rect);
      }
    });
  }
});
.chart {
  position: absolute;
  left: 0px;
  top: 0px;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="chart" id="chart_div_0"></div>
<div class="chart" id="chart_div_1"></div>
<div class="chart" id="chart_div_2"></div>
<div class="chart" id="chart_div_3"></div>
WhiteHat
  • 59,912
  • 7
  • 51
  • 133
  • firstly thanks for the great example! One thing i noticed is that your legend fits perfectly for 3 items (one left one middle, one right), but what about if there were 4 sets of data? I would only want to go up to a maximum of 4.... – Gillardo Mar 07 '18 at 08:50
  • You can change the 'x' attribute on the label when the chart's 'ready' event fires... – WhiteHat Mar 07 '18 at 14:18
  • I havent yet implemented it, as soon as i do (very soon) i will mark your answer. Great if you could give example with 4 plots and show the legend fix as well :D – Gillardo Apr 03 '18 at 08:30
  • i never used this option to be honest, but instead created different type of series, using bars and dots. But this was a nice idea – Gillardo Mar 20 '20 at 14:33