web-dev-qa-db-fra.com

d3.js - comment insérer de nouveaux éléments frères

J'ai un problème avec l'insertion de nouveaux frères et sœurs dans des éléments existants.

J'ai cette structure

<svg> 
  <g> 
    <path class="data"></path> 
    <path class="data"></path> 
  </g>
</svg>

et je veux cette structure

<svg> 
  <g> 
    <path class="data"></path> 
    <text></text>
    <path class="data"></path> 
    <text></text>
  </g>
</svg>

mais si j'utilise la fonction d'insertion d3.js

d3.select("g").insert("text", "path.data");

j'obtiens ce qui suit (malgré la sélection par nom de classe)

<svg> 
  <g> 
    <text></text>
    <path class="data"></path> 
    <path class="data"></path> 
  </g>
</svg>

des idées?

27
Codetoffel

Tout d'abord, il convient de noter que le deuxième argument de la fonction d'insertion est un sélecteur avant. De plus, les opérations chaînées agissent sur le résultat de gauche.

Vous avez donc fait

// select all the g elements (only 1)
d3.select("g")
    // For each g, insert a text element before "path.data"
    .insert("text", "path.data");

Vous souhaitez effectuer une opération pour chaque enfant ".data", vous devez donc sélectionner chacun des éléments ".data" et effectuer une action pour chacun d'eux. Je ne sais pas exactement comment d3 attend de vous que vous insériez un élément après un enfant spécifique. Je trouve qu'il est beaucoup plus facile d'utiliser l'API DOM pour faire la création et l'insertion d'élément, mais en utilisant la fonction d3.each pour parcourir une sélection.

d3.selectAll("g > .data").each(function () {
    var t = document.createElement('text');
    this.parentNode.insertBefore(t, this.nextSibling);       
});​
31
Matt Esch