23. Встраивание диаграмм
Хостируемый Viewer на archlang.dev/demo хорош для “вставил — посмотрел”. Для дашбордов, ADR, внутренних порталов и маркетинговых страниц вам нужны диаграммы на собственных страницах. Ответ — пользовательский элемент <archlang-viewer>: один тег <script>, один пользовательский элемент, и диаграмма появляется.
В этой главе разбираются атрибуты элемента, встроенный исходник, многофайловый сценарий, собственный хостинг, тематизация и протокол событий, которые Viewer возвращает вашей странице.
Правило. То, что вы встраиваете, — это выводимое представление исходника
.arch, а не рисунок, который вы поддерживаете отдельно. Текст — источник истины; диаграмма отрисовывается из него при каждой загрузке. Поэтому встраивание всегда отражает модель — нет картинки, которую нужно вручную держать синхронной, и нечего перерисовывать. Держите модель точной, и встраивание остаётся точным.
Самый простой случай
Заголовок раздела «Самый простой случай»Один .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.
Основное представление остаётся чистым: оно показывает граф бизнес-вызовов, а не транспортную обвязку под ним. Инфраструктурные планы — брокер сообщений, сетевая зона, логи, метрики — моделируются как аспекты (разделяемые классификации), и Viewer раскрывает их как слои-оверлеи по требованию. Читатель переключает раскладку аспекта брокера, чтобы увидеть, какие вызовы идут через какой брокер, затем выключает её обратно; план данных проявляется только по запросу, так что встроенная диаграмма никогда не топит свою аудиторию в инфраструктуре, за которой та не приходила (Глава 9).
Встроенный исходник — один файл
Заголовок раздела «Встроенный исходник — один файл»Когда исходник — часть самой страницы (например, встроен в Markdown-пост), используйте паттерн дочернего инлайн-скрипта:
<archlang-viewer style="width: 100%; height: 480px"> <script type="text/arch" data-path="/main.arch"> service Orders { aspect team: "Commerce" rest_create createOrder rest_read getOrder }
service Inventory { aspect team: "Commerce" } </script></archlang-viewer><script type="text/arch"> не выполняется браузером — его содержимое читается Viewer. Атрибут data-path именует путь внутри рабочего пространства, по которому файл должен оказаться.
Без явного package.archspace Viewer вставляет дефолтный, который импортирует arch.backend и arch.extras, чтобы разрешались стандартные типы. Это поведение управляется wrap-manifest (ниже).
Встроенный исходник — многофайловое рабочее пространство
Заголовок раздела «Встроенный исходник — многофайловое рабочее пространство»Для рабочих пространств с несколькими файлами объявите каждый со своим <script>:
<archlang-viewer wrap-manifest="false" style="width: 100%; height: 600px">
<script type="text/arch" data-path="/package.archspace"> package: my.shop use service, rest_create from arch.backend </script>
<script type="text/arch" data-path="/orders.arch"> service Orders { aspect team: "Commerce" rest_create createOrder } </script>
<script type="text/arch" data-path="/payments.arch"> service Payments { aspect team: "Payments" rest_create 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/viewer в 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/render практичнее всего. Либо, когда нужна не картинка, а весь интерактивный Viewer, выгрузите самодостаточный файл:
archlang export html . -o architecture.htmlОдин HTML-файл с оболочкой, моделью и шрифтами внутри; открывается офлайн без развёрнутого Viewer (глава 21). Годится, чтобы отправить архитектуру письмом, приложить к ревью или положить в релиз. Это снимок — он не обновляется вслед за моделью, и ровно для этого существует встраивание.
Встраивание — для живых, интерактивных поверхностей: дашбордов, внутренних порталов, 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/engine, @archlang/lsp, @archlang/render) для авторов инструментов.