I was recently working on a few D3 projects. I have used D3 in the past and think it is really awesome. Here is a list of notes I am using as I refresh my mind to think in terms of data-driven documents:

Selections

With one element selected, append one additional element
d3.select("body").append("h1").text("hello world")
Select all existing h1s and update their text
d3.selectAll("h1").text("hello world again 1")
Add a bunch of h1 elements bound to data array:
d3.select("body").selectAll("h1")
.data([1,2,3]).enter().append("h1").text("hello world")

Data Binding

  • data can be arrays or objects
  • use data to create new elements
  • existing elements on a page that were hard coded have no data bound to them. this can be very confusing
  • to see what data is bound to a given element, use d3.select and than look at the __data__ element in the chrome console
  • to specify what data gets bound to which element, use the key function
var circle = svg.selectAll("circle")
.data([32, 57, 293], function(d) { return d; });
  • given three circles on the page, bind some data to them and update their radius. note this does not update the enter selection, just the current circles that are on the page
d3.select("svg").selectAll("circle")
.data([2,4,6,7]).attr("r",function(d){ return 2*d})

`

  • given three circles on a page, bind data to them, add an additional circles per the data source ( one circle for datum 7) and and it to the page. this does not update the existing circles on the page (update selection), just the enter selection.
d3.select("svg").selectAll("circle")
.data([2,4,6,7]).enter().append("circle")
.attr("r",function(d){ return 2*d})
Enter, Updated, Exit

-Thinking In Joins

Enter

Given three existing circles, a new data point was added to the enter select corresponding to datum 7. Since we call append here, this new 4th circle was added to the DOM

d3.select("svg").selectAll("circle")
.data([2,4,6,7]).enter()
.append("circle")
.attr("r",function(d){ return 2*d})
Update

Given 3 existing circles in the SVG, new data was bound to these circles (2,4,6). After the data was bound to the circle, we updated the circle radius using the newly bound data. Note that even though we are passing an array of size 4, we are not doing anything with the last element (7) here, because that is in the enter selection, and right now we are only working with the update selection.

d3.select("svg")
.selectAll("circle").data([2,4,6,7])
.attr("r",function(d){ return 2*d})
Exit

Given three existing circles with data bound to them [2,4,6], remove 2, and 6 and add 7:

Given three circles, bind some new data to them and perform UPDATE

d3.select("svg").selectAll("circle").data([2,4,6])
.attr("r", function(d){ return 2*d})

Now, add a 4th circle using new data element, which goes into enter select, and update it

d3.select("svg").selectAll("circle")
.data([2,4,6,7]).attr("r", function(d){ return 2*d})
.enter().append("circle").attr("r", function(d){ return 2*d})

Finally, remove 2,6 leaving data bound to 4 and 7

d3.select("svg").selectAll("circle")
.data([4,7]).exit().remove()