La siguiente es otra versión de la solución de Mike Bostock e inspirada en el comentario de @hughes a la respuesta de @ kashesandr. Hace una única llamada atransition
final.
Dada una drop
función ...
function drop(n, args, callback) {
for (var i = 0; i < args.length - n; ++i) args[i] = args[i + n];
args.length = args.length - n;
callback.apply(this, args);
}
... podemos extendernos d3
así:
d3.transition.prototype.end = function(callback, delayIfEmpty) {
var f = callback,
delay = delayIfEmpty,
transition = this;
drop(2, arguments, function() {
var args = arguments;
if (!transition.size() && (delay || delay === 0)) { // if empty
d3.timer(function() {
f.apply(transition, args);
return true;
}, typeof(delay) === "number" ? delay : 0);
} else { // else Mike Bostock's routine
var n = 0;
transition.each(function() { ++n; })
.each("end", function() {
if (!--n) f.apply(transition, args);
});
}
});
return transition;
}
Como JSFiddle .
Utilizar transition.end(callback[, delayIfEmpty[, arguments...]])
:
transition.end(function() {
console.log("all done");
});
... o con un retraso opcional si transition
está vacío:
transition.end(function() {
console.log("all done");
}, 1000);
... o con callback
argumentos opcionales :
transition.end(function(x) {
console.log("all done " + x);
}, 1000, "with callback arguments");
d3.transition.end
aplicará el pasado callback
incluso con un vacío transition
si se especifica el número de milisegundos o si el segundo argumento es verdadero. Esto también enviará cualquier argumento adicional al callback
(y solo esos argumentos). Es importante destacar que esto no aplicará de forma predeterminadacallback
si transition
está vacío, lo que probablemente sea una suposición más segura en tal caso.