API движка
createVisualLinker(container, config?) — framework-agnostic движок, на котором построена вся остальная часть пакета. Элементы блоков и их позиционирование остаются за вами — это только измеряет их и рисует SVG-соединения.
function createVisualLinker(container: HTMLElement, config?: VisualLinkerConfig): VisualLinkerРендерит в абсолютно позиционированный <svg>-слой, который движок создаёт внутри container. Движок сам задаёт container позиционирующий контекст (position: relative, только если его вычисленная позиция была static), чтобы этот слой совпадал с блоками внутри — вручную задавать CSS не нужно.
Конфигурация
config — это VisualLinkerConfig: один объект, разбитый на группы theme, lines, markers, ports, labels, blocks и interaction. Каждое поле необязательно. Группы и их поля описаны на странице Структура конфигурации, цвета — в Темах, а виды при наведении, выделении и фокусе — в Визуальных состояниях.
Пример:
const linker = createVisualLinker(diagramEl, {
theme: darkTheme, // цвета линий, портов и подписей в одном месте
lines: {
curve: 'smoothstep',
width: 2,
hover: { width: 3 },
routing: { avoidObstacles: true },
jumps: true,
},
markers: { end: { shape: 'arrow', hover: { size: 10 } } },
ports: { radius: 5, spread: true },
blocks: { draggable: true, drag: { grid: 20, bounds: 'container' } },
interaction: { selectable: true },
})Методы
setBlocks(blocks: BlockDescriptor[]): void
Заменяет весь набор блоков, которые измеряет движок и между которыми рисует соединения. Форму BlockDescriptor смотрите на странице Блоки и порты. Вызывает немедленный рендер.
setConnections(connections: ConnectionDescriptor[]): void
Заменяет весь набор соединений. Форму ConnectionDescriptor смотрите на странице Соединения. Вызывает немедленный рендер.
updateBlock(id: string, patch: Partial<Omit<BlockDescriptor, 'id'>>): void
Примешивает patch к блоку с указанным id — например, чтобы изменить его ports или флаг draggable, не передавая заново все остальные блоки. Не делает ничего, если id сейчас не зарегистрирован.
addConnection(connection: ConnectionDescriptor): void
Добавляет одно соединение, не заменяя остальные.
removeConnection(id: string): void
Удаляет одно соединение по id.
setSelectedConnections(ids: readonly string[]): void
Заменяет набор выделенных соединений — чтобы управлять выделением из собственного состояния (нужен interaction.selectable). Id, которых нет среди текущих соединений, игнорируются. Событие не отправляется. См. Выделение и доступность.
setConfig(patch: VisualLinkerConfig): void
Глубоко сливает patch с текущей конфигурацией и перерисовывает всё. Ключ со значением undefined удаляется. Слушатели подхватывают изменение: blocks.draggable и interaction.selectable подключают или отключают то, что им нужно. См. Структура конфигурации.
replaceConfig(next: VisualLinkerConfig): void
Заменяет конфигурацию целиком на next и перерисовывает всё.
getConfig(): VisualLinkerConfig
Возвращает копию действующей конфигурации. Изменение копии движок не меняет.
refresh(): void
Принудительно пересчитывает пути немедленно, в обход батчинга через requestAnimationFrame движка — полезно прямо перед снимком экрана диаграммы.
on(event, handler): () => void
Подписывается на событие движка (см. «События» ниже). Возвращает функцию отписки.
destroy(): void
Снимает все подписки (resize/scroll/pointer), очищает все блоки и соединения и удаляет SVG-слой. Вызывайте это, когда контейнер вот-вот покинет DOM — <VisualLinker> и useVisualLinker() уже делают это сами при размонтировании.
События
Подписка через linker.on(eventName, handler).
block:dragstart
{ blockId: string }
Срабатывает при начале перетаскивания блока.
block:drag
{ blockId: string; x: number; y: number }
Срабатывает при каждом движении указателя во время перетаскивания, с текущим смещением блока от его базовой позиции.
block:dragend
{ blockId: string; x: number; y: number }
Срабатывает при завершении перетаскивания блока, с его итоговым смещением.
block:mouseenter
{ blockId: string }
Срабатывает, когда указатель входит в область блока — при включённом interaction.highlight (или highlightable у блока) также переводит все соединения, связанные с ним, в состояние highlight.
block:mouseleave
{ blockId: string }
Срабатывает, когда указатель покидает область блока.
connection:click
{ connection: ConnectionDescriptor }
Срабатывает по клику на линию соединения (или на её более широкую невидимую область для клика).
connection:mouseenter
{ connection: ConnectionDescriptor }
Срабатывает, когда указатель входит в область линии соединения — при включённом interaction.hover (или hoverable у соединения) она также переходит в состояние hover.
connection:mouseleave
{ connection: ConnectionDescriptor }
Срабатывает, когда указатель покидает область линии соединения.
connection:selectionchange
{ selectedIds: string[] }
Срабатывает, когда набор выделенных соединений меняется из-за действия пользователя (режим interaction.selectable) — но не при вызове setSelectedConnections().
connection:delete-request
{ connections: ConnectionDescriptor[] }
Срабатывает, когда на сфокусированном соединении нажали Delete или Backspace: выделенные соединения или только сфокусированное, если оно не выделено. Ничего не удаляется — решает приложение.
layout
{ connections: ConnectionLayout[]; ports: PortLayout[] }
Срабатывает в конце каждого прохода рендера с посчитанной геометрией (точки, углы, середины) каждого соединения и порта — именно это приводит в движение слоты-оверлеи компонента Vue #connection-label/#port/#marker. Полезно для позиционирования собственного оверлея при прямой работе с движком. Каждый ConnectionLayout также несёт labels — каждую подпись, приведённую к точке и углу на линии, — и fromClipped / toClipped, которые выставляются, если конец прижат к краю обрезающего предка.