Playing around with transitions as a result of this question on Stack Overflow.
The bl.ock adds a method to d3.selection() that allows a user to force the transition to its end state:
Circles start are drawn intially as black. On the beginning of the transition, after the delay (the transition is initalized prior to the delay start) the nodes turn green and begin to transition across the screen. When the transition ends, the nodes turn blue.
Clicking on the nodes forces the transition to its end point while triggering the end event (nodes turn blue). I've added a second transition on click to show those nodes that have been clicked, this transition reduces node radii.
xxxxxxxxxx
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.js"></script>
<body>
<script>
d3.selection.prototype.finish = function() {
// check if there is a transition to finish:
if (this.node().__transition) {
// if there is transition data in any slot in the transition array, call the timer callback:
var slots = this.node().__transition;
var keys = Object.keys(slots);
keys.forEach(function(d,i) {
if(slots[d]) slots[d].timer._call();
})
}
return this;
}
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500);
var circle = svg.selectAll("circle")
.data([1,2,3,4,5,6,7,8])
.enter()
.append("circle")
.attr("cx",50)
.attr("cy",function(d) { return d * 50 })
.attr("r",20)
.on("click", function() { d3.select(this).finish().transition().attr("r",10).duration(1000); })
circle
.transition()
.delay(function(d) { return d * 500; })
.duration(function(d) { return d * 5000; })
.attr("cx", 460)
.on("start", function(d) {
d3.select(this).attr("fill","olive");
})
.on("end", function(d) {
d3.select(this).attr("fill","steelblue");
})
</script>
https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.js