Pular para o conteúdo

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 chamadaParâmetrosDescriçã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 chamadaParâmetrosDescriçã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 chamadaParâmetrosDescriçã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 chamadaDemitido quandoRetorno
onBeforeDeleteO usuário pede para excluir nós/arestas/notas, antes que qualquer coisa seja removidafalse para vetar, true para excluir a solicitação, { accept, nodes, edges, notes } para restringi-la
onBeforeNodeCreateO usuário cria um nó (Criar ▸ Adicionar nó, tela ▸ Adicionar nó aqui)false para vetar, ou { accept, id, data, style }
onBeforeEdgeCreateUm gesto de conexão resolveu um alvo, antes que a borda existafalse para vetar, ou { accept, data, style, id, directed }
isValidConnectionAo 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
onBeforeNodeEditCommitUma edição de nó foi confirmadafalse recusa o commit, deixando os dados do nó intactos
onBeforeEdgeEditCommitUma edição de borda foi confirmadafalse 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.

js
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.

js
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:

BandeiraRemove
editors.deletion.enabledO volume da barra lateral Delete e as entradas de exclusão de nó/borda/nota
editors.nodeCreator.enabledCriar ▸ Adicionar nó e o menu de tela Adicionar nó aqui
editors.nodeEditor.enabledCriar ▸ Editar nó
editors.edgeEditor.enabledO 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 chamadaParâmetrosDescriçã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 ​

js
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)