Retornos de chamada
Pivotick permite que você se conecte às interações do usuário e eventos de simulação por meio da opção callbacks. Você pode fornecer funções para vários eventos na tela, nos nós e nas arestas.
Retornos de chamada de tela
| Retorno de chamada | Parâmetros | Descrição |
|---|---|---|
onCanvasClick | (event: PointerEvent) | Disparado quando a tela é clicada. |
onCanvasContextmenu | (event: PointerEvent) | Disparado na tela, clique com o botão direito. |
onCanvasMousemove | (event: MouseEvent) | Disparado quando o mouse se move sobre a tela. |
onCanvasZoom | (event: unknown) | Disparado quando o nível de zoom da tela muda. |
Retornos de chamada de nó
| Retorno de chamada | Parâmetros | Descrição |
|---|---|---|
onNodeClick | (event: PointerEvent, node: Node, element: TElement) | Disparado quando um nó é clicado. |
onNodeDbclick | (event: PointerEvent, node: Node, element: TElement) | Disparado quando um nó é clicado duas vezes. |
onNodeContextmenu | (event: PointerEvent, node: Node, element: TElement) | Disparado no nó, clique com o botão direito. |
onNodeHoverIn | (event: PointerEvent, node: Node, element: TElement) | Disparado quando o mouse entra em um nó. |
onNodeHoverOut | (event: PointerEvent, node: Node, element: TElement) | Disparado quando o mouse sai de um nó. |
onNodeSelect | (node: Node, element: TElement) | Disparado quando um nó é selecionado. |
onNodeBlur | (node: Node, element: TElement) | Disparado quando um nó perde o foco/seleção. |
onNodeDragging | (event: MouseEvent, node: Node) | Disparado continuamente enquanto um nó está sendo arrastado. |
onNodeExpansion | (event: PointerEvent, edge: Edge, element: TElement) | Disparado quando um nó é expandido ou recolhido. |
Retornos de chamada de borda
| Retorno de chamada | Parâmetros | Descrição |
|---|---|---|
onEdgeClick | (event: PointerEvent, edge: Edge, element: TElement) | Disparado quando uma borda é clicada. |
onEdgeDbclick | (event: PointerEvent, edge: Edge, element: TElement) | Disparado quando uma aresta é clicada duas vezes. |
onEdgeContextmenu | (event: PointerEvent, edge: Edge, element: TElement) | Disparado na borda, clique com o botão direito. |
onEdgeHoverIn | (event: PointerEvent, edge: Edge, element: TElement) | Disparado quando o mouse entra em uma borda. |
onEdgeHoverOut | (event: PointerEvent, edge: Edge, element: TElement) | Disparado quando o mouse sai de uma borda. |
onEdgeSelect | (edge: Edge, element: TElement) | Disparado quando uma aresta é selecionada. |
onEdgeBlur | (edge: Edge, element: TElement) | Disparado quando uma borda perde o foco/seleção. |
Ganchos do ciclo de vida do caminho de gravação
Cada mutação que um usuário pode realizar passa por um before-hook: a biblioteca propõe, seu código decide — de forma assíncrona, e a decisão pode falhar. Na ausência de um gancho, o comportamento permanece inalterado e a mutação programática (graph.addNode(), graph.removeNode(), graph.removeEdge()) nunca os invoca, portanto, seu próprio código que conduz o modelo não é controlado por seu próprio gancho.
| Retorno de chamada | Demitido quando | Retorno |
|---|---|---|
onBeforeDelete | O usuário pede para excluir nós/arestas/notas, antes que qualquer coisa seja removida | false para vetar, true para excluir a solicitação, { accept, nodes, edges, notes } para restringi-la |
onBeforeNodeCreate | O usuário cria um nó (Criar ▸ Adicionar nó, tela ▸ Adicionar nó aqui) | false para vetar, ou { accept, id, data, style } |
onBeforeEdgeCreate | Um gesto de conexão resolveu um alvo, antes que a borda exista | false para vetar, ou { accept, data, style, id, directed } |
isValidConnection | Ao vivo, em cada passagem durante a conexão (deve ser sincronizado + barato) | false marca o alvo como inválido — o gancho before-create não é consultado |
onBeforeNodeEditCommit | Uma edição de nó foi confirmada | false recusa o commit, deixando os dados do nó intactos |
onBeforeEdgeEditCommit | Uma edição de borda foi confirmada | false recusa o commit, deixando os dados da borda intactos |
Um commit de edição aceito se anuncia no barramento de dados — nodeChange / edgeChange, com previousData e nextData — e é redesenhado imediatamente; um recusado não muda absolutamente nada.
Suas contrapartes de UI — onNodeEdit/onEdgeEdit (retorna o corpo modal) e onNodeEditCancel/onEdgeEditCancel — permitem substituir o editor em vez de bloqueá-lo. Além disso, editors.nodeEditor.fields / editors.edgeEditor.fields declara o formulário que o modal padrão constrói (um menu suspenso de relacionamento em vez de um campo de texto livre, digamos); sem eles, um campo de texto por chave de dados é inferido. Um corpo personalizado possui o rascunho — altere session.draft conforme o usuário digita, já que não há formulário para ler no envio.
Excluindo
onBeforeDelete recebe toda a consequência do gesto, resolvido pela biblioteca: os elementos que o usuário nomeou, mais cascadingEdges — as arestas que a remoção desses nós destruiria (graph.removeNode cascatas). Os dois nunca se sobrepõem, portanto cada um pode persistir exatamente uma vez.
O estreitamento é por tipo: um array fornecido substitui o conjunto solicitado desse tipo, uma chave omitida o deixa conforme solicitado (então { accept: true } corresponde a true e { accept: true, nodes: [] } não exclui nenhum nó). Um veto não remove nada, não dispara nodeRemove / edgeRemove / noteRemove e deixa a seleção intacta.
callbacks: {
onBeforeDelete: async ({ nodes, edges, cascadingEdges, origin, confirm }) => {
if (!await confirm({
title: 'Delete from event?',
body: `${nodes.length} element(s) and ${edges.length + cascadingEdges.length} link(s).`,
})) return false
const saved = await deleteServerSide(nodes, [...edges, ...cascadingEdges])
// Keep exactly what the server actually deleted.
return { accept: true, nodes: nodes.filter((n) => saved.has(n.id)) }
},
}ctx.confirm(options) abre o modal de confirmação da biblioteca, resolvendo false em cada caminho de cancelamento. ctx.origin diz qual affordance solicitada ('bulk-action' ou 'context-menu').
Enquanto um gancho decide
Um gancho que busca ou salva antes de responder deixa o usuário esperando. Após 200 ms sem resposta, o gráfico mostra que está aguardando: um cursor de progresso e um pequeno botão giratório no final da borda de visualização (onBeforeEdgeCreate), no ponto de lançamento (onBeforeNodeCreate) ou como uma pílula "Aguardando…" na parte inferior da tela (exclusões, commits de edição, onBeforeIngest). Um gancho que responde mais cedo não mostra nada.
Um prompt que o gancho abre através de seu contexto (promptLabel, promptData, confirm) desativa o sinal enquanto ele está na tela, e a espera após ele fechar recebe o mesmo tratamento, portanto, um gancho que pergunta e depois salva é lido como ocupado apenas enquanto está ocupado. Escape durante a espera de um gesto de conexão sai do modo de conexão e desativa o sinal; um gancho que aceita depois disso ainda ganha vantagem, pois pode já tê-lo salvo.
UI: {
busyIndicator: { delay: 300, label: 'Saving…' }, // or false, to draw your own
}Enquanto a sugestão é exibida, o elemento raiz do gráfico carrega data-pvt-busy.
Removendo a affordance em vez disso
Um veto é a resposta errada quando uma operação é nunca permitida — para uma integração cuja verificação de ACL é conhecida antes da construção do gráfico, elimine a affordance. Cada sinalizador editors.<editor>.enabled (ativado, a menos que explicitamente false) remove seus botões e entradas de menu:
| Bandeira | Remove |
|---|---|
editors.deletion.enabled | O volume da barra lateral Delete e as entradas de exclusão de nó/borda/nota |
editors.nodeCreator.enabled | Criar ▸ Adicionar nó e o menu de tela Adicionar nó aqui |
editors.nodeEditor.enabled | Criar ▸ Editar nó |
editors.edgeEditor.enabled | O menu de borda Edit Edge |
Veja o cartão da galeria Persistir exclusões, edições e cria para todos os três ganchos em um back-end substituto.
Retornos de chamada de simulação
| Retorno de chamada | Parâmetros | Descrição |
|---|---|---|
onSimulationTick | () | Disparou todos os ticks de simulação. |
onSimulationSlowTick | () | Disparado ocasionalmente durante a simulação (a cada décimo de simulationTick). |
informações
O tipo element é svg somente se a opção render.type == "svg".
Exemplo
import Pivotick from './pivotick.es.js'
options = {
callbacks: {
onNodeClick: (event, node) => {
console.log('Node clicked:', node.id)
},
onNodeHoverIn: (event, node) => {
console.log('Mouse entered node:', node.id)
},
onSimulationTick: () => {
console.log('Simulation tick')
}
}
}
const graph = new Pivotick(container, data, options)