Getting Started with Data Joins

To begin to use d3 effectively, I realize I need to have a very good grasp of . The idea of the “data join” is essentially what it sounds like: the act of joining (or binding) data to DOM elements. Here I’ll demonstrate a few things I’ve picked up so far. You can follow along here by creating an empty HTML document, loading it with Chrome, and using the JavaScript console to type the commands and see the results.

First, let’s create an array containing some data. In this case, a set of names:

> var names = ["Sam", "Diane", "Norm", "Cliff"]

Now we create an empty table row that we can populate with these names:


This should produce an empty table containing one (empty) row in the html:


Before joining data to the table the “correct” way, I think it’s instructive to first see what happens when we try to do it incorrectly. Here’s one way that fails:

>"tr").append("td").data(names).text(function(d) {return d;})

This will result in only one column, having joined just the first element of the array, and the output in your browser will look like:


Interestingly, if you run the same command a second time, you will simply get:

Sam Sam

We can start over from scratch to get it right, but even from here we can fix it:

>"tr").selectAll("td").data(names).text(function(d) {return d;})

This gives:

Sam Diane

Since we had already created two td elements, the last command joined the first two elements of the names array to those elements. This is an update according to the terminology of d3. However, we still want to get those other two names in the table. To do this, we must use the enter() function and append two columns:

>"tr").selectAll("td").data(names).enter().append("td").text(function(d) {return d;})

Sam Diane Norm Cliff

What this command did was figure out that there were 4 elements in the data array, but only two td elements to join, so it put the “extra” two elements (Norm and Cliff) into the enter array. It then appended two new td elements and bound Norm and Cliff to those.

You might think it also re-wrote the first two names, but that is not the case. It’s an important point, so let’s extend the example further. From here, let’s shift the names in the array and add one more:

> names.shift(1);
> names.push("Sam");
> names.push("Carla");
> names.push("Woody");

Now names = ["Diane", "Norm", "Cliff", "Sam", "Carla", "Woody"].

Let’s see what happens when we re-run the command from before:

>"tr").selectAll("td").data(names).enter().append("td").text(function(d) {return d;})

Sam Diane Norm Cliff Carla Woody

Ah, notice that while the last two (“entering”) elements have been added to the table, the first four elements did not change. To change those elements, we must run an update:

>"tr").selectAll("td").data(names).text(function(d) {return d;})

Diane Norm Cliff Sam Carla Woody

Note that an update is simply the previous command minus the enter() and append() functions.

So how do we delete elements? Let’s get rid of Diane (don’t worry, in time you’ll get over it).

> names = names.slice(1)

["Norm", "Cliff", "Sam", "Carla", "Woody"]

We can run the update first and then remove the extra element or vice-versa. Let’s run the update first:

>"tr").selectAll("td").data(names).text(function(d) {return d;})

Norm Cliff Sam Carla Woody Woody

To get rid of the extra Woody, we use the exit() function:

> d3.selectAll("td").data(names).exit().remove()

Norm Cliff Sam Carla Woody

Voila! Just to show one more piece of functionality, be aware that you can use the data() function to simply return the current data join:

> d3.selectAll("td").data()

> ["Norm", "Cliff", "Sam", "Carla", "Woody"]

This seems like a good place to stop for now. There is a lot more to the data function that I haven’t quite wrapped my head around yet, namely, the second argument (not used here) which creates a key function to replace the default one which simply uses the array index. In the meantime, I hope this post has been useful to you in some way.

Posted on by
Tagged :

Categories :data joinstutorial

Post comment as twitter logo facebook logo
Sort: Newest | Oldest