d3.js experiments in the console

March 30, 2012

d3 (aka Data-Driven Documents) is a great little JavaScript framework for data visualization. It’s got a nice declarative syntax for DOM manipulation that’s quite readable, but takes a bit of effort to understand exactly what it’s doing.

Favorite links:

I like to understand stuff by playing with it interactively, so I created a skeleton index.html which just includes d3.js and a style a div where I’ll display some data.

UPDATE: blank file below posted here


<html>
  <head>
    <title>d3 experiment</title>
    <script type="text/javascript"
            src="https://raw.github.com/mbostock/d3/master/d3.js">
    </script>
    <style type="text/css">
      .box {
        background-color: skyblue;
        width: 24px;
        height: 18px;
        padding: 4px;
        margin: 1px;
      }
    </style>
  </head>
  <body>
  </body>
</html>



Then in the FireBug console, we can interact with d3, the top-level object that allows us to access all of d3’s goodness.


>>> d3
Object { version="3.0.1", random={...}, ns={...}, more...}
>>>  body = d3.select("body")
[[body]]

Like jQuery, d3 let’s us “select” one or more DOM elements to operate on them. I only have one body tag, so I just get one element in an array — not yet sure why it needs a nested array. Now I can manipulate the DOM:


>>>  body.append('p').text('Hello d3!')
[[p]]

and “Hello d3!” appears at the top of my page. Yay! Of course that could have been written in a single line like:


d3.select("body").append('p').text('Hello d3!')

and if I want to change the text, I can use a regular old css selector to grab the paragraph element I just created:


d3.select("body p").text("Welcome to d3")

or, using the reference to the ‘body’ variable I created above:


body.select("p").text("d3 is cool")

Data-driven Boxes

Ok, now that we understand the basics, let’s put some boxes on the page:


body.append('div').attr('class','box')

and let’s add a couple with text in them:

 
body.append('div').attr('class','box').text('hi')
body.append('div').attr('class','box').text('foo')

With my set of boxes, I can select one or all of them:


>>> d3.select('.box')
[[div.box]]
>>> d3.selectAll('.box')
[[div.box, div.box, div.box]]

Then I can specify data to bind to each box and display it. I’ve read that d3 can deal with all sorts of data (like json, csv, etc.) but we’ll start with an array of numbers.


>>> my_data = [20, 7, 32]
[20, 7, 32]
>>> d3.selectAll('.box').data(my_data).text( function(d) { return d } )
[[div.box, div.box, div.box]]


We can see that our data is associated with the DOM element and we can get at it via JavaScript in the console. (Of course, we should only do that for debugging. I would guess that __data__ is the private implementation of d3’s data binding.)


>>> d3.select('.box')[0][0].__data__
20

We can change the data like this:


>>> new_data = [10, 50, 25]
[10, 50, 25]
>>> d3.selectAll('.box').data(new_data)

You’ll see that the page doesn’t change visually, but in the console, you can see that the data does:

We need to explicitly tell d3 to do something with the data like this:


d3.selectAll('.box').text( function(d) { return d } )

We can also use this handy shortcut:


d3.selectAll('.box').text( String )

Comments

EvanZ May 14, 2012

Just wanted to say I appreciate your tutorial. Hopefully somebody writes a d3 book soon.

Nischay July 6, 2012

Awesome ones, would be amazing if you could now explain complex ones :)

Marc Baiges August 6, 2012

About your question regarding nested arrays as result of selections, there is a note on https://github.com/mbostock/d3/wiki/Selections :

Operating on Selections

Selections are arrays of elements—literally. D3 binds additional methods to the array so that you can apply operators to the selected elements, such as setting an attribute on all the selected elements. One nuance is that selections are grouped: rather than a one-dimensional array, each selection is an array of arrays of elements. This preserves the hierarchical structure of subselections. Most of the time, you can ignore this detail, but that's why a single-element selection looks like [[node]] rather than [node]. For more on nested selections, see Nested Selections.

RomaS August 8, 2012

This are very useful tricks, thanks!

Henrik December 9, 2012

Great intro. Thanks!

Denny Lim January 23, 2013

I love this experiments.
Gracias.

Tapan April 19, 2013

Best way to dig into D3, it's awesome :)

Bill June 24, 2013

Finally! A way to get into the guts of d3 and play without constantly refreshing a page and the browser. Thanks!

Santosh Marigowda September 25, 2013

Thank you. Its awesome.