Skip to content

Minimap & UI Components

Built-in canvas UI: minimap, toolbar, search, tooltips, context menus, and info panels. No external DOM needed.

Minimap

Zoomed-out overview with viewport rectangle. Click or drag to navigate.

TypeScript
const app = create(container, {
  nodes: [...],
  edges: [...],
  layout: 'force',
  minimap: {
    enabled: true,
    position: 'bottom-left',
    width: 180,
    height: 120,
    mode: 'dots',         // 'dots' | 'heatmap' | 'both'
  },
});
OptionTypeDefaultDescription
enabledbooleanfalseShow/hide minimap.
positionstring'bottom-left'Corner placement.
widthnumber180Width in px.
heightnumber120Height in px.
mode'dots' | 'heatmap' | 'both''dots'Render mode. See Render modes.
heatmapGridnumber8Grid resolution for heatmap/both: density aggregates into a n × n lattice.
heatmapPalettestring[]5-stop blue→redCold-to-hot color ramp for heatmap cells.
compactBreakpointnumber640Container width below which the minimap shrinks to a compact size.
hideBreakpointnumber480Container width below which the minimap hides entirely.

Render modes

ModeWhat it showsWhen to use
'dots' (default)One dot per visible node, plus edges.Small / medium graphs where identity matters.
'heatmap'Grid-aggregated node density shaded cold → hot. Edges suppressed.Large graphs where individual dots become a hairball-in-miniature.
'both'Heatmap underneath dots, edges suppressed.Recommended when node count > 30 — orientation and identity.

Heatmap helpers

Both helpers used to compute the heatmap are exported for embedders who want to drive their own overlays.

TypeScript
import {
  computeHeatmapDensity,
  sampleHeatmapColor,
  DEFAULT_HEATMAP_PALETTE,
} from '@topokit/renderer-canvas';

const { counts, max } = computeHeatmapDensity(nodes, bounds, 8);
// counts: Uint32Array of length gridSize²; max: peak cell count

const color = sampleHeatmapColor(DEFAULT_HEATMAP_PALETTE, 0.7);
// Interpolates between cold-to-hot stops at t ∈ [0, 1]

Toolbar

TypeScript
const app = create(container, {
  nodes: [...],
  edges: [...],
  toolbar: {
    enabled: true,
    position: 'top-right',
    items: ['zoom-in', 'zoom-out', 'fit', 'fullscreen', 'separator', 'layout-select'],
  },
});
ItemDescription
'zoom-in'Increase zoom
'zoom-out'Decrease zoom
'fit'Fit graph to viewport
'fullscreen'Toggle fullscreen
'layout-select'Layout algorithm dropdown
'separator'Visual separator
TypeScript
const app = create(container, {
  nodes: [...],
  edges: [...],
  search: {
    enabled: true,
    placeholder: 'Search nodes...',
    position: 'top-left',
    fields: ['style.label', 'data.name', 'data.email'],
    highlightMatches: true,
    dimOpacity: 0.1,
    panToMatch: true,
  },
});

Tooltip

TypeScript
const app = create(container, {
  nodes: [...],
  edges: [...],
  tooltip: {
    enabled: true,
    delay: 300,
    node: (node) => [
      { label: 'Name', value: node.data.name },
      { label: 'Type', value: node.data.type },
    ],
    edge: (edge) => [
      { label: 'Relationship', value: edge.data.type },
    ],
  },
});

Context Menu

TypeScript
const app = create(container, {
  nodes: [...],
  edges: [...],
  contextMenu: {
    enabled: true,
    node: (node) => [
      { label: 'Expand neighbors', action: () => graph.expand(node.id) },
      { label: 'Highlight connections', action: () => {
        const ids = [node.id, ...graph.getNeighbors(node.id).map(n => n.id)];
        graph.highlightNodes(ids);
      }},
      { separator: true },
      { label: 'Remove node', action: () => graph.removeNode(node.id), danger: true },
    ],
  },
});

Info Panel

TypeScript
const app = create(container, {
  nodes: [...],
  edges: [...],
  infoPanel: {
    enabled: true,
    position: 'right',
    width: 320,
    trigger: 'click',
    node: (node) => ({
      title: node.data.name,
      subtitle: node.data.type,
      fields: [
        { label: 'ID', value: node.id },
        { label: 'Department', value: node.data.department },
      ],
      actions: [
        { label: 'Expand', onClick: () => graph.expand(node.id) },
      ],
    }),
  },
});

All Components Together

TypeScript
const app = create(container, {
  nodes: data.nodes,
  edges: data.edges,
  layout: 'force',
  theme: 'dark',
  minimap:     { enabled: true, position: 'bottom-right' },
  toolbar:     { enabled: true, position: 'top-right' },
  search:      { enabled: true, position: 'top-left' },
  tooltip:     { enabled: true, delay: 200 },
  contextMenu: { enabled: true },
  infoPanel:   { enabled: true, position: 'right' },
  legend:      { enabled: true, groupBy: 'data.type', position: 'bottom-left' },
});

Runtime Control

TypeScript
// Toggle components at runtime
app.setMinimap({ enabled: true });
app.setMinimap({ enabled: false });
app.setToolbar({ enabled: false });
app.setSearch({ enabled: true });
app.setTooltip({
  node: (node) => [{ label: 'Name', value: node.data.name }],
});

Next Steps