Horizontal Stacked Barplot

Dataviz logo representing a Bar chart.

This tutorial is a variation around the general introduction to barplot with react and d3.js. You should probably understand the concepts described there before digging into stacking.

This example shows how to represent 2 levels of grouping in a barplot, resulting in a stacked barplot. The items of the dataset are divided in groups (reprented as bars) and subgroups (represented as sections in each bar).

A code sandbox is provided for the final result, but explanations target what's different compared to an usual barplot.

Useful links

Plot and code

This is a stacked barplot built using React and d3.js. The dummy dataset provides information about how much my friends spent the last month. The people are the group here. Each bar represents a group.

A second level of grouping is available. We know if the money was spent on travel, food or beer. It is possible to represent this additional amount of info using a process called stacking.

How much my friends spend on travel, food and beer.
50100150200250300312Jean294Nicolas270Mark159Marion102Emily69Mélanie54Gabriel36Robert6Paul

A horizontal stacked barplot built with d3.js for scales, and react for rendering

Now, let's see how to implement such a graph.

The Data

There are several ways to store this information in javascript. I suggest an array of object where each object provides the valueof 1 specific expense, with the group (friend name) and the subgroup (category of expense).

export const data = [
  {group:"Mark", subgroup: "travel",  value: 90},
  {group:"Mark", subgroup: "food",  value: 23},
  {group:"Mark", subgroup: "beer",  value: 14},
  ...
]

Stacking

The trickiest part of the stacked barplot implementation is the stacking step.

Subgroups are displayed one next to each other. We need to compute their positions on the X axis. Fortunately d3.js is here to the rescue with a d3.stack() function.

→ Build a stack generator

d3.stack() constructs a stack generator. This stack generator is a function that takes a list of group names and will stack the data for each item.

This is how it can be applied to our dataset:

// You need the list of subgroups
const subGroups = ['travel', 'beer', 'food']

// Creates the stacking function
const stackGenerator = d3
  .stack<string>()
  .keys(subGroups)
  .value((d) => data.filter((item) => item.group === d)[0].value); // This is the accessor function: how to retrieve all values for a group

→ Use the generator

Now that this stack generator is available, we just have to run it on our list of group names to get the stacked values:

// Use the stack generator to stack the data in each group
const series = stackGenerator(groups);

→ Output

The output has kind of an usual shape and it's important to understand how it's formatted. It's an array with the same length than the initial dataset. Once more, each item is linked to a positon on the x axis.

Each item is an array of length 2, associated with a specific series. This is a mess to explain.

[
  // Subgroup 1 (travel)
  [
    [0, 90, data: 'Mark'], // subgroup travel goes from x=0 to x=90 for Mark
    [0, 12, data: 'Robert'],
    [0, 34, data: 'Emily'],
    ...
  ],
  // Subgroup 2 (food)
  [
    [90, 180, data: 'Mark'], // subgroup food goes from x=90 to x=180 for Mark
    [12, 24, data: 'Robert'],
    [34, 68, data: 'Emily'],
    ...
  ]
]

Rendering

Once you get the stacked data above, rendering the chart is business as usual. You can loop through the object and plot a rect for each item.

How much my friends spend on travel, food and beer.
50100150200250300312Jean294Nicolas270Mark159Marion102Emily69Mélanie54Gabriel36Robert6Paul

A horizontal stacked barplot built with d3.js for scales, and react for rendering

Variation

Check those other barplot and stacked barplot that can interest you:

Picture of a horizontal barplot made with React and d3

Basic barplot

Most basic barplot built with React and d3

GIF of a data update on a React barplot

Barplot dataset transition

How to smoothly animate the transition between dataset

Picture of a vertical stacked barchart made with react and d3

Vertical Stacked Barplot

Represent group and subgroup values by stacking the data

Ranking

Contact

👋 Hey, I'm Yan and I'm currently working on this project!

Feedback is welcome ❤️. You can fill an issue on Github, drop me a message on Twitter, or even send me an email pasting yan.holtz.data with gmail.com. You can also subscribe to the newsletter to know when I publish more content!