简体   繁体   中英

How to make a react + d3 stacked bar chart grouped?

I am using react + d3 to create a stacked and grouped bar chart, I made it stacked but couldn't find how to make it grouped also?

I want something like this image

在此处输入图片说明

data looks like:


    const data = [
      {
        name: "Brand 1",
        Affiliate: 10,
        Social: 20,
        Media: 30
      },
      {
        name: "Brand 2",
        Affiliate: 20,
        Social: 40,
        Media: 60
      },
      {
        name: "Brand 3",
        Affiliate: 30,
        Social: 45,
        Media: 80
      },
      {
        name: "Brand 4",
        Affiliate: 40,
        Social: 60,
        Media: 100
      },
      {
        name: "Brand 5",
        Affiliate: 50,
        Social: 80,
        Media: 120
      }
    ];


and the part that generate stack looks like:


    const stackGenerator = stack().keys(keys);
    const layers = stackGenerator(data);

you can check the full code and demo in demo

any help to make it stacked + grouped will be appreciated

Based on this example , something like this should work: you can find the entire example here .

const data = [
  {
    name: "Brand 1",
    type: 1,
    Affiliate: 10,
    Social: 20,
    Media: 30
  },
  {
    name: "Brand 1",
    type: 2,
    Affiliate: 20,
    Social: 40,
    Media: 60
  },
  {
    name: "Brand 2",
    type: 1,
    Affiliate: 30,
    Social: 45,
    Media: 80
  },
  {
    name: "Brand 3",
    type: 1,
    Affiliate: 40,
    Social: 60,
    Media: 100
  },
  {
    name: "Brand 3",
    type: 2,
    Affiliate: 50,
    Social: 80,
    Media: 120
  }
];

Make two nested axes:

    const x0Scale = scaleBand()
      .domain(data.map((d) => d.name))
      .range([0, width])
      .padding(0.46);
    const x1Scale = scaleBand()
      .domain(data.map((d) => d.type))
      .rangeRound([0, x0Scale.bandwidth()])
      .padding(0.12);

and make the width of the bar dependent on the width of the smallest axis:

.attr("x", (sequence) => x0Scale(sequence.data.name)
                         + x1Scale(sequence.data.type))
.attr("width", x1Scale.bandwidth())

This yields the following picture:

结果图像

The only downside is that the solution assumes that every group has the same members - otherwise it doesn't draw them, as you can see from the gap to the right of "Brand 2".

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