23. Встраивание диаграмм
Хостируемый Viewer на archlang.dev/demo хорош для “вставил — посмотрел”. Для дашбордов, ADR, внутренних порталов и маркетинговых страниц вам нужны диаграммы на собственных страницах. Ответ — пользовательский элемент <archlang-viewer>: один тег <script>, один пользовательский элемент, и диаграмма появляется.
В этой главе разбираются атрибуты элемента, встроенный исходник, многофайловый сценарий, собственный хостинг, тематизация и протокол событий, которые Viewer возвращает вашей странице.
Самый простой случай
Один .arch файл, загруженный с URL:
<script type="module" src="https://archlang.dev/viewer/archlang-viewer.js"></script>
<archlang-viewer src="./checkout.arch" style="width: 100%; height: 480px"></archlang-viewer>И всё. Скрипт регистрирует пользовательский элемент. Элемент загружает ./checkout.arch, парсит его, отрисовывает диаграмму внутри изолированного через shadow DOM iframe. Диаграмма интерактивна — панорамирование, зум, клик по узлам, наведение для деталей. Применяется всё поведение LOD из Главы 20.
Встроенный исходник — один файл
Когда исходник — часть самой страницы (например, встроен в Markdown-пост), используйте паттерн дочернего инлайн-скрипта:
<archlang-viewer style="width: 100%; height: 480px"> <script type="text/arch" data-path="/main.arch"> service Orders { team: Commerce command CreateOrder query GetOrder }
service Inventory { team: Commerce } </script></archlang-viewer><script type="text/arch"> не выполняется браузером — его содержимое читается Viewer. Атрибут data-path именует путь внутри рабочего пространства, по которому файл должен оказаться.
Без явного package.archspace Viewer вставляет дефолтный, который импортирует arch.modules и arch.kinds, чтобы разрешались стандартные виды. Это поведение управляется wrap-manifest (ниже).
Встроенный исходник — многофайловое рабочее пространство
Для рабочих пространств с несколькими файлами объявите каждый со своим <script>:
<archlang-viewer wrap-manifest="false" style="width: 100%; height: 600px">
<script type="text/arch" data-path="/package.archspace"> name: my.shop use * from arch.modules use * from arch.kinds </script>
<script type="text/arch" data-path="/orders.arch"> service Orders { team: Commerce command CreateOrder } </script>
<script type="text/arch" data-path="/payments.arch"> service Payments { team: Payments command Authorize } </script></archlang-viewer>wrap-manifest="false" отключает автоматическую вставку манифеста, потому что вы предоставляете свой. Используйте это всегда, когда у вас несколько файлов или вы хотите не-дефолтные импорты.
Атрибуты
| Атрибут | По умолчанию | Эффект |
|---|---|---|
src | (нет) | URL для загрузки одного .arch файла. Загружается как /main.arch в рабочем пространстве. |
host | Origin, с которого пришёл archlang-viewer.js | Базовый URL развёрнутого iframe Viewer. Переопределите при собственном хостинге. |
wrap-manifest | "true" | Когда true и package.archspace отсутствует, Viewer вставляет дефолтный. Установите "false", когда передаёте свой манифест. |
Элемент расширяет HTMLElement, поэтому стандартное CSS-сайзинг (style, class) применяется как обычно. iframe живёт внутри shadow root, так что CSS вашей страницы не сможет случайно его застилизовать.
События
Элемент пробрасывает три CustomEvent для интеграции со страницей-хостом:
| Событие | detail | Когда |
|---|---|---|
arch-ready | {} | Встроенный iframe закончил инициализацию. Viewer готов принять исходник. |
arch-loaded | { moduleCount } | Рендер успешно завершился. moduleCount — число разрешённых модулей. |
arch-error | { message } | Ошибка парсинга или разрешения. message — текст диагностики. |
const v = document.querySelector("archlang-viewer");v.addEventListener("arch-ready", () => console.log("viewer up"));v.addEventListener("arch-loaded", (e) => console.log("rendered", e.detail.moduleCount, "modules"));v.addEventListener("arch-error", (e) => console.error("arch error:", e.detail.message));События — это поверхность интеграции для телеметрии, отчётов об ошибках и индикаторов статуса на странице.
Собственный хостинг
По умолчанию атрибут host равен origin, с которого пришёл archlang-viewer.js. То есть если вы отдаёте скрипт со своего деплоя на https://internal.example.com/arch/archlang-viewer.js, iframe автоматически загружается с того же origin.
Чтобы разделить: отдавайте скрипт с одного origin, а Viewer запускайте на другом:
<script type="module" src="/static/archlang-viewer.js"></script>
<archlang-viewer host="https://viewer.internal.example.com" src="./diagram.arch" style="width: 100%; height: 480px"></archlang-viewer>Сборка Viewer — это одно статическое SPA: положите dist/ из @archlang/web в S3-бакет или за nginx — и готово. Никакого SSR, никакого бэкенда для рендеринга.
Размеры и адаптивная вёрстка
Элемент отрисовывает iframe на 100% ширины и 100% высоты самого себя. Задавайте размер элемента так же, как любому другому блочному элементу:
<archlang-viewer style="width: 100%; height: 60vh"></archlang-viewer><archlang-viewer class="my-diagram-grid-cell"></archlang-viewer>.my-diagram-grid-cell { width: 100%; aspect-ratio: 16 / 9; }Рендерер Viewer перетекает при изменении размеров хоста. В узких лейаутах правила LOD предпочитают компактный зум; в широких — всё расходится.
Тематизация
Тема Viewer по умолчанию соответствует хостируемому демо. Своя тематизация для виджетов, поставляемых внутри вашего пакета, работает через CSS-утилиты arch-* (Глава 20) — те же утилиты UnoCSS работают и во встроенном Viewer, потому что обе поверхности потребляют одну и ту же скомпилированную CSS.
Кросс-origin тематизация самого встраивания (переопределение токенов --au-* с хост-страницы) требует, чтобы хост и Viewer разделяли origin: пользовательские CSS-свойства не наследуются через границы iframe. Хостируйте Viewer на том же origin, что и хост-страницу, чтобы дать ему доступ к вашей CSS.
Когда НЕ встраивать
- Для
README.mdна GitHub — GitHub вырезает теги<script>. Встраиванию нужен JavaScript для рендера. - Для слайдовой презентации — та же проблема. Диаграмме нужен живой браузер.
- Для письма — нет среды исполнения JavaScript.
Для поверхностей, не способных запускать встраивание, отрисуйте диаграмму на этапе сборки и закоммитьте изображение рядом с исходником .arch. Эндпоинт скриншотов хостируемого Viewer и headless-рендеры из @archlang/web — два практичных пути.
Встраивание — для живых, интерактивных поверхностей: дашбордов, внутренних порталов, ADR-страниц с обратной связью через события.
Итог
- Один тег
<script>плюс один элемент<archlang-viewer>отрисовывают диаграмму на любой странице. srcдля одного загружаемого файла; встроенные дочерние<script type="text/arch" data-path="...">для многофайловых рабочих пространств.wrap-manifestуправляет автоматической вставкой манифеста.hostпереопределяет origin iframe; по умолчанию — тот же origin, с которого пришёл скрипт.- События
arch-ready,arch-loaded,arch-errorинтегрируют Viewer с телеметрией страницы-хоста. - Стилизация виджетов переиспользует CSS-утилиты
arch-*из Главы 20.
Что дальше
Глава 24: Библиотечные API → — нижележащие пакеты (@archlang/parser, @archlang/core, @archlang/lsp) для авторов инструментов.