Recherche…


Syntaxe

  • d3. sélectionnez (sélecteur)
  • d3. selectAll (sélecteur)
  • sélection sélectionnez (sélecteur)
  • sélection selectAll (sélecteur)
  • sélection filtre (filtre)
  • sélection fusionner (autre)

Remarques

Lectures connexes:

Sélection de base et modifications

Si vous êtes familier avec la syntaxe jQuery et Sizzle, les sélections d3 ne devraient pas être très différentes. d3 imite l'API des sélecteurs du W3C pour faciliter les interactions avec les éléments.

Pour un exemple élémentaire, sélectionnez tous <p> et ajoutez une modification à chacun d’eux:

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

En bref, c'est relativement le même que dans jQuery

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

En général, vous commencerez par une seule sélection sur votre div pour ajouter un élément SVG qui sera assigné à une variable (le plus souvent appelée svg).

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

De là, nous pouvons faire appel à svg pour faire nos sous-sélections de plusieurs objets (même s'ils n'existent pas encore).

svg.selectAll('path')

Différents sélecteurs

Vous pouvez sélectionner des éléments avec des sélecteurs différents:

  • par tag: "div"
  • par classe: ".class"
  • par id: "#id"
  • par attribut: "[color=blue]"
  • sélecteurs multiples (OR): "div1, div2, class1"
  • plusieurs sélecteurs (AND): "div1 div2 class1"

Sélection limitée des données simples

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

Le rôle des espaces réservés dans les sélections "enter"

Qu'est-ce qu'une sélection entrée?

Dans D3.js, quand on lie des données à des éléments DOM, trois situations sont possibles:

  1. Le nombre d'éléments et le nombre de points de données sont les mêmes.
  2. Il y a plus d'éléments que de points de données.
  3. Il y a plus de points de données que d'éléments.

Dans la situation n ° 3, tous les points de données sans élément DOM correspondant appartiennent à la sélection entrée . Ainsi, dans D3.js, les sélections de saisie sont des sélections qui, après avoir joint des éléments aux données, contiennent toutes les données qui ne correspondent à aucun élément DOM. Si nous utilisons une fonction d' append dans une sélection d' entrée , D3 créera de nouveaux éléments liant ces données pour nous.

Ceci est un diagramme de Venn expliquant les situations possibles concernant le nombre de points de données / nombre d'éléments DOM:

entrer la description de l'image ici

Comme on peut le voir, la sélection d' entrée est la zone bleue à gauche: les points de données sans éléments DOM correspondants.

La structure de la sélection d'entrée

En règle générale, une sélection de saisie comporte les 4 étapes suivantes:

  1. selectAll : sélectionne les éléments dans le DOM;
  2. data : Compte et analyse les données;
  3. enter : La comparaison de la sélection avec les données crée de nouveaux éléments.
  4. append : Ajoute les éléments réels dans le DOM;

Ceci est un exemple très basique (regardez les 4 étapes des 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; });

Et voici le résultat ( jsfiddle ici ):

entrer la description de l'image ici

Notez que, dans ce cas, nous avons utilisé selectAll("div") comme première ligne de notre variable de sélection "enter". Nous avons un jeu de données avec 6 valeurs et D3 a créé 6 divs pour nous.

Le rôle des espaces réservés

Mais supposons que nous ayons déjà une div dans notre document, quelque chose comme <div>This is my chart</div> en haut. Dans ce cas, quand on écrit:

body.selectAll("div")

nous sélectionnons cette div existante. Ainsi, notre sélection d'entrée n'aura que 5 données sans éléments correspondants. Par exemple, dans ce jsfiddle , où il existe déjà un div dans le HTML ("Ceci est mon graphique"), ce sera le résultat:

entrer la description de l'image ici

Nous ne voyons plus la valeur "40": notre première "barre" a disparu, et la raison en est que notre sélection "enter" ne comporte plus que 5 éléments.

Ce que nous devons comprendre ici, c'est que dans la première ligne de notre variable de sélection d’entrée, selectAll("div") , ces divs ne sont que des espaces réservés . Nous n'avons pas à sélectionner tous les divs si nous ajoutons des divs , ou tout le circle si nous ajoutons des circle . Nous pouvons sélectionner différentes choses. Et, si nous ne prévoyons pas de "mise à jour" ou de "sortie", nous pouvons sélectionner n'importe quoi :

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

En faisant cela, nous sélectionnons tous les ".foo". Ici, "foo" est une classe qui non seulement n’existe pas, mais qui n’est jamais créée nulle part ailleurs dans le code! Mais peu importe, ce n'est qu'un espace réservé. La logique est la suivante:

Si dans votre sélection "enter" vous sélectionnez quelque chose qui n'existe pas, votre sélection "enter" contiendra toujours toutes vos données.

Maintenant, en sélectionnant .foo , notre sélection "enter" a 6 éléments, même si nous avons déjà une div dans le document:

entrer la description de l'image ici

Et voici le jsfiddle correspondant .

Sélectionner null

Le meilleur moyen de garantir que vous ne sélectionnez rien est de sélectionner null . Non seulement cela, mais cette alternative est beaucoup plus rapide que tout autre.

Ainsi, pour une sélection de saisie, il suffit de faire:

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

Voici un violon de démonstration: https://jsfiddle.net/gerardofurtado/th6s160p/

Conclusion

Lorsque vous utilisez les sélections "enter", prenez soin de ne pas sélectionner quelque chose qui existe déjà. Vous pouvez utiliser n'importe quoi dans votre selectAll , même les choses qui n'existent pas et n'existeront jamais (si vous ne prévoyez pas d'avoir une sélection de "mise à jour" ou de "sortie").

Le code dans les exemples est basé sur ce code par Mike Bostock: https://bl.ocks.org/mbostock/7322386

Utiliser "this" avec une fonction de flèche

La plupart des fonctions de D3.js acceptent une fonction anonyme comme argument. Les exemples communs sont .attr , .style , .text , .on et .data , mais la liste est beaucoup plus grande que cela.

Dans de tels cas, la fonction anonyme est évaluée pour chaque élément sélectionné, dans l'ordre, en passant:

  1. Le datum actuel ( d )
  2. L'index actuel ( i )
  3. Le groupe actuel ( nodes )
  4. this comme l'élément DOM actuel.

Le datum, l'index et le groupe courant sont passés en arguments, les fameux premier, deuxième et troisième arguments de D3.js (dont les paramètres sont traditionnellement nommés d , i et p dans D3 v3.x). Pour l' utilisation de this , cependant, on n'a pas besoin d'utiliser aucun argument:

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

Le code ci-dessus sélectionnera this quand la souris est sur l'élément. Vérifiez qu'il fonctionne dans ce violon: https://jsfiddle.net/y5fwgopx/

La fonction flèche

En tant que nouvelle syntaxe ES6, une fonction de flèche a une syntaxe plus courte par rapport à l’expression de fonction. Cependant, pour un programmeur D3 qui utilise this constante, il y a un piège: une fonction de flèche ne crée pas son propre this contexte. Cela signifie que, dans une fonction de flèche, this a sa signification originale à partir du contexte englobant.

Cela peut être utile dans plusieurs circonstances, mais il est un problème pour un codeur habitué à utiliser this dans D3. Par exemple, en utilisant le même exemple dans le violon ci-dessus, cela ne fonctionnera pas:

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

Si vous en doutez, voici le violon: https://jsfiddle.net/tfxLsv9u/

Eh bien, ce n'est pas un gros problème: on peut simplement utiliser une expression de fonction classique, à l'ancienne, si nécessaire. Mais que faire si vous voulez écrire tout votre code en utilisant les fonctions de flèche? Est - il possible d'avoir un code avec des fonctions de direction et toujours utiliser correctement this dans D3?

Les deuxième et troisième arguments combinés

La réponse est oui , car this va de même pour les nodes[i] . L'indice est effectivement présent partout dans l'API D3, lorsqu'il décrit ceci:

... avec this comme élément DOM actuel ( nodes[i] )

L'explication est simple: puisque nodes est le groupe actuel d'éléments dans le DOM et que i est l'index de chaque élément, les nodes[i] font référence à l'élément DOM actuel. C'est this .

Par conséquent, on peut utiliser:

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

Et voici le violon correspondant: https://jsfiddle.net/2p2ux38s/



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