Smarter ideas worth writing about.

D3 as a Data Visualization Tool

Data visualization is becoming increasingly important in the modern workplace, especially when it comes to interactive content.  D3 - which stands for Data Driven Documents - is a very flexible and robust JavaScript framework that can be used to add visually appealing and interactive data visualizations to any project.

Why D3?
D3 is a highly customizable and open source library that makes it possible to create graphs and charts that are responsive, interactive, and useful.  Because of its open source nature, you can take a look at the inner workings of D3, and even fork the code directly from GitHub and make your own modifications. While the learning curve for D3 can be steeper than other frameworks, the level of customization and power you have over the code makes this cost worthwhile.  This freedom allows you to create visualizations from the simple to the very advanced.  Below you can see two examples, both created with D3: 

Standard Histogram

Sunset Chart

Structure of a D3 Application
Most applications written with D3 are comprised of three primary steps:

  1. Load data into the browser.  Because D3 is a JavaScript library, data that it uses is loaded directly into the browser's memory.  This means that there is no server-side implementation necessary to use D3.  However, this also means that any data used will be visible in the markup of the page, which means it is not a suitable solution when the source data needs to remain private.

  2. Bind DOM elements to that data.  After the data is loaded, D3 adds DOM elements to the markup in order to manipulate them later.  These objects can be HTML tags, SVG elements, or others depending on the needs of the project.
  3. Makes changes to that data (through transformations and transitions).  After the data has been loaded, and the DOM elements have been created, you can start to apply properties and transitions to the page.

Let's take a look at a very simple example.  We will be using an array of numbers (data), binding DOM elements (<p> tags) to the data points, and making changes to that data by changing the 'color' attribute based on whether or not the number is even or odd.  Take a look at the code below:

var dataset = [5, 10, 3, 9, 4];"body")                  //find the body element
    .selectAll("p")                //select all <p> tags (none exist yet, but they will)
    .data(dataset)                 //bind the data
    .enter()                       //select DOM elements that aren't bound (or create them)
    .append("p")                   //add the new elements
    .text(function(d) {            //set the text
      return d;
    .style("color", function(d) {  //and conditionally set the color based on the data value
      if(d % 2 === 0) {
        return "blue";
      else {
        return "black";

If you run this code you will see the following:

You can see that the output works as we would expect it to.  While most of the functions invoked are fairly straightforward, there are a few worth taking a more detailed look into.  Specifically, we will take a look into selectAll(), select(), and enter().

The select() function is simply passed a selector - any selector that you might otherwise use in CSS or jQuery - and returns the element specified.  This is often used to get the parent container of what you will eventually add DOM elements to.

The selectAll() function works a bit differently.  It is similar to select(), but here we are doing something that might not be completely intuitive.  It looks like we are selecting all <p> tags in the DOM.  "Wait," you say, "there are no <p> tags in the document yet! This will only return an empty selection!"  Not to worry, we are taking a bit of a leap of faith here and selecting elements that don't exist yet so that we might use those references and append them to the document.  So, while it looks like we are going to come up empty handed, D3 recognizes that we just want these references so we can change their attributes and later bind them to data.

Finally, enter() looks at the DOM and the data and determines whether or not there are more elements in your dataset than in the DOM.  If there are, it goes ahead and creates references to the elements you are intending to create and passes references down the chain for you to manipulate.

Now, this is a great proof of concept, but it really isn’t a practical example.  While there might be some applications of D3 that are used to manipulate text directly, usually it is used to create graphical representations of data.  The next example will use very similar code to what was shown above to create a bar chart with SVG objects out of a static dataset.  Take a look at the code:

var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
                11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];

var w = 500;
var h = 100;

//create the svg used for drawing
var svg ="body")
            .attr("width", w)
            .attr("height", h);

//create the rectangles used for the bar chart
   .attr("x", function(d, i) {
     return i * 21;
   //here we need to subtract from the height because SVG starts
   //in the top left corner
   .attr("y", function(d) {
     return h - (d * 4);     
   .attr("width", 20)
   .attr("height", function(d) {
     return d * 4;
   .attr("fill", function(d) {
     return "rgb(" + (d * 8) + ", 0, 0)";

We are doing a lot of what we did before, initializing a dataset, and setting a few variables that will be used to define the width and height of the SVG area that will be used for drawing.  From there, we can call select() on the SVG object itself to draw the rectangles within.  The same steps are being followed as before, selecting elements that don’t quite exist yet, passing those references to the data function to associate them with data, then creating the markup and changing its attributes.

There are two attributes that change for each bar, fill and height.  Width is based on a variable that is set and does not change.  Because this is an SVG, the function for height has to take steps to account for a starting point in the top left corner, which is why we see h - (d * 4) instead of d * 4 like you might expect.

What the function passed to the attr() function for fill is actually doing is setting an rgb value for each rect object.  We are taking the data value and multiplying it by 8 and then concatenating that into a string that represents the rgb value of the bar.  So, the higher the data value, the higher the red color in the rgb value.  Here is the final result:

Both of these examples have given an introductory look at how D3 can be used for powerful data visualizations.  There is much more you can do with D3, from adding axes or transitions to making your data interactive by responding to user input.  For more examples and instructions on how to get the latest source code, make sure to visit  

To download the source code for the examples above, you can visit the GitHub repo for the examples here:


About The Author

App Dev Consultant

Adam is a Senior I Consultant in Cardinal's Cincinnati office whose work focuses primarily on the Microsoft stack - including C#, MVC, .NET, and SharePoint.  He also does work on the client-side using languages such as HTML5 and JavaScript.