Aller au contenu
Pivotick
Main Navigation Accueil
Bien démarrer
Configuration
Référence de l’API
GalerieProjetsEssayer !

Français

English
简体中文
Deutsch
Português

Français

English
简体中文
Deutsch
Português

Apparence

Sidebar Navigation

Bien démarrer

Projets utilisant Pivotick

Configuration

Fonctions de rappel

Couches d’arêtes

Simplifier

Disposition

Rendu

Simulation

Personnaliser l’interface

Barre latérale

Infobulle

Menu contextuel

Filtres

Légende

Tableau de données

Style de l’interface

Traduire l’interface

Extensions

API Pivotick

Pivots et enrichissement

Enregistrer les résultats des pivots

Annulation et historique

Sécurité

Documentation de l’API

Galerie

Bases

Style des nœuds

Style des arêtes

Dispositions

Événements et rappels

Personnalisation de l’interface

Édition et création

Notes et annotations

Filtres, recherche et hiérarchie

Contrôle par programmation

Thèmes et performances

Pivots et enrichissement

Démonstrations complètes

Étendre avec un plugin ​

Un plugin est un ensemble autonome d'éléments d'interface utilisateur, de raccourcis clavier et de hooks de cycle de vie qui s'installe dans un graphique - le noyau n'a jamais besoin de savoir qu'il existe. Enregistrez les plugins de manière déclarative via l'option plugins, ou impérativement à tout moment avec graph.use(plugin).

Lors de l'installation, un plugin reçoit un PluginContext avec tout ce dont il a besoin : addElement() pour déposer un élément d'interface utilisateur dans un emplacement de mise en page (son cycle de vie est ensuite géré pour vous), onPhase() pour accrocher afterMount / graphReady / destroy, addKeybinding() pour les raccourcis qui sont nettoyés automatiquement, plus un accès direct à graph, ui et layout.

L'exemple ci-dessous installe un plugin à un élément : une superposition de statistiques **** épinglée sur le canevas qui lit le nombre de nœuds/bords en direct une fois que le graphique est prêt. Il étend UIComponent, de sorte que son cycle de vie mount → afterMount → graphReady → destroy (et tous les auditeurs qu'il suit) est piloté par le même mécanisme que la barre latérale, la barre d'outils et l'info-bulle intégrées : l'ajout d'une nouvelle interface n'est qu'un addElement.

Cliquez sur le graphique, puis appuyez sur B pour basculer la superposition.

js
// import { UIComponent } from 'pivotick'

// A plugin bundles UI elements, keybindings and lifecycle hooks and installs
// itself through the PluginContext it is handed — the core never needs to know
// it exists.
//
// Our plugin contributes one custom UI element: a small stats overlay pinned to
// the canvas. Because it extends UIComponent, its lifecycle (mount → afterMount
// → graphReady → destroy) and any tracked listeners are driven for free — the
// same machinery the built-in sidebar/toolbar/tooltip use.
class StatsOverlay extends UIComponent {
    // Build the DOM and drop it into the slot we were mounted into.
    onMount(slot) {
        this.el = document.createElement('div')
        // Bottom-right corner: the top-left / top / left edges are taken by the
        // B3 chrome (top bar, mode rail), so pin the overlay clear of them.
        this.el.style.cssText = [
            'position:absolute', 'bottom:12px', 'right:12px', 'z-index:5',
            'padding:8px 12px', 'border-radius:8px', 'font:12px/1.6 sans-serif',
            'background:rgba(20,24,32,0.85)', 'color:#fff',
            'box-shadow:0 2px 8px rgba(0,0,0,0.25)', 'pointer-events:none'
        ].join(';')
        slot?.appendChild(this.el)
    }

    // Runs once the graph data is ready — read live counts off the graph.
    onGraphReady() {
        this.render()
        const graph = this.uiManager.graph
        const cb = () => this.render()
        graph.on('dataBatchChanged', cb)
        // graph.on lives on the Graph, which outlives the UI — so track the
        // unsubscribe and destroy() tears it down with everything else.
        this.track(() => graph.off('dataBatchChanged', cb))
    }

    render() {
        const graph = this.uiManager.graph
        this.el.innerHTML =
            '<strong>Graph stats</strong><br>' +
            `${graph.getNodes().length} nodes · ${graph.getEdges().length} edges`
    }

    toggle() {
        this.el.style.display = this.el.style.display === 'none' ? '' : 'none'
    }

    // Only DOM cleanup needed here; children and everything registered via
    // track() (including the dataBatchChanged unsubscribe above) are torn down
    // by UIComponent.
    onDestroy() {
        this.el?.remove()
    }
}

const statsPlugin = {
    name: 'stats-overlay',
    install(ctx) {
        const overlay = new StatsOverlay(ctx.ui)
        // Mount the element into the canvas slot; its lifecycle is then managed.
        ctx.addElement(overlay, ctx.layout?.canvas)
        // Bonus: click the graph, then press "B" to toggle the overlay.
        ctx.addKeybinding({ key: 'b', callback: () => overlay.toggle() })
    }
}

// Register plugins declaratively with `plugins`, or imperatively at any time
// with `graph.use(statsPlugin)` (late installs are caught up to the current
// lifecycle phase automatically).
const options = {
    // Off: `full` mode brings a minimap and the data dock, and this card is about
    // neither (see the Minimap and Data table cards for those).
    UI: { mode: 'full', minimap: false, table: false, sidebar: { collapsed: true } },
    plugins: [statsPlugin]
}
js
const data = {
    nodes: [
        { id: 'web', data: { label: 'Web' } },
        { id: 'api', data: { label: 'API' } },
        { id: 'db', data: { label: 'Database' } },
        { id: 'cache', data: { label: 'Cache' } },
        { id: 'worker', data: { label: 'Worker' } }
    ],
    edges: [
        { from: 'web', to: 'api', data: { label: 'calls' } },
        { from: 'api', to: 'db', data: { label: 'reads' } },
        { from: 'api', to: 'cache', data: { label: 'reads' } },
        { from: 'worker', to: 'db', data: { label: 'writes' } }
    ]
}
Pager
Page suivanteBien démarrer