d3-selection
https://github.com/d3/d3-selection
Table of Contents
- Chaining
- Selecting
- Modifying
selection.attr(name[, value])selection.classed(names[, value])selection.style(name[, value[, priority]])selection.property(name[, value])selection.text([value])selection.html([value])selection.append(type)selection.insert(type[, before])selection.remove()selection.clone([deep])selection.sort(compare)selection.order()selection.raise()selection.lower()
- Joining
- Events
- Control
- Locals
- Thinking with Joins
- How Selections Work
- Nested Selections
- General Update Patterns
- Get the computed width and height for an arbitrary element
Chaining
By convention, selection methods that return the current selection use four spaces of indent, while methods that return a new selection use only two.
d3.select("body")
.append("svg")
.attr("width", 960)
.attr("height", 500)
.append("g")
.attr("transform", "translate(20,20)")
.append("rect")
.attr("width", 920)
.attr("height", 460);Selecting
- Based on W3C selector strings
d3.selection() reference
- Selects the root element,
document.documentElement. - Can be used to test for selections, like
instance of d3.selection - Can be used to extend the selection prototype.
d3.select(selector) reference
- Selects the first element that matches the specified
selectorstring. - If no elements match the
selector, returns an empty selection. selectorcan also be a specified DOM node.
d3.selectAll(selector) reference
- Selects all elements that match the specified
selectorstring. - The elements will be selected in document order.
- If no elements in the document match the selector, returns an empty selection.
- If the selector is not a string, instead selects the specified array of nodes.
selection.select(selector) reference
- For each selected element, selects the first descendant element that matches the specified
selectorstring. selectorcan be a function which acceptsdatum,indexandnodesand returns an element ornull.
selection.selectAll(selector) reference
- Similar to
d3.selectAll(selector)andselection.select(selector). - If no element matches the specified
selectorfor the current element, the element at the current index will be null in the returned selection. A funciton
selectorexample:
selection.filter(filter) reference
- Filters the selection, returning a new selection that contains only the elements for which the specified
filteris true. - The filter may be specified either as a selector
stringor afunction.
selection.merge(other) reference
- Returns a new selection merging this selection with the specified
otherselection.
Modifying
selection.attr(name[, value]) reference
- The function’s return value is then used to set each element’s style property.
- A
nullvalue will remove the style property.
selection.classed(names[, value])
selection.style(name[, value[, priority]]) reference
- Caution: unlike many SVG attributes, CSS styles typically have associated units.
- Make sure you put units like
10px, instead of10.
selection.property(name[, value])
selection.text([value])
selection.html([value])
selection.append(type) reference
- If the specified
typeis a string, appends a new element of this type (tag name) as the last child of each selected element, - Or before the next following sibling in the update selection if this is an enter selection.
- If the specified
typeis a function, it is evaluated for each selected element, in order.
selection.insert(type[, before])
selection.remove()
selection.clone([deep])
selection.sort(compare)
selection.order()
selection.raise()
selection.lower()
Joining
selection.data([data[, key]]) reference
- Joins the specified array of data with the selected elements, returning a new selection that represents the update selection.
- Also defines the
enterandexitselections on the returned selection, which can be used to add or remove elements to correspond to the new data. - The specified
datais an array of arbitrary values (e.g., numbers or objects), or afunctionthat returns an array of values for each group. The
datais specified for each group in the selection.var matrix = [ [11975, 5871, 8916, 2868], [ 1951, 10048, 2060, 6171], [ 8010, 16145, 8090, 8045], [ 1013, 990, 940, 6907] ]; var tr = d3.select("body") .append("table") .selectAll("tr") .data(matrix) .enter().append("tr"); var td = tr.selectAll("td") .data(function(d) { return d; }) .enter().append("td") .text(function(d) { return d; });- If a
keyfunction is not specified, then the first datum in data is assigned to the first selected element, the second datum to the second selected element, and so on. A
keyfunction may be specified to control which datum is assigned to which element, replacing the default join-by-index, by computing a string identifier for each datum and element.<div id="Ford"></div> <div id="Jarrah"></div> <div id="Kwon"></div> <div id="Locke"></div> <div id="Reyes"></div> <div id="Shephard"></div>var data = [ {name: "Locke", number: 4}, {name: "Reyes", number: 8}, {name: "Ford", number: 15}, {name: "Jarrah", number: 16}, {name: "Shephard", number: 31}, {name: "Kwon", number: 34} ]; d3.selectAll("div") .data(data, function(d) { return d ? d.name : this.id; }) .text(function(d) { return d.number; });
selection.enter() reference
- Returns the enter selection: placeholder nodes for each datum that had no corresponding DOM element in the selection.
selection.exit() reference
- Returns the exit selection: existing DOM elements in the selection for which no new datum was found.
selection.datum([value]) reference
- Gets or sets the bound data for each selected element.
- Unlike
selection.data, this method does not compute a join and does not affect indexes or the enter and exit selections.
Events
selection.on(typenames[, listener[, capture]])
selection.dispatch(type[, parameters])
d3.event
d3.customEvent(event, listener[, that[, arguments]])
d3.mouse(container)
d3.touch(container[, touches], identifier)
d3.touches(container[, touches])
d3.clientPoint(container, event)
Control
selection.each(function)
selection.call(function[, arguments…])
selection.empty()
selection.nodes()
selection.node()
selection.size()
Locals
- D3 locals allow you to define local state independent of data.
- D3 locals are scoped by DOM elements
- On
set, the value is stored on the given element. - On
get, the value is retrieved from given element or the nearest ancestor that defines it.
d3.local()
local.set(node, value)
local.get(node)
local.remove(node)
local.toString()
Thinking with Joins tutorial

- Data points joined to existing elements produce the update (inner) selection.
- Leftover unbound data produce the enter selection (left)
- Likewise, any remaining unbound elements produce the exit selection (right)
svg.selectAll("circle")returns a new empty selection- By
.data(data), this selection is then joined to an array of data, resulting in three new selections that represent the three possible states - The update selection is returned by
.data(data) - The missing elements are added to the SVG container by calling
.append("circle")on the enter selection.
The beauty of the data join is that it generalizes.
var circle = svg.selectAll("circle")
.data(data);
circle.exit().remove();
circle.enter().append("circle")
.attr("r", 2.5)
.merge(circle)
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });If the new dataset is smaller than the old one, the surplus elements end up in the exit selection and get removed. If the new dataset is larger, the surplus data ends up in the enter selection and new nodes are added.
How Selections Work discussion
Grouping Elements
- Selections are a subclass of array
A selection is an array of groups, and each group is an array of elements.


- The only way for you to obtain a selection with multiple groups is
selection.selectAll. Every element in the old selection becomes a group in the new selection.


The second argument to your function (i) is the within-group index rather than the within-selection index.
Non-Grouping Operations
selectpreserves the existing grouping.- The
appendandinsertmethods are wrappers on top ofselect, so they also preserve grouping and propagate data.

Null Elements
- Groups can contain nulls to indicate missing elements.
- Nulls are ignored for most operations.
- For example: if only the last two sections have asides:

Bound to Data
- Data is not a property of the selection, but a property of its elements.
- When you bind data to a selection, the data is stored in the DOM rather than in the selection
- Data is assigned to the
__data__property of each element.

What is Data?
selection.datadefines data per-group rather than per-element

The Key to Enlightenment


key function returns the key for a given datum or element.Enter, Update and Exit





update and exit are normal selections, enter is a subclass of selection. This is necessary because it represents elements that do not yet exist.- An
enterselection containsplaceholdersrather than DOM elements; - These
placeholdersare simply objects with a__data__property
enter.appendhas a convenient side-effect: it replacesnullelements in theupdateselection with the newly-created elements from theenterselection. Thus, afterenter.append, theupdateselection is modified to contain both entering and updating elements.
Nested Selections discussion
- Pass a function to
selection.data()
let matrix = [
[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15],
];
let td = d3.selectAll("tbody tr")
.data(matrix)
.selectAll("td")
.data(d => d); // d is matrix[i]General Update Patterns discussion
let text = g.selectAll('text').data(data);
// UPDATE
text.attr('class', 'update');
// ENTER
text.enter().append('text')
.attr('class', 'enter')
.merge(text)
.text(d => d); // place common things
// EXIT
text.exit().remove();transition()
let text = g.selectAll('text').data(data);
let t = d3.transition().duration(750);
// EXIT
text.exit()
.attr('class', 'exit')
.transition(t)
.attr('y', 0)
.remove();
// UPDATE
text.attr('class', 'update');
.transition(t)
.attr('x', (d, i) => i * 32);
// ENTER
text.enter().append('text')
.attr('class', 'enter')
.attr('y', -60)
.text(d => d); // place common things
.transition(t)
.attr('y, 0)