Ir al contenido
Pivotick
Main Navigation Inicio
Primeros pasos
Configuración
Documentación generada de la API
GaleríaProyectos¡Pruébalo!

Español

English
简体中文
Français
Deutsch
Português
Nederlands
日本語
العربية

Español

English
简体中文
Français
Deutsch
Português
Nederlands
日本語
العربية

Apariencia

Sidebar Navigation

Primeros pasos

Proyectos que usan Pivotick

Configuración

Funciones de retorno

Capas de aristas

Simplificar

Distribución

Renderizado

Simulación

Personalizar la interfaz

Barra lateral

Información emergente

Menú contextual

Filtros

Leyenda

Tabla de datos

Estilos de la interfaz

Traducir la interfaz

Complementos

API de Pivotick

Pivotes y enriquecimiento

Guardar resultados de pivotes

Deshacer e historial

Seguridad

Documentación de la API

Galería

Fundamentos

Estilos de nodos

Estilos de aristas

Distribuciones

Eventos y funciones de retorno

Personalización de la interfaz

Edición y creación

Notas y anotaciones

Filtros, búsqueda y jerarquía

Control programático

Temas y rendimiento

Pivotes y enriquecimiento

Ejemplos destacados

Agregar un modo ferroviario ​

El riel izquierdo contiene modos, no botones. Seleccionar, Crear, Ver y Física están integrados, y cada uno muestra solo sus propias herramientas, razón por la cual el riel mantiene cuatro ranuras de altura cuánto puede hacer el gráfico. addRailMode() agrega un quinto.

Esta tarjeta agrega un modo Explorar para recorrer un gráfico de servicio: elija un nodo, seleccione su vecinos, limite el lienzo a ellos y luego retroceda. Presione E o haga clic en la brújula debajo del divisor.

Donde aterriza tu modo ​

Los modos registrados se encuentran debajo de un divisor, después de los integrados, ordenados entre sí por order. Un complemento no puede reordenar ni eliminar los cuatro integrados, por lo que todo lo que está encima de la línea es el mismo en cada gráfico Pivotick, y todo lo que está debajo es tuyo.

Declarar herramientas, no marcas ​

Los tools de un modo se convierten en filas en el panel contextual, dibujadas como las de Seleccionar y Crear. Tú proporcionas los verbos; El kind de cada fila dice cómo se comporta:

kindComportamiento
'action'se ejecuta una vez y deja el modo solo: las tres herramientas aquí
'toggle'arma una herramienta: el panel colapsa y el botón del riel se convierte en esa herramienta, de la misma manera que la ranura de Seleccionar se convierte en Lasso
'default'la herramienta en la que se basa el modo, y a qué palanca se remonta

enabled() se vuelve a marcar cada vez que cambia la selección; es por eso que Seleccionar vecinos y Aislar permanece atenuado hasta que elijas un nodo.

Aquí nada es privilegiado ​

Cada herramienta anterior llama a una API pública que usted mismo podría llamar: getEdges() para recorrer las relaciones, selectNodes() para seleccionarlos, setVisibleNodes() para limitar el lienzo. El modo simplemente les da un lugar donde vivir: una ranura ferroviaria, un atajo, un estado armado y un panel.

Cuál es el punto: un modo Explorar que sepa qué significa "vecino" para sus datos es algo que tú puedes construir y nosotros no.

Los modos se excluyen entre sí.

Al abrir Explorar se cierra Vista y Física, y viceversa: una tienda, un modo activo. Deshacer cualquiera que sea tu modo armado en onExit; también se ejecuta si el modo se elimina mientras está activo y el carril vuelve a Seleccionar.

Cuando un menú desplegable encaja mejor ​

Un modo que configura en lugar de actuar quiere una superposición amplia, no una franja de herramientas estrecha. Establezca kind: 'flyout', subclase el Flyout exportado y pase addRailMode una fábrica: consulte Contribuir con un modo ferroviario.

js
// The rail's four modes — Select, Create, View, Physics — are built in. `addRailMode`
// is how you add a fifth. It renders below a divider, after them, and drives the same
// contextual tool panel the built-ins do: declare `tools`, and the arming, the
// enabled/disabled states and the collapse are handled for you.
//
// This card adds an **Explore** mode for walking the graph: reach the neighbours of what
// is selected, isolate a subgraph, and step back out. Nothing here is privileged — every
// tool is public graph API a consumer could call themselves.

const compass = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20"><path fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" d="M12 21a9 9 0 1 0 0-18a9 9 0 0 0 0 18Z"/><path fill="currentColor" d="M15.5 8.5l-2 5l-5 2l2-5z"/></svg>'
const expandIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18"><path fill="currentColor" d="M11 13v3a1 1 0 0 0 2 0v-3h3a1 1 0 0 0 0-2h-3V8a1 1 0 0 0-2 0v3H8a1 1 0 0 0 0 2zm1 9a10 10 0 1 1 0-20a10 10 0 0 1 0 20m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16"/></svg>'
const isolateIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="18" height="18" fill="none" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"><path d="M16 6H8a2 2 0 0 0-2 2v8m10 26H8a2 2 0 0 1-2-2v-8m26 10h8a2 2 0 0 0 2-2v-8M32 6h8a2 2 0 0 1 2 2v8"/><circle cx="24" cy="24" r="6"/></svg>'
const resetIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18"><path fill="currentColor" d="M12 5V2L8 6l4 4V7a5 5 0 1 1-5 5H5a7 7 0 1 0 7-7"/></svg>'

function exploreMode() {
    return {
        name: 'explore-mode',
        install(ctx) {
            const interaction = () => ctx.graph.renderer.getGraphInteraction()
            const selected = () => interaction().getSelectedNode()?.node

            /** Every node one hop from `id`, itself included. */
            const withNeighbours = (id) => {
                const keep = new Set([id])
                for (const edge of ctx.graph.getEdges()) {
                    if (edge.from.id === id) keep.add(edge.to.id)
                    if (edge.to.id === id) keep.add(edge.from.id)
                }
                return keep
            }

            ctx.addRailMode({
                id: 'explore',
                label: 'Explore',
                icon: compass,
                // Pressing E switches to the mode, or toggles its panel when it is
                // already active — exactly what V and C do for Select and Create.
                shortcut: 'E',
                tools: [
                    {
                        // A one-shot action: it runs and leaves the mode as it was.
                        id: 'expand',
                        label: 'Select neighbours',
                        icon: expandIcon,
                        kind: 'action',
                        // Re-checked on every selection change, so the row greys out
                        // when it would do nothing.
                        enabled: () => !!selected(),
                        run: () => {
                            const node = selected()
                            if (!node) return
                            const keep = withNeighbours(node.id)
                            interaction().selectNodes(
                                ctx.graph.getMutableNodes()
                                    .filter(n => keep.has(n.id))
                                    .map(n => ({ node: n, element: n.getGraphElement() }))
                            )
                        },
                    },
                    {
                        id: 'isolate',
                        label: 'Isolate neighbourhood',
                        icon: isolateIcon,
                        kind: 'action',
                        enabled: () => !!selected(),
                        run: () => {
                            const node = selected()
                            if (!node) return
                            const keep = withNeighbours(node.id)
                            ctx.graph.setVisibleNodes(
                                ctx.graph.getMutableNodes().filter(n => keep.has(n.id))
                            )
                        },
                    },
                    {
                        id: 'reset',
                        label: 'Show everything',
                        icon: resetIcon,
                        kind: 'action',
                        run: () => ctx.graph.setVisibleNodes(ctx.graph.getMutableNodes()),
                    },
                ],
            })
        },
    }
}

const options = {
    UI: {
        mode: 'full',
        // Neither is what this card is about, and both crowd a small canvas.
        minimap: false,
        table: false,
    },
    plugins: [exploreMode()],
}
js
const data = {
    nodes: [
        { id: 'api', data: { label: 'api-gateway', kind: 'service' } },
        { id: 'auth', data: { label: 'auth-service', kind: 'service' } },
        { id: 'billing', data: { label: 'billing-service', kind: 'service' } },
        { id: 'search', data: { label: 'search-service', kind: 'service' } },
        { id: 'users-db', data: { label: 'users-db', kind: 'datastore' } },
        { id: 'orders-db', data: { label: 'orders-db', kind: 'datastore' } },
        { id: 'index', data: { label: 'search-index', kind: 'datastore' } },
        { id: 'cache', data: { label: 'edge-cache', kind: 'datastore' } },
        { id: 'mailer', data: { label: 'mailer', kind: 'worker' } },
        { id: 'reindexer', data: { label: 'reindexer', kind: 'worker' } },
    ],
    edges: [
        { from: 'api', to: 'auth' },
        { from: 'api', to: 'search' },
        { from: 'api', to: 'billing' },
        { from: 'api', to: 'cache' },
        { from: 'auth', to: 'users-db' },
        { from: 'billing', to: 'orders-db' },
        { from: 'billing', to: 'mailer' },
        { from: 'search', to: 'index' },
        { from: 'reindexer', to: 'index' },
        { from: 'reindexer', to: 'orders-db' },
    ],
}
Pager
Página siguientePrimeros pasos