Reputation: 1517
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
Upvotes: 2
Views: 2625
Reputation: 13129
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".
Upvotes: 3