简体   繁体   中英

How do you create a stacked bar chart in d3 when each individual segment is an object?

I'm trying to create a chart in d3 so it appear as such: https://ibb.co/j13i5T

The data format is the following and cannot change:

  var data = [
  {
  "year": "1991",
  "color":"purple",
  "value":12,
  },
  {
  "year":"1991",
  "color":"red",
  "value":8,
  },
  {
  "year": "1992",
  "color":"red",
  "value":20,
  },
  {
  "year": "1993",
  "color":"blue",
  "value":9,
  },
  {
  "year": "1993",
  "color":"red",
  "value":7,
  },
  {
  "year": "1993",
  "color":"purple",
  "value":3,
  },
]

I've been able to get each object to get placed in the corresponding year, but I'm struggling to stack them.

This is the code, however although it shows on my computer locally, I haven't made it work in the fiddle: https://jsfiddle.net/joat1/kug91hm0/34/

If there's a better way to go about things overall as well, am definitely open to advice.

As I commented above, my preferred solution is to use ChartJS for these kinds of projects. I went ahead and took a quick stab at recreating your example chart with a (relatively) simple data transform to map your incoming data into a format that ChartJS can read.

The codepen for that is here https://codepen.io/jsanderlin/pen/dKqEod

I would look at the code performing the data mapping/preprocessing for ChartJS below, as that is the most complicated bit of JavaScript involved in this process. The rest of the JS/HTML is just pulled from ChartJS documentation and the Stacked Chart sample here .

data.forEach((val) => {
  // Add the label if it doesn't exist already
  if(!barChartData.labels.includes(val.year)) {
    barChartData.labels.push(val.year);
  }

  // Search for the correct dataset
  let valsDataset;
  let datasetName = `Dataset ${val.color}`;
  barChartData.datasets.forEach((dataset) => {
    if(dataset.label === datasetName) valsDataset = dataset;
  });

  // Add the dataset if it doesn't exist already
  if(valsDataset === undefined) {
    valsDataset = {
      label: datasetName,
      backgroundColor: val.color,
      data: []
    }
    barChartData.datasets.push(valsDataset);
  }

  // Find the correct index of the data array for this value, by looking up the year
  let valIndex = barChartData.labels.indexOf(val.year);
  // Set the correct data attribute according to val.value
  valsDataset.data[valIndex] = val.value;
});

Fun project to work on this afternoon ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM