1
votes

Let's say I have a datatable like this:

    drivingData.addColumn('string', 'VehicleGroup');
    drivingData.addColumn('number', 'TimeType');
    drivingData.addColumn('number', 'TimeTarget');
    drivingData.addColumn('number', 'TimeUsed');

then I add 4 rows like this:

 drivingData.addRow(['Trucks-S',0, 1000, 1200])
 drivingData.addRow(['Trucks-F',1, 300, 500])
 drivingData.addRow(['Trailer-S',0, 1200, 1500])
 drivingData.addRow(['Trailer-F',1, 100, 500])

I would like to have a 'stacked' column chart. First one shows Trucks-S with TimeType 0 with yellow and orange colors. Second would show Trucks-F with TimeType 1 with grey and light-grey colors.

Third would then again be yellow and orange and fourth grey and light-grey and so on...

Is this possible?

Something like this: https://imgur.com/a/oNOiP

1

1 Answers

0
votes

the requested chart is only available as a Material bar chart

Material --> google.charts.Bar -- packages: ['bar']

Classic --> google.visualization.ColumnChart -- packages: ['corechart']

you can break Material bar charts into multiple stacks,
by assigning a group of series to a different y-axis
this is accomplished by using the series option

series: {
  2: {
    targetAxisIndex: 1
  },
  3: {
    targetAxisIndex: 1
  }
},

this will create a second axis on the right side of the chart,
which will have a different scale by default
to keep both y-axis in sync, assign a specific view window

vAxis: {
  viewWindow: {
    min: 0,
    max: 3000
  }
}

see following working snippet...

google.charts.load('current', {
  packages: ['bar']
}).then(function () {
  var drivingData = new google.visualization.DataTable();
  drivingData.addColumn('string', 'VehicleGroup');
  drivingData.addColumn('number', 'TimeTarget');
  drivingData.addColumn('number', 'TimeUsed');
  drivingData.addColumn('number', 'TimeTarget');
  drivingData.addColumn('number', 'TimeUsed');
  drivingData.addRow(['Trucks-S', 1000, 1200, 600, 800])
  drivingData.addRow(['Trucks-F', 300, 500, 700, 900])
  drivingData.addRow(['Trailer-S', 1200, 1500, 800, 1000])
  drivingData.addRow(['Trailer-F', 100, 500, 600, 1000])

  var container = document.getElementById('chart_div');
  var chart = new google.charts.Bar(container);
  var options = google.charts.Bar.convertOptions({
    colors: ['#fbc02d', '#616161'],
    height: 400,
    isStacked: true,
    series: {
      2: {
        targetAxisIndex: 1
      },
      3: {
        targetAxisIndex: 1
      }
    },
    vAxis: {
      viewWindow: {
        min: 0,
        max: 3000
      }
    }
  });

  chart.draw(drivingData, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

note: just keep in mind,
there are several configuration options that are not supported by Material charts
see --> Tracking Issue for Material Chart Feature Parity


EDIT

isStacked: 'percent' is currently not support by Material charts

to work around this issue, convert the data manually, before drawing the chart

see following working snippet,
y-axis columns will be converted in groups of two...

google.charts.load('current', {
  packages: ['bar']
}).then(function () {
  var drivingData = new google.visualization.DataTable();
  drivingData.addColumn('string', 'VehicleGroup');
  drivingData.addColumn('number', 'TimeTarget');
  drivingData.addColumn('number', 'TimeUsed');
  drivingData.addColumn('number', 'TimeTarget');
  drivingData.addColumn('number', 'TimeUsed');
  drivingData.addRow(['Trucks-S', 1000, 1200, 600, 800])
  drivingData.addRow(['Trucks-F', 300, 500, 700, 900])
  drivingData.addRow(['Trailer-S', 1200, 1500, 800, 1000])
  drivingData.addRow(['Trailer-F', 100, 500, 600, 1000])

  // convert data to percent
  var percentData = new google.visualization.DataTable();
  for (var col = 0; col < drivingData.getNumberOfColumns(); col++) {
    percentData.addColumn(drivingData.getColumnType(col), drivingData.getColumnLabel(col));
  }
  for (var row = 0; row < drivingData.getNumberOfRows(); row++) {
    var newRow = percentData.addRow();
    percentData.setValue(newRow, 0, drivingData.getValue(row, 0));
    for (var col = 1; col < drivingData.getNumberOfColumns(); col++) {
      if ((col % 2) !== 0) {
        var rowTotal = drivingData.getValue(row, col) + drivingData.getValue(row, (col + 1));
        percentData.setValue(newRow, col, (drivingData.getValue(row, col) / rowTotal));
        percentData.setValue(newRow, (col + 1), (drivingData.getValue(row, (col + 1)) / rowTotal));
      }
    }
  }

  var container = document.getElementById('chart_div');
  var chart = new google.charts.Bar(container);
  var options = google.charts.Bar.convertOptions({
    colors: ['#fbc02d', '#616161'],
    height: 400,
    isStacked: true,
    series: {
      2: {
        targetAxisIndex: 1
      },
      3: {
        targetAxisIndex: 1
      }
    },
    vAxis: {
      format: '0%',
      viewWindow: {
        min: 0,
        max: 1
      }
    }
  });

  chart.draw(percentData, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>