pivotick / RendererOptions / NodeStyle
Interface: NodeStyle
Defined in: interfaces/RendererOptions.ts:468
Properties
badges?
Defined in: interfaces/RendererOptions.ts:585
Small indicators pinned to the node's rim, independent of every other channel — see NodeBadge.
Resolved like any other channel: the narrowest declaration wins outright rather than merging, so a node's own badges replaces whatever nodeStyleMap or defaultNodeStyle gave it. An empty array is the way to say "this one wears none"; undefined renders no badge group at all.
Four fit on a plain node, two on one with children (the expand affordance reserves the East corners). Anything beyond that collapses into a +n badge naming the rest.
color
color:
string| (node) =>string
Defined in: interfaces/RendererOptions.ts:478
The main color of the node
Default
'var(--pvt-node-color, #007acc)'focusTier?
optionalfocusTier:Clearable<Omit<Partial<NodeStyle>,"tiers"|"focusTier"|"focusTierYieldsAt"|"layoutSize"|"styleCb">>
Defined in: interfaces/RendererOptions.ts:615
The drawing used while this node is hovered, or selected on its own — whatever the zoom. This is where a node says everything about itself.
It merges over the resolved base style rather than over the active tier, so a chip tier's shape or html cannot leak into it, and it holds a constant size on screen however far the graph is zoomed out. It never changes the node's geometry: edges keep landing on the tier underneath and nothing moves.
When it fires is GraphRendererOptions.focusTierTrigger's to say.
focusTierYieldsAt?
optionalfocusTierYieldsAt:number
Defined in: interfaces/RendererOptions.ts:630
The index into tiers from which focusTier stops firing. While the node is drawn at that tier or a richer one, hover and a lone selection leave it as it is, for a focus drawing that the zoom tier already shows. Unset, the focus drawing fires at every tier. Ignored on a node with no tiers.
Example
// Hovering the dot shows the chip; once the chip tier is drawn, hovering adds nothing.
tiers: [{ width: 140, height: 44, style: { shape: 'none', html: chipFor } }],
focusTier: { shape: 'none', html: chipFor },
focusTierYieldsAt: 0,fontFamily
fontFamily:
string
Defined in: interfaces/RendererOptions.ts:486
Default
'var(--pvt-font-family)'html()?
optionalhtml: (node) =>string|void|HTMLElement
Defined in: interfaces/RendererOptions.ts:572
The html to be used inside the node as an SVGForeignObject element.
Resolved like every other channel, so a card can be declared at any level — nodeStyleMap[type].html gives one kind of node a card while the rest keep their shapes, and a single node's own style overrides that. Returning nothing draws no card, so one callback can card some nodes and leave the others alone.
Pair it with shape: 'none' for a card that is the node. Otherwise the shape is still drawn behind it, and size is the smallest the node can be.
The card is measured and the node grows to it, so it is never clipped and edges land on its border. You do not have to make the returned element self-sizing — it is measured inside a shrink-to-fit box, so width: 100% resolves against its own content rather than against the placeholder.
Trusted HTML only. Whatever this returns is inserted as-is, so build it with textContent (or escape it) rather than interpolating node data into a markup string.
Parameters
node
Returns
string | void | HTMLElement
iconClass?
optionaliconClass:string
Defined in: interfaces/RendererOptions.ts:530
iconUnicode?
optionaliconUnicode:string
Defined in: interfaces/RendererOptions.ts:531
imageFit?
Defined in: interfaces/RendererOptions.ts:548
How an imagePath picture sits on the node's shape. Resolvable per node so different nodes can mix modes (e.g. screenshots 'cover', other attachments 'icon').
Default
'icon'imagePath?
optionalimagePath:string
Defined in: interfaces/RendererOptions.ts:542
URL of a picture to draw on the node. Restricted to the http:, https:, data: and blob: schemes; anything else is ignored. Rendering it fetches the URL.
layoutSize?
optionallayoutSize:number
Defined in: interfaces/RendererOptions.ts:641
The half-width of the box this node reserves for itself in the layout, in graph units. This is the only size the simulation ever sees: set it and the drawing no longer drives the collision radius, so a node can change how it is drawn without moving anything.
Leave it unset and the drawing owns the spacing, as it always has — a shape spaces by its size, an HTML card by what it measures.
Default
half the widest declared tier width, or unset when there are no tiers
shape
Defined in: interfaces/RendererOptions.ts:473
The shape of the node, either a standard shape or a custom SVG path
Default
circlesize
size:
number| (node) =>number
Defined in: interfaces/RendererOptions.ts:480
Default
10strokeColor
strokeColor:
string| (node) =>string
Defined in: interfaces/RendererOptions.ts:482
Default
'var(--pvt-node-stroke, #fff)'strokeWidth
strokeWidth:
string|number
Defined in: interfaces/RendererOptions.ts:484
Default
'var(--pvt-node-stroke-width, 2)'styleCb()?
optionalstyleCb: (node) =>Partial<NodeStyle>
Defined in: interfaces/RendererOptions.ts:653
Callback to dynamically override style properties based on the node.
Where it sits depends on which style block declares it. On a node's own style it wins outright, and nodeStyleMap is skipped entirely. On render.defaultNodeStyle it is the computed form of the default slot: it fills only what neither the node nor nodeStyleMap set (and what a per-node styleCb left out), and its result still loses to both.
Runs once per node per render, so keep it cheap.
Parameters
node
Returns
Partial<NodeStyle>
svgIcon?
optionalsvgIcon:string
Defined in: interfaces/RendererOptions.ts:537
Inline SVG markup drawn inside the node. Sanitized before it reaches the DOM (scripting and event handlers are stripped), but a remote <image href> inside it is still fetched when the node renders — see the security guide.
text?
optionaltext:string| (node) =>string
Defined in: interfaces/RendererOptions.ts:552
The text to be used inside the node as an SVGText element
textAnchorPosition
textAnchorPosition:
"end"|"start"|"middle"
Defined in: interfaces/RendererOptions.ts:490
Default
'middle'textColor
textColor:
string| (node) =>string
Defined in: interfaces/RendererOptions.ts:488
Default
'var(--pvt-node-text-color, #fff)'textFontSize?
optionaltextFontSize:number| (node) =>number
Defined in: interfaces/RendererOptions.ts:529
Font size of the node's label, in graph units (CSS pixels at zoom 1). The label's offset, its built-in character budget and the zoom gate all follow it.
Default
undefined — derived from the node's size: max(12, size × 0.45)textHorizontalShift
textHorizontalShift:
number| (node) =>number
Defined in: interfaces/RendererOptions.ts:497
The horizontal shift applied to the node's label position. A value of 0 means it is centered to the node, a value of 1 is east of the node, -1 is west of the node. Other values are also accepted, e.g., 0.5 would be halfway between the center and the east of the node.
Default
0textMaxWidth?
optionaltextMaxWidth:number| (node) =>number
Defined in: interfaces/RendererOptions.ts:523
Widest a node label may be drawn, in graph units (CSS pixels at zoom 1). A longer label is shortened with a middle ellipsis to fit. Replaces the built-in budget, which is sized to the node. Ignored when textTruncate is false.
Default
undefined — the built-in budgettextRotateDegree
textRotateDegree:
number| (node) =>number
Defined in: interfaces/RendererOptions.ts:510
Rotation degree applied to the node's label. Positive values rotate clockwise, negative values rotate counter-clockwise.
Default
0textTruncate
textTruncate:
boolean| (node) =>boolean
Defined in: interfaces/RendererOptions.ts:516
Shorten an over-wide label with a middle ellipsis (head…tail); false draws it in full, on a themed pill where it spills past the node.
Default
truetextVerticalShift
textVerticalShift:
number| (node) =>number
Defined in: interfaces/RendererOptions.ts:504
The vertical shift applied to the node's label position. A value of 0 means it is centered to the node, a value of 1 is north of the node, -1 is south of the node. Other values are also accepted, e.g., 0.5 would be halfway between the center and the north of the node.
Default
0tiers?
optionaltiers:NodeTier[]
Defined in: interfaces/RendererOptions.ts:603
Alternative drawings of this node, chosen by how large it currently renders — a glyph on an overview, a labelled chip once there is room for one, a card once there is room for that. Ordered smallest first; the richest one that fits wins, and the base style is the floor when none do.
The node's footprint never changes with the drawing (see layoutSize), so swapping tiers moves nothing.
Example
tiers: [
{ width: 32, height: 32, style: { shape: 'circle', size: 16 } },
{ width: 140, height: 44, style: { shape: 'none', html: chipFor } },
]