Skip to content

Instantly share code, notes, and snippets.

@jonnolen
Forked from mbostock/.block
Last active March 29, 2017 17:08
Show Gist options
  • Save jonnolen/dd7b7595d1365b9fa3a21d90086fdef6 to your computer and use it in GitHub Desktop.
Save jonnolen/dd7b7595d1365b9fa3a21d90086fdef6 to your computer and use it in GitHub Desktop.
General Update Pattern, I
license: gpl-3.0

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.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) {
// DATA JOIN
// Join new data with old elements, if any.
// Added key function so that letters update in the correct order
// and resort (original implementation just updated by index)
var text = g.selectAll("text")
.data(data, d => d);
// UPDATE
// Update old elements as needed.
var newElements = text.enter().append("text");
//animate updated items to the right color and location.
text.transition()
.duration(500)
.attr("x", function(d,i) { return i * 32; })
.attr("class", "update");
newElements.attr("class", "enter")
.attr("x", function(d, i) { return i * 32; })
.attr("dy", ".35em")
//animate new items in... delay 300, animate over 200, matches 500 duration of updated item animations.
newElements.style('opacity', 0.0)
.transition()
.delay(300)
.duration(200)
.style('opacity', 1.0)
newElements.merge(text).text(function(d) { return d; });
//added tranistion with duration to animate things out.
text.exit().transition()
.duration(200)
.style('opacity', 0.0)
.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