简体   繁体   English

当每个单独的片段都是一个对象时,如何在d3中创建堆叠的条形图?

[英]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 我正在尝试在d3中创建一个图表,因此它显示如下: 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/ 这是代码,但是尽管它在我的计算机上本地显示,但我没有使它在小提琴中工作: 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. 如上所述,我的首选解决方案是将ChartJS用于此类项目。 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. 我继续进行了快速尝试,使用(相对)简单的数据转换来重新创建示例图表,以将输入的数据映射为ChartJS可以读取的格式。

The codepen for that is here https://codepen.io/jsanderlin/pen/dKqEod 为此的代码笔在这里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. 我将在下面查看为ChartJS执行数据映射/预处理的代码,因为这是此过程中涉及的JavaScript中最复杂的部分。 The rest of the JS/HTML is just pulled from ChartJS documentation and the Stacked Chart sample here . 其余的JS / HTML只是从ChartJS文档和此处的Stacked Chart示例中提取的。

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 ;) 有趣的项目,今天下午开始工作;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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