Incorporation de SVG externe en HTML pour la manipulation JavaScript

J'ai une image SVG, montrant des régions géographiques. Http://upload.wikimedia.org/wikipedia/commons/7/71/Nederland_gemeenten_2009.svg

Je souhaite afficher l'image SVG sur une page Web et utiliser une combinaison de JavaScript et CSS pour interagir avec l'image. (C'est-à-dire détecter les clics sur une région, définir une couleur d'arrière-plan différente pour une région).

Je sais que cette question est posée à plusieurs reprises sur StackOverflow, mais je ne peux pas trouver un exemple de code complet pour continuer. Toutes les recommandations sur les packages JavaScript, comme jQuery, ou les plug-ins sont les bienvenues.

Ma compréhension de la question est qu'il y a différents aspects à résoudre:

  1. Comment préparer l'image pour l'interaction
  2. Comment intégrer l'image dans la page
  3. Comment utiliser CSS avec SVG
  4. Comment utiliser JavaScript pour l'interaction

Préparation de l'image

Tout d'abord, je recommanderais de nettoyer l'image. Inkscape laisse toutes sortes de choses dont vous n'avez pas besoin, ce qui inclut des éléments et des attributs dans le site de sodipodi: inkscape: namespaces ainsi que des attributs de style répétitifs et / ou redondants. Vous ne devez pas supprimer cela, mais cela vous permet d'économiser de la bande passante / temps de chargement, et si vous souhaitez travailler avec une correspondance CSS, les attributs de style sont sur votre chemin.

Dans votre fichier d'exemple, vous avez 472 fois le même attribut de style. Supprimez-les et créez une règle CSS équivalente une fois.

Vous pouvez également ajouter des informations sur les municipalités à la balise. Vous pouvez, par exemple, modifier les ID de chaque chemin représentant une municipalité en fonction de son nom. Vous pouvez également utiliser un attribut data-* à cette fin. Ce dernier a l'avantage que vous pouvez utiliser des espaces. Voir ci-dessous pour savoir comment cela est utile pour l'interaction, en particulier avec CSS.

Incorporation de l'image

Je recommanderais l'utilisation du SVG en ligne, surtout si vous souhaitez interagir avec CSS / JavaScript. Cela signifie que vous venez d'ajouter le balisage SVG à votre code HTML, ou vous le chargez et l'insérez en utilisant Ajax. Ce dernier bénéficie du fait que la page environnante se charge plus rapidement et se sent plus sensible.

Un exemple d'un élément SVG en ligne:

 <div id="svgContainer"> <!-- This is an HTML div, and inside goes the SVG --> <svg xmlns="http://www.w3.org/2000/svg" width="100px" height="100px"> <circle r="50" cx="50" cy="50" fill="green"/> </svg> </div> 

Un exemple simplifié de la façon de charger SVG en utilisant Ajax:

 xhr = new XMLHttpRequest(); xhr.open("GET","my.svg",false); // Following line is just to be on the safe side; // not needed if your server delivers SVG with correct MIME type xhr.overrideMimeType("image/svg+xml"); xhr.send(""); document.getElementById("svgContainer") .appendChild(xhr.responseXML.documentElement); 

Comment utiliser CSS

SVG peut être stylé comme HTML. Bien sûr, SVG a son propre ensemble de propriétés, comme l' fill-opacity ou le stroke-dasharray et ne supporte pas beaucoup de propriétés HTML, comme la margin , la position ou autre. Mais les mécanismes de sélection sont 100% les mêmes.

Vous pouvez mélanger le CSS pour votre SVG en ligne avec le CSS pour votre HTML, soit dans un élément <style> ou un fichier CSS externe. Vous pouvez également utiliser l'élément <style> à l'intérieur du code SVG et style attributs de style .

En supposant que vous donniez à vos éléments SVG des ID significatifs ou des attributs data-* , deux façons de mettre en évidence les municipalités utilisant CSS seraient:

 #Bronckhorst, #Laarbeek {fill:red} 

ou

 *[data-gemeente=Bronckhorst], *[data-gemeente=Laarbeek] {fill:red} 

Ou, bien sûr, vous pouvez modifier les attributs de style des éléments respectifs. Les propriétés sont également prises en charge en tant qu'attribut, c'est-à-dire que style="stroke-width:2" peut également être spécifié comme stroke-width="2" . Si la même propriété est définie en utilisant à la fois un attribut et CSS (soit en utilisant l'attribut de style, un élément de style ou une feuille de style externe), le CSS remplace l'attribut.

Interaction JavaScript

Il n'y a pratiquement aucune différence entre HTML et SVG en ce qui concerne l'interaction JavaScript, au moins aussi longtemps que vous utilisez le DOM simple de vanilla. Cela signifie que les fonctionnalités spécifiques au HTML comme innerHTML ne sont pas prises en charge dans SVG (c'est-à-dire qu'il n'y a pas de innerSVG ). Mais SVG a son propre ensemble graphique spécifique de DOM ( voir les spécifications du W3C ).

Une chose à prendre en compte est le travail avec les espaces de noms. Tous les éléments SVG doivent être dans l'espace de noms SVG et, lors de leur création en utilisant JavaScript, createElementNS() doit être utilisé au lieu de createElement() :

 var use = document.createElementNS("http://www.w3.org/2000/svg","use") 

De même, les attributs dans l'espace de noms XLink (à savoir xlink:href ) doivent être manipulés à l'aide de setAttributeNS() au lieu de setAttribute() :

 use.setAttributeNS("http://www.w3.org/1999/xlink","href","#foo") 

Comme les bibliothèques comme jQuery dépendent en partie de fonctionnalités spécifiques au HTML, il est plus sûr de les éviter lors de la manipulation de SVG. Il existe également des bibliothèques spécifiques au SVG comme Raphaël et D3.js qui peuvent être utiles à des fins spécifiques et valent le coup d'oeil. Raphaël est particulièrement utile pour être compatible avec les versions de pré-HTML5 Internet Explorer 6 à 8, qui n'ont pas de support SVG. Cependant, si je comprends bien, il est vraiment utile de générer des graphiques en utilisant entièrement JavaScript plutôt que de travailler avec des graphiques existants, car il s'agit d'une couche d'abstraction au-dessus de SVG. D3.js serait plus adapté à des applications comme la vôtre si vous n'êtes pas satisfait du DOM simple (et, honnêtement, je le fais injustice quand je l'appelle simplement une bibliothèque spécifique SVG, car c'est plus).

Vous pouvez utiliser onclick et des attributs similaires et DOM addEventListener() standard addEventListener() . Un exemple très simple d'utilisation des événements JavaScript serait d'ajouter un auditeur d'événements à l'élément <svg> qui rapporte le nom d'une municipalité sur laquelle un utilisateur a cliqué:

 document.getElementsByTagName("svg")[0] .addEventListener("click",function(evt){ alert(evt.target.getAttribute("data-gemeente")) }, false) 

Note latérale: Toopltips Le même effet que vous obtenez en utilisant l'attribut title en HTML peut être obtenu en utilisant l'élément <title> dans SVG. Mettez juste un élément <title> dans un élément SVG et survolez, vous voyez une info-bulle avec le contenu de l'élément <title> .

 <svg xmlns="http://www.w3.org/2000/svg" width="100px" height="100px"> <rect width="100" height="100"> <title>test</title> </rect> </svg> 

Juste pour le compte rendu (en sachant qu'il y a un an de retard), j'ai trouvé SnapSVG génial pour la manipulation SVG. Le même mec qui était derrière Raphaël:

http://snapsvg.io