Skip to content
Pivotick
Main Navigation Home
Getting Started
Configuration
Generated API docs
GalleryProjectsTry it out!

English

简体中文
Français
Deutsch
Português

English

简体中文
Français
Deutsch
Português

Appearance

Sidebar Navigation

Getting Started

Projects using Pivotick

Configuration

Callbacks

Edge layers

Simplify

Layout

Render

Simulation

Customizing UI

Sidebar

Tooltip

Context Menu

Filters

Legend

Data table

Styling UI

Translating the 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

Labels arrive as you zoom in ​

A label rides the graph, so the further out the view is the smaller it is painted. Past a point it is no longer text, just grey texture over the graph. render.minLabelFontSize is the size, in rendered pixels, below which it is not drawn at all.

The graph below opens with none of its labels. Scroll in and the site names appear first, then the host names and the edge labels.

Things worth provoking:

  • Scroll in slowly. The site names arrive before the host names. A node's label is derived from its size, so a site drawn at 40 has an 18-unit label and a host drawn at 10 has the floor of 12. One number for the whole canvas, and the difference you want falls out of the sizes already there.
  • Park the zoom on the point a label appears and nudge it. A label that is showing holds until its rendered size falls to 85% of the threshold, so the picture settles instead of flickering. Every label at one size answers together.
  • Select an edge, then scroll back out. It keeps its label while every other one goes, held at a constant size on screen rather than shrinking with the graph. An edge has no tooltip and no panel, so its label is the only thing that answers for it.
  • Scroll in on one site, then pan to another. A label is re-picked for what is on screen, so a site you zoomed past gets its name when you pan back to it rather than while it is out of sight.

Turning it off

minLabelFontSize: 0 draws every label at every zoom, which is what the library did before the option existed.

js
const options = {
    render: {
        // The default. Below 9 rendered pixels a label is not drawn — and a node's label is
        // derived from its size, so the sites keep theirs to a lower zoom than the hosts.
        minLabelFontSize: 9,
        defaultNodeStyle: { shape: 'circle', textColor: '#ffffff' },
        defaultEdgeStyle: { strokeColor: '#cbd5e1', strokeWidth: 2 },
    },
    // Every node is pinned, so the layout is the one written above.
    simulation: { enabled: false },
}
js
/**
 * Seven sites — one in the middle, six around it — each with four hosts. Pinned wide enough
 * that the graph opens well under zoom 1, which is the point of the card, and dense enough in
 * the middle that scrolling in anywhere lands on something with a name.
 *
 * A site is drawn at size 40 and a host at 10, so their labels are 18 and 12 graph units: a
 * node's label is derived from its size, with a floor at 12.
 */
const SITES = [
    { id: 'core', name: 'Frankfurt', x: 0, y: 0, tone: '#2563eb' },
    { id: 'us', name: 'Ashburn', x: 1000, y: -560, tone: '#0891b2' },
    { id: 'sa', name: 'São Paulo', x: 1000, y: 560, tone: '#d97706' },
    { id: 'ap', name: 'Singapore', x: -1000, y: 560, tone: '#7c3aed' },
    { id: 'uk', name: 'London', x: -1000, y: -560, tone: '#059669' },
    { id: 'no', name: 'Oslo', x: 0, y: -900, tone: '#db2777' },
    { id: 'za', name: 'Cape Town', x: 0, y: 900, tone: '#65a30d' },
]

const HOSTS = [
    { name: 'edge', relation: 'routes to' },
    { name: 'cache', relation: 'caches for' },
    { name: 'api', relation: 'serves' },
    { name: 'db', relation: 'reads from' },
]

const nodes = []
const edges = []

for (const site of SITES) {
    nodes.push({
        id: site.id,
        fx: site.x,
        fy: site.y,
        style: { size: 40, color: site.tone, text: site.name, textVerticalShift: 1 },
    })
    HOSTS.forEach((host, index) => {
        const angle = (index / HOSTS.length) * Math.PI * 2 + Math.PI / 4
        const id = `${site.id}-${host.name}`
        nodes.push({
            id,
            fx: site.x + Math.cos(angle) * 250,
            fy: site.y + Math.sin(angle) * 230,
            style: { size: 10, color: '#94a3b8', text: `${host.name}.${site.id}`, textVerticalShift: 1 },
        })
        edges.push({ from: site.id, to: id, data: { label: host.relation } })
    })
}

// Every outer site peers with the middle one, so this is one network rather than seven.
for (const site of SITES.slice(1)) {
    edges.push({ from: 'core', to: site.id, data: { label: 'peers with' } })
}

const data = { nodes, edges }

See Rendering → Labels at a readable size for the contract, and Detail that follows the zoom for the node half of the same idea.

Last updated:

Pager
Next pageGetting Started