2017-01-11 5 views
1

Es gibt Dinge, die ich nicht klar über die Datenbindung in d3.js verstehe.d3.js Update Datenbindung

Ich habe ein einfaches Beispiel eingerichtet (die here gefunden werden kann), wo vier Zahlen angezeigt:

var data0 = [1, 2, 3, 4]; 
var data1 = [5, 6, 7,8]; 
var data2 = [10, 11,12]; 

var lgth = 100; 
var wdth = 50; 
var position = [[0,0],[0,wdth], [lgth,0],[lgth,wdth]]; 

var svg = d3.select("#test").append("svg") 
      .attr("width", wdth+100) 
      .attr("height", lgth+100); 

svg.selectAll("text").data(data0) 
     .enter().append("text") 
     .text(function(d){return d;}) 
     .attr("x",function(d,i){return position[i][0]+30;}) 
     .attr("y",function(d,i){return position[i][1]+30;}); 

aber wenn ich versuche, diese 4 Zahlen zu aktualisieren, die Funktion:

function draw1(){ 
svg.selectAll("text").data(data1) 
     //.enter().append("text") /* if not commented does nothing*/ 
     .text(function(d){return d;}) 
     .attr("x",function(d,i){return position[i][0]+30;}) 
     .attr("y",function(d,i){return position[i][1]+30;}); 
} 

funktioniert nur, wenn .enter().append("text") kommentiert ist. Warum ? Was passiert, wenn in der neuen Bindung weniger Daten enthalten sind als in der vorherigen?

Vielen Dank im Voraus für die Erklärung!

Antwort

1
svg.selectAll("text").data(data0) 
    .enter().append("text") 
    .text(function(d){return d;}) 
    .attr("x",function(d,i){return position[i][0]+30;}) 
    .attr("y",function(d,i){return position[i][1]+30;}); 

.enter(). Anhängen ("text") werden neue Elemente erstellen, wie gebraucht. Hier haben in diesem Fall beide Arrays data0 und data1 gleiche Anzahl von Elementen, so dass keine neuen Textelemente benötigt werden d3 aktualisiert nur die Werte. Daher keine Notwendigkeit von .enter(). Anhängen („text“)

svg.selectAll("text").data(data1) 
    .text(function(d){return d;}) 
    .attr("x",function(d,i){return position[i][0]+30;}) 
    .attr("y",function(d,i){return position[i][1]+30;}); 

Sie die folgende Zeile in aufnahme1() für Ausfahrt hinzufügen sollten die alten Elemente entfernen (wenn weniger Daten in neue Bindung)

svg.selectAll("text").exit().remove() 

ich empfehle Ihnen, den Prozess das folgende Beispiel bezieht deutlicher zum Verständnis: https://bl.ocks.org/mbostock/3808218

+0

Vielen Dank für Ihren Kommentar. Aber selbst wenn die beiden Datensätze die gleiche Länge haben, sollte .enter(). Append ("text") nicht wie ursprünglich funktionieren und den Text überschreiben? (was nicht der Fall ist!) Ich habe auch svg.selectAll ("text"). exit(). remove() in einer zweiten Funktion [hier] (http://codepen.io/anon/pen/MJKRER? Editoren = 1010) mit einem kleineren Datensatz und es entfernt nicht das alte Element ... – Guillaume

+0

@Guillaume Sobald Sie 'enter()' schreiben, haben Sie eine Eingabeauswahl, deren Größe ** null ** ist, wenn die Länge von Das Datenfeld ist das gleiche. Somit wird '.enter(). Append (" text ")' niemals funktionieren. –

+0

@GerardoFurtado Danke für Ihren Kommentar. Es ist ein wenig klarer: es bedeutet, dass enter() nur für ein neues Element ist. Sagen wir beispielsweise data1.length = 5, was bedeutet, dass ich 4 zu aktualisierende und 1 zu erstellende Texte habe. Wie kann ich das erreichen? Wenn ich enter() schreibe, erzeugt es das fünfte Element, aber nicht die vier anderen, und umgekehrt, wenn ich nicht enter() schreibe, aktualisiert es die 4 Texte, aber der fünfte wird nicht erstellt ... Beispiel [hier ] (http://jsbin.com/herikojeke/edit?html,js,output) – Guillaume