D3 layouts do not generate any visual output rather they take data as input and produces data that is more convenient to use either in generators or manually drawing in SVG or canvas. We have already seen one such layout called pie in the previous post where we created a pie chart using the pie layout present in d3-shape module. In pie layout we show how d3.pie() generates the startAngle and endAngle for us which can become very cumbersome if we create them manually. This data is then fed to the arc generator to create the pie slices.
D3 has a rich set of different kinds of layouts viz:
In this post we are going to cover the stack and tree layout. I will create recipes for other layouts in the Recipes section.
Using d3 stack layout we can create stacked visualizations like stacked bar chart, stacked area chart, streamgraph etc. It provides the baseline value for each datum which can then be used to stack data on top of one another. Lets see how this works by building a stacked bar chart.
We are going to use the following dataset:
Here we have the sales data of three fruits (apple, banana, orange) for the last five years and we intend to show this data in a stacked bar chart as shown below:
Lets understand how this is achieved.
Use the d3.stack() method to construct a stack generator by passing the required configuration. Here we set the keys for our stack data as follows:
Now pass data to the stack generator which then returns an array of arrays called series.
The series contains all the necessary information to draw the stacked diagram and that’s all a stack layout does. So lets have a peek inside the returned series array in console.
As evident from the above output, the series is an array containing three arrays one for each of the key(i.e apples, bananas and oranges). Each of these array contains further five arrays representing the five years (2013-2017). If we open one of the inner most array we can see two very important points with key as 0 and 1. The 0 represents the baseline value and 1 represents the topline value. For each year we have this two important values. Now we can use this information to draw the rectangles for each fruit category for each year. In the screenshot the data for 2013 is expanded for each fruit. We can see apples start at 0-100, bananas is stacked on top of it 100-300 (height of 200 which is what we want as per our dataset). Oranges are on top of the stack as 300-430 (height value of 130). With this information we can very easily draw the rectangles on to the svg. Lets see the relevant code:
Please read the comments inline for the explanation of the code. So one thing is clear from the above discussion – D3 layouts do not produce any visual layout. They just provide the data in a convenient way to be used in drawing the corresponding visual element.
Till now we have only dealt with flat data. But in real world we often encounter hierarchical data which has a parent-child relationship. D3 provides the tree layout to draw a tidy tree. But before using the tree layout we need to make sure that we have our dataset in the correct format. The data must have a root node and the node should contain information about its child nodes. We often get hierarchical data in a flat format e.g csv as shown below:
First step is to parse the CSV:
Ok now looking at the data we can say the parent-child relationship but still data is not ready to be fed in the tree layout. We need to create a hierarchical data out of it using the d3.stratify() method.
We gave an id to each node and assigned a parentId link to it’s parent. Now if we pass data to stratify, it will generate a hierarchical data for us as shown below:
Here you can see we have the root node with information about its children, depth, height and (x,y) coordinates which can be used to draw these nodes in our svg or canvas container. Now that we have hierarchical data, we can feed this data to the tree layout.
Here we are first getting all the nodes using d3.tree(root).descendants() including the root node. Then remove the root node from the array (as it doesn’t have a parent) and for all the child nodes we draw a curve connecting the node and it’s parent. This creates the links of the tree. Next we need to create the nodes and the labels.
Create a svg:g element to contain the nodes and the labels together:
Now add svg:circle elements to the svg:g element created above:
Put the labels on:
That creates the tidy tree diagram as shown below:
Well that’s all for the layouts. There are lot of others and I encourage you to explore them. Do check Mike Bostock’s Blocks. Next up we will see how to interact with the visualizations we have created in this tutorial series.