selection.data([data[, key]])
Joins the specified array of data with the selected elements, returning a new selection that it represents the update selection: the elements successfully bound to data. Also defines the enter and exit 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 a function that returns an array of values for each group. When data is assigned to an element, it is stored in the property __data__
, thus making the data “sticky” and available on re-selection.
The data is specified for each group in the selection. If the selection has multiple groups (such as d3.selectAll followed by selection.selectAll), then data should typically be specified as a function. This function will be evaluated for each group in order, being passed the group’s parent datum (d, which may be undefined), the group index (i), and the selection’s parent nodes (nodes), with this as the group’s parent element. For example, to create an HTML table from a matrix of numbers:
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; });
In this example the data function is the identity function: for each table row, it returns the corresponding row from the data matrix.
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. This key function is evaluated for each selected element, in order, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element. The key function is then also evaluated for each new datum in data, being passed the current datum (d), the current index (i), and the group’s new data, with this as the group’s parent DOM element. The datum for a given key is assigned to the element with the matching key. If multiple elements have the same key, the duplicate elements are put into the exit selection; if multiple data have the same key, the duplicate data are put into the enter selection.
For example, given this document:
<div id="Ford"></div> <div id="Jarrah"></div> <div id="Kwon"></div> <div id="Locke"></div> <div id="Reyes"></div> <div id="Shephard"></div>
You could join data by key as follows:
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; });
This example key function uses the datum d if present, and otherwise falls back to the element’s id property. Since these elements were not previously bound to data, the datum d is null when the key function is evaluated on selected elements, and non-null when the key function is evaluated on the new data.
The update and enter selections are returned in data order, while the exit selection preserves the selection order prior to the join. If a key function is specified, the order of elements in the selection may not match their order in the document; use selection.order or selection.sort as needed. For more on how the key function affects the join, see A Bar Chart, Part 2 and Object Constancy.
Although the data-join can be used simply to create (to enter) a set of elements corresponding to data, more generally the data-join is designed to let you create, destroy or update elements as needed so that the resulting DOM corresponds to the new data. The data-join lets you do this efficiently by executing only the minimum necessary operations on each state of element (entering, updating, or exiting), and allows you to declare concise animated transitions between states as well. Here is a simple example of the General Update Pattern:
var circle = svg.selectAll("circle") // 1 .data(data) // 2 .style("fill", "blue"); // 3 circle.exit().remove(); // 4 circle.enter().append("circle") // 5 .style("fill", "green") // 6 .merge(circle) // 7 .style("stroke", "black"); // 8
Breaking this down into discrete steps:
- Any existing circles (that are descendants of the
svg
selection) are selected. - These circles are joined to new
data
, returning the matching circles: the update selection. - These updating circles are given a blue fill.
- Any existing circles that do not match new data—the exit selection—are removed.
- New circles are appended for any new data that do not match any existing circle: the enter selection.
- These entering circles are given a green fill.
- A new selection representing the union of entering and updating circles is created.
- These entering and updating circles are given a black stroke.
As described in the preceding paragraphs, the “matching” logic is determined by the key function passed to selection.data; since no key function is used in the above code sample, the elements and data are joined by index.
If data is not specified, this method returns the array of data for the selected elements.
This method cannot be used to clear bound data; use selection.datum instead.
Please login to continue.