Chartjs-Chart.js – How to create group stacked chart bars

1👍

To summarize:

  1. x-axis label should be the device.

  2. The dataset in which each item’s label should be the category such as "amckinlay", "cvu" etc. And each item’s data contains the value according to the device.

The problem is your data values from alldata which is key-value pair makes it difficult to extract the key. Would recommend converting it into the form:

{ "category": "amckinlay", "value": 100 }
var colorSettings = [
  {
    category: 'amckinlay',
    backgroundColor: 'rgba(75, 192, 192, 0.6)',
  },
  {
    category: 'cvu',
    backgroundColor: 'rgba(255, 99, 132, 0.6)',
  },
];

var labels = alldata.map((x) => x.device);
alldata = alldata
  .map((x) =>
    x.values.reduce((acc, cur) => {
      for (let k in cur) {
        acc.push({
          device: x.device,
          category: k,
          value: cur[k],
        });
      }

      return acc;
    }, [])
  )
  .flat();

var subLabels = [...new Set(alldata.map((x) => x.category))];

var datasets = subLabels.reduce((acc, cur) => {
  for (let device of labels) {
    var value =
      alldata.find((x) => x.device == device && x.category == cur)?.value ??
      0;

    var category = acc.find((x) => x.label == cur);
    if (category == null) {
      acc.push({
        label: cur,
        data: [value],
        backgroundColor: colorSettings.find((x) => x.category == cur)
          .backgroundColor,
      });
    } else {
      category.data.push(value);
    }
  }

  return acc;
}, []);

Note that, your chart configuration options should have the stacked setting as mentioned in the Stacked bar chart documentation.

const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: labels,
    datasets: datasets,
  },
  options: {
    responsive: true,
    scales: {
      x: {
        stacked: true,
      },
      y: {
        stacked: true,
      },
    },
  },
});

Demo @ .NET Fiddle

Leave a comment