web-dev-qa-db-fra.com

Un d3.select ... équivalent à jQuery.children ()

J'utilise d3 pour ajouter des éléments sur enter (), puis pour les mettre à jour ultérieurement. Cependant, la prochaine fois que j'essaie de sélectionner ces éléments, la sélection est beaucoup plus grande que l'original. En effet, les éléments de sélection d'origine ont maintenant des enfants du même type, par exemple. <g>, <svg>. Je m'attendais à ce que selectAll () ne fonctionne qu'au premier niveau, jQuery.children (). Existe-t-il un équivalent en d3? Si non, quel est le moyen le plus efficace de le faire?

17
QueueHammer

Il n'y a pas d'équivalent à jQuery.children(). Ceci est généralement traité en attribuant une classe de distinction aux éléments que vous souhaitez sélectionner ensemble, par exemple. quelque chose comme ça.

svg.selectAll("g").data(data)
   .enter()
   .append("g")
   .attr("class", "parent")
   .append("g")
   .attr("class", "child");

svg.selectAll("g"); // all g elements
svg.selectAll("g.parent"); // only parents
svg.selectAll("g.child"); // only children
14
Lars Kotthoff

Voici une bien meilleure façon de le faire:

var parent = d3.selectAll(".myParentClass");
parent.each(function(d,i) {            
   var children = d3.selectAll(this.childNodes);
   console.log(children);
});

De cette façon, vous n'avez pas besoin d'ajouter inutilement des classes à ce que pourraient être des centaines de nœuds enfants (voire plus).

9
friek108

Vous pouvez également sélectionner des enfants uniquement avec un sélecteur CSS. Voici ce que je fais pour sélectionner un enfant dans l'index:

d3.select(`#${parentId} > *:nth-child(${index + 1})`)

donc je suppose que cela fonctionne:

d3.selectAll(`#${parentId} > *`)
1
FXG

Comme dit Lars, il n'y a pas d'équivalent à la méthode 'children ()' dans D3, mais ici, j'ai laissé une petite extension au prototype d3.selection que j'ai écrit. J'espère devoir vous aider (si tard).

d3.selection.prototype.children = function(d){
    var that = this.node();
    return this
        .selectAll(d)
        .filter(function(){ return that == this.parentNode; });
};
0
MR0

En retard pour le parti, mais au moins dans d3 version 4, selection.selectAll() peut prendre une fonction dont le résultat est un tableau contenant les nouveaux éléments à sélectionner en fonction de l'élément sélectionné dans la sélection précédente:

var parent = d3.selectAll(".myParentClass");
var children = parent
    //Convert selection to selection representing the children
    .selectAll(function() { return this.childNodes; })
    //Apply filter to children
    .filter('g')
    ;

Le principal avantage de cette approche par rapport aux réponses précédentes est que la fonction selection.data() fonctionnera toujours correctement. Les méthodes précédemment proposées, qui attribuent les résultats d'un nouvel appel distinct d3.select(), ne le permettent pas.

0
Walt W