События и API

Компонент диаграммы намеренно ничего не навязывает по части UI-обвязки: он испускает события с данными и предоставляет хосту самому рисовать меню и диалоги, а затем даёт методы для управления моделью. Именно поэтому панель свойств или контекстное меню — это ваш UI, привязанный к событиям компонента.

События

Подписка через diagram.on(event, handler); возвращается функция отписки.

  • nodeAdded / nodeRemoved / nodeMoved — жизненный цикл узлов.
  • linkAdded / linkRemoved / linkRelinked — жизненный цикл связей.
  • linkValidation{ allowed, reason } для каждой попытки соединения.
  • selectionChanged / nodeSelected / linkSelected — выделение.
  • contextMenuRequested{ x, y, node, link, port, commands } по правому клику.
  • fullscreenRequested{ fullscreen }; макет применяет хост.
const off = diagram.on('linkAdded', ({ links }) => console.log('connected', links[0]));
// позже:
off();

Контекстное меню

Компонент сообщает позицию клика и список доступных команд; вы рисуете попап и выполняете выбранную команду:

diagram.on('contextMenuRequested', ({ x, y, commands }) => {
  // commands: { command, enabled }[], где command — одно из значений:
  // undo | redo | cut | copy | paste | open | delete | properties | help
  const menu = renderMenu(commands.filter(c => c.enabled), x, y);
  menu.onPick = command => diagram.executeContextCommand(command);
});

Валидация связей

Порты типизированы, и компонент отклоняет несовместимые или переполненные связи, испуская linkValidation с причиной reason (incompatible-type, duplicate-link, source-limit, target-limit, same-node, …). Добавьте своё правило через setLinkValidator:

diagram.setLinkValidator(({ fromPort, toPort }) => fromPort.type === toPort.type);

Сохранение и загрузка

const scheme = diagram.save();              // { nodes, links }
diagram.load(scheme.nodes, scheme.links);

const document = diagram.saveDocument();     // версионированный документ
diagram.loadDocument(document);

Undo, redo и буфер обмена

diagram.undo() / redo() с canUndo() / canRedo() для блокировки кнопок; copySelection() / cutSelection() / pasteSelection() и deleteSelection() для буфера обмена. setReadOnly(true) переводит диаграмму в режим предпросмотра.

Доступность undo/redo принадлежит контролу, поэтому отслеживайте его канонический сигнал undoStackChanged, чтобы кнопки оставались в синхроне для каждой команды (delete, drag, relink, paste), а не только для событий мутации модели выше:

diagram.on('undoStackChanged', ({ canUndo, canRedo }) => {
  undoButton.disabled = !canUndo;
  redoButton.disabled = !canRedo;
});

Состояние выполнения и подсветка ошибок

Диаграмма может накладывать состояние выполнения поверх схемы. setNodeError мигает рамкой узла анимацией (~1 секунда) и помечает его красной подсветкой — используйте это, чтобы сообщить о сбое во время выполнения. Кнопка Error в Интерактивный редактор делает ровно это.

diagram.setNodeError('sma', 'Сбой SMA: источник данных не настроен.');
diagram.setNodeError('sma', 'Предупреждение', { animate: false }); // пометить его, но пропустить начальную вспышку

Ошибки, существующие на момент загрузки, красят фон красным вместо мигания — передайте их в load:

diagram.load(nodes, links, { nodeErrors: { sma: 'Сохранённое значение периода недопустимо.' } });

Другие runtime-хуки: setActiveNode(id) подсвечивает узел, выполняющийся сейчас (курсор отладчика), setPortRuntimeState(id, direction, portId, patch) аннотирует отдельный порт, а setGlobalError(message) мигает ошибкой уровня всей схемы. Очистить всё — clearRuntimeState().

Смотрите также