Skip to content

Instantly share code, notes, and snippets.

@mbostock
Forked from mbostock/.block
Last active July 14, 2022 13:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 13 You must be signed in to fork a gist
  • Save mbostock/3808234 to your computer and use it in GitHub Desktop.
Save mbostock/3808234 to your computer and use it in GitHub Desktop.
General Update Pattern, III
license: gpl-3.0
redirect: https://observablehq.com/@d3/selection-join

By adding transitions, we can more easily follow the elements as they are entered, updated and exited. Separate transitions are defined for each of the three states. To avoid repeating transition timing parameters for the enter, update, and exit selections, a top-level transition t sets the duration, and then subsequent transitions use selection.transition, passing in t to inherit timing:

var t = d3.transition()
    .duration(750);

Want to read more? Try these tutorials:

See the D3 wiki for even more resources.

Previous: Key Functions

<!DOCTYPE html>
<meta charset="utf-8">
<style>
text {
font: bold 48px monospace;
}
.enter {
fill: green;
}
.update {
fill: #333;
}
.exit {
fill: brown;
}
</style>
<svg width="960" height="500"></svg>
<script src="https://d3js.org/d3.v4.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) {
var t = d3.transition()
.duration(750);
// JOIN new data with old elements.
var text = g.selectAll("text")
.data(data, function(d) { return d; });
// EXIT old elements not present in new data.
text.exit()
.attr("class", "exit")
.transition(t)
.attr("y", 60)
.style("fill-opacity", 1e-6)
.remove();
// UPDATE old elements present in new data.
text.attr("class", "update")
.attr("y", 0)
.style("fill-opacity", 1)
.transition(t)
.attr("x", function(d, i) { return i * 32; });
// ENTER new elements present in new data.
text.enter().append("text")
.attr("class", "enter")
.attr("dy", ".35em")
.attr("y", -60)
.attr("x", function(d, i) { return i * 32; })
.style("fill-opacity", 1e-6)
.text(function(d) { return d; })
.transition(t)
.attr("y", 0)
.style("fill-opacity", 1);
}
// 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