Eventos e API

O componente de diagrama é deliberadamente independente da interface visual: ele emite eventos contendo os dados e deixa que o host renderize menus e diálogos, expondo em seguida métodos para controlar o modelo. É por isso que um painel de propriedades ou um menu de contexto é a sua UI conectada aos eventos do componente.

Eventos

Assine com diagram.on(event, handler); a chamada retorna uma função de cancelamento da assinatura.

  • nodeAdded / nodeRemoved / nodeMoved — ciclo de vida do nó.
  • linkAdded / linkRemoved / linkRelinked — ciclo de vida da conexão.
  • linkValidation{ allowed, reason } para cada tentativa de conexão.
  • selectionChanged / nodeSelected / linkSelected — seleção.
  • contextMenuRequested{ x, y, node, link, port, commands } ao clicar com o botão direito.
  • fullscreenRequested{ fullscreen }; o host aplica o layout.
const off = diagram.on('linkAdded', ({ links }) => console.log('connected', links[0]));
// depois:
off();

O componente informa a posição do clique e a lista de comandos habilitados; você desenha o popup e executa o comando escolhido:

diagram.on('contextMenuRequested', ({ x, y, commands }) => {
  // commands: { command, enabled }[] onde command é um de
  // 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);
});

Validação de conexões

As portas são tipadas, e o componente rejeita conexões incompatíveis ou que excedam o limite, emitindo linkValidation com um reason (incompatible-type, duplicate-link, source-limit, target-limit, same-node, …). Adicione sua própria regra com setLinkValidator:

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

Salvar e carregar

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

const document = diagram.saveDocument();     // documento versionado
diagram.loadDocument(document);

Desfazer, refazer e área de transferência

diagram.undo() / redo() com canUndo() / canRedo() para habilitar ou desabilitar os botões; copySelection() / cutSelection() / pasteSelection() e deleteSelection() para a área de transferência. setReadOnly(true) bloqueia o diagrama em modo de visualização.

A disponibilidade de desfazer/refazer pertence ao controle, portanto acompanhe seu evento canônico undoStackChanged para manter os botões sincronizados a cada comando (excluir, arrastar, reconectar, colar), não apenas nos eventos de mutação do modelo acima:

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

Estado de execução e destaque de erros

O diagrama pode sobrepor o estado de execução ao esquema. setNodeError faz a borda de um nó piscar com uma pulsação animada (~1 segundo) e o marca com um destaque vermelho — use-o para reportar uma falha em tempo de execução. O botão Error no Editor interativo faz exatamente isso.

diagram.setNodeError('sma', 'SMA falhou: nenhuma fonte de dados está configurada.');
diagram.setNodeError('sma', 'Aviso', { animate: false }); // marca o nó, mas ignora o piscar inicial

Erros que já existem no momento do carregamento pintam um fundo vermelho em vez de piscar — passe-os para load:

diagram.load(nodes, links, { nodeErrors: { sma: 'O valor de período salvo é inválido.' } });

Outros hooks de tempo de execução: setActiveNode(id) destaca o nó em execução no momento (um cursor de depurador), setPortRuntimeState(id, direction, portId, patch) anota uma única porta, e setGlobalError(message) faz piscar um erro que abrange todo o esquema. Limpe tudo com clearRuntimeState().

Veja também