Szukaj…


Składnia

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

Aktualizacja danych: podstawowy przykład wprowadzania, aktualizowania i wychodzenia z wybranych opcji

Tworzenie wykresu wyświetlającego statyczny zestaw danych jest stosunkowo proste. Na przykład, jeśli mamy tę tablicę obiektów jako dane:

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

Możemy utworzyć wykres słupkowy, w którym każdy słupek reprezentuje miarę o nazwie „tytuł”, a jej szerokość reprezentuje wartość tej miary. Ponieważ ten zestaw danych się nie zmienia, nasz wykres słupkowy ma tylko opcję „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});

Tutaj ustawiamy szerokość każdego słupka na 0, a po przejściu do jego końcowej wartości.

Samo wprowadzenie zaznaczenia wystarczy, aby utworzyć nasz wykres, który można zobaczyć w tym skrzypce .

Ale co jeśli moje dane się zmienią?

W takim przypadku musimy dynamicznie zmieniać nasz wykres. Najlepszym sposobem na to jest utworzenie opcji „enter”, „update” i „exit”. Ale wcześniej musimy wprowadzić pewne zmiany w kodzie.

Najpierw przeniesiemy zmieniające się części do funkcji o nazwie draw() :

function draw(){
    //changing parts
};

Te „części zamienne” obejmują:

  1. Wprowadź, zaktualizuj i wyjdź;
  2. Domena każdej skali;
  3. Przejście osi;

Wewnątrz tej funkcji draw() wywołujemy inną funkcję, która tworzy nasze dane. Tutaj jest to tylko funkcja, która zwraca tablicę 5 obiektów, wybierając losowo 5 liter na 10 (sortowanie alfabetyczne) i dla każdego z nich wartość od 0 do 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;
};

A teraz przejdźmy do naszych wyborów. Ale wcześniej słowo ostrzeżenia: aby zachować to, co nazywamy stałością obiektu , musimy określić funkcję kluczową jako drugi argument wyboru.data:

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

Bez tego nasze paski nie przejdą płynnie i trudno byłoby śledzić zmiany w osi (widać, że usunięcie drugiego argumentu w skrzypce poniżej).

Zatem po prawidłowym ustawieniu naszych var bars możemy poradzić sobie z naszymi wyborami. Oto wybór wyjścia:

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

Oto wybory Enter i aktualizacji (w D3 v4.x wybór aktualizacji jest scalany z wyborem Enter za pomocą 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});

Na koniec wywołujemy funkcję draw() każdym kliknięciu przycisku:

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

I to jest skrzypce pokazujące wszystkie te 3 selekcje w akcji.

Scalanie selekcji

Wzór aktualizacji w wersji 3 D3

Prawidłowe zrozumienie działania opcji „enter”, „update” i „exit” ma fundamentalne znaczenie dla prawidłowej zmiany dataviz przy użyciu D3.

Od wersji 3 D3 (właściwie od wersji 2) ten fragment kodu może ustawiać przejścia dla opcji „enter” i „update” ( tutaj wersja demonstracyjna na żywo ):

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

Podanie tego wyniku po przejściu:

wprowadź opis zdjęcia tutaj

Ale co stanie się z dokładnie tym samym kodem, jeśli użyjemy D3 w wersji 4? Możesz to zobaczyć w tym demo na żywo : nic !

Dlaczego?

Zmiany we wzorcu aktualizacji w wersji D3 4

Sprawdźmy kod. Po pierwsze, mamy divs . Ten wybór wiąże dane z <div> .

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

Następnie mamy divs.enter() , która jest wyborem zawierającym wszystkie dane z niedopasowanymi elementami. Ten wybór zawiera wszystkie divy przy pierwszym wywołaniu funkcji draw i ustawiamy ich szerokości na zero.

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

Następnie mamy divs.transition() , a tutaj mamy interesujące zachowanie: W wersji 3 D3 divs.transition() powoduje zmianę wszystkich <div> w zaznaczeniu „enter” na ich końcową szerokość. Ale to nie ma sensu! divs nie zawiera wyboru „enter” i nie powinien modyfikować żadnego elementu DOM.

Istnieje powód, dla którego to dziwne zachowanie zostało wprowadzone w D3 w wersji 2 i 3 ( źródło tutaj ), a zostało „poprawione” w D3 w wersji 4. Tak więc, w powyższym demo na żywo nic się nie dzieje i jest to oczekiwane! Ponadto, jeśli klikniesz przycisk, pojawią się wszystkie sześć poprzednich pasków, ponieważ znajdują się one teraz w opcji „aktualizacja”, a nie w opcji „enter”.

Dla przejścia działającego nad wyborem „enter” musimy stworzyć osobne zmienne lub, łatwiejsze podejście, scalić selekcje :

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

Teraz połączyliśmy opcje „enter” i „update”. Zobacz, jak to działa w tym demo na żywo .



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow