Szukaj…


Składnia

  • d3. wybierz (selektor)
  • d3. selectAll (selektor)
  • wybór . wybierz (selektor)
  • wybór . selectAll (selektor)
  • wybór . filtr (filtr)
  • wybór . scal (inne)

Uwagi

Powiązane odczyty:

Podstawowy wybór i modyfikacje

Jeśli znasz jQuery i składnię Sizzle, wybory d3 nie powinny się znacznie różnić. d3 naśladuje interfejs API Selektorów W3C, aby ułatwić interakcję z elementami.

W podstawowym przykładzie wybierz wszystkie <p> i dodaj zmianę do każdego z nich:

d3.selectAll('p')
  .attr('class','textClass') 
  .style('color', 'white');

W skrócie jest to względnie to samo, co w jQuery

$('p')
  .attr('class','textClass') 
  .css('color, 'white')

Zasadniczo zaczniesz od pojedynczego wyboru do div kontenera, aby dodać element SVG, który zostanie przypisany do zmiennej (najczęściej nazywanej svg).

var svg = d3.select('#divID').append('svg');

Stąd możemy wywołać svg aby dokonać selekcji podrzędnej wielu obiektów (nawet jeśli jeszcze nie istnieją).

svg.selectAll('path')

Różne selektory

Możesz wybierać elementy za pomocą różnych selektorów:

  • według tagu: "div"
  • według klasy: ".class"
  • według identyfikatora: "#id"
  • według atrybutu: "[color=blue]"
  • wiele selektorów (OR): "div1, div2, class1"
  • wiele selektorów (AND): "div1 div2 class1"

Prosty wybór ograniczony danymi

var myData = [
    { name: "test1", value: "ok" },
    { name: "test2", value: "nok" }
]

// We have to select elements (here div.samples)
// and assign data. The second parameter of data() is really important,
// it will determine the "key" to identify part of data (datum) attached to an 
// element.
var mySelection = d3.select(document.body).selectAll("div.samples") // <- a selection
                   .data(myData, function(d){ return d.name; }); // <- data binding

// The "update" state is when a datum of data array has already
// an existing element associated.
mySelection.attr("class", "samples update")

// A datum is in the "enter" state when it's not assigned
// to an existing element (based on the key param of data())
// i.e. new elements in data array with a new key (here "name")
mySelection.enter().append("div")
    .attr("class", "samples enter")
    .text(function(d){ return d.name; });

// The "exit" state is when the bounded datum of an element
// is not in the data array
// i.e. removal of a row (or modifying "name" attribute)
// if we change "test1" to "test3", "test1" bounded
//          element will figure in exit() selection
// "test3" bounded element will be created in the enter() selection
mySelection.exit().attr("class", "samples remove");

Rola symboli zastępczych w selekcjach „enter”

Co to jest wybór wejścia?

W D3.js, gdy ktoś wiąże dane z elementami DOM, możliwe są trzy sytuacje:

  1. Liczba elementów i liczba punktów danych są takie same;
  2. Jest więcej elementów niż punktów danych;
  3. Jest więcej punktów danych niż elementów;

W sytuacji, # 3, wszystkie punkty danych bez odpowiedniego elementu DOM należą do wprowadzić wybór. Zatem w D3.js wprowadzane selekcje to selekcje, które po połączeniu elementów z danymi zawierają wszystkie dane, które nie pasują do żadnego elementu DOM. Jeśli użyjemy funkcji append w zaznaczeniu Enter , D3 utworzy nowe elementy wiążące te dane za nas.

Oto diagram Venna wyjaśniający możliwe sytuacje dotyczące liczby punktów danych / liczby elementów DOM:

wprowadź opis zdjęcia tutaj

Jak widzimy, enter wybór jest niebieski obszar po lewej stronie: punkty danych bez odpowiednich elementów DOM.

Struktura wprowadzania wyboru

Zazwyczaj wybór Enter składa się z 4 następujących kroków:

  1. selectAll : Wybierz elementy w DOM;
  2. data : Zlicza i analizuje dane;
  3. enter : Porównując zaznaczenie z danymi, tworzy nowe elementy;
  4. append : Dołącz rzeczywiste elementy w DOM;

To jest bardzo prosty przykład (spójrz na 4 kroki w var divs ):

var data = [40, 80, 150, 160, 230, 260];

var body = d3.select("body");

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

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

I to jest wynik ( tutaj jsfiddle ):

wprowadź opis zdjęcia tutaj

Zauważ, że w tym przypadku użyliśmy selectAll("div") jako pierwszego wiersza w naszej zmiennej wyboru „enter”. Mamy zestaw danych z 6 wartościami, a D3 stworzył dla nas 6 elementów div.

Rola symboli zastępczych

Załóżmy jednak, że w naszym dokumencie znajduje się już div, coś w rodzaju <div>This is my chart</div> na górze. W takim przypadku, kiedy piszemy:

body.selectAll("div")

wybieramy istniejący div. Zatem nasz wybór enter będzie miał tylko 5 punktów odniesienia bez pasujących elementów. Na przykład w tym pliku jsfiddle , gdzie w kodzie HTML jest już div („To jest mój wykres”), będzie to wynik:

wprowadź opis zdjęcia tutaj

Nie widzimy już wartości „40”: nasz pierwszy „pasek” zniknął, a powodem tego jest to, że nasz wybór „enter” ma teraz tylko 5 elementów.

Musimy tu zrozumieć, że w pierwszym wierszu naszej zmiennej wyboru enter, selectAll("div") , te div są tylko symbolami zastępczymi . Nie musimy wybierać wszystkich elementów divs jeśli dodajemy elementy divs , ani całego circle jeśli dodajemy circle . Możemy wybierać różne rzeczy. A jeśli nie planujemy mieć opcji „aktualizacja” lub „wyjście”, możemy wybrać wszystko :

var divs = body.selectAll(".foo")//this class doesn't exist, and never will!
    .data(data)
    .enter()
    .append("div");

W ten sposób wybieramy wszystkie pliki „.foo”. Tutaj „foo” to klasa, która nie tylko nie istnieje, ale nigdy nie została stworzona nigdzie indziej w kodzie! Ale to nie ma znaczenia, to tylko symbol zastępczy. Logika jest następująca:

Jeśli w wyborze „enter” wybierzesz coś, co nie istnieje, wybór „enter” zawsze będzie zawierał wszystkie dane.

Teraz, wybierając .foo , nasz wybór „enter” ma 6 elementów, nawet jeśli mamy już div w dokumencie:

wprowadź opis zdjęcia tutaj

A oto odpowiedni jsfiddle .

Wybranie null

Zdecydowanie najlepszym sposobem na zagwarantowanie, że nic nie wybierasz, jest wybranie null . Nie tylko to, ale ta alternatywa jest znacznie szybsza niż jakakolwiek inna.

Tak więc, aby wprowadzić wybór, po prostu wykonaj:

selection.selectAll(null)
    .data(data)
    .enter()
    .append(element);

Oto skrzypce demonstracyjne: https://jsfiddle.net/gerardofurtado/th6s160p/

Wniosek

Podczas wybierania opcji „enter” należy zachować szczególną ostrożność, aby nie wybrać czegoś, co już istnieje. Możesz użyć wszystkiego w swoim selectAll , nawet rzeczy, które nie istnieją i nigdy nie będą istnieć (jeśli nie planujesz mieć opcji „aktualizacja” lub „wyjście”).

Kod w przykładach jest oparty na tym kodzie autorstwa Mike'a Bostocka: https://bl.ocks.org/mbostock/7322386

Używanie „tego” z funkcją strzałki

Większość funkcji w D3.js akceptuje funkcję anonimową jako argument. Wspólne przykłady .attr , .style , .text , .on i .data , ale lista jest o wiele większe niż to.

W takich przypadkach anonimowa funkcja jest oceniana dla każdego wybranego elementu, po kolei:

  1. Aktualny punkt odniesienia ( d )
  2. Aktualny indeks ( i )
  3. Bieżąca grupa ( nodes )
  4. this jako bieżący element DOM.

Punkt odniesienia, indeks i bieżąca grupa są przekazywane jako argumenty, słynny pierwszy, drugi i trzeci argument w D3.js (którego parametry tradycyjnie nazywane są d , i p w D3 v3.x). Aby jednak this użyć, nie trzeba używać żadnego argumentu:

.on("mouseover", function(){
    d3.select(this);
});

Powyższy kod wybierze this gdy wskaźnik myszy znajdzie się nad elementem. Sprawdź, czy działa w tym skrzypcach: https://jsfiddle.net/y5fwgopx/

Funkcja strzałki

Jako nowa składnia ES6, funkcja strzałki ma krótszą składnię w porównaniu do wyrażenia funkcji. Jednak dla programisty D3, kto używa this stale, istnieje pułapka: funkcja strzałka nie tworzy własnego this kontekst. Oznacza to, że w zależności strzałki, this ma swoje pierwotne znaczenie z kontekstu otaczającego.

Może to być przydatne w kilku okolicznościach, ale jest to problem dla kodera przyzwyczajonego do używania this w D3. Na przykład przy użyciu tego samego przykładu w skrzypcach powyżej to nie zadziała:

.on("mouseover", ()=>{
    d3.select(this);
});

Jeśli masz co do tego wątpliwości, oto skrzypce: https://jsfiddle.net/tfxLsv9u/

Cóż, to nie jest duży problem: w razie potrzeby można po prostu użyć zwykłego, staroświeckiego wyrażenia funkcyjnego. Ale co, jeśli chcesz napisać cały kod za pomocą funkcji strzałek? Czy można mieć kod z funkcjami strzałek i nadal poprawnie używać this w D3?

Drugi i trzeci argument łącznie

Odpowiedź brzmi tak , ponieważ this samo dotyczy nodes[i] . Wskazówka jest obecna w całym interfejsie API D3, gdy opisuje to:

... z this jako bieżącym elementem DOM ( nodes[i] )

Wyjaśnienie jest proste: ponieważ nodes są bieżącą grupą elementów w DOM, a i jest indeksem każdego elementu, nodes[i] odnoszą się do samego bieżącego elementu DOM. To znaczy this .

Dlatego można użyć:

.on("mouseover", (d, i, nodes) => {
    d3.select(nodes[i]);
});

A oto odpowiednie skrzypce: https://jsfiddle.net/2p2ux38s/



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