PerfectVector
Par Irene Kim11 min de lecture

Images SVG Graphviz : des illustrations portables

Ajoute un SVG à un nœud Graphviz, examine sa référence d’image et teste les ressources complètes, le diagramme déplacé et une copie de livraison autonome.

Sur cette page

Un diagramme Graphviz peut contenir des nœuds et des flèches vectoriels alors que les illustrations personnalisées de ses nœuds renvoient encore à un fichier image distinct. Si ces illustrations disparaissent après déplacement du SVG, examine la référence d’image générée avant de modifier le dessin. Le problème peut venir des fichiers livrés.

Dans la sortie SVG testée ci-dessous, Graphviz conserve motif.svg comme image liée. L’ensemble complet des fichiers l’affiche ; le diagramme déplacé seul la perd. Une copie explicitement empaquetée inclut les octets de l’illustration et s’affiche dans le même test de navigateur. Cette étape conserve toutefois un élément image SVG, sans transformer le motif en tracés natifs du graphe.

Conserve la source DOT pour les noms des nœuds et leurs relations. Garde l’original de l’illustration séparément et teste la sortie exacte dans le logiciel de visualisation ou le processus de publication qui la recevra.

Distingue le nœud, son illustration et sa référence de fichier

L’attribut image de Graphviz désigne l’illustration affichée dans un nœud. Il ne remplace pas l’identité du nœud ni ses relations dans le graphe. La documentation exige des dimensions sources ; pour les images SVG, fournis des valeurs explicites de width et height avec des unités adaptées.

Le motif d’origine est ici un dessin de deux tracés dans un espace de coordonnées de 96 sur 64. Ses dimensions extérieures sont 96pt sur 64pt. Le nœud qui l’entoure et la flèche appartiennent à Graphviz.

PartieConservée dansProblèmes possibles
Noms des nœuds, libellés et arêtesSource DOTRelations ou texte incorrects
Motif personnaliséOriginal SVG de l’illustrationDimensions absentes, détails inadaptés ou proportions incorrectes
Lien du diagramme vers le motifRéférence d’image dans le SVG exportéIllustration absente au chemin résolu
Position et taille finalesSortie du moteur de rendu et logiciel destinataireDécoupage, étirement ou dépendances non prises en charge

Un élément image peut pointer vers une illustration SVG ou vers des pixels. Pour examiner une source matricielle, consulte le diagnostic des images intégrées dans un SVG. Un nom de fichier se terminant par .svg ne suffit pas à déterminer le contenu de l’un ou l’autre fichier.

Exécute un petit exemple avec un moteur de rendu explicite

Nous avons utilisé @viz-js/viz 3.31.0, une version WebAssembly indiquant Graphviz 16.1.0, avec le moteur de disposition dot et la sortie SVG intégrée. Ce test concerne cette version et ce moteur de rendu ; il ne signifie pas que toutes les installations Graphviz chargent les images de manière identique.

Dans un nouveau dossier de projet Node.js, installe cette version précise du paquet :

npm install @viz-js/viz@3.31.0

Enregistre l’illustration d’origine sous motif.svg :

<svg xmlns="http://www.w3.org/2000/svg"
     width="96pt" height="64pt" viewBox="0 0 96 64">
  <path fill="#173b40" fill-rule="evenodd"
    d="M48 4C70 4 88 17 88 32S70 60 48 60S8 47 8 32S26 4 48 4Z
       M48 14C31 14 19 22 19 32S31 50 48 50S77 42 77 32S65 14 48 14Z"/>
  <path fill="#28bfa3"
    d="M43 20H53V27H60V37H53V44H43V37H36V27H43Z"/>
</svg>

Enregistre le graphe sous diagram.dot :

digraph G {
  graph [rankdir=LR, bgcolor="white", margin=0.1];
  node [shape=box, fontname="Arial", fontsize=16,
        color="#173b40", penwidth=1.5,
        fixedsize=true, width=1.8, height=1.1];
  artwork [label="", image="motif.svg", imagescale=true];
  review [label="Review"];
  artwork -> review [color="#173b40", penwidth=1.5];
}

Puis enregistre ceci sous render.mjs et exécute node render.mjs depuis ce dossier :

import { instance } from '@viz-js/viz';
import fs from 'node:fs';
 
const viz = await instance();
const dot = fs.readFileSync('diagram.dot', 'utf8');
const svg = viz.renderString(dot, {
  engine: 'dot',
  format: 'svg',
  images: [{ name: 'motif.svg', width: '96pt', height: '64pt' }]
});
 
fs.mkdirSync('bundle', { recursive: true });
fs.copyFileSync('motif.svg', 'bundle/motif.svg');
fs.writeFileSync('bundle/diagram.svg', svg);
process.stdout.write(`Graphviz ${viz.graphvizVersion}\n`);

La documentation de l’API Viz.js décrit l’option images comme une information sur les dimensions des images. La fournir renseigne la disposition sur cette illustration nommée ; elle n’inclut pas les octets du fichier dans le résultat. Les unités explicites évitent de traiter un nombre sans unité comme des pixels CSS. L’API utilise les points pour les dimensions sans unité.

Pour une installation native de Graphviz, la documentation officielle de image décrit les ressources d’image locales et les dimensions lues dans le fichier source. Ne transpose pas la configuration des métadonnées WebAssembly dans une commande native en supposant que le mécanisme de chargement est identique.

Examine ce que le moteur de rendu a écrit

Notre SVG généré contient cet élément :

<image xlink:href="motif.svg"
       width="118.8px" height="79.2px"
       preserveAspectRatio="xMinYMin meet"
       x="5.4" y="-79.2"/>

Les dimensions et la position sont des valeurs observées dans cet exemple. La partie déterminante pour la livraison est xlink:href="motif.svg" : le résultat a encore besoin d’une ressource à ce chemin relatif.

Copie uniquement diagram.svg dans un autre dossier, sans l’illustration. Compare-le à l’ensemble complet. Nous avons servi les deux dossiers en HTTP local et affiché chaque SVG comme document au moyen d’un élément HTML object.

Trois diagrammes SVG Graphviz réels : illustration présente avec toutes ses ressources, absente après déplacement du diagramme seul et présente dans une copie intégrant les octets de l’image SVG
Le fichier central possède la même géométrie de graphe et la même référence d’illustration que celui de gauche. Son motif est absent au chemin résolu. La copie de droite inclut explicitement cette illustration sous forme d’URL de données SVG.

Les boîtes de nœuds et la flèche générées restent présentes lorsque le motif lié manque. Reconstruire la disposition du graphe ne fournit pas le fichier absent. Rétablis l’emplacement attendu de la ressource, livre l’ensemble des fichiers ou choisis une étape d’empaquetage adaptée à la destination.

Ouvrir un SVG comme document et l’afficher au moyen d’un élément HTML img sont deux tests différents. Le guide MDN sur le SVG comme image explique que les contextes d’image peuvent limiter les ressources externes, tandis que les URL de données permettent de les intégrer. Les restrictions de contexte d’image décrites ne s’appliquent pas aux documents SVG ouverts directement ni à l’intégration de documents via object et iframe. Vérifie le contexte de livraison que tu utilises réellement.

Empaquette explicitement ce motif simple

Pour ce motif original autonome, le script suivant remplace exactement une référence connue par les octets SVG du fichier. Enregistre-le sous package.mjs et exécute-le après le rendu :

import fs from 'node:fs';
 
const svg = fs.readFileSync('bundle/diagram.svg', 'utf8');
const needle = 'xlink:href="motif.svg"';
if (svg.split(needle).length !== 2) {
  throw new Error('Expected exactly one motif reference');
}
 
const data = 'data:image/svg+xml;base64,' +
  fs.readFileSync('bundle/motif.svg').toString('base64');
const packaged = svg.replace(needle, `xlink:href="${data}"`);
fs.writeFileSync('self-contained.svg', packaged);

Cet exemple d’empaquetage est ciblé ; ce n’est pas un outil général d’intégration de SVG. Il traite la référence connue de cette sortie et un motif sans polices, images, feuilles de style ni autres dépendances externes. Une illustration plus complexe nécessite sa propre vérification des dépendances.

La copie empaquetée affichait le motif dans notre test de navigateur. La comparaison des deux chaînes de sortie après masquage de la valeur de référence d’image a montré une géométrie de graphe identique. Le fichier contient encore un élément image ; sa référence commence désormais par data:image/svg+xml;base64,.

Intégrer les octets d’une image SVG peut supprimer cette dépendance au chemin de fichier tout en conservant la source vectorielle de l’illustration. Cela ne transforme pas l’illustration en forme de nœud Graphviz native, n’ajoute pas de points de connexion à l’intérieur et ne garantit pas qu’un autre éditeur exposera directement ses tracés. Teste le comportement d’importation du destinataire.

Évite également de confondre svg_inline avec l’intégration des images. La documentation de la sortie SVG de Graphviz le décrit comme une sortie sans en-tête pour inclusion dans du HTML. Avec le même graphe, sélectionner svg_inline produisait encore la référence motif.svg. Ce mode de sortie n’empaquetait pas l’illustration.

Distingue les dimensions et la mise à l’échelle de la portabilité

La référence imagescale de Graphviz distingue l’ajustement de l’image dans le nœud de sa taille naturelle. Dans cet exemple, imagescale=true la redimensionne uniformément pour qu’elle tienne. L’option both redimensionne séparément la largeur et la hauteur, ce qui peut modifier les proportions.

Si le motif apparaît étiré, examine l’option de mise à l’échelle. Si seule une partie apparaît, examine ses propres limites et l’espace disponible dans le nœud. S’il disparaît après déplacement du fichier, examine d’abord le chemin de la ressource. Le guide des dimensions SVG explique la différence entre la taille déclarée et les coordonnées du dessin.

SymptômePremière vérificationCorrection à essayer
L’illustration disparaît après déplacement du diagrammeRéférence d’image générée et emplacement relatif de la ressourceRétablir l’ensemble des fichiers ou empaqueter explicitement la source testée
La disposition fonctionne, mais l’illustration est absenteDimensions sources et configuration d’image propre à la versionConfirmer le fichier et les métadonnées d’image attendus par cette version
Le motif semble étiréRéglage imagescale et proportions souhaitéesUtiliser un ajustement uniforme si la déformation n’est pas souhaitée
Le SVG fonctionne directement, mais échoue sur une page webContexte d’image ou de document utilisé par la pageTester le mode d’intégration pris en charge et sa politique de ressources
La sortie change après changement de moteur de renduMoteur choisi et structure de son SVGRéexaminer le XML exporté et l’apparence finale

La page officielle de la sortie SVG indique que la sortie Cairo peut différer de la sortie SVG intégrée en matière de lisibilité XML et de possibilités de transformation. Nous n’avons pas testé Cairo ici. Indique explicitement le moteur de rendu dans un projet reproductible et répète la vérification de l’empaquetage lorsque tu le changes.

Récupère l’illustration en amont si sa source est perdue

PerfectVector peut t’aider lorsqu’un motif illustratif adapté ne subsiste que sous forme de PNG ou de scan. Son processus de récupération d’illustrations scientifiques fournit un candidat vectoriel à examiner avant utilisation. Recadre sur le motif, vérifie sa silhouette et ses espaces vides, puis vérifie les limites et les dimensions du SVG téléchargé avant de l’ajouter au graphe.

Cette récupération ne reconstruit pas les relations entre nœuds, le sens des flèches ni les libellés DOT. Conserve ces éléments dans la source du graphe. Utilise le SVG original s’il est disponible, redessine un symbole simple si cela facilite la maintenance et garde les photographies sous forme matricielle. La présentation de la vectorisation d’images explique cette limite de récupération.

D’autres outils de diagramme empaquettent différemment les illustrations personnalisées. Le guide des icônes Mermaid traite des données d’icônes enregistrées, tandis que les illustrations SVG personnalisées dans draw.io distinguent une image importée d’un gabarit natif. Tiens compte des exigences de la destination lorsque tu prépares l’illustration.

FAQ

La sortie SVG de Graphviz inclut-elle automatiquement mon image de nœud ? Dans la sortie SVG intégrée testée, le diagramme contient une référence d’image vers le fichier motif.svg distinct. Examine ta propre sortie et livre ses dépendances ou utilise une étape d’empaquetage testée.

svg_inline fusionne-t-il les tracés d’une image SVG dans le graphe ? Non. Il s’agit d’un mode de sortie sans en-tête pour inclusion dans du HTML. Dans notre test, il conservait la référence externe motif.svg.

Un SVG autonome équivaut-il à une géométrie de nœud native modifiable ? Non. L’exemple empaqueté conserve un élément image contenant les octets SVG. La structure du graphe reste dans DOT, et l’éditeur destinataire détermine comment il expose cette illustration.

Sources

  1. Graphviz — image — Ressources d’image locales des nœuds et dimensions SVG requises.
  2. Graphviz — imagescale — Ajustement uniforme et mise à l’échelle indépendante de la largeur et de la hauteur.
  3. Graphviz — sortie SVG — Sorties intégrée et Cairo, et signification de svg_inline.
  4. Viz.js — API — Métadonnées de dimensions d’image, unités explicites et appels de rendu SVG.
  5. MDN — SVG comme image — Restrictions des ressources externes dans les contextes d’image et distinction avec l’intégration de documents.

Teste un nœud dans le processus de livraison avant de préparer une bibliothèque complète d’illustrations. S’il ne reste qu’un motif matriciel, prépare un candidat SVG, examine ses espaces et ses proportions, puis ajoute-le à ton graphe DOT et vérifie la sortie déplacée ou empaquetée dans le logiciel destinataire.

Plus depuis le blog

Repartez d’un SVG plus net
et plus facile à modifier