Skip to content

@graphty/graphty-element / index / Node

Class: Node ​

Defined in: graphty-element/src/Node.ts:116

Represents a node in the graph visualization with its mesh, label, and associated data. Manages node rendering, styling, drag behavior, and interactions with the layout engine.

Constructors ​

Constructor ​

new Node(graph, nodeId, paint, data, opts?): Node

Defined in: graphty-element/src/Node.ts:311

Creates a new Node instance with mesh, label, and behaviors.

THE PAINT IS HANDED IN RATHER THAN ASKED FOR, because at this moment there is nothing to ask. The session's paint is addressed by the dense row index the store assigns AFTER the node is constructed, so a node builds its first mesh from bootstrapNodePaint() and the first style pass replaces it.

Parameters ​

graph ​

Graph | GraphContext

The parent graph or graph context that owns this node

nodeId ​

NodeIdType

Unique identifier for this node

paint ​

NodePaint

The source mesh, the style behind it and the per-instance colour to draw

data ​

AdHocData<string | number>

Custom data associated with this node

opts? ​

NodeOpts = {}

Optional configuration options for the node

Returns ​

Node

Properties ​

dragging ​

dragging: boolean = false

Defined in: graphty-element/src/Node.ts:213


dragHandler? ​

optional dragHandler?: NodeDragHandler

Defined in: graphty-element/src/Node.ts:212


id ​

readonly id: NodeIdType

Defined in: graphty-element/src/Node.ts:119


label? ​

optional label?: RichTextLabel

Defined in: graphty-element/src/Node.ts:158


mesh ​

mesh: AbstractMesh

Defined in: graphty-element/src/Node.ts:157


opts ​

opts: NodeOpts

Defined in: graphty-element/src/Node.ts:118


parentGraph ​

parentGraph: Graph | GraphContext

Defined in: graphty-element/src/Node.ts:117


pinOnDrag ​

pinOnDrag: boolean

Defined in: graphty-element/src/Node.ts:214


shapeType? ​

optional shapeType?: "box" | "sphere" | "cylinder" | "cone" | "capsule" | "torus" | "torus-knot" | "tetrahedron" | "octahedron" | "dodecahedron" | "icosahedron" | "rhombicuboctahedron" | "triangular_prism" | "pentagonal_prism" | "hexagonal_prism" | "square_pyramid" | "pentagonal_pyramid" | "triangular_dipyramid" | "pentagonal_dipyramid" | "elongated_square_dipyramid" | "elongated_pentagonal_dipyramid" | "elongated_pentagonal_cupola" | "goldberg" | "icosphere" | "geodesic"

Defined in: graphty-element/src/Node.ts:224

The shape type of the mesh currently on screen, cached beside Node.size.

It exists ONLY so that the repaint can tell a geometry change from a colour change; see the invalidation block in paintFrom for the defect it fixes. It is read from style.shape.type, so it is undefined for a style that names no shape.


size ​

size: number

Defined in: graphty-element/src/Node.ts:215


tooltip? ​

optional tooltip?: RichTextLabel

Defined in: graphty-element/src/Node.ts:169

The tooltip on screen, and undefined whenever the pointer is not over this node.

A tooltip is HOVER-ONLY, which is the whole difference between it and a label: a label is part of the picture and a tooltip is an answer to pointing at something. So it exists only between Node.showTooltip and Node.hideTooltip, and a graph of fifty thousand nodes with a tooltip on every one of them carries at most one label mesh for them.

Accessors ​

data ​

Get Signature ​

get data(): AdHocData<string | number>

Defined in: graphty-element/src/Node.ts:151

The record this node carries, as the graph holds it: deep-frozen, so a write to it throws. A change goes through the graph (updateNodes, session.data.updateNodes, ...), which is what undo sees.

Returns ​

AdHocData<string | number>

The record.


index ​

Get Signature ​

get index(): number

Defined in: graphty-element/src/Node.ts:138

This node's index in the element's current GraphSnapshot, assigned at add time as builder.addNode(id) and walked through report.nodeRemap on a renumbering freeze (graph-format design 14.4 rule 5). INVALID_INDEX until the node reaches the builder.

Returns ​

number

The row.

Set Signature ​

set index(row): void

Defined in: graphty-element/src/Node.ts:142

Parameters ​
row ​

number

Returns ​

void


roundRadius ​

Get Signature ​

get roundRadius(): number | null

Defined in: graphty-element/src/Node.ts:383

How far this node's drawn surface is from its centre, when that distance is the same in every direction -- and null when it is not, or cannot be trusted to be.

WHAT IT IS FOR. An edge has to stop at the node's surface, and for a shape that is round from every side that point is one radius along the line, which is arithmetic. For anything else the only honest answer is to intersect the drawn geometry, which is what a null sends the caller back to.

COMPUTED ONCE PER MESH, because every edge on this node would otherwise ask the same question every frame: at ten edges a node that is twenty bounding-box reads per node per frame for an answer that changes only when the node is rebuilt. Measured on a live layout of two thousand nodes, asking per edge cost 13 ms a frame against 4 ms for asking once.

Returns ​

number | null

The radius in world units, or null when this node is not round.


tooltipText ​

Get Signature ​

get tooltipText(): string | undefined

Defined in: graphty-element/src/Node.ts:1385

The words this node's tooltip draws, or undefined when no layer gave it one.

Returns ​

string | undefined

The tooltip text.

Methods ​

applySessionPaint() ​

applySessionPaint(paint): void

Defined in: graphty-element/src/Node.ts:531

Draw this node as the session's style stack resolved it.

Parameters ​

paint ​

NodePaint

The source mesh, the style behind it and the per-instance colour.

Returns ​

void


dispose() ​

dispose(): void

Defined in: graphty-element/src/Node.ts:826

Tears down every Babylon resource this node owns.

THE DEFECT THIS CLOSES: no Node.dispose existed at all. DataManager.clear() emptied its maps and called meshCache.clear(), which disposes the cached SOURCE meshes -- and Babylon disposes a source's instances with it, which is the only reason node spheres vanished on a dataset clear. Everything a node creates OUTSIDE the cache survived: its label (RichTextLabel builds its own plane and dynamic texture) and its drag handler's observers. See Edge.dispose for the visible half of the same bug, the arrowheads.

ORDER MATTERS. The highlight layer is told first, because it keeps this mesh's uniqueId in a list and does not watch for disposal; then the label and drag handler, which hold their own meshes and scene observers; then the mesh itself last, so nothing is asked about a mesh that is already gone.

NEITHER EFFECT IS DELIBERATELY REMOVED HERE. Membership of both the glow layer and the highlight layer is keyed by the SHARED source mesh that MeshCache hands out instances of -- one source per style id -- so calling NodeEffects.applyGlowEffect(mesh, undefined) from here would darken every OTHER node that still uses this style, and resolving the source before removing it from the highlight layer would take those nodes' outlines away too. The source is owned by the cache, so it is freed when the cache is cleared, and the layer's leftover uniqueId is inert: Babylon's uniqueIds are monotonic per scene and never reused, so no future mesh can inherit a dead style's glow or its outline. The removeFromHighlight call below is what is safe to do: it removes THIS mesh, which for an instanced node the layer never held.

A DISPOSED NODE STILL RECEIVES CALLS, which is why the private disposed flag exists rather than this method simply freeing things. DataManager.clear() does not notify the layout engine (its own standing TODO), so UpdateManager keeps iterating the engine's node and edge lists; and SelectionManager.selectedNode holds a Node across a dataset boundary and calls updateStyle + update on it when the selection is finally cleared. Both paths would have hit update()'s recreate-if-disposed branch and rebuilt the mesh of a node nobody owns. Calling this twice is safe.

Returns ​

void


getPosition() ​

getPosition(): object

Defined in: graphty-element/src/Node.ts:1550

Gets the current 3D position of the node's mesh.

Returns ​

object

An object containing the x, y, and z coordinates of the node

x ​

x: number

y ​

y: number

z ​

z: number


getRenderState() ​

getRenderState(): NodeRenderState

Defined in: graphty-element/src/Node.ts:892

How the renderer is currently drawing this node.

Returns ​

NodeRenderState

The render state.


hideTooltip() ​

hideTooltip(): void

Defined in: graphty-element/src/Node.ts:1376

Take this node's tooltip off the screen.

Called when the pointer leaves, and on dispose. Disposing rather than hiding, because a tooltip's plane carries a dynamic texture of its own: keeping one per node that has ever been hovered is a texture per node, which is the cost the hover-only rule exists to avoid.

Returns ​

void


isDisposed() ​

isDisposed(): boolean

Defined in: graphty-element/src/Node.ts:884

Reports whether Node.dispose has run on this node.

Note this is about the NODE, not about node.mesh.isDisposed(): a live node's mesh is disposed and rebuilt on every style change and on a 2D/3D switch, so the mesh's own flag says nothing about whether the node is still part of the graph.

Returns ​

boolean

True once this node has been disposed


isPinned() ​

isPinned(): boolean

Defined in: graphty-element/src/Node.ts:1565

Checks whether the node is currently pinned in place.

Answers from the element's own position array, so the answer does not change because the reader switched arrangement, switched between 2D and 3D, or applied a style template.

Returns ​

boolean

True if the node is pinned, false otherwise


isSelected() ​

isSelected(): boolean

Defined in: graphty-element/src/Node.ts:921

Whether this node is in the session's selection.

Returns ​

boolean

True when it is selected.


pin() ​

pin(): void

Defined in: graphty-element/src/Node.ts:1198

Pins the node in place, so that no layout moves it again until it is released.

THE ELEMENT OWNS THE PIN, in the byte beside this node's coordinates. It used to be owned by whichever layout engine happened to be current, which meant every pin was lost the moment the reader changed arrangement or switched between 2D and 3D -- and meant nothing at all under fourteen of the sixteen engines, whose pin() does nothing. Recorded here it is one fact that survives a layout change, a re-freeze and a renumbering, and the shared position array refuses a layout step onto a pinned row whatever engine is running.

THE ENGINE IS STILL TOLD, because a live simulation that knows a body is fixed stops spending force on it -- ngraph's pinNode, d3's fx/fy/fz. That copy is a projection of the element's bit and never a second source of truth. The order is load-bearing: the bit is recorded FIRST, so an engine that calls back into Node.isPinned while being told sees the pin.

In a graph with a session the pin is an undoable step: it is recorded in the session's pins, which writes the byte and tells the engine.

Returns ​

void


refreshSelectionOverlay() ​

refreshSelectionOverlay(): void

Defined in: graphty-element/src/Node.ts:1000

Redraw this node's selection halo from the configuration as it now stands.

Called for every node when graph.setSelectionStyle() changes it. A node that is not selected has no halo and nothing happens.

Returns ​

void


setRenderState() ​

setRenderState(state): boolean

Defined in: graphty-element/src/Node.ts:906

Say how the renderer should draw this node.

HIDING IS NOT DELETION. The node keeps its row in the store, its dense index, its position, its results and its place in the layout engine; only the meshes stop being drawn. Showing it again re-enables the meshes it already has, so nothing is rebuilt and no layout runs.

Parameters ​

state ​

NodeRenderState

What the visibility mask says about this node.

Returns ​

boolean

True when this changed the state, which is what lets the renderer apply a mask as a delta and touch nothing that did not move.


setSelected() ​

setSelected(selected): boolean

Defined in: graphty-element/src/Node.ts:930

Say whether this node is selected.

Parameters ​

selected ​

boolean

What the selection mask says about this node.

Returns ​

boolean

True when this changed the state.


showTooltip() ​

showTooltip(): void

Defined in: graphty-element/src/Node.ts:1357

Draw this node's tooltip, if a layer gave it one.

Called when the pointer arrives over the node. Does nothing at all when no layer has written node.tooltip, which is the ordinary case, so hovering an unannotated graph costs one comparison per node entered.

Returns ​

void


unpin() ​

unpin(): void

Defined in: graphty-element/src/Node.ts:1222

Unpins the node, allowing the layout engine to move it again.

The element's bit is cleared FIRST and the forward is guarded, so this cannot throw. It used to: a node pinned under one engine and released after a layout change forwarded the release to a DIFFERENT engine, which threw "Internal error: Node not found" for a node it had never been told about.

Returns ​

void


update() ​

update(): void

Defined in: graphty-element/src/Node.ts:450

Updates the node's mesh position and style based on layout engine and style changes. Handles mesh recreation if disposed.

Returns ​

void


updateStyle() ​

updateStyle(): void

Defined in: graphty-element/src/Node.ts:498

Rebuild this node's mesh, its label and its effects from the paint it is currently drawn from, preserving its position and reattaching its behaviours.

A REBUILD REQUEST, NOT A STYLE CHANGE. The 2D/3D switch calls this for exactly one reason -- every mesh has just been disposed -- and update() calls it when it finds a mesh that has gone. What to draw is the style stack's answer; WHETHER to draw is the caller's.

Returns ​

void