d3-selection

https://github.com/d3/d3-selection

Table of Contents

Chaining

d3.selectAll("p")
  .attr("class", "graf")
  .style("color", "red");
The code above is equivalent to:

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

d3.selection() reference

d3.select(selector) reference

d3.selectAll(selector) reference

selection.select(selector) reference

selection.selectAll(selector) reference

selection.filter(filter) reference

Almost equivalent examples:

selection.merge(other) reference

Modifying

selection.attr(name[, value]) reference

selection.classed(names[, value])

selection.style(name[, value[, priority]]) reference

selection.property(name[, value])

selection.text([value])

selection.html([value])

selection.append(type) reference

selection.insert(type[, before])

selection.remove()

selection.clone([deep])

selection.sort(compare)

selection.order()

selection.raise()

selection.lower()

Joining

selection.data([data[, key]]) reference

selection.enter() reference

selection.exit() reference

selection.datum([value]) reference

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.local()

local.set(node, value)

local.get(node)

local.remove(node)

local.toString()

Thinking with Joins tutorial

Consider:
  1. svg.selectAll("circle") returns a new empty selection
  2. By .data(data), this selection is then joined to an array of data, resulting in three new selections that represent the three possible states
  3. The update selection is returned by .data(data)
  4. 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

Non-Grouping Operations

Null Elements

Bound to Data

What is Data?

The Key to Enlightenment

Joining by index is convenient if your data and elements are in the same order.
Joining by index is convenient if your data and elements are in the same order.
The key function returns the key for a given datum or element.
The key function returns the key for a given datum or element.

Enter, Update and Exit

While update and exit are normal selections, enter is a subclass of selection. This is necessary because it represents elements that do not yet exist.
While update and exit are normal selections, enter is a subclass of selection. This is necessary because it represents elements that do not yet exist.

enter.append has a convenient side-effect: it replaces null elements in the update selection with the newly-created elements from the enter selection. Thus, after enter.append, the update selection is modified to contain both entering and updating elements.

Nested Selections discussion

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();
Updates with transition()

Get the computed width and height for an arbitrary element howto

selection.node().getBBox()