Zoeken…


Syntaxis

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

Updaten van de gegevens: een basisvoorbeeld van selecties voor invoeren, bijwerken en afsluiten

Het maken van een grafiek met een statische gegevensset is relatief eenvoudig. Als we bijvoorbeeld deze reeks objecten als gegevens hebben:

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

We kunnen een staafdiagram maken waarbij elke staaf een meetwaarde, genaamd "titel", vertegenwoordigt en de breedte de waarde van die meetwaarde weergeeft. Omdat deze dataset niet verandert, heeft ons staafdiagram alleen een "enter" -selectie:

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 stellen we de breedte van elke balk in op 0 en, na de overgang, op de uiteindelijke waarde.

Deze enter-selectie alleen is voldoende om onze grafiek te maken, die u in deze viool kunt zien.

Maar wat als mijn gegevens veranderen?

In dit geval moeten we onze grafiek dynamisch wijzigen. De beste manier om dit te doen is door een "enter", een "update" en een "exit" selecties te maken. Maar daarvoor moeten we enkele wijzigingen in de code aanbrengen.

Eerst verplaatsen we de veranderende delen binnen een functie met de naam draw() :

function draw(){
    //changing parts
};

Deze "veranderende onderdelen" omvatten:

  1. De enter-, update- en exit-selecties;
  2. Het domein van elke schaal;
  3. De overgang van de as;

Binnen die draw() -functie noemen we een andere functie die onze gegevens maakt. Hier is het gewoon een functie die een array van 5 objecten retourneert, waarbij willekeurig 5 letters uit 10 worden gekozen (alfabetisch gesorteerd) en voor elke een waarde tussen 0 en 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;
};

En laten we nu naar onze selecties gaan. Maar daarvoor, een woord van waarschuwing: om te behouden wat we objectconstantiteit noemen, moeten we een sleutelfunctie opgeven als het tweede argument voor selectie. Gegevens:

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

Zonder dat zullen onze balken niet soepel overgaan, en het zou moeilijk zijn om de veranderingen in de as te volgen (je kunt zien dat het verwijderen van het tweede argument in de onderstaande viool).

Dus, na het correct instellen van onze var bars , kunnen we omgaan met onze selecties. Dit is de uitgangsselectie:

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

En dit zijn de enter- en de updateselecties (in D3 v4.x wordt de updateselectie samengevoegd met de enter-selectie met behulp van 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});

Ten slotte roepen we de functie draw() op telkens wanneer op de knop wordt geklikt:

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

En dit is de viool die al deze 3 selecties in actie toont.

Selecties samenvoegen

Het updatepatroon in D3 versie 3

Een correct begrip van hoe de "enter", "update" en "exit" selecties werken, is van fundamenteel belang voor het correct wijzigen van de dataviz met D3.

Sinds D3 versie 3 (eigenlijk, sinds versie 2), kon dit fragment de overgangen instellen voor zowel "enter" als "update" selecties ( 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; });

Dit resultaat geven na de overgang:

voer hier de afbeeldingsbeschrijving in

Maar wat gebeurt er met dezelfde code als we D3 versie 4 gebruiken? Je kunt het zien in deze live demo : niets !

Waarom?

Wijzigingen in het updatepatroon in D3 versie 4

Laten we de code controleren. Ten eerste hebben we divs . Deze selectie bindt de gegevens aan de <div> .

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

Vervolgens hebben we divs.enter() , een selectie die alle gegevens met niet-overeenkomende elementen bevat. Deze selectie bevat alle divs wanneer we de functie draw de eerste keer aanroepen en hun breedte op nul zetten.

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

Dan hebben we divs.transition() , en hier hebben we het interessante gedrag: in D3 versie 3 laat divs.transition() alle <div> in de "enter" -selectie veranderen naar hun uiteindelijke breedte. Maar dat slaat nergens op! divs bevat geen "enter" -selectie en mag geen DOM-element wijzigen.

Er is een reden waarom dit vreemde gedrag is geïntroduceerd in D3 versie 2 en 3 ( bron hier ), en het is "gecorrigeerd" in D3 versie 4. Dus gebeurt er in de live demo hierboven niets, en dit wordt verwacht! Als u bovendien op de knop klikt, verschijnen alle voorgaande zes balken, omdat ze nu in de selectie "update" staan, niet meer in de selectie "Enter".

Voor de overgang die werkt via de "enter" -selectie, moeten we afzonderlijke variabelen maken of, een eenvoudiger benadering, de selecties samenvoegen :

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 hebben we de selecties “enter” en “update” samengevoegd. Bekijk hoe het werkt in deze live demo .



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow