Recherche…


Syntaxe

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

Mise à jour des données: exemple de base des sélections d'entrée, de mise à jour et de sortie

La création d'un graphique affichant un jeu de données statique est relativement simple. Par exemple, si nous avons ce tableau d'objets comme données:

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

Nous pouvons créer un graphique à barres où chaque barre représente une mesure, nommée "title", et sa largeur représente la valeur de cette mesure. Comme ce jeu de données ne change pas, notre diagramme à barres ne comporte qu'une sélection "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});

Ici, nous réglons la largeur de chaque barre à 0 et, après la transition, à sa valeur finale.

Cette entrée, seule, suffit à créer notre tableau, que vous pouvez voir dans ce violon .

Mais que se passe-t-il si mes données changent?

Dans ce cas, nous devons changer dynamiquement notre graphique. La meilleure façon de le faire est de créer des sélections "enter", "update" et "exit". Mais avant cela, nous devons apporter des modifications au code.

Tout d'abord, nous déplacerons les parties changeantes dans une fonction nommée draw() :

function draw(){
    //changing parts
};

Ces "pièces changeantes" comprennent:

  1. Les sélections d'entrée, de mise à jour et de sortie;
  2. Le domaine de chaque échelle;
  3. La transition de l'axe;

Dans cette fonction draw() , nous appelons une autre fonction, qui crée nos données. Ici, c'est juste une fonction qui retourne un tableau de 5 objets, en choisissant au hasard 5 lettres sur 10 (tri par ordre alphabétique) et, pour chacune, une valeur entre 0 et 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;
};

Et maintenant, passons à nos sélections. Mais avant cela, un mot de prudence: pour maintenir ce que nous appelons la constance des objets , nous devons spécifier une fonction clé comme second argument de selection.data:

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

Sans cela, nos barres ne se transforment pas en douceur, et il serait difficile de suivre les changements dans l'axe (vous pouvez voir que supprimer le second argument dans le violon ci-dessous).

Ainsi, après avoir réglé correctement nos var bars , nous pouvons traiter nos sélections. Ceci est la sélection de sortie:

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

Et ce sont les sélections d’entrée et de mise à jour (dans D3 v4.x, la sélection de mise à jour est fusionnée avec la sélection d’entrée à l’aide de la 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});

Enfin, nous appelons la fonction draw() chaque fois que le bouton est cliqué:

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

Et c'est le violon qui montre toutes ces 3 sélections en action.

Fusion de sélections

Le modèle de mise à jour dans la version D3 3

Une compréhension correcte de la façon dont les sélections «enter», «update» et «exit» fonctionnent est fondamentale pour changer correctement le dataviz en utilisant D3.

Depuis la version 3 de D3 (en fait, depuis la version 2), cet extrait pouvait définir les transitions pour les sélections «enter» et «update» ( démonstration en direct ici ):

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

Donner ce résultat après la transition:

entrer la description de l'image ici

Mais que se passe-t-il avec le même code si nous utilisons la version D3 4? Vous pouvez le voir dans cette démo en direct : rien !

Pourquoi?

Changements dans le modèle de mise à jour dans D3 version 4

Vérifions le code. Premièrement, nous avons des divs . Cette sélection lie les données au <div> .

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

Ensuite, nous avons divs.enter() , qui est une sélection qui contient toutes les données avec des éléments sans correspondance. Cette sélection contient tous les divs de la première fois que nous appelons la fonction draw , et nous définissons leur largeur à zéro.

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

Ensuite, nous avons divs.transition() , et ici nous avons le comportement intéressant: dans D3 version 3, divs.transition() rend toutes les <div> dans la sélection "enter" à leur largeur finale. Mais cela n'a aucun sens! divs ne contient pas la sélection “enter” et ne doit modifier aucun élément DOM.

Il y a une raison pour laquelle ce comportement étrange a été introduit dans D3 version 2 et 3 ( source ici ), et il a été «corrigé» dans la version D3 4. Ainsi, dans la démonstration ci-dessus, rien ne se passe, et c'est prévu! De plus, si vous cliquez sur le bouton, toutes les six barres précédentes apparaissent, car elles sont maintenant dans la sélection «mise à jour», et non plus dans la sélection «entrée».

Pour la transition agissant sur la sélection «enter», nous devons créer des variables distinctes ou, plus facilement, fusionner les sélections :

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

Maintenant, nous avons fusionné les sélections “enter” et “update”. Voyez comment cela fonctionne dans cette démo en direct .



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow