Skip to content

Instantly share code, notes, and snippets.

@manzaloros
Forked from mbostock/.block
Created August 14, 2020 13:42
Show Gist options
  • Save manzaloros/1bd0591e61648f21b46b829a435f74f0 to your computer and use it in GitHub Desktop.
Save manzaloros/1bd0591e61648f21b46b829a435f74f0 to your computer and use it in GitHub Desktop.
General Update Pattern, I
license: gpl-3.0
redirect: https://observablehq.com/@d3/selection-join

Note: d3-selection 1.4 introduced selection.join which greatly simplifies the general update pattern! This series of examples is useful for understanding how joins work in D3, but I recommend you use selection.join in practice.

This example demonstrates D3’s general update pattern, where a data-join is followed by operations on the enter, update and exit selections. Entering elements are shown in green, while updating elements are shown in black. Exiting elements are removed immediately, so they're invisible.

This example does not use a key function for the data-join, so elements may change their associated letter. Entering elements are always added to the end: when the new data has more letters than the old data, new elements are entered to display the new letters. Likewise, exiting letters are always removed from the end when the new data has fewer letters than the old data.

Next: Key Functions

<!DOCTYPE html>
<meta charset="utf-8">
<style>
text {
font: bold 48px monospace;
}
.enter {
fill: green;
}
.update {
fill: #333;
}
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
var alphabet = "abcdefghijklmnopqrstuvwxyz".split("");
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
g = svg.append("g").attr("transform", "translate(32," + (height / 2) + ")");
function update(data) {
// DATA JOIN
// Join new data with old elements, if any.
var text = g.selectAll("text")
.data(data);
// UPDATE
// Update old elements as needed.
text.attr("class", "update");
// ENTER
// Create new elements as needed.
//
// ENTER + UPDATE
// After merging the entered elements with the update selection,
// apply operations to both.
text.enter().append("text")
.attr("class", "enter")
.attr("x", function(d, i) { return i * 32; })
.attr("dy", ".35em")
.merge(text)
.text(function(d) { return d; });
// EXIT
// Remove old elements as needed.
text.exit().remove();
}
// The initial display.
update(alphabet);
// Grab a random sample of letters from the alphabet, in alphabetical order.
d3.interval(function() {
update(d3.shuffle(alphabet)
.slice(0, Math.floor(Math.random() * 26))
.sort());
}, 1500);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment