Sie möchten auf das "End" -Ereignis des Übergangs warten.
// d3 v5
d3.select("#myid").transition().style("opacity","0").on("end", myCallback);
// old way
d3.select("#myid").transition().style("opacity","0").each("end", myCallback);
- Diese Demo verwendet das "Ende" -Ereignis, um viele Übergänge der Reihe nach zu verketten.
- Das mit D3 gelieferte Donut-Beispiel verwendet dies auch, um mehrere Übergänge miteinander zu verketten.
- Hier ist meine eigene Demo , die den Stil der Elemente zu Beginn und am Ende des Übergangs ändert.
Aus der Dokumentation für transition.each([type],listener)
:
Wenn der Typ angegeben ist, wird ein Listener für Übergangsereignisse hinzugefügt, der sowohl "Start" - als auch "Ende" -Ereignisse unterstützt. Der Listener wird für jedes einzelne Element im Übergang aufgerufen, auch wenn der Übergang eine konstante Verzögerung und Dauer aufweist. Das Startereignis kann verwendet werden, um eine sofortige Änderung auszulösen, wenn jedes Element mit dem Übergang beginnt. Das Endereignis kann verwendet werden, um mehrstufige Übergänge einzuleiten, indem das aktuelle Element ausgewählt this
und ein neuer Übergang abgeleitet wird. Während des Endereignisses erstellte Übergänge erben die aktuelle Übergangs-ID und überschreiben daher keinen neueren Übergang, der zuvor geplant wurde.
Weitere Informationen finden Sie in diesem Forenthread zum Thema .
Beachten Sie schließlich, dass Sie die Elemente verwenden können, wenn Sie sie nur nach dem Ausblenden (nach Abschluss des Übergangs) entfernen möchten transition.remove()
.
d3.selectAll()
(stattdessen nach Abschluss jedes Elements)? Mit anderen Worten, ich möchte nur eine Funktion zurückrufen, sobald alle Elemente den Übergang abgeschlossen haben..each
Ereignis-Listener noch das"end"
Ereignis verwendet. Es scheint keine Übergänge zu "verketten". Der zweite Link zeigt auf einen Github, der für mich nicht geladen wird.Mike Bostocks Lösung für v3 mit einem kleinen Update:
quelle
if (transition.size() === 0) { callback(); }
function endall(transition, callback){ if(!callback) return; // ... }
oder, da es mit Sicherheit ein Fehler ist, diese Funktion ohne Rückruf aufzurufen, eine Ausnahme auslöst Ich denke, dieser Fall muss nicht zu kompliziert sein. Ausnahmefunction endall(transition, callback){ if(!callback) throw "Missing callback argument!"; // .. }
enter()
undexit()
Übergänge haben und warten möchten, bis alle drei abgeschlossen sind, müssen wir Code in den Rückruf einfügen, um sicherzustellen, dass er dreimal aufgerufen wurde, oder? D3 ist so chaotisch! Ich wünschte, ich hätte eine andere Bibliothek ausgewählt.In d3 v4.0 gibt es jetzt eine Möglichkeit, Ereignishandler explizit an Übergänge anzuhängen:
https://github.com/d3/d3-transition#transition_on
Um Code auszuführen, wenn ein Übergang abgeschlossen ist, benötigen Sie lediglich:
quelle
transition.remove()
( Link ), der einen allgemeinen Anwendungsfall für den Übergang eines Elements aus der Ansicht behandelt: `" Entfernt für jedes ausgewählte Element das Element, wenn der Übergang endet, solange das Element keine anderen aktiven oder ausstehenden Übergänge aufweist Element hat andere aktive oder ausstehende Übergänge, tut nichts. "Ein etwas anderer Ansatz, der auch funktioniert, wenn viele Übergänge mit vielen Elementen gleichzeitig ausgeführt werden:
quelle
Das Folgende ist eine andere Version von Mike Bostocks Lösung und inspiriert von @hughes 'Kommentar zu @ kashesandrs Antwort. Es macht einen einzelnen Rückruf am
transition
Ende.Gegeben eine
drop
Funktion ...... wir können
d3
so erweitern:Als JSFiddle .
Verwendung
transition.end(callback[, delayIfEmpty[, arguments...]])
:... oder mit einer optionalen Verzögerung, wenn
transition
leer:... oder mit optionalen
callback
Argumenten:d3.transition.end
wendet das übergebenecallback
auch mit einem Leerzeichen an,transition
wenn die Anzahl der Millisekunden angegeben ist oder wenn das zweite Argument wahr ist. Dadurch werden auch alle zusätzlichen Argumente ancallback
(und nur diese Argumente) weitergeleitet. Wichtig ist, dass dies nicht standardmäßig gilt,callback
wenn iftransition
leer ist, was in einem solchen Fall wahrscheinlich eine sicherere Annahme ist.quelle
Ab D3 v5.8.0 + gibt es jetzt eine offizielle Möglichkeit, dies mit zu tun
transition.end
. Die Dokumente sind hier:https://github.com/d3/d3-transition#transition_end
Ein Arbeitsbeispiel von Bostock finden Sie hier:
https://observablehq.com/@d3/transition-end
Und die Grundidee ist, dass
.end()
der Übergang nur durch Anhängen ein Versprechen zurückgibt , das sich erst auflöst, wenn alle Elemente übergangen sind:Weitere Informationen finden Sie in den Versionshinweisen zur Version:
https://github.com/d3/d3/releases/tag/v5.8.0
quelle
Die Lösung von Mike Bostock wurde verbessert, indem kashesandr + Argumente an die Rückruffunktion übergeben wurden:
quelle
Tatsächlich gibt es noch eine Möglichkeit, dies mithilfe von Timern zu tun.
quelle
Ich habe ein ähnliches Problem gelöst, indem ich mithilfe einer Variablen eine Dauer für Übergänge festgelegt habe. Dann habe ich
setTimeout()
die nächste Funktion aufgerufen. In meinem Fall wollte ich eine leichte Überlappung zwischen dem Übergang und dem nächsten Anruf, wie Sie in meinem Beispiel sehen werden:quelle