1
votes

Donner des nombres pour les éléments de chemin svg

J'ai le fichier svg suivant avec un marqueur défini et des chemins différents.

var number    = document.querySelectorAll('.number');
var polygons  = document.getElementsByTagName("path");

for (var i = 0; i < polygons.length; i++) {
      number[i].innerHTML = i;
      console.log(i);
}

Pour chaque élément de chemin, je veux un marqueur affiché avec des nombres énumérés. Donc 1,2,3 ......

Je veux le résoudre via javascript mais j'obtiens le message "Impossible de définir la propriété 'innerHTML' sur undefined".

<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="629" version="1.1" xmlns:xlink= "http://www.w3.org/1999/xlink">
<defs>
    <marker id="start" viewBox="0 0 42 42" refX="10" refY="20" markerWidth="20" markerHeight="20">
      <rect width="20" height="20" fill="#000"></rect>
      <text x="10" y="10" font-family="Verdana" font-size="10" fill="#fff" text-anchor="middle" alignment-baseline="central" class="number"></text>
    </marker>
</defs>

<path d="M110 543 L98 366" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start)" />
<path d="M172 544 L139 454 L140 420 L144 357 L146 283" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start)"/>
<path d="M151 447 L171 403 L174 326 L164 284 L158 279" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start)"/>
<path d="M234 571 L224 520 L244 465 L256 404 L248 361 L234 307 L236 256" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start)"/>
<path d="M383 578 L376 465 L361 430 L325 378 L325 311 L348 234" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start)"/>
<path d="M376 435 L380 356 L365 331 L358 284 L354 240" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-start="url(#start)"/>
</svg>

Quelqu'un qui peut m'aider?


0 commentaires

3 Réponses :


2
votes

Votre problème ici est que vous utilisez des définitions pour rendre le nombre. Cela a deux implications:

  1. Partout où vous utilisez cette définition, elle imprimera le même contenu, pas des contenus différents (comme la copie de l'élément)
  2. La définition elle-même n'existe qu'une seule fois

Le premier point signifie que vous ne pouvez changer tous les nombres que par la même valeur, pas par des valeurs différentes (quoi, btw., semble être ce que vous voulez , donc vous ne pouvez pas le faire comme vous l'avez fait maintenant).

Le second est la cause de votre erreur: vous essayez d'itérer sur plusieurs nombres, cependant, votre liste de nœuds (renvoyée par document.querySelectorAll ('. number') ) ne contient qu'un seul élément, car le DOM de votre page n'a qu'une occurrence de cette classe. Donc, votre boucle sort en fait des limites du tableau, lançant l'erreur que vous avez mentionnée.

En fait, je ne connais aucun moyen de résoudre votre problème sans avoir besoin de dupliquer les marqueurs pour chaque élément que vous voulez avoir un numéro différent pour. Vous pourriez le faire en Javascript, quelque chose comme ça:

var number    = document.querySelectorAll('.number');
var polygons  = document.getElementsByTagName("path");

for (var i = 0; i < polygons.length; i++) {
      var node = number[0].parentNode.cloneNode(true);
      document.getElementsByTagName('defs')[0].appendChild(node);
      node.querySelector('.number').innerHTML = i;
      node.id = 'start' + i;
      polygons[i].setAttribute("marker-start", 'url(#' + node.id + ')');
}

Cependant, même si ce code fonctionne, je ne l'utiliserais probablement pas en production sans réfléchir soigneusement à la solution. Il y en a peut-être un meilleur ou au moins, jetez un œil là où ce code pourrait se casser.


1 commentaires

Cher Florian, merci beaucoup pour votre réponse. C'est exactement le résultat que je voulais. Je vais le tester en production. Mais de toute façon avec votre code, je pense que je suis sur la bonne voie. Merci beaucoup.



1
votes

Vous ne pouvez pas modifier le marqueur. Cependant, vous pouvez faire quelque chose comme ceci:

  • pour chaque chemin auquel vous ajoutez un élément de texte:
    x = "110" y = "543" >
  • les valeurs x et y du texte proviennent de l'attribut d :
    dans ce cas d = "M 110 543 L98 366" li >

Vous pouvez également choisir d'ajouter ces éléments de texte dynamiquement dans un groupe séparé.

<svg viewBox="70 230 350 370" >
<defs>
    <marker id="start" viewBox="0 0 42 42" refX="10" refY="10" markerWidth="20" markerHeight="20">
      <rect width="20" height="20"></rect>
    </marker>
</defs>

<path d="M110 543 L98 366" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start)" />
<text class="number" x="110" y="543" ></text>
<path d="M172 544 L139 454 L140 420 L144 357 L146 283" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start)" />
  <text class="number" x="172" y="544" ></text>
<path d="M151 447 L171 403 L174 326 L164 284 L158 279" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start)"/>
  <text class="number" x="151" y="447" ></text>
<path d="M234 571 L224 520 L244 465 L256 404 L248 361 L234 307 L236 256" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start)"/>
  <text class="number" x="234" y="571" ></text>
<path d="M383 578 L376 465 L361 430 L325 378 L325 311 L348 234" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start)" marker-start="url(#start)"/>
  <text class="number" x="383" y="578" ></text>
<path d="M376 435 L380 356 L365 331 L358 284 L354 240" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-start="url(#start)"/>
   <text class="number" x="376" y="435" ></text>
</svg>
svg{border:solid; width:90vh;}
text{font-family:Verdana;font-size:8px;fill:#fff;text-anchor:middle; dominant-baseline:middle}
var number    = document.querySelectorAll('.number');
var polygons  = document.getElementsByTagName("path");

for (var i = 0; i < polygons.length; i++) {
      number[i].innerHTML = i;    
}


1 commentaires

Bonne réponse. Mais j'ai pensé en lisant le début de la réponse que les coordonnées du texte seront tirées du chemin en utilisant JS



0
votes

La solution consiste à ajouter une balise marqueur pour chaque polygone

<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="629" version="1.1" xmlns:xlink= "http://www.w3.org/1999/xlink">
<defs>
    <marker id="start" viewBox="0 0 42 42" refX="10" refY="20" markerWidth="20" markerHeight="20">
      <rect width="20" height="20" fill="#000"></rect>
      <text x="10" y="10" font-family="Verdana" font-size="10" fill="#fff" text-anchor="middle" alignment-baseline="central" class="number">1</text>
    </marker>
	
    <marker id="start2" viewBox="0 0 42 42" refX="10" refY="20" markerWidth="20" markerHeight="20">
      <rect width="20" height="20" fill="#000"></rect>
      <text x="10" y="10" font-family="Verdana" font-size="10" fill="#fff" text-anchor="middle" alignment-baseline="central" class="number">2</text>
    </marker>
	
    <marker id="start3" viewBox="0 0 42 42" refX="10" refY="20" markerWidth="20" markerHeight="20">
      <rect width="20" height="20" fill="#000"></rect>
      <text x="10" y="10" font-family="Verdana" font-size="10" fill="#fff" text-anchor="middle" alignment-baseline="central" class="number">3</text>
    </marker>
	
</defs>

<path d="M110 543 L98 366" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start)" />
<path d="M172 544 L139 454 L140 420 L144 357 L146 283" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start2)"/>
<path d="M151 447 L171 403 L174 326 L164 284 L158 279" stroke="#E42522" stroke-width="2" stroke-dasharray="20,5" fill="none" marker-end="url(#dot)" marker-start="url(#start3)"/>

</svg>

Via javascript, vous devrez ajouter dynamiquement dans la balise defs un nœud de repère pour chaque polygone (à l'intérieur de la boucle for).


0 commentaires