Suche…


Syntax

  • selection.enter ()
  • selection.exit ()
  • selection.merge ()

Aktualisieren der Daten: Ein einfaches Beispiel für die Eingabe, Aktualisierung und Beendigung von Auswahlen

Das Erstellen eines Diagramms mit einem statischen Datensatz ist relativ einfach. Wenn wir zum Beispiel dieses Array von Objekten als Daten haben:

var data = [
    {title: "A", value: 53},
    {title: "B", value: 12},
    {title: "C", value: 91},
    {title: "D", value: 24},
    {title: "E", value: 59}
];

Wir können ein Balkendiagramm erstellen, in dem jeder Balken eine Kennzahl namens "Titel" darstellt und deren Breite den Wert dieser Kennzahl darstellt. Da sich dieser Datensatz nicht ändert, enthält unser Balkendiagramm nur eine Auswahl "Enter":

var bars = svg.selectAll(".bars")
    .data(data);

bars.enter()
    .append("rect")
    .attr("class", "bars")
    .attr("x", xScale(0))
    .attr("y", function(d){ return yScale(d.title)})
    .attr("width", 0)
    .attr("height", yScale.bandwidth())
    .transition()
    .duration(1000)
    .delay(function(d,i){ return i*200})
    .attr("width", function(d){ return xScale(d.value) - margin.left});

Hier setzen wir die Breite jedes Balkens auf 0 und nach dem Übergang auf den endgültigen Wert.

Diese Auswahl allein reicht aus, um unser Diagramm zu erstellen, das Sie in dieser Geige sehen können .

Was aber, wenn sich meine Daten ändern?

In diesem Fall müssen wir unseren Chart dynamisch ändern. Am besten erstellen Sie eine Auswahl für "Eingabe", "Aktualisierung" und "Beenden". Vorher müssen wir jedoch einige Änderungen am Code vornehmen.

Zuerst verschieben wir die sich ändernden Teile in eine Funktion namens draw() :

function draw(){
    //changing parts
};

Diese "wechselnden Teile" umfassen:

  1. Die Eingabe-, Aktualisierungs- und Beendigungsauswahl;
  2. Die Domäne jeder Skala;
  3. Der Übergang der Achse;

Innerhalb dieser draw() Funktion rufen wir eine andere Funktion auf, die unsere Daten erstellt. Hier handelt es sich lediglich um eine Funktion, die ein Array von 5 Objekten zurückgibt. Dabei werden zufällig 5 von 10 Buchstaben (alphabetisch sortiert) und für jedes Objekt ein Wert zwischen 0 und 99 ausgewählt:

function getData(){
    var title = "ABCDEFGHIJ".split("");
    var data = [];
    for(var i = 0; i < 5; i++){
        var index = Math.floor(Math.random()*title.length);
        data.push({title: title[index],
            value: Math.floor(Math.random()*100)});
        title.splice(index,1);
    }
    data = data.sort(function(a,b){ return d3.ascending(a.title,b.title)});
    return data;
};

Und nun zu unserer Auswahl. Aber vorher noch ein Wort der Vorsicht: Um die so genannte Objektkonstanz zu erhalten , müssen wir eine Schlüsselfunktion als zweites Argument für selection.data angeben:

var bars = svg.selectAll(".bars")
    .data(data, function(d){ return d.title});

Ohne das wechseln unsere Balken nicht reibungslos und es wäre schwierig, den Änderungen in der Achse zu folgen (Sie können sehen, dass das zweite Argument unten in der Geige entfernt wird).

Wenn wir also die var bars richtig eingestellt haben, können wir unsere Auswahl treffen. Dies ist die Ausgangsauswahl:

bars.exit()
    .transition()
    .duration(1000)
    .attr("width", 0)
    .remove();

Dies sind die Eingaben und die Aktualisierungsauswahlen (in D3 v4.x wird die Aktualisierungsauswahl mit der Eingabeauswahl durch merge ):

bars.enter()//this is the enter selection
    .append("rect")
    .attr("class", "bars")
    .attr("x", xScale(0) + 1)
    .attr("y", function(d){ return yScale(d.title)})
    .attr("width", 0)
    .attr("height", yScale.bandwidth())
    .attr("fill", function(d){ return color(letters.indexOf(d.title)+1)})
    .merge(bars)//and from now on, both the enter and the update selections
    .transition()
    .duration(1000)
    .delay(1000)
    .attr("y", function(d){ return yScale(d.title)})
    .attr("width", function(d){ return xScale(d.value) - margin.left});

Zum Schluss rufen wir die draw() -Funktion jedes Mal auf, wenn auf die Schaltfläche geklickt wird:

d3.select("#myButton").on("click", draw);

Und dies ist die Geige, die all diese drei Auswahlen in Aktion zeigt.

Auswahl zusammenführen

Das Aktualisierungsmuster in D3 Version 3

Ein korrektes Verständnis der Funktionsweise der Auswahlmöglichkeiten "Eintreten", "Aktualisieren" und "Beenden" ist für das korrekte Ändern des Dataviz mit D3 von grundlegender Bedeutung.

Seit D3 Version 3 (eigentlich seit Version 2) konnte dieses Snippet die Übergänge sowohl für die Eingabe- als auch für die Aktualisierungsauswahl festlegen ( Live-Demo hier ):

var divs = body.selectAll("div")
    .data(data);//binding the data

divs.enter()//enter selection
    .append("div")
    .style("width", "0px");

divs.transition()
    .duration(1000)
    .style("width", function(d) { return d + "px"; })
    .attr("class", "divchart")
    .text(function(d) { return d; });

Dieses Ergebnis nach dem Übergang geben:

Geben Sie hier die Bildbeschreibung ein

Aber was passiert mit genau demselben Code, wenn wir D3 Version 4 verwenden? Sie können es in dieser Live-Demo sehen : nichts !

Warum?

Änderungen im Update-Pattern in D3 Version 4

Lassen Sie uns den Code überprüfen. Zuerst haben wir divs . Diese Auswahl bindet die Daten an das <div> .

var divs = body.selectAll("div")
    .data(data); 

Dann haben wir divs.enter() , eine Auswahl, die alle Daten mit nicht übereinstimmenden Elementen enthält. Diese Auswahl enthält alle Divs beim ersten Aufruf der Funktion draw , und wir setzen deren Breite auf Null.

divs.enter()
    .append("div")
    .style("width", "0px");

Dann haben wir divs.transition() , und hier haben wir das interessante Verhalten: In D3 Version 3 divs.transition() dass alle <div> in der Auswahl "enter" auf ihre endgültige Breite divs.transition() . Das macht aber keinen Sinn! divs enthält nicht die Eingabe- divs und sollte kein DOM-Element ändern.

Es gibt einen Grund, warum dieses seltsame Verhalten in D3 Version 2 und 3 ( Quelle hier ) eingeführt wurde, und es wurde in D3 Version 4 "korrigiert". In der obigen Live-Demo passiert also nichts, und dies wird erwartet! Wenn Sie auf die Schaltfläche klicken, werden außerdem alle vorherigen sechs Balken angezeigt, da sie sich jetzt in der Auswahl „Aktualisieren“ befinden und nicht mehr in der Auswahl „Eingeben“.

Für den Übergang, der über die Auswahl "enter" wirkt, müssen wir separate Variablen erstellen oder die Auswahl einfacher zusammenführen:

divs.enter()//enter selection
    .append("div")
    .style("width", "0px")
    .merge(divs)//from now on, enter + update selections
    .transition().duration(1000).style("width", function(d) { return d + "px"; })
    .attr("class", "divchart")
    .text(function(d) { return d; });

Jetzt haben wir die Auswahlen "enter" und "update" zusammengeführt. Sehen Sie, wie es in dieser Live-Demo funktioniert.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow