Sök…


Syntax

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

Uppdatering av data: ett grundläggande exempel på val, ange, uppdatera och avsluta

Att skapa ett diagram som visar ett statiskt datasätt är relativt enkelt. Om vi till exempel har denna grupp av objekt som data:

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

Vi kan skapa ett stapeldiagram där varje stapel representerar ett mått, med namnet "titel", och dess bredd representerar värdet på det måttet. Eftersom detta datasätt inte ändras har vårt stapeldiagram bara ett "enter" -val:

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});

Här ställer vi bredden på varje stapel på 0 och, efter övergången, till dess slutliga värde.

Det här inmatningsvalet, ensam, är tillräckligt för att skapa vårt diagram som du kan se i denna fiol .

Men vad händer om mina data ändras?

I det här fallet måste vi dynamiskt ändra vårt diagram. Det bästa sättet att göra det är att skapa val "enter", "update" och "exit". Men innan detta måste vi göra några ändringar i koden.

Först flyttar vi de växlande delarna inuti en funktion som heter draw() :

function draw(){
    //changing parts
};

Dessa "växlande delar" inkluderar:

  1. Valet för enter, uppdatering och utgång;
  2. Domänen för varje skala;
  3. Övergången till axeln;

Inuti funktionen draw() kallar vi en annan funktion som skapar våra data. Här är det bara en funktion som returnerar en matris med 5 objekt, valt slumpmässigt 5 bokstäver av 10 (sortering alfabetiskt) och, för var och en, ett värde mellan 0 och 99:

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;
};

Och nu, låt oss gå till våra val. Men innan detta, ett försiktighetsord: för att upprätthålla det vi kallar objektkonstans måste vi ange en nyckelfunktion som det andra argumentet till Selection.data:

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

Utan det kommer våra staplar inte att övergå smidigt, och det skulle vara svårt att följa ändringarna i axeln (du kan se att ta bort det andra argumentet i fiolen nedan).

Så efter korrekt inställning av våra var bars kan vi hantera våra val. Detta är utgångsvalet:

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

Och det här är valet för enter och uppdatering (i D3 v4.x slås uppdateringsvalet samman med entervalet med hjälp av 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});

Slutligen kallar vi funktionen draw() varje gång du klickar på knappen:

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

Och detta är fiolen som visar alla dessa tre val i aktion.

Sammanfoga val

Uppdateringsmönstret i D3 version 3

En korrekt förståelse för hur valet “enter”, “update” och “exit” fungerar är grundläggande för att korrekt ändra dataviz med D3.

Sedan D3 version 3 (faktiskt sedan version 2), kan detta utdrag ställa övergångarna för både "enter" och "update" -val ( live demo här ):

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; });

Ger detta resultat efter övergången:

ange bildbeskrivning här

Men vad händer med exakt samma kod om vi använder D3 version 4? Du kan se det i denna live-demo : ingenting !

Varför?

Ändringar i uppdateringsmönstret i D3 version 4

Låt oss kolla koden. Först har vi divs . Detta val binder data till <div> .

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

Sedan har vi divs.enter() , som är ett urval som innehåller all data med oöverträffade element. Detta urval innehåller alla Divar i första gången vi kallar funktionen draw och vi sätta sina bredder till noll.

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

Sedan har vi divs.transition() , och här har vi det intressanta beteendet: I D3 version 3 gör divs.transition() all <div> i "enter" -valet till sin slutliga bredd. Men det är meningslöst! divs innehåller inte "enter" -valet och bör inte modifiera något DOM-element.

Det finns en anledning till att detta konstiga beteende har introducerats i D3 version 2 och 3 ( källa här ), och det "korrigerades" i D3 version 4. Således händer ingenting i live demo ovan, och detta förväntas! Om du klickar på knappen visas alla sex tidigare fält, eftersom de nu är i "uppdatera" -valet, inte längre i "enter" -valet.

För övergången som verkar över “enter” -valet måste vi skapa separata variabler eller, en enklare strategi, slå samman valen :

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; });

Nu slog vi in valen "enter" och "update". Se hur det fungerar i den här live-demonstrationen .



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow