Skip to content

Instantly share code, notes, and snippets.

@EmbraceLife
Last active August 1, 2016 09:27
Show Gist options
  • Save EmbraceLife/d6e2c44f9c525849c4a06bfe1c5f5def to your computer and use it in GitHub Desktop.
Save EmbraceLife/d6e2c44f9c525849c4a06bfe1c5f5def to your computer and use it in GitHub Desktop.
9. key-function-update-pattern
license: gpl-3.0
<!DOCTYPE html>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="960" height="500"></svg>
<style>
text {
font: bold 48px monospace;
}
.enter {
fill: green;
}
.update {
fill: #333;
}
</style>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
g = svg.append("g").attr("transform", "translate(32," + (height / 2) + ")");
var alphabet = "abcdefghijklmnopqrstuvwxyz".split("");
function update(data) {
// ---- step 6: map/update new data to existing doms ---------------------
// 1. bind data with dom using index
// Code: var text = g.selectAll("text").data(data);
// 1. split new data into update,enter,exit groups by index or length of array
// 2. update = newData.slice(0, min([oldData.length-1, newData.length-1]))
// 3. if oldData.length > newData.length, then enter = []
// 4. if oldData.length < newData.length, then enter = newData.slice[oldData.length, newData.length-1]
// 2. bind data with dom using key-function
// Code: var text = g.selectAll("text")
// .data(data, function(d) { return d; });
// 1. update = intersect(newData, oldData), intersection datum keep their index from newData;
// 2. enter = elements in newData & out oldData, elements keep their index from newData
// 3. merge = enter + update = full newData, index as they are in newData
// 3. exit = elements in oldData & out newData, elements keep their index from oldData
var text = g.selectAll("text")
.data(data, function(d) { return d; });
// Joining by index is convenient if your data and elements are in the same order. However, when orders differ, joining by index is insufficient! In this case, you can specify a key function as the second argument to selection.data. The key function returns the key for a given datum or element.
// 3. add className attr to
text.attr("class", "update")
// .attr("dy", ".35em")
// .attr("x", function(d,i){return i*32})
// .text(function(d) { return d; });
var enterText = text.enter().append("text")
.attr("class", "enter")
// .attr("dy", ".35em")
// .attr("x", function(d,i){return i*32})
// .text(function(d) { return d; });
var mergedText = enterText
.merge(text)
.attr("dy", ".35em")
.attr("x", function(d,i){return i*32})
.text(function(d) { return d; });
text.exit().remove();
}
update(alphabet);
d3.interval(function() {
update(d3.shuffle(alphabet)
.slice(0, Math.floor(Math.random() * 26))
.sort());
}, 1000);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment