Quieres escuchar el evento "final" de la transición.
// d3 v5
d3.select("#myid").transition().style("opacity","0").on("end", myCallback);
// old way
d3.select("#myid").transition().style("opacity","0").each("end", myCallback);
- Esta demostración utiliza el evento "end" para encadenar muchas transiciones en orden.
- El ejemplo de donut que se envía con D3 también usa esto para encadenar múltiples transiciones.
- Aquí está mi propia demostración que cambia el estilo de los elementos al principio y al final de la transición.
De la documentación para transition.each([type],listener)
:
Si se especifica el tipo , agrega un detector para eventos de transición, que admite eventos de "inicio" y "finalización". Se invocará al oyente para cada elemento individual de la transición, incluso si la transición tiene un retraso y una duración constantes. El evento de inicio se puede utilizar para activar un cambio instantáneo a medida que cada elemento comienza a realizar la transición. El evento final se puede utilizar para iniciar transiciones de varias etapas seleccionando el elemento actual this
y derivando una nueva transición. Cualquier transición creada durante el evento final heredará el ID de transición actual y, por lo tanto, no anulará una transición más nueva que se programó previamente.
Ver este hilo del foro sobre el tema para obtener más detalles.
Finalmente, tenga en cuenta que si solo desea eliminar los elementos después de que se hayan desvanecido (una vez finalizada la transición), puede usar transition.remove()
.
d3.selectAll()
(en lugar de eso, después de que finalice cada elemento)? En otras palabras, solo quiero volver a llamar a una función una vez que todos los elementos terminen de hacer la transición..each
detector de eventos, ni el"end"
evento. No parece "encadenar" las transiciones. El segundo enlace apunta a un github que no se carga para mí.Solución de Mike Bostock para v3 con una pequeña actualización:
fuente
if (transition.size() === 0) { callback(); }
function endall(transition, callback){ if(!callback) return; // ... }
o, dado que es más seguro un error llamar a esta función sin una devolución de llamada, arrojar una excepción a ser la forma adecuada de manejar la situación Creo que este caso no necesita una excepción demasiado complicadafunction endall(transition, callback){ if(!callback) throw "Missing callback argument!"; // .. }
enter()
y separadasexit()
, y queremos esperar hasta que las tres hayan terminado, debemos poner código en la devolución de llamada para asegurarnos de que se haya invocado tres veces, ¿verdad? ¡D3 es tan desordenado! Ojalá hubiera elegido otra biblioteca.Ahora, en d3 v4.0, hay una función para adjuntar explícitamente controladores de eventos a las transiciones:
https://github.com/d3/d3-transition#transition_on
Para ejecutar código cuando se completa una transición, todo lo que necesita es:
fuente
transition.remove()
( enlace ), que maneja un caso de uso común de transición de un elemento de la vista: `" Para cada elemento seleccionado, elimina el elemento cuando finaliza la transición, siempre que el elemento no tenga otras transiciones activas o pendientes. Si el elemento tiene otras transiciones activas o pendientes, no hace nada. "Un enfoque ligeramente diferente que funciona también cuando hay muchas transiciones con muchos elementos, cada uno ejecutándose simultáneamente:
fuente
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 a
transition
final.Dada una
drop
función ...... podemos extendernos
d3
así:Como JSFiddle .
Utilizar
transition.end(callback[, delayIfEmpty[, arguments...]])
:... o con un retraso opcional si
transition
está vacío:... o con
callback
argumentos opcionales :d3.transition.end
aplicará el pasadocallback
incluso con un vacíotransition
si se especifica el número de milisegundos o si el segundo argumento es verdadero. Esto también enviará cualquier argumento adicional alcallback
(y solo esos argumentos). Es importante destacar que esto no aplicará de forma predeterminadacallback
sitransition
está vacío, lo que probablemente sea una suposición más segura en tal caso.fuente
A partir de D3 v5.8.0 +, ahora hay una forma oficial de hacer esto usando
transition.end
. Los documentos están aquí:https://github.com/d3/d3-transition#transition_end
Un ejemplo práctico de Bostock está aquí:
https://observablehq.com/@d3/transition-end
Y la idea básica es que con solo agregar
.end()
, la transición devolverá una promesa que no se resolverá hasta que todos los elementos hayan terminado de hacer la transición:Consulte las notas de la versión para obtener más información:
https://github.com/d3/d3/releases/tag/v5.8.0
fuente
La solución de Mike Bostock fue mejorada por kashesandr + pasando argumentos a la función de devolución de llamada:
fuente
En realidad, hay una forma más de hacer esto usando temporizadores.
fuente
Resolví un problema similar estableciendo una duración en las transiciones usando una variable. Entonces solía
setTimeout()
llamar a la siguiente función. En mi caso, quería una ligera superposición entre la transición y la siguiente llamada, como verá en mi ejemplo:fuente