Author avatar

Hong Xiao

Short Guide to Getting Started with D3

Hong Xiao

  • May 17, 2019
  • 9 Min read
  • 104 Views
  • May 17, 2019
  • 9 Min read
  • 104 Views
Web Development
D3

Introduction

D3 (short for Data-Driven Documents) is a Javascript library to manipulate documents with given data. In this guide, we will set up the environment with d3js, explore some basic concepts, and a bar chart which you can build directly with d3js, like this: result bar chart

Then, we will provide some "next-step" tasks, as well as links to more information and references. Let's get started.

Setup and Verification

There are a few options to set up a d3js environment on your machine, and we will explore each of them in this section.

First of all, you can use d3js in a vanilla <script> tag, like this:

1
<script src="https://d3js.org/d3.v5.min.js"></script>
javascript

This will expose a d3 global variable, and you can verify this by typing

1
console.log(d3.version);
javascript

in the console of your browser. This statement will print out the version of d3js you are using, which is 5.9.2 at the tie of this writing.

The second option is to install d3js via a package manager, like npm or yarn, create a bundle with a bundler, and import d3 accordingly.

1
import * as d3 from "d3";
javascript

The third option is to use d3js in nodejs, as such:

1
var d3 = require("d3");
javascript

For the simplicity of this guide, we use the first approach (with a <script> tag) to set up our environment.

Concepts

Before we dive in, there are a few concepts in d3js to be clarified. The typical way is to attach data to the DOM (document object model) in d3js. We will cover d3-scale, d3-axis, and the "data-join" pattern, before we actually build our vertical bar chart.

Use d3-scale for abstract-data-to-visual-representation Mapping

When directly programming with SVG (short for 'Scalable Vector Graphics'), typically you will do the following for a simple rectangle:

1
2
3
4
5
6
<svg>
    <g>
        <rect x="0" y="0" height="100" width="50">
        </rect>
    </g>
</svg>
html

As you can imagine, in a bar chart, we need to create many <rect> elements, calculate their attributes, and attach them to the <svg> element This is a daunting task by itself, and d3-scale can help us to do the calculation. From the official documentation, we will use the scaleBand() method for x, and scaleLinear() for y. These are the building blocks in our case for calculating the x, y, height and width attributes for the rectangles.

We will use the following logic to create the x and y scale functions:

1
2
3
4
5
6
7
var x = d3.scaleBand()
  .domain(DOMAIN_OF_DATA)
  .range([RANGE_LEFT, RANGE_RIGHT]);

var y = d3.scaleLinear()
  .domain([0, MAX_OF_VALUE_DATA])
  .range([RANGE_BOTTOM, RANGE_TOP]);
javascript

Note that scales does the mapping from domain to range.

Render Human-readable Marks for Scales Using d3-axis

Besides the rectangles, we also need to add the x-axis and y-axis in our bar chart. This is where d3-axis comes in handy. We would like to have a bottom axis for x, and a left axis for y. Here are the code snippets to create them:

1
2
3
4
5
6
7
var xAxis = g => g
  .attr("transform", `translate(0,${height - margin.bottom})`)
  .call(d3.axisBottom(x));

var yAxis = g => g
  .attr("transform", `translate(${margin.left},0)`)
  .call(d3.axisLeft(y));
javascript

Note that the SVG coordinates start with the top-left point as (0, 0). This means we need to do a translate for the y-axis so that the logic (0, 0) is at the bottom left. More details of SVG transforming can be found here.

The data-join Pattern and Its Usage

The last concept of d3js in use is the 'data-join' pattern, which might look strange at first sight.

1
2
3
4
5
6
7
8
9
10
var svg = d3.select('svg');
var g = svg.append("g");

g.selectAll("rect")
  .data(data)
  .join("rect")
  .attr("x", d => x(d.name))
  .attr("y", d => y(d.value))
  .attr("height", d => y(0) - y(d.value))
  .attr("width", x.bandwidth());
javascript

Essentially, the above code snippet creates a few rect elements with given 'data', and 'join' them accordingly. Then it calls the x and y scale functions to map the name-value pairs in the data to the proper x and y coordinates on the screen. It also calculates the height and width attributes for each rectangle. You can verify the result by looking at the result elements in Chrome Developer Tool, for something like this:

1
<rect x="41.95402298850573" y="150.11923076923077" height="219.88076923076923" width="17.586206896551726"></rect>
html

There are a few tutorials online explaining this pattern in d3js, and my personal favorite is this article by the author of d3js.

Putting Everything Together

With all the above concepts explained and code snippets available, let us put everything together to build our bar chart. Note that we have the following components in the chart:

  • The rectangle elements in the document, based on the data.
  • The x-axis and y-axis with ticks and text, which are built on top the of x and y scale functions.

In our html file, we create a svg element:

1
<svg height="450" width="600"></svg>
html

In the javascript, first we’ll define the data variable:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var data = [
  {name: "A", value: "0.08167"},
  {name: "B", value: "0.01492"},
  {name: "C", value: "0.02782"},
  {name: "D", value: "0.04253"},
  {name: "E", value: "0.12702"},
  {name: "F", value: "0.02288"},
  {name: "G", value: "0.02015"},
  {name: "H", value: "0.06094"},
  {name: "I", value: "0.06966"},
  {name: "J", value: "0.00153"},
  {name: "K", value: "0.00772"},
  {name: "L", value: "0.04025"},
  {name: "M", value: "0.02406"},
  {name: "N", value: "0.06749"},
  {name: "O", value: "0.07507"},
  {name: "P", value: "0.01929"},
  {name: "Q", value: "0.00095"},
  {name: "R", value: "0.05987"},
  {name: "S", value: "0.06327"},
  {name: "T", value: "0.09056"},
  {name: "U", value: "0.02758"},
  {name: "V", value: "0.00978"},
  {name: "W", value: "0.0236"},
  {name: "X", value: "0.0015"},
  {name: "Y", value: "0.01974"},
  {name: "Z", value: "0.00074"}
];
javascript

Then, we define the constant variables of height, width, and margin:

1
2
3
var height = 400;
var width = 550;
var margin = ({top: 20, right: 20, bottom: 20, left: 20});
javascript

After that comes the x and y scale functions:

1
2
3
4
5
6
7
8
var x = d3.scaleBand()
  .domain(data.map(d => d.name))
  .range([margin.left, width - margin.right])
  .padding(0.1);

var y = d3.scaleLinear()
  .domain([0, d3.max(data, d => d.value)])
  .range([height - margin.bottom, margin.top]);
javascript

The xAxis and yAxis functions:

1
2
3
4
5
6
7
var xAxis = g => g
  .attr("transform", `translate(0,${height - margin.bottom})`)
  .call(d3.axisBottom(x));

var yAxis = g => g
  .attr("transform", `translate(${margin.left},0)`)
  .call(d3.axisLeft(y));
javascript

And finally, use all the above constants and functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var svg = d3.select('svg');

var g = svg.append("g").attr("fill", "orange");

g.selectAll("rect")
  .data(data)
  .join("rect")
  .attr("x", d => x(d.name))
  .attr("y", d => y(d.value))
  .attr("height", d => y(0) - y(d.value))
  .attr("width", x.bandwidth());

svg.append("g").call(xAxis);

svg.append("g").call(yAxis);
javascript

Here we go, we have the final bar chart with all the components mentioned above.

Next Steps

There are many different types of visualizations you can do with d3js, and in this guide we merely scratched the surface of it. Some improvement ideas include:

  • Adding interactions using CSS.
  • Adding transformations using functionalities provided in d3-transform.
  • Visualize a line chart with the same data.

Conclusion and Additional Information

The code example in this guide is inspired by the examples on bl.ocoks.org and observablehq.com, the official d3js website is https://d3js.org/, and D3 In Depths also provides good tutorials for d3js.

The finished project can be found here.

You can find more courses on d3js on Pluralsight:

0