We are so used to the name D3.js that it's possible to forget that D3 is actually DDD (Data-Driven Documents). And that's what D3 does well, a data-driven approach to DOM (Document Object Model) manipulation: D3 binds data to DOM elements and manipulates those elements based on the bounded data.
Let's see a very basic feature of D3 in this example. Here, we won't append any SVG element. Instead, we'll use an SVG already present on the page, something like this:
<svg width="400" height="400">
<circle cx="50" cy="50" r="10"></circle>
<circle cx="150" cy="50" r="10"></circle>
<circle cx="210" cy="320" r="10"></circle>
<circle cx="210" cy="30" r="10"></circle>
<circle cx="180" cy="200" r="10"></circle>
</svg>
This is a pretty basic SVG, with 5 circles. Right now, those circles are not "bound" to any data. Let's check this last allegation:
In our code, we write:
var svg = d3.select("svg");
var circles = svg.selectAll("circle");
console.log(circles.nodes());
Here, d3.select("svg")
returns a d3 object containing <svg width="400" height="400"></svg>
tag and all child tags, the <circle>
s. Note that if multiple svg
tags exist on the page, only the first is selected. If you do not want this, you can also select by tag id, like d3.select("#my-svg")
. The d3 object has built in properties and methods that we will use a lot later.
svg.selectAll("circle")
creates an object from all <circle></circle>
elements from within the <svg>
tag. It can search through multiple layers, so it does not matter if the tags are direct children.
circles.nodes()
returns the circle tags with all of their properties.
If we look at the console and choose the first circle, we're gonna see something like this:
First, we have attributes
, then childNodes
, then children
, and so on... but no data.
Let's bind some data
But, what happens if we bind data to these DOM elements?
In our code, there is a function that creates an object with two properties, x
and y
, with numeric values (this object is inside an array, check the fiddle below). If we bind this data to the circles...
circles.data(data);
This is what we are going to see if we inspect the console:
We have something new just before attributes
! Something named __data__
... and look: the values of x
and y
are there!
We can, for instance, change the position of the circles based on these data. Have a look at this fiddle.
This is what D3 does best: binding data to DOM elements and manipulating those DOM elements based on the bounded data.