Skip to content

Instantly share code, notes, and snippets.

@Andrew-Reid
Last active May 2, 2018 20:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Andrew-Reid/318d19505c3665d214022ad359124605 to your computer and use it in GitHub Desktop.
Save Andrew-Reid/318d19505c3665d214022ad359124605 to your computer and use it in GitHub Desktop.
Canvas Enter/Update/Exit/Transition
<!DOCTYPE html>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.js"></script>
<body>
<script>
var canvas = d3.select("body")
.append("canvas")
.attr("width", 600)
.attr("height", 200);
var context = canvas.node().getContext("2d");
var data = [1,2,3,4,5];
// container for dummy elements:
var faux = d3.select(document.createElement("custom"));
// normal update exit selection with dummy elements:
function update() {
// modify data:
manipulateData();
var selection = faux.selectAll("circle")
.data(data, function(d) { return d;});
var exiting = selection.exit().size();
var exit = selection.exit()
.transition()
.attr("r",0)
.attr("cy", 70)
.attr("fill","white")
.duration(1200)
.remove();
var enter = selection.enter()
.append("circle")
.attr("cx", function(d,i) {
return (i + exiting) * 20 + 20;
})
.attr("cy", 50)
.attr("r", 0)
.attr("fill",function(d) { return ["orange","steelblue","crimson","violet","yellow"][d%5]; });
enter.transition()
.attr("r", 8)
.attr("cx", function(d,i) {
return i * 20 + 20;
})
.duration(1200);
selection
.transition()
.attr("cx", function(d,i) {
return i * 20 + 20;
})
.duration(1200);
}
// update every 1.2 seconds
setInterval(update,1200);
// rendering function, called repeatedly:
function render() {
context.clearRect(0, 0, 600, 200);
faux.selectAll("circle").each(function() {
var sel = d3.select(this);
context.beginPath();
context.arc(sel.attr("cx"),sel.attr("cy"),sel.attr("r"),0,2*Math.PI);
context.fillStyle = sel.attr("fill");
context.fill();
context.stroke();
})
window.requestAnimationFrame(render)
}
window.requestAnimationFrame(render)
// to manipulate data:
var index = 6; // to keep track of elements.
function manipulateData() {
data.forEach(function(d,i) {
var r = Math.random();
if (r < 0.5 && data.length > 1) {
data.splice(i,1);
}
else {
data.push(index++);
}
})
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment