web-dev-qa-db-fra.com

Accéder aux attributs de l'élément d3.js à partir du datum?

J'essaie d'accéder aux attributs cx & cy de certains cercles svg spécifiques que j'ai déjà dessinés à l'écran en utilisant la fonction .data () de d3.js, quelqu'un peut-il m'aider? Le code qui essaie d'y accéder est ci-dessous.

d3.selectAll(".mynode").each( function(d, i){
  if(d.someId == targetId){
    console.log( d.attr("cx") );    // just trying to demo my point, doesn't work
  }
}

Je suis assez nouveau sur d3.js et javascript, donc je ne suis pas sûr si j'approche cela de l'arrière en avant de toute façon ou peut-être ai-je raté une solution intégrée?

44
Mike Winter

Votre code essaie d'obtenir un attribut svg à partir d'un élément de données, alors que ce que vous voulez vraiment, c'est obtenir cet attribut à partir de l'élément DOM svg, comme dans:

console.log(d3.selectAll(".mynode").attr("cx"));

Cela vous donnera uniquement l'attribut du premier élément non nul de votre sélection; Vous pouvez également filtrer votre sélection pour obtenir l'élément DOM que vous recherchez:

console.log(d3.selectAll(".mynode").filter(_conditions_).attr("cx"));

Ou, si vous souhaitez accéder aux attributs de tous les éléments sélectionnés, utilisez this dans chacune de vos fonctions:

d3.selectAll(".mynode").each( function(d, i){
  if(d.someId == targetId){
    console.log( d3.select(this).attr("cx") );
  }
}
66
Josh

Il existe un moyen encore plus simple: (fournir l'index i est donné)

d3.selectAll("circle")[0][i].attributes.cx.value

comme on peut le voir ici .

12
VividD

La méthode de filtrage dans la réponse acceptée est correcte. La deuxième approche de la réponse acceptée (en utilisant .each) est incorrecte et contient la même erreur que le questionneur faisait: si .data () n'est pas appelé (ce qui est le cas ici), alors le premier argument d est passé à .each ne sera pas défini (et non pas le "nœud dom actuel", comme tous les débutants, y compris moi-même, s’attendraient); le noeud dom actuel que vous obtenez via d3.select (this), qui est correct dans l'instruction if à la toute fin - l'erreur se trouve dans la condition de test if. La version correcte suit.

d3.selectAll(".mynode").each(function(d,i){
    var elt = d3.select(this);
    if (elt.attr("id") == "yourTargetIdGoesHere"){
        console.log( elt.attr("cx") );
    }
});

violon: violon (contenant le code pour les deux versions, c'est-à-dire le filtre et chacune)

MISE À JOUR: ma réponse supposait que vous n'avez pas utilisé .data (), puisque vous n'avez pas donné le code pour cela; plus tard, j'ai vu que vous aviez écrit que vous utilisiez .data ()

dans ce cas, en fonction de votre structure de données, le remplacement de d.attr ("cx") par d.cx ordinaire peut fonctionner.

10
mathheadinclouds