SVG-изображения Graphviz: переносимая графика узлов
Добавьте SVG-графику в узел Graphviz, проверьте ссылку на изображение и сравните полный комплект ресурсов, перенесенную диаграмму и автономную копию для передачи.
На этой странице
- Различайте узел, его графику и ссылку на файл
- Запустите небольшой пример с явно выбранным средством отрисовки
- Проверьте, что записало средство отрисовки
- Явно упакуйте этот простой мотив
- Рассматривайте размеры и масштабирование отдельно от переносимости
- Восстановите графику на предыдущем этапе, если исходник утерян
- Частые вопросы
- Источники
Диаграмма Graphviz может содержать векторные узлы и стрелки, тогда как собственная графика узлов по-прежнему ссылается на отдельный файл изображения. Если эта графика исчезает после переноса SVG, проверьте созданную ссылку на изображение, прежде чем менять рисунок. Возможно, не хватает части передаваемого комплекта.
В проверенном SVG-выводе ниже Graphviz сохраняет motif.svg как связанное изображение. Полный комплект отображает его; диаграмма, перенесенная отдельно, теряет его. Копия с явно упакованными ресурсами содержит байты изображения и отображается в том же браузерном тесте. После такой упаковки остается элемент изображения SVG: мотив не превращается в собственные контуры графа.
Сохраните исходник DOT с именами узлов и связями. Храните оригинал изображения отдельно и проверьте именно тот вывод в программе просмотра или процессе публикации, который его получит.
Различайте узел, его графику и ссылку на файл
Атрибут image в Graphviz задает изображение внутри узла. Он не заменяет идентичность узла в графе или его связи. Документация требует указания размеров исходника; для SVG-изображений задавайте явные width и height с подходящими единицами.
Исходный мотив здесь — рисунок из двух контуров в координатном пространстве 96 на 64. Его внешние размеры — 96pt на 64pt. Окружающий узел и стрелка принадлежат Graphviz.
| Часть | Где поддерживается | Что может пойти не так |
|---|---|---|
| Имена узлов, подписи и ребра | Исходник DOT | Неверные связи графа или формулировки |
| Собственный мотив | Оригинал изображения SVG | Отсутствующие размеры, неподходящая детализация или неверные пропорции |
| Ссылка из диаграммы на мотив | Ссылка на изображение в экспортированном SVG | Изображение отсутствует по вычисленному пути |
| Итоговое положение и размер | Вывод средства отрисовки и принимающая программа просмотра | Обрезка, растяжение или неподдерживаемые зависимости |
Элемент изображения может ссылаться на SVG-графику или на пиксели. Для исследования растрового источника используйте отдельное руководство по диагностике встроенных изображений SVG. Одного имени файла с окончанием .svg недостаточно, чтобы установить содержимое любого из этих файлов.
Запустите небольшой пример с явно выбранным средством отрисовки
Мы использовали @viz-js/viz 3.31.0 — сборку WebAssembly, сообщающую версию Graphviz 16.1.0, — с движком компоновки dot и встроенным выводом SVG. Это проверка именно этой сборки и средства отрисовки, а не утверждение, что все установки Graphviz загружают изображения одинаково.
В новой папке проекта Node.js установите пакет закрепленной версии:
npm install @viz-js/viz@3.31.0Сохраните исходное изображение как 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>Сохраните граф как 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];
}Затем сохраните следующий код как render.mjs и запустите node render.mjs из этой папки:
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`);Документация API Viz.js описывает параметр images как информацию о размере изображения. Его передача сообщает компоновщику об этом именованном изображении, но не помещает байты файла в результат. Явные единицы предотвращают трактовку числа без единиц как CSS-пикселей. API использует пункты для размеров без единиц.
Для нативной установки Graphviz официальная документация image описывает локальные изображения и размеры, считываемые из исходного файла. Не переносите настройку метаданных WebAssembly в нативную команду в предположении, что механизм загрузки будет тем же.
Проверьте, что записало средство отрисовки
Созданный нами SVG содержит этот элемент:
<image xlink:href="motif.svg"
width="118.8px" height="79.2px"
preserveAspectRatio="xMinYMin meet"
x="5.4" y="-79.2"/>Размеры и положение — значения, наблюдавшиеся в этом образце. Передачу файла определяет xlink:href="motif.svg": результату по-прежнему нужен ресурс по этому относительному пути.
Скопируйте только diagram.svg в другую папку, оставив изображение на прежнем месте. Сравните его с полным комплектом. Мы отдавали обе папки через локальный HTTP и отображали каждый SVG как документ через HTML-элемент object.

Созданные прямоугольники узлов и стрелка остаются на месте, когда связанный мотив отсутствует. Повторное построение компоновки графа не добавляет отсутствующий файл. Восстановите ожидаемое расположение ресурса, передайте весь комплект или выберите способ упаковки, подходящий для целевой среды.
Открытие SVG как документа и отображение через HTML img — разные проверки. Руководство MDN по SVG как изображению объясняет, что контексты изображений могут ограничивать внешние ресурсы, тогда как data URL позволяют включать их внутрь. Описанные ограничения контекста изображения не применяются к прямым SVG-документам или встраиванию документов через object и iframe. Проверяйте тот контекст передачи, который действительно используете.
Явно упакуйте этот простой мотив
Для этого исходного автономного мотива следующий скрипт заменяет ровно одну известную ссылку байтами SVG из файла. Сохраните его как package.mjs и запустите после отрисовки:
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);Это адресный пример упаковки, а не универсальный инструмент встраивания SVG. Он обрабатывает известную ссылку в этом выводе и мотив без внешних шрифтов, изображений, таблиц стилей или других зависимостей. Более сложной графике нужна отдельная проверка зависимостей.
В нашей браузерной проверке упакованная копия отобразилась с мотивом. Сравнение двух строк вывода после маскирования значения ссылки на изображение показало одинаковую геометрию графа. Файл по-прежнему содержит один элемент изображения; его ссылка теперь начинается с data:image/svg+xml;base64,.
Встраивание байтов SVG-изображения может устранить эту зависимость от пути к файлу, сохранив векторный исходник графики. Оно не превращает изображение в собственную форму узла Graphviz, не добавляет точки соединения внутри него и не гарантирует, что другой редактор откроет его контуры напрямую. Проверьте поведение импорта у получателя.
Также не путайте svg_inline со встраиванием изображений. Документация по SVG-выводу Graphviz описывает его как вывод без заголовка для включения в HTML. Для того же графа выбор svg_inline по-прежнему создавал ссылку на motif.svg. Режим вывода не упаковал изображение.
Рассматривайте размеры и масштабирование отдельно от переносимости
Справка Graphviz по imagescale различает вписывание изображения в узел и естественный размер исходника. В этом примере imagescale=true равномерно масштабирует его для вписывания. Параметр both масштабирует ширину и высоту независимо, что может изменить пропорции.
Если мотив появляется, но растянут, проверьте параметр масштабирования. Если видна только часть, проверьте его собственные границы и доступное пространство узла. Если он исчезает после переноса файла, сначала проверьте путь к ресурсу. Руководство по размерам SVG объясняет различие между объявленным размером и координатами рисунка.
| Симптом | Первая проверка | Какое исправление попробовать |
|---|---|---|
| Графика исчезает после переноса диаграммы | Созданная ссылка на изображение и относительное расположение ресурса | Восстановите комплект или явно упакуйте проверенный исходник |
| Компоновка графа работает, но графика отсутствует | Размеры исходника и настройка изображений для конкретной сборки | Проверьте файл и метаданные изображения, ожидаемые этой сборкой |
| Мотив выглядит растянутым | Настройка imagescale и задуманные пропорции | Используйте равномерное вписывание, если искажение нежелательно |
| SVG работает напрямую, но не на веб-странице | Использует ли страница контекст изображения или документа | Проверьте поддерживаемый способ встраивания и его политику ресурсов |
| Вывод отличается после смены средства отрисовки | Выбранное средство отрисовки и его структура SVG | Повторно проверьте экспортированный XML и итоговый вид |
Официальная страница SVG-вывода отмечает, что вывод Cairo может отличаться от встроенного SVG-вывода по читаемости XML и возможности преобразования. Здесь мы не проверяли Cairo. В воспроизводимом проекте выбирайте средство отрисовки явно и повторяйте проверку упаковки при его смене.
Восстановите графику на предыдущем этапе, если исходник утерян
PerfectVector может помочь, когда подходящий иллюстративный мотив сохранился только как PNG или скан. Его процесс восстановления научной графики дает пробный векторный вариант для проверки перед использованием. Обрежьте изображение до мотива, проверьте его силуэт и пустые пространства, затем проверьте границы и размеры скачанного SVG перед добавлением в граф.
Эта операция не восстанавливает связи узлов, значения стрелок или подписи DOT. Храните их в исходнике графа. Используйте исходный SVG, если он доступен, перерисуйте простой символ, если его так легче поддерживать, а фотографии сохраняйте в растре. Обзор векторизации изображений объясняет границы восстановления.
Другие инструменты диаграмм упаковывают собственную графику иначе. Руководство по значкам Mermaid рассматривает зарегистрированные данные значков, а статья о собственной SVG-графике draw.io различает импортированное изображение и собственный трафарет. Учитывайте требования целевой среды при подготовке графики.
Частые вопросы
Включает ли SVG-вывод Graphviz изображение узла автоматически? В проверенном встроенном SVG-выводе диаграмма содержит ссылку на отдельный файл motif.svg. Проверьте свой вывод и передайте его зависимости или примените проверенный способ упаковки.
Объединяет ли svg_inline контуры SVG-изображения с графом? Нет. Это режим вывода без заголовка для включения в HTML. В нашем тесте он сохранил внешнюю ссылку на motif.svg.
Является ли автономный SVG собственной редактируемой геометрией узла? Нет. Упакованный пример сохраняет элемент изображения, содержащий байты SVG. Структура графа остается в DOT, а принимающий редактор определяет, как он открывает эту графику.
Источники
- Graphviz — image — Локальные ресурсы изображений узлов и обязательные размеры SVG.
- Graphviz — imagescale — Равномерное вписывание и независимое масштабирование ширины и высоты.
- Graphviz — SVG output — Встроенный вывод и вывод Cairo, а также значение svg_inline.
- Viz.js — API — Метаданные размеров изображения, явные единицы и вызовы отрисовки SVG.
- MDN — SVG as an image — Ограничения внешних ресурсов в контекстах изображения и отличие от встраивания документа.
Проверьте один узел через процесс передачи, прежде чем готовить целую библиотеку графики. Если сохранился только растровый мотив, подготовьте пробный SVG, проверьте его зазоры и пропорции, затем добавьте в граф DOT и проверьте перенесенный или упакованный результат в принимающей программе просмотра.
Ещё из блога

SVG в WeasyPrint: верните пропавшие логотипы в PDF
Исправьте пропавшие SVG-логотипы в PDF WeasyPrint с помощью правильного базового URL и явных размеров CSS, затем проверьте контуры, пропорции и графику в сохраненном PDF.

SVG в Matplotlib: график и логотип в виде контуров
Экспортируйте график Matplotlib в SVG, добавьте отдельные контуры логотипа через svgutils и проверьте итоговый файл на встроенные пиксели, размещение и изменения шрифтов.