D3.js does two things: (1) It adds HTML to a page and (2) it binds data to that HTML. That’s it. The simplest example of this you will ever see of D3 data are bar charts binded to pixel size. Most examples of D3 in the wild use SVGs or Path html elements. Understanding those are almost different skills entirely. In this tutorial, we’re going to look at D3 code that does not require any knowledge of SVGs or Paths whatsoever.
Caveat: This isn’t a graph that you would want to put into production. This is a very simple example showing what D3 does.
Let’s take a look at some code and then dissect it to see exactly what’s going on behind the scenes.
See the Pen The Simplest d3 example you’ll ever see by Bob Cavezza (@cavezza) on CodePen.
As you can see, this code is generating a bar graph with no labels and no axes. In this post, we will dissect the code line by line to see what is happening.
If you want to recreate this, you will need all three elements as seen in the CodePen. You need the html and to load the d3 script into your page. You will also need to style the single-line-bar
class. The most important part of this code is the javascript section as that is where we’re using D3. Let’s dive into the code.
const data = [4, 30, 15, 16, 23];
d3.select('#chart')
.selectAll('div')
.data(data)
.enter()
.append('div')
.classed('single-bar', true)
.style('height', (d) => ( d + 'px'));
The very first line is the data we will graph. const data = [4, 30, 15, 16, 23];
is a plain javascript array containing five integers. In the next line, we start to see D3 specific syntax.
The first line of d3, d3.select('#chart')
works in the exact same way that a CSS selector works. You are selecting the area in your HTML where you want to create your visualization. These selectors work in the exact same way they would work in any front end framework. #
s are appended for ids, .
s are appended for classes, and any HTML element would be selected like d3.select('div')
. Other selectors will work too,
The next thing that you will notice is that D3 supports chaining. Notice there isn’t a semicolon after the first line. The result of the first line is an object that we can chain additional d3 commands to. This is neat because the output of every method can then be used by the next method.
The next line, .selectAll('div')
, selects all div
s that live inside #chart
. This is intriguing because there are no div
s that live inside the #chart
div in our sample HTML. When this occurs, D3 returns an empty selection. I know this is confusing, but let’s continue to break down the rest of the code and this will make sense soon.
The magic starts to happen in the next line. In .data(data)
, we are binding data to the div elements. .data
is calling the data method in d3. Thedata
variable inside the parentheses is a reference to our array of integers we want to graph. We initialized this variable on the first line of our code. The data is now binded to our d3 object, but we still have the issue that there are no divs inside the #chart
element. So we’re binding this data to nothing?!?!?
This is where .enter
comes into play. If there is a mismatch in number of elements we have selected and the data we binded it to, .enter()
allows us to add div elements to make up the difference. .enter()
is usually followed by an .append
. Our example here is no different.
Important note: There is a corresponding exit
method that can be used to remove elements in a similar way that enter
adds elements.
Now that we called .enter()
, we now have to append values to the selection to bridge the gap from 0 div
s to the number of integers in our array. Since we call .append('div')
, what this does is adds the difference of number of divs to get to 5 (the length of our array).
If you cut off the rest of the code here, you will see 5 empty divs inside chart.
.classed
assigns a class to all the divs you are appending if the second parameter is true. In our example, .classed('single-bar', true)
assigns a single-bar
class to every div
that we just appended because true
will always be truthy.
The final line .style('height', (d) => ( d + 'px'));
adds an inline style attribute to every div that we appended. The first parameter defines the inline style element. The second parameter is a javascript function with d
referring to each specific item in our data array.
If you’re not familiar with fat arrow functions, don’t worry. The line is the exact same as the following:
.style('height', function(d) {
return d + 'px';
}
You can call d
whatever you want, but d
is generally the convention you’ll see in D3 code. Since d
refers to each data item in the array, the first appended div element, it will render as style="height: 4px;"
.
As you can probably tell, all this D3 code is doing is creating HTML elements. That is all D3 does! It creates and binds data to HTML elements.
In our example above, the d3 code created this html output:
<div id="chart">
<div class="single-bar" style="height: 4px;"></div>
<div class="single-bar" style="height: 30px;"></div>
<div class="single-bar" style="height: 15px;"></div>
<div class="single-bar" style="height: 16px;"></div>
<div class="single-bar" style="height: 23px;"></div>
</div>
Don’t forget the importance of the CSS in this example. If you comment out the css in the CodePen, the graph stops appearing.
This happens because when you create empty divs, there is no minimum width. You are left with HTML elements that you created , but cannot see.
The CSS in our example sets the width of each div, assigns space in between each div, sets the background color of each div, and sets a display value so they will display next to each other like a graph.
.single-bar {
display: inline-block;
background: #4285F4;
width: 8px;
margin-right: 2px;
}
There is a lot of buzz around D3 because of the crazy graphs it helps create. Everything will get much more complicated as you need to build more complex visualizations. You will need to learn SVGs and Path HTML elements. But don’t let D3 scare you. At the end of the day, it’s just HTML, CSS, and javascript.
Get my periodic email with the best resources and links online
https://tinyletter.com/rcavezza
Read more at my blog
Connect with me
Top comments (0)