Skip to content
Pivotick
Main Navigation HomeGetting StartedConfigurationGalleryTry it out!Generated API docs

Appearance

Sidebar Navigation

Getting Started

Configuration

Callbacks

Edge layers

Layout

Render

Simulation

Customizing UI

Sidebar

Tooltip

Context Menu

Filters

Legend

Data table

Styling UI

Plugins

Pivotick API

Pivots & enrichment

Saving pivot results

Undo & history

Security

API docs

Gallery

Basics

Node styling

Edge styling

Layouts

Events & callbacks

UI customization

Editing & authoring

Notes & annotations

Filtering, search & hierarchy

Programmatic control

Theming & performance

Pivots & enrichment

Showpieces

Minimap ​

full mode already docks an overview of the whole graph in a canvas corner, and one line — plugins: [minimap()], as below — puts your own configured one there instead, in any mode. Click anywhere in it to bring the view there; drag the rectangle to pan. The graph below is wider than its viewport, so there is somewhere to go. The tiny arrow in the minimap's inner corner folds it away to just that button when the canvas matters more than the overview.

Even so it is a plugin, not built-in chrome — full mode simply installs it for you, and stands aside for the copy passed here. It installs itself through the PluginContext it is handed and uses nothing a plugin of your own couldn't — it reads the graph's extent with renderer.getContentBounds(), works out the visible region by inverting the canvas corners through renderer.screenToGraphCoordinates(), and moves the view with renderer.setViewport(). See Plugins for the whole surface.

It also stays cheap on a graph that actually needs one. The picture lives in a cached offscreen bitmap that is only re-rasterised when the graph changes (or every 10th simulation tick while a layout settles); panning and zooming redraw one image and one rectangle, whatever the node count. Past 1500 nodes it stops drawing each node and paints density instead, which reads better than tens of thousands of overlapping dots and resolves no per-node styles at all.

Zoom in with the viewport controls, then drag the rectangle in the minimap — the content picture never redraws, only the rectangle moves.

js
// import { minimap } from 'pivotick'

const options = {
    UI: {
        // `full` mode brings a minimap of its own; `light` and `viewer` need asking
        // (`UI.minimap: true`, or the plugin below). `static` never has one.
        mode: 'full',
        // The other thing full mode brings. Off here: this card is about the minimap.
        table: false
    },
    // A plugin installs itself through the PluginContext it is handed — the core never
    // needs to know it exists. `graph.use(minimap())` works just as well, at any time.
    // Passed here it replaces the one full mode would have mounted, configuration and all.
    plugins: [
        minimap({
            position: 'bottom-right', // the corner the built-in chrome leaves free
            width: 220
            // height: omitted → follows the canvas's aspect ratio
        })
    ],
    render: {
        nodeTypeAccessor: (node) => node.getData()?.kind,
        nodeStyleMap: {
            hub: { color: '#0072B2', size: 13 },
            leaf: { color: '#E69F00', size: 7 }
        }
    },
    simulation: {
        d3LinkDistance: 60
    }
}
js
// A graph deliberately bigger than the viewport, so the minimap has something to
// navigate: six clusters of satellites around a spine.
const nodes = []
const edges = []
const hubs = ['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta']

hubs.forEach((hub, hubIndex) => {
    const angle = (hubIndex / hubs.length) * Math.PI * 2
    nodes.push({
        id: hub,
        data: { name: hub, kind: 'hub' },
        x: Math.cos(angle) * 420,
        y: Math.sin(angle) * 420
    })
    if (hubIndex > 0) edges.push({ from: hubs[hubIndex - 1], to: hub })

    for (let leafIndex = 0; leafIndex < 9; leafIndex++) {
        const id = `${hub}-${leafIndex}`
        const spread = (leafIndex / 9) * Math.PI * 2
        nodes.push({
            id,
            data: { name: id, kind: 'leaf' },
            x: Math.cos(angle) * 420 + Math.cos(spread) * 130,
            y: Math.sin(angle) * 420 + Math.sin(spread) * 130
        })
        edges.push({ from: hub, to: id })
    }
})

const data = { nodes, edges }

Last updated:

Pager
Next pageGetting Started