PerfectVector
Por Irene Kim10 min de lectura

Imágenes SVG en Graphviz: conserva portátiles los gráficos de nodos

Añade un gráfico SVG a un nodo Graphviz, revisa su referencia de imagen y prueba un paquete completo frente a un diagrama movido y una copia de entrega autónoma.

En esta página

Un diagrama Graphviz puede contener nodos y flechas vectoriales mientras el gráfico personalizado de un nodo sigue apuntando a un archivo de imagen independiente. Si ese gráfico desaparece al mover el SVG, revisa la referencia de imagen generada antes de cambiar el dibujo. Puede que falte parte del paquete de entrega.

En la salida SVG probada a continuación, Graphviz conserva motif.svg como imagen vinculada. El paquete completo la renderiza; al mover el diagrama sin el archivo del gráfico, este desaparece. Una copia empaquetada explícitamente incluye los bytes del gráfico y se renderiza en la misma prueba de navegador. Ese paso de empaquetado sigue dejando un elemento de imagen SVG, en lugar de convertir el motivo en trazados nativos del grafo.

Conserva la fuente DOT para nombres de nodos y relaciones. Guarda por separado el maestro del gráfico y prueba la salida exacta mediante el visor o flujo de publicación que la recibirá.

Distingue el nodo, su gráfico y su referencia de archivo

El atributo image de Graphviz nombra el gráfico mostrado dentro de un nodo. No sustituye la identidad del nodo ni sus relaciones en el grafo. La documentación requiere dimensiones de origen; para imágenes SVG, proporciona width y height explícitos con unidades adecuadas.

El motivo original de este ejemplo es un dibujo de dos trazados con un espacio de coordenadas de 96 por 64. Sus dimensiones exteriores son 96pt por 64pt. El nodo que lo rodea y la flecha pertenecen a Graphviz.

ParteSe mantiene enQué puede fallar
Nombres de nodos, etiquetas y aristasFuente DOTRelaciones o texto del grafo incorrectos
Motivo personalizadoMaestro SVG del gráficoDimensiones ausentes, detalle inadecuado o proporciones incorrectas
Vínculo del diagrama al motivoReferencia de imagen del SVG exportadoFalta el gráfico en la ruta resuelta
Colocación y tamaño finalesSalida del renderizador y visor receptorRecorte, estiramiento o dependencias no compatibles

Un elemento de imagen puede apuntar a un gráfico SVG o a píxeles. Para investigar una fuente raster, utiliza el diagnóstico específico de imágenes incrustadas en SVG. Un nombre de archivo terminado en .svg no basta para determinar el contenido de ninguno de los dos archivos.

Ejecuta un ejemplo pequeño con un renderizador explícito

Utilizamos @viz-js/viz 3.31.0, una compilación WebAssembly que informa de Graphviz 16.1.0, con el motor de disposición dot y salida SVG integrada. Es una prueba de esa compilación y renderizador, no una afirmación de que todas las instalaciones de Graphviz carguen imágenes de forma idéntica.

En una carpeta nueva de proyecto Node.js, instala el paquete con la versión fijada:

npm install @viz-js/viz@3.31.0

Guarda el gráfico original como 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>

Guarda el grafo como 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];
}

Guarda después lo siguiente como render.mjs y ejecuta node render.mjs desde esa carpeta:

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 documentación de la API de Viz.js describe la opción images como información de tamaño de imagen. Proporcionarla informa a la disposición sobre ese gráfico con nombre; no incluye los bytes del archivo en el resultado. Las unidades explícitas evitan interpretar una cifra sin unidad como píxeles CSS. La API utiliza puntos para dimensiones sin unidades.

Para una instalación nativa de Graphviz, la documentación oficial de image describe recursos de imagen locales y dimensiones leídas del archivo de origen. No copies la configuración de metadatos WebAssembly a un comando nativo suponiendo que utiliza el mismo mecanismo de carga.

Revisa lo que escribió el renderizador

Nuestro SVG generado contiene este elemento:

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

Las dimensiones y posición son valores observados en este ejemplo de prueba. La parte que controla la entrega es xlink:href="motif.svg": el resultado sigue necesitando un recurso en esa ruta relativa.

Copia solo diagram.svg a otra carpeta y deja atrás el gráfico. Compáralo con el paquete completo. Servimos ambas carpetas mediante HTTP local y mostramos cada SVG como documento a través de un elemento HTML object.

Tres diagramas SVG reales de Graphviz: gráfico presente en su paquete completo de recursos, ausente al mover solo el diagrama y presente en una copia con los bytes de imagen SVG incrustados
El archivo central tiene la misma geometría de grafo y referencia de gráfico que el izquierdo. Su motivo falta en la ruta resuelta. La copia derecha incluye explícitamente ese gráfico como URL de datos SVG.

Los recuadros de nodos y la flecha generados siguen presentes cuando falta el motivo vinculado. Reconstruir la disposición del grafo no aporta el archivo ausente. Restaura la ubicación esperada del recurso, entrega el paquete completo o elige un paso de empaquetado adecuado para el destino.

Abrir un SVG como documento y mostrarlo mediante un img HTML son pruebas distintas. La guía de SVG como imagen de MDN explica que los contextos de imagen pueden restringir recursos externos, mientras que las URL de datos pueden incluirlos en línea. Las restricciones de contexto de imagen que describe no se aplican a documentos SVG directos ni a la incrustación de documentos mediante object e iframe. Comprueba el contexto de entrega que realmente utilizas.

Empaqueta este motivo sencillo de forma explícita

Para este motivo original autónomo, el siguiente script sustituye exactamente una referencia conocida por los bytes SVG del archivo. Guárdalo como package.mjs y ejecútalo después del renderizado:

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);

Es un ejemplo específico de empaquetado, no una herramienta general para integrar SVG. Trata la referencia conocida de esta salida y un motivo sin fuentes, imágenes, hojas de estilo externas ni otras dependencias. Los gráficos más complejos necesitan su propia comprobación de dependencias.

La copia empaquetada se renderizó con el motivo presente en nuestra prueba de navegador. Comparar las dos cadenas de salida después de ocultar el valor de referencia de imagen mostró una geometría de grafo idéntica. El archivo sigue conteniendo un elemento de imagen; su referencia comienza ahora por data:image/svg+xml;base64,.

Incrustar bytes de imagen SVG puede eliminar esta dependencia de ruta manteniendo la fuente vectorial del gráfico. No convierte ese gráfico en una forma nativa de nodo Graphviz, no añade puntos de conexión dentro de él ni garantiza que otro editor exponga sus trazados directamente. Prueba el comportamiento de importación del destinatario.

Evita también confundir svg_inline con la incrustación de imágenes. La documentación de salida SVG de Graphviz lo describe como salida sin cabecera para incluir en HTML. En nuestro mismo grafo, seleccionar svg_inline siguió produciendo la referencia motif.svg. El modo de salida no empaquetó el gráfico.

Mantén dimensiones y escalado separados de la portabilidad

La referencia de imagescale de Graphviz distingue entre encajar la imagen dentro del nodo y el tamaño natural de la fuente. En este ejemplo, imagescale=true la escala uniformemente para encajar. La opción both escala anchura y altura por separado, lo que puede cambiar las proporciones.

Si el motivo aparece, pero está estirado, revisa la opción de escalado. Si solo aparece una parte, revisa sus propios límites y el espacio disponible del nodo. Si desaparece al mover el archivo, revisa primero la ruta del recurso. La guía de tamaños SVG explica la diferencia entre tamaño declarado y coordenadas de dibujo.

SíntomaPrimera comprobaciónCorrección que probar
El gráfico desaparece al mover el diagramaReferencia de imagen generada y ubicación relativa del recursoRestaurar el paquete o empaquetar explícitamente la fuente probada
Se ejecuta la disposición del grafo, pero falta el gráficoDimensiones de origen y configuración de imagen específica de la compilaciónConfirmar el archivo y los metadatos de imagen que espera esa compilación
El motivo parece estiradoAjuste imagescale y proporciones previstasUtilizar un ajuste uniforme cuando no se quiera deformación
El SVG funciona directamente, pero falla en una página webSi la página utiliza un contexto de imagen o documentoProbar la vía de incrustación compatible y su política de recursos
La salida cambia al cambiar de renderizadorRenderizador elegido y su estructura SVGVolver a revisar el XML exportado y el aspecto final

La página oficial de salida SVG indica que la salida Cairo puede diferir de la SVG integrada en legibilidad y capacidad de transformación del XML. Aquí no probamos Cairo. Mantén explícito el renderizador en un proyecto reproducible y repite la comprobación de empaquetado al cambiarlo.

Recupera el gráfico antes cuando se haya perdido la fuente

PerfectVector puede ayudar cuando un motivo ilustrativo adecuado solo se conserva como PNG o escaneo. Su flujo de recuperación de gráficos científicos proporciona un vector candidato que revisar antes de usar. Recorta el motivo, comprueba su silueta y espacios vacíos y verifica después los límites y dimensiones del SVG descargado antes de añadirlo al grafo.

Esa recuperación no reconstruye relaciones de nodos, significados de flechas ni etiquetas DOT. Conserva esos elementos en la fuente del grafo. Utiliza el SVG original cuando esté disponible, redibuja un símbolo sencillo cuando sea más fácil de mantener y conserva las fotografías como imágenes raster. La descripción general de vectorización de imágenes explica el límite de recuperación.

Otras herramientas de diagramas empaquetan gráficos personalizados de forma distinta. La guía de iconos Mermaid trata datos de iconos registrados, mientras que los gráficos SVG personalizados de draw.io distinguen una imagen importada de una plantilla nativa. Incorpora los requisitos del destino a la preparación del gráfico.

Preguntas frecuentes

¿La salida SVG de Graphviz incluye automáticamente mi imagen de nodo? En la salida SVG integrada probada, el diagrama contiene una referencia de imagen al archivo motif.svg independiente. Revisa tu propia salida y entrega sus dependencias o utiliza un paso de empaquetado probado.

¿svg_inline fusiona los trazados de una imagen SVG con el grafo? No. Es un modo de salida sin cabecera para incluir en HTML. En nuestra prueba conservó la referencia externa motif.svg.

¿Un SVG autónomo equivale a geometría de nodo nativa editable? No. El ejemplo empaquetado conserva un elemento de imagen con bytes SVG. La estructura del grafo permanece en DOT y el editor receptor determina cómo expone ese gráfico.

Fuentes

  1. Graphviz — image — Recursos locales de imágenes de nodos y dimensiones SVG necesarias.
  2. Graphviz — imagescale — Ajuste uniforme y escalado independiente de anchura y altura.
  3. Graphviz — Salida SVG — Salida integrada y Cairo, además del significado de svg_inline.
  4. Viz.js — API — Metadatos de tamaño de imagen, unidades explícitas y llamadas de renderizado SVG.
  5. MDN — SVG como imagen — Restricciones de recursos externos en contextos de imagen y distinción respecto a la incrustación de documentos.

Prueba un nodo a través del flujo de entrega antes de preparar toda una biblioteca de gráficos. Si solo queda un motivo raster, prepara un gráfico SVG candidato, revisa sus huecos y proporciones, añádelo después a tu grafo DOT y verifica la salida movida o empaquetada en el visor receptor.

Más del blog

Empieza con un SVG más limpio
y fácil de editar