.Enter()
stage LEFT
What D3's superstar method
gets up to behind the scenes
Plus! intro to the D3 source
Hello
So, THIS CAUGHT MY EYE RECENTLY...
"I’ve been reflecting on the
world-consuming popularity of
Mike Bostock and Jason Davies’s
D3 library...
everyone wants to do something
with it, but very few people
claim to understand it."
Mike Migurski
"...I attempted to explain the
“.data()” method to a friend
at JS.Geo and realized that
I also was missing
a critical piece myself."
WHY THIS TALK, WHY TODAY
THE QUESTIONS I SET OUT TO ANSWER...
CAVEAT
JOURNEY TO THE SOURCE
GETTING STARTED
npm reads package.json and installs:
-
jsdom (JavaScript implementation of the DOM)
-
uglify (for minification)
-
vows (for testing)
GETTING STARTED
IN ASCending order of interest...
index.js - used by npm
d3.min.js - compiled D3 file
src/ - THE SOURCE
MAKING D3
MAKING D3
HOW THE MAKEFILE WORKS
HOW THE MAKEFILE WORKS
LOGICAL, HIERARCHICAL STRUCTURE
FOLLOW"s D3's INternal structure...
...AND SO DO THE DOCS
EVERYTHING IS FALLING NICELY INTO PLACE!
WHERE ARE .Enter() and .DATA()?
var svg = d3.select('body').append('svg');
var data = [2,3,5,10];
var circle = svg.selectAll('circle').data(data);
circle.enter().append('circle').attr('r', 10);
circle.attr('cx', function(d) { return d*10 });
circle.attr('cy', function(d) { return d*10 });
circle.exit().remove();
SOURCE: THINKING WITH JOINS
THINKING WITH JOINS
WHAT .DATA() DOES (APPROX)
d3_selectionPrototype.data = function(value, key) { function bind(group, groupData) { // Bind data to nodes! } // enter, update and exit are also d3_selectionPrototypes - // arrays with methods like .select and .data defined. var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); // Bind data to nodes! (which are in 'this') while (++i < n) { bind(group = this[i], value); } update.enter = function() { return enter; }; update.exit = function() { return exit; }; return update; }
Full version in the source: line 1676 onwards.
What .DATA() DOES (PSEUDOCODE)
-
Called on 'd3 selection' objects - arrays of nodes with a bunch of extra functions defined, like .select() and .attr().
-
Take a dataset, and optionally a key function.
-
Defines new 'd3 selection' objects called update, enter and exit.
- Runs bind for each node... see next slide.
- Set enter and exit as properties on update, and return the update object.
HOW DATA IS BOUND
function bind(group, groupData) {
var i,
n = group.length,
m = groupData.length,
n0 = Math.min(n, m),
// for the length of the nodes, or the length of the data,
// whichever is less, bind the data to the existing nodes.
for (i = -1; ++i < n0;) {
node = group[i];
nodeData = groupData[i];
node.__data__ = nodeData;
updateNodes[i] = node;
}
// Add any leftover data to the enter selection.
for (; i < m; ++i) {
enterNodes[i] = d3_selection_dataNode(groupData[i]);
}
// And any leftover nodes to the exit selection.
for (; i < n; ++i) {
exitNodes[i] = group[i];
}
}
Full version in the source: line 1687 onwards.
HOW BINDING WORKS (PSEUDOCODE)
-
Bind the data to the nodes:
- For the length of the data or the nodes (whichever is shorter), update the __data__ attribute of each node, and add it to update.
- For the extra length of the data (if any): create a new node and add it to enter.
- For the extra length of the nodes (if any): add the node to exit.
THINKING WITH JOINS (MY VERSION)
The LAST WORDS
"A... useful metaphor I’ve been exploring
in code this week is D3 as nuclear fuel.
This starts to feel a bit more helpful,
because it suggests a clear approach
to D3 for mortal developers: use the power,
but keep it carefully contained."
D3: Journey to the source
By annaps
D3: Journey to the source
- 22,146