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
selector
string. - If no elements match the
selector
, returns an empty selection. selector
can also be a specified DOM node.
d3.selectAll(selector)
reference
- Selects all elements that match the specified
selector
string. - 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
selector
string. selector
can be a function which acceptsdatum
,index
andnodes
and returns an element ornull
.
selection.selectAll(selector)
reference
- Similar to
d3.selectAll(selector)
andselection.select(selector)
. - If no element matches the specified
selector
for the current element, the element at the current index will be null in the returned selection. A funciton
selector
example:
selection.filter(filter)
reference
- Filters the selection, returning a new selection that contains only the elements for which the specified
filter
is true. - The filter may be specified either as a selector
string
or afunction
.
selection.merge(other)
reference
- Returns a new selection merging this selection with the specified
other
selection.
Modifying
selection.attr(name[, value])
reference
- The function’s return value is then used to set each element’s style property.
- A
null
value 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
type
is 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
type
is 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
enter
andexit
selections on the returned selection, which can be used to add or remove elements to correspond to the new data. - The specified
data
is an array of arbitrary values (e.g., numbers or objects), or afunction
that returns an array of values for each group. The
data
is 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
key
function 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
key
function 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
select
preserves the existing grouping.- The
append
andinsert
methods 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.data
defines data per-group rather than per-element
The Key to Enlightenment
Enter, Update and Exit
- An
enter
selection containsplaceholders
rather than DOM elements; - These
placeholders
are simply objects with a__data__
property
enter.append
has a convenient side-effect: it replacesnull
elements in theupdate
selection with the newly-created elements from theenter
selection. Thus, afterenter.append
, theupdate
selection 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)