Skip to content

API reference

import {
Graphraum,
defineVisuals,
graphraumTheme,
type GraphraumData,
type GraphraumDataPatch,
type GraphraumDiagnostics,
type GraphraumLayoutPositions,
type GraphraumNodeUpdate,
type GraphraumOptions,
} from "@yggy-tech/graphraum";
new Graphraum(container: HTMLElement, options?: GraphraumOptions)

The container must have a non-zero width and height. graphraum appends one canvas, observes container resizing, creates the selected camera, and renders on demand.

interface GraphraumOptions {
mode?: "2d" | "3d"; // default: "2d"
antialias?: boolean; // default: false
maxPixelRatio?: number; // default: 2
maxVisibleEdges?: number; // default: 100_000
maxVisibleNodes?: number; // default: 100_000
viewportCulling?: boolean; // default: true
viewportOverscan?: number; // default: 16 world units
theme?: Partial<GraphraumTheme>;
visuals?: GraphraumVisualMapper<NodeAttributes, EdgeAttributes>;
}

Invalid node and edge budgets, overscan values, positions, and node sizes fail at the boundary with an actionable error.

interface GraphraumData<NodeAttributes = undefined, EdgeAttributes = undefined> {
nodes: readonly GraphraumNode<NodeAttributes>[];
edges: readonly GraphraumEdge<EdgeAttributes>[];
}
interface GraphraumDataPatch<NodeAttributes = undefined, EdgeAttributes = undefined> {
addedNodes?: readonly GraphraumNode<NodeAttributes>[];
addedEdges?: readonly GraphraumEdge<EdgeAttributes>[];
removedNodeIds?: readonly string[];
removedEdgeIds?: readonly string[];
}
interface GraphraumNode {
id: string;
position: { x: number; y: number; z?: number };
color?: string | number;
shape?: GraphraumNodeShape;
size?: number; // shorthand; width/height default to size (then 4)
width?: number;
height?: number;
strokeWidth?: number; // world units; 0 by default (no stroke)
strokeColor?: string | number; // defaults to theme.nodeStroke when strokeWidth > 0
glow?: number; // 0..1, opt-in halo; 0 by default (no halo)
}
type GraphraumNodeShape =
| "circle"
| "square"
| "diamond"
| "hexagon"
| "triangle"
| "pill"
| "rounded";
interface GraphraumEdge {
id: string;
source: string;
target: string;
color?: string | number;
width?: number;
opacity?: number;
style?: "solid" | "dashed" | "dotted";
marker?: "none" | "triangle";
markerSize?: number;
markerEnd?: "target" | "source" | "both";
path?: "straight" | "quadratic" | "cubic";
controlPoints?: readonly { x: number; y: number; z?: number }[];
}

Node and edge IDs must be unique, every edge endpoint must exist, coordinates must be finite, and node size, width, and height must be positive when present. strokeWidth must be finite and non-negative. glow must be a finite number between 0 and 1. An unknown shape fails with the node ID in the error. Edge width and markerSize must be positive, and opacity must be between 0 and 1. Positions and sizes use world units.

Supply generic attribute types and defineVisuals() to compile domain data into node color, shape, size (or independent width/height), stroke, glow, edge color, width, opacity, style, markers, and path, and immutable presentation metadata. See Data and visuals for the complete contract.

interface GraphraumEdgeVisual {
color?: string | number;
width?: number;
opacity?: number;
style?: "solid" | "dashed" | "dotted";
marker?: "none" | "triangle";
markerSize?: number;
markerEnd?: "target" | "source" | "both";
path?: "straight" | "quadratic" | "cubic";
controlPoints?: readonly { x: number; y: number; z?: number }[];
}

defineVisuals() maps typed edge attributes to this contract; direct edge fields use the same shape without a mapper. style selects a dash pattern, marker draws a triangle at markerEnd (target by default), and markerSize scales the triangle relative to width. path selects a polyline sampling of a straight, quadratic, or cubic curve; omit controlPoints for auto handles, or supply 1 (quadratic) / 2 (cubic) world-space points. Overview LOD collapses curves to a single straight segment. Endpoints always come from the source and target node positions. See Data and visuals for the full contract.

theme.endpointAttach ("boundary" by default) stops each edge at its node’s outline. trimEdgeEndpoints() and attachPointOnOutline() export the same trim; see Camera and 3D.

setData(data)

Validates and replaces the complete topology, rebuilds canonical buffers, fits the camera, materializes the viewport, and schedules a render.

applyDataPatch(patch)

Merges streamed additions and removals without fitting the camera. Changes that stay within the preallocated capacity reuse existing GPU meshes; capacity growth falls back to one controlled rebuild.

updateNodes(updates)

Changes position, size, shape, or color for existing nodes and updates only the affected instance data and incident edge endpoints. Use setData when topology changes.

applyLayout(layout)

Applies a transferable XYZ position batch for existing nodes. Call it repeatedly as a worker produces progressive positions.

setSelection(nodeIds)

Applies the selected-node theme color without mutating source graph data. Missing and off-screen IDs are safe.

setEdgeSelection(edgeIds)

Highlights edges with theme.selectedEdge. Only the edges whose selection changed are repainted, so per-hover calls stay cheap on large graphs. Unknown IDs are ignored.

setEdgeState(“dimmed”, edgeIds)

Recedes edges with theme.dimmedEdge and theme.dimmedEdgeOpacity, mirroring setNodeState(“dimmed”, ids). A selected edge stays selected. Unknown IDs are ignored and removed edges drop out of the state.

getNodePresentation(id)

Returns the compiled title, subtitle, properties, and action descriptors for a node, or null.

getEdgePresentation(id)

Returns the compiled presentation for an edge, or null.

render()

Schedules one render on the next animation frame. Repeated calls in the same frame are coalesced.

const updates: readonly GraphraumNodeUpdate[] = [
{ id: "person:ada", position: { x: 20, y: 12 } },
{ id: "place:london", color: "#73c7a5", shape: "square", size: 6 },
];
graph.updateNodes(updates);

GraphraumLayoutPositions carries node IDs and a transferable XYZ Float32Array. See Layout.

computeForcePositions(), computeClusteredForcePositions() and createForceSimulation() accept ForceSettings (defaults in DEFAULT_FORCE_SETTINGS). See Layout for settings, live simulations and clusters.

Use bindGraphology() when Graphology owns the mutable graph. The adapter renders the current graph immediately, maps node visual attributes (x, y, z, color, shape, and size), preserves all attributes for defineVisuals(), and subscribes to later mutations.

import Graph from "graphology";
import { Graphraum, bindGraphology } from "@yggy-tech/graphraum";
type NodeAttributes = {
kind: "person" | "place";
x?: number;
y?: number;
};
type EdgeAttributes = Record<string, never>;
const source = new Graph<NodeAttributes, EdgeAttributes>();
source.addNode("person:ada", { kind: "person" });
source.addNode("place:london", { kind: "place", x: 20, y: 12 });
source.addEdgeWithKey("born-in", "person:ada", "place:london");
const container = document.querySelector<HTMLElement>("#graph");
if (!container) throw new Error("Missing #graph container");
const graph = new Graphraum<NodeAttributes, EdgeAttributes>(container);
const unbind = bindGraphology(graph, source);
source.mergeNodeAttributes("person:ada", { x: -20, y: 12 });
// Stop Graphology mutations from reaching this renderer.
unbind();
graph.destroy();

Missing coordinates default to zero so layout does not block the first render. Mutations are coalesced into one snapshot replacement per microtask, which reruns defineVisuals() for changed domain attributes. The source graph and renderer remain application-owned; unbind() only removes the adapter’s listeners.

pick(clientX, clientY)

Returns the nearest node ID or null. Uses the spatial grid in 2D and instance raycasting in 3D.

setMode(mode)

Switches between orthographic 2D and perspective 3D, replaces controls, and fits the current graph.

getMode()

Returns the active “2d” or “3d” mode.

setAutoOrbit(options | false)

Slowly orbits the 3D camera around the graph. Off by default; pass false to stop. Throws in 2D, and switching to 2D turns it off.

setTheme(theme)

Applies a named preset (“dark” / “light”) or merges a partial palette, then rematerializes colors.

setBackground(background)

Sets a solid color, “transparent” / null for host CSS, or a { type: "pattern", source } texture.

fitView(options?)

Fits the active camera to the complete graph and rematerializes the viewport. Pass { nodeIds } to frame only those nodes, for example a highlighted path; unknown IDs are ignored, and when none match (or the list is empty) it frames every node. In 2D it frames every node and resets any wheel zoom. In 3D it returns to the front view and moves as close as it can while every node, including its glow halo, stays on the canvas, leaving a small margin on the tighter canvas axis for labels beside edge nodes.

flyTo(options)

Animates the camera to the fitView({ nodeIds }) framing over durationMs (default 1200) and resolves true on arrival or false when cancelled by canvas input, another flight, fitView, setMode or destroy(). In 3D it keeps the current view direction, so an auto-orbit continues around the new target; distanceScale multiplies the fitted distance. Jumps with durationMs: 0 or reduced motion. See Fly to nodes.

resize()

Synchronizes the renderer and active camera immediately. A ResizeObserver already calls this for normal container changes.

destroy()

Disconnects observation and controls, cancels pending rendering, disposes GPU resources, and removes the canvas.

createOverlay(options)

Adds a bounded DOM layer for labels, a toolbar, and optional rich HTML focus cards. See Labels and focus.

setAutoOrbit({ speed, resumeAfterMs }) orbits the 3D camera; see Camera and 3D.

graphraumThemes.dark / graphraumThemes.light (and the graphraumTheme dark alias) are immutable. Constructor options and setTheme copy values per renderer.

const graph = new Graphraum(container, {
theme: "light", // or { ...graphraumTheme, edgeWidth: 2 }
});
graph.setTheme("dark");
graph.setBackground("transparent");
graph.setBackground({ type: "pattern", source: image, repeat: [2, 2] });

background accepts a CSS color, "transparent" / null (clear canvas for host CSS), or a pattern object as shown in the example above.

See Theme for every token and the canonical palette.

const diagnostics: GraphraumDiagnostics = graph.getDiagnostics();
interface GraphraumDiagnostics {
aggregatedNodeClusters: number;
autoOrbit: "active" | "off" | "paused";
cpuFrameMilliseconds: number;
gpuFrameMilliseconds: number | null;
gpuDrawCalls: number;
gpuGeometries: number;
gpuTextures: number;
lodLevel: "density" | "detail" | "overview";
pickingStrategy: "raycaster-3d" | "spatial-grid-2d";
dimmedEdges: number;
selectedEdges: number;
selectedNodes: number;
totalEdges: number;
totalNodes: number;
visibleEdgeCandidates: number;
visibleEdgeMarkers: number;
visibleEdgeSegments: number;
visibleEdges: number;
visibleGlowNodes: number;
visibleNodes: number;
visibleNodeCandidates: number;
}

Diagnostics describe the final rendered frame. GPU frame time is null when WebGL timer queries are unavailable. Node candidates and aggregate clusters expose density LOD decisions; total and visible counts expose the effective node and edge reductions without asking applications to re-derive them. visibleEdgeSegments counts rendered edge lines and visibleEdges is an alias for it; visibleEdgeMarkers counts rendered direction triangles, which the overview LOD tier drops first. autoOrbit is "paused" when the orbit is enabled but stopped by input, a hidden tab or an off-screen canvas. visibleGlowNodes counts rendered glow halos (at most 256, and 0 in the density LOD tier). gpuDrawCalls is 2 without halos and 3 while at least one halo is visible; see Glow.