d3 Transition Promise
Creates a then() function on a D3 prototype to allow the use of Promises on completion of transitions.
CSS
circle {
fill: red;
}
JavaScript
// CLASSIFICATION: EXTERNAL. Copyright (c) 2016 MooD Enterprises Ltd. All Rights Reserved.
/**
* The then() method returns a Promise that will be fullfilled upon the completion of all transitions.
* @param {Function} - A Function called when the Transition has completed. This function has one argument, the fulfillment value.
* @param {Function} - A Function called when the Transition fails for any reason. This function has one argument, the rejection reason.
* @return {Function} - A Promise
*/
d3.transition.prototype.then = function(onFulfilled, onRejected) {
// Create a sub transition. Within `then` we use the .each("end) function
// which will over-write any that have already been called on the
// transition object. Therefore the best way is to create a sub-transition
// to preserve the original that doesn't do anything
//let promiseTransition = this.transition();
let promiseTransition = this;
// Work out the transition object which is either __transition__ or __transition_fill_
// depending on whether or not it is named
const transitionName = this.namespace || "__transition__";
// Construct a promise that is going to be returned, this
// promise will be stored (with any other promises) against
// the transition object
return new Promise((resolve, reject) => {
// We're going to count the number of elements
// that we're transitioning over, such that the promise
// only fires when all elements have finished transitioning
let n = 0;
// Store the resolve of the promise against each element,
// along with incrementing our counter. Note that we don't
// currently fire a rejected
promiseTransition.each(function() {
const transition = this[transitionName];
transition._promises = transition._promises || [];
transition._promises.push(resolve);
n++;
})
.each("end.test", function() {
const transition =...