Basic D3.js for Data-Driven User Experiences


  • Share on Google+

I was recently tasked with creating some fairly unique data visualizations with D3.js for some big name companies, displaying aggregate data sets in visual pleasing and easily discernible graphics. I figured it would be good to document my experience so others can also learn what D3 is all about.

What is D3?

The D3.js library is a powerful javascript library for integrating data into interactive documents. The documents could be hosted by a web service to allow data display and visualization on large scales. The full source and tests are also available for download on GitHub.

D3 allows data to be bound to the DOM (Document Object Model) and apply contextual transformation to these items. For example, you could generate pie charts and 3D bar charts that are really SVG’s having their height and width manipulated in response to a REST API response. This library’s responsibility lies solely in the efficient manipulation of documents based on large data sets.

Working with the DOM

One of the annoyances of working directly with the Document Object Model is that selecting and applying changes to objects can be both verbose and require iteration of elements. With D3 we are able to select and modify items with ease. Take the following example that changes the appearance of all div tags on a given page:

If we are using D3 the process is a bit easier, the node selection of elements in the DOM can be applied in the same iterative approach; just having it abstracted away into the D3 library like so:

By this point, you see no difference between this and a jQuery call to manipulate the DOM. Technically there is nearly no difference between this and a jquery call; yet additional parameters to the proceding calls can add some truly powerful contextual action to your documents. For example say that you only want the odd nodes of a chart/document to be colored differently based on their order. This could be achieved in jquery or direct DOM manipulation; but not as easily as this:

Selecting elements via W3C selector strings (css, html, svg) comes with some frustration as nested elements can be tricky to select. D3 also simplifies the selection of nested items such that when you are selecting one item nested within another you have several options to do so. The enter/exit command makes a selection of a parent element and then enter will allow the selection to traverse inside this parent element to the first child element like the following code (This allows us to traverse inside all circles and add another green circle inside of it):

Fetching Data

After all, data is what we are after for our document isn’t it? Data can be fetched in several different ways using D3. The in-built fetches API in D3 uses HTTP requests and response handling to allow images, jsons, blobs, svgs, xml, and more to be used easily in your data document. For example here is a fetch of an image that is output to the javascript console window:

Common usage for data fetching would be obtaining a JSON file at a specified URL and passing it along to your document. The following is a fetch call for a JSON that obtains user information:

Which will produce the JSON below in the console:

If needed, these same fetches can be done by setting the MIME type of the request. The following is an example of fetching a CSV using the request method in D3 and outputting it to the console:

Binding Data

Once we have the data we need to bind it. What is binding exactly? Well, D3 is data driven and a binding funtion data() is used to join an array of data to a selected DOM element and return the updated selection. You can speficy a function instead of an array to the data function if the selection returns more than one group. When returning from these functions, return the element of data you which to be bound to the selected DOM element. The function supplied to data() will be executed for each group in the selection. The following example will bind an array of elements to an HTML table and log the times to a console:

As you can see, we have specified a function as a parameter in the data() after selection of td. The tr.selectAll("td") returns multiple td for the selection of each tr and thus it forms multiple <tr><td></td></tr> groups. As you can see in the result, console.log(d) returns 1st element in the two dimensional array that is a row in an array. The parameter d in the text(function(d)) represents a single element of a row returned from the previous data() function.