2014-07-23 9 views
16

Ich habe eine kombinierte Balken/Liniendiagramm. Für jede Zeile in der Eingabedatei, erstelle ich eine Gruppe, die mehrere Elemente (Linien, Rechtecke, Texte) enthält:D3: Daten mit mehreren Elementen in einer Gruppe aktualisieren

var myGroups = svg.selectAll('g').data(myData) 
myGroups.enter().append('g') 
... 
myGroups.append('line') 
... 
myGroups.append('polygon') 
... 
myGroups.append('text') 
... 

ich zur Zeit nur

svg.selectAll('*').remove() 

und schaffen alles von Grund auf die Daten jedes Mal, sind aktualisiert. Ich möchte jedoch einen reibungslosen Übergang für alle Elemente haben.

Ich habe durch this tutorial mehrmals gegangen, aber ich verstehe immer noch nicht, wie ich es in meinem Fall tun kann.

Antwort

39

Der Schlüssel ist es, alle Auswahlen zu handhaben, nicht nur die Auswahl eingeben:

var myGroups = svg.selectAll('g').data(myData); 

// enter selection 
var myGroupsEnter = myGroups.enter().append("g"); 
myGroupsEnter.append("line"); 
myGroupsEnter.append("polygon"); 
// ... 

// update selection -- this will also contain the newly appended elements 
myGroups.select("line").attr(...); 
// ... 

// exit selection 
myGroups.exit().remove(); 

Es gibt zwei Dinge, die hier eine weitere Erklärung rechtfertigen. Zuerst werden Elemente in der Eingabeauswahl, an die neue Elemente angehängt wurden, in die Aktualisierungsauswahl eingefügt. Das heißt, es müssen keine Attribute für die Elemente in der Eingabeauswahl festgelegt werden, wenn dasselbe bei der Aktualisierungsauswahl geschieht. Auf diese Weise können Sie neue Elemente hinzufügen und vorhandene aktualisieren, ohne Code zu duplizieren.

Die zweite Sache, wird bei nachfolgenden Aufrufen mit aktualisierten Daten wichtig. Da die Elemente, an die Sie Daten binden, nicht die Daten sind, die tatsächlich gezeichnet werden, müssen die neuen Daten an sie weitergegeben werden. Dies ist, was .select() tut. Das heißt, durch myGroups.select("line") tun, sind propagieren Sie die neuen Daten gebunden an die g Elemente, um ihre Kinder line Elemente. Daher ist der Code zum Festlegen der Attribute der gleiche wie für den Eingabevorgang.

Jetzt können Sie einfach Übergänge hinzufügen, wo es erwünscht ist, bevor die neuen Attribute zu setzen.

+4

Du bist der Wind unter meinen Flügeln! – Mikhail

+1

Laut d3 docs soll 'select()' ein einzelnes Element zurückgeben. Aber hier scheint es, alle Linienelemente in der Anweisung 'myGroups.select (" line ") auszuwählen. Attr (...);'. Und in meinen Experimenten schien 'selectAll()' nicht zu funktionieren. Können Sie die offensichtliche Diskrepanz erklären? – brainjam

+3

'myGroups' enthält mehrere Elemente und' .select() 'führt die Auswahl für jeden von ihnen aus. Das heißt, Sie wählen ein einzelnes Element für mehrere Elemente aus. '.selectAll()' hat wahrscheinlich nicht funktioniert, da die Daten nicht aktualisiert werden. –

Verwandte Themen