Skip to main content

GraphXR API Reference

Common Types

These types are used throughout the GraphXR API.

type PropertyValue = string | number | boolean

type Properties = Record<string, PropertyValue>

type Dimension = "x" | "y" | "z"

type GxrEdgeId = string

type GxrNodeId = string

type PropertyFilter = (value: PropertyValue) => boolean

type StyleFilter = (value: NodeStyleValue) => boolean

type GetNodesOptions = GetNodesOptionsObject | GxrNodeId | GxrNodeId[] | GxrNode | GxrNode[] | IterableNodes

type PropertySetter = <T extends GxrNode | GxrEdge>(any: T) => PropertyValue

type CategoryConfigType = {
captions: string[];
avatar_property: string;
size_property: string;
label: CategoryId;
background_color: string;
icon: GxrIcon;
caption_color: string;
template: string;
visible: boolean;
properties: Properties;
}

type NodeStyles = {
alpha: number;
color: Color;
icon: number;
pinned: boolean;
position: Position;
selected: boolean;
size: number;
twinkled: boolean;
}

type EdgeStyles = {
alpha: number;
color: Color;
selected: boolean;
twinkled: boolean;
width: number;
}

type GxrEdge = EdgeStyles & {
id: GxrEdgeId;
sourceId: GxrNodeId;
targetId: GxrNodeId;
_neo4jID?: string; // Used in expandNodes
name: RelationshipId; // The old name for relationship
properties: Properties;
uid: string; // On construction, md5 hash the JSON stringified properties
relationship: RelationshipId;
source: GxrNode;
target: GxrNode;
toJSON: () => SerializedGxrEdge;
tagColor: string;
}

type GxrNode = NodeStyles & {
id: GxrNodeId;
index: number;
category: CategoryId;
categories: string[]; /* see web/libs/CSVTransform/index.ts */
collection?: GxrNodeCollection;
data: {
detail: {
type: CategoryId;
data: Properties;
uid?: string
};
};
properties: Properties;
neighbor: GxrNodeId[];
neighbors: Neighbor[];
connectedEdge: GxrEdgeId[];
degree: number;
toJSON: () => SerializedGxrNode;
tagColor: string;
}

type RelationshipConfigType = {
captions: string[];
color: string;
draggedIndex: number;
hidden: Record<string, boolean>;
hiddenConfig: unknown;
isUserAction: boolean;
order: string[];
properties: Record<string, boolean>;
relationship: string;
showPopover: boolean;
size: number;
visible: boolean;
width_property: string;
_id: string;
}

type GxrView = {
__v: number;
_id: string;
createTime: string;
fileName: string;
graphxr: {
labels: number;
relationships: number;
};
name: string;
neo4jAppInfo: {
id: string;
};
password?: string;
projectId: string;
thumbnail: string;
requireAuth: boolean;
updateTime: string;
user: string;
remark?:string
}

type RandomizeOptions = | {
min: number;
max: number;
}

interface GxrGraphDelta {
addedNodes?: (GxrNode | Partial<SerializedGxrNode>)[];
addedEdges?: (GxrEdge | Partial<SerializedGxrEdge>)[];
updatedNodes?: (GxrNode | Partial<SerializedGxrNode>)[];
updatedEdges?: (GxrEdge | Partial<SerializedGxrEdge>)[];
removedNodeIds?: GxrNodeId[];
removedEdgeIds?: GxrEdgeId[];
}

interface AxisOptions {
title: string;
ticks: PropertyValue[];
data: number[];
}

interface AxesOptions {
axes: {
x: AxisOptions;
y: AxisOptions;
z: AxisOptions;
};
showAxes: boolean;
showGrid: boolean;
scale: number;
}

interface TweenLayoutOptions {
duration?: number;
interpolate?: InterpolateLayoutFunction;
}

class IterableNodes {
// Array-like methods
ids(): GxrNodeId[]
filter(callback: (node: GxrNode) => boolean): IterableNodes
find(callback: (node: GxrNode) => boolean): GxrNode | undefined
sort(callback: (a: GxrNode, b: GxrNode) => number): IterableNodes
slice(start: number, end?: number): IterableNodes
forEach(callback: (node: GxrNode) => void): void
map<T>(callback: (node: GxrNode) => T): T[]

// Property methods
property(key: string, value?: PropertySetter | PropertyValue): IterableNodes | PropertyValue[]
properties(props?: Record<string, PropertySetter | PropertyValue>): IterableNodes | Properties[]

// Style methods
style<T extends keyof NodeStyles>(key: T, value?: NodeStyles[T]): IterableNodes | NodeStyles[T][]
alpha(value: number): IterableNodes
color(value: Color | string): IterableNodes
size(value: number): IterableNodes
pinned(value: boolean): IterableNodes

// Selection methods
select(): IterableNodes
deselect(): IterableNodes

// Graph operations
remove(): IterableNodes
hide(): IterableNodes
show(): IterableNodes
highlight(): IterableNodes

// Layout methods
ego(options?: EgoOptions): IterableNodes | Promise<NodeIdToPosition>
circle(options?): IterableNodes | Promise<NodeIdToPosition>
grid(options?): IterableNodes | Promise<NodeIdToPosition>
line(options?): IterableNodes | Promise<NodeIdToPosition>
// ... and more layout methods
}

Camera

gxr.flyToCenter(maybeNodes, options)

Fly the camera to the center of a slice of nodes, optionally with an offset, optionally with a custom duration or tween function

@synonyms centerTo

Types

function flyToCenter(maybeNodes?: GetNodesOptions, options?: FlyToPositionOptions): Promise<Position>

Example

await gxr.flyToCenter();
await gxr.flyToCenter(gxr.nodes().slice(0, 10).ids())
await gxr.flyToCenter(gxr.nodes().slice(0, 10).ids(), { duration: 0, offset: -3 }));

gxr.flyToPosition(position, options)

Fly the camera to a position, optionally with an offset, optionally with a custom duration or tween function

Types

type FlyToPositionOptions = TweenPositionOptions & {
offset?: number;
}
type InterpolatePositionFunction = (t: number, initial: Position, final: Position) => Position
interface TweenPositionOptions {
duration?: number;
interpolate?: InterpolatePositionFunction;
}
interface TweenPositionUpdateEvent {
t: number;
}
function flyToPosition(
position: Position,
options: FlyToPositionOptions = {}
): Promise<Position>

Example

const position = gxr.nodes({name: "Flo"}).at(0).position;
await gxr.flyToPosition(position); // no offset
await gxr.flyToPosition(position, {offset: -3}); // with an offset
await gxr.flyToPosition(position, {duration: 0}); // instantly

gxr.flyOut(options)

Zoom out until all nodes are visible

Types

type FlyOutOptions = TweenPositionOptions & {
nodes?: GetNodesOptions;
offset?: number;
scale?: number;
}
function flyOut(options?: FlyOutOptions): void

Example

await gxr.flyOut();

gxr.zoomIn(delta, options)

Zoom the camera in by a delta value, optionally with animation

Types

interface ZoomOptions {
duration?: number;
}
interface TweenZoomUpdateEvent {
t: number;
}
function zoomIn(
delta: number = 1.0,
options: ZoomOptions = {}
): Promise<Position>

Example

await gxr.zoomIn(); // zoom in by 1.0
await gxr.zoomIn(2.0); // zoom in by 2.0
await gxr.zoomIn(1.5, { duration: 500 }); // zoom in by 1.5 with animation

gxr.zoomOut(delta, options)

Zoom the camera out by a delta value, optionally with animation

Types

function zoomOut(
delta: number = 1.0,
options: ZoomOptions = {}
): Promise<Position>

Example

await gxr.zoomOut(); // zoom out by 1.0
await gxr.zoomOut(0.5); // zoom out by 0.5
await gxr.zoomOut(0.5, { duration: 300 }); // zoom out by 0.5 with animation

gxr.setCameraOptions(options)

Types

interface CameraOptions {
hideAxes?: boolean;
rotating?: boolean;
speed?: number;
}
function setCameraOptions(options: CameraOptions): void

Example

gxr.setCameraOptions({
hideAxes: true,
rotating: true,
speed: 0.5,
});

gxr.setCameraRotating(rotating)

Types

function setCameraRotating(rotating: boolean): void

Example

gxr.setCameraRotating(true);

Captions

gxr.captionNodesByProperties(options)

Types

interface CaptionNodesByProperties {
category: CategoryId;
properties: string[];
}
function captionNodesByProperties({category, properties}: CaptionNodesByProperties): Promise<unknown>

Example

gxr.captionNodesByProperties({category: "Person", properties: ["name", "age"]});

Events

gxr.onGraphDataUpdate(callback)

Types

function onGraphDataUpdate(callback: { (): () => void, before: number })

Example

gxr.onGraphDataUpdate(() => console.log("Graph data updated"));

gxr.useGraphDataUpdate()

React hook that subscribes to graph data changes. Returns a value that changes whenever graph data is updated.

Types

function useGraphDataUpdate(): number

Example

const dataVersion = gxr.useGraphDataUpdate();
useEffect(() => {
// Re-run when graph data changes
}, [dataVersion]);

gxr.onSelect(id, fn)

Types

function onSelect(id: string, fn: OnSelectCallback): UnregisterCallback

Example

gxr.onSelect((event) => console.log("Selected nodes/edges", event));

Files

gxr.files

Example

gxr.files.upload({
path: "/documents/story.pdf",
file: new File(["Once upon a time..."], "story.pdf"),
})
gxr.files.ls("/documents");
gxr.files.rmrf("/documents");
// get returns a Response, so the caller decides how to consume it
const text = await gxr.files.get("/documents/story.txt").then(r => r.text());
const data = await gxr.files.get("/config.json").then(r => r.json());
const blob = await gxr.files.get("/images/photo.png").then(r => r.blob());

gxr.setCurrentPanel(id, subTab)

@deprecated Use gxr.workspace.setActiveTab(panelId, ${panelId}.${subTab}) instead.

Types

function setCurrentPanel(id: string, subTab?: string): void

Example

gxr.setCurrentPanel("algorithm");
gxr.setCurrentPanel("algorithm", "centrality");
gxr.setCurrentPanel("Grove");

As a convenience, you can pass the name of the extension as the first argument
instead of the extension's id, because extension ids are random and hard to remember.

gxr.setSubTab(panelIdOrTab, tab)

@deprecated Use setCurrentPanel(panelId, subTab) instead.

Types

function setSubTab(panelIdOrTab: string, tab?: string): void

Example

gxr.setSubTab("centrality");
// Prefer: gxr.setCurrentPanel("algorithm", "centrality");

Graph

gxr.add(...args)

@deprecated

DEPRECATED: DO NOT USE THIS FUNCTION. Prefer addNode, addNodes, addEdge, or addEdges instead. Why are we deprecating this function?

  • It's too complicated.
  • Too many conditions.
  • AI messes up using it. We should prefer the simpler functions like addNode, addNodes, addEdge, or addEdges instead.

Alias: gxr.add(...) is equivalent to gxr.graph().add(...)

Example

// DEPRECATED: DO NOT USE THIS FUNCTION.
gxr.add("A") -> Node with id "A"
gxr.add("A", "B") -> Edge
gxr.add(["A", "B"]) -> Node[]
gxr.add({ id: "A", category: "Person", properties: {name: "Flo"} }) -> Node
gxr.add([{ id: "A", category: "Person", properties: {name: "Flo"} }]) -> Node[]
gxr.add({ sourceId: "A", targetId: "B" }) -> Edge
gxr.add([{ sourceId: "A", targetId: "B" }]) -> Edge[]
gxr.add([{ source: {...}, edge: {...}, target: {...} }], {...}) -> Edge[] // mergeRelationships
gxr.add({ name: "Flo" }, { category: "Person" }) -> Node
gxr.add([{ name: "Flo" }], { category: "Person" }) -> Node[]
gxr.add([{ name: "Flo" }]) -> Node[]
gxr.add({ id: "A" }, { id: "B" }) -> Edge
gxr.add({ id: "A" }, { id: "B" }, { relationship: "LINK" }) -> Edge with relationship "LINK"

gxr.addNode(node)

Add node to the graph.

Alias: gxr.addNode(...) is equivalent to gxr.graph().addNode(...)

Example

gxr.addNode({ id: "A", category: "Person", properties: {name: "Flo"} });

gxr.addNodes(nodes)

Add multiple nodes to the graph.

Alias: gxr.addNodes(...) is equivalent to gxr.graph().addNodes(...)

Example

gxr.addNodes([{ id: "A", category: "Person" }, { id: "B", category: "Person" }]);

gxr.addEdge(input, target, options)

Add a single edge to the graph.

Alias: gxr.addEdge(...) is equivalent to gxr.graph().addEdge(...)

Example

gxr.addEdge({ sourceId: "A", targetId: "B", relationship: "KNOWS" });
gxr.addEdge(nodeA, nodeB);
gxr.addEdge(nodeA, nodeB, { relationship: "KNOWS" });

gxr.addEdges(edges)

Add multiple edges to the graph.

Alias: gxr.addEdges(...) is equivalent to gxr.graph().addEdges(...)

Example

gxr.addEdges([{ sourceId: "A", targetId: "B" }, { sourceId: "B", targetId: "C" }]);

gxr.clear()

Clear the graph

Alias: gxr.clear(...) is equivalent to gxr.graph().clear(...)

Example

gxr.clear();

gxr.edges(options)

Alias: gxr.edges(...) is equivalent to gxr.graph().edges(...)

Example

ids = gxr.edges().ids();
gxr.edges().forEach(console.log);
gxr.edges().property('since', 2023);
gxr.edges().property('since', () => Math.random() * 3000);
gxr.edges().style('width', 10)
gxr.edges({relationship: 'LINKS'}).style('width', 10);
gxr.edges({properties: {since: 2023}}).style('width', 10);

gxr.getCanvasSchema(graph)

Get schema from the visible nodes and edges on the canvas.

Types

interface GraphSchema {
nodes: NodeSchema[];
relationships: RelationshipSchema[];
}
interface NodeSchema {
label: string;
properties: PropertySchema[];
}
interface RelationshipSchema {
label: string;
sourceNodeLabel: string;
targetNodeLabel: string;
properties: PropertySchema[];
}
interface PropertySchema {
name: string;
type: 'string' | 'number' | 'boolean' | 'date';
isPrimaryKey?: boolean;
enum?: string[];
}
function getVisibleGraphSchema(graph?: GxrGraph): GraphSchema

Example

const schema = gxr.getCanvasSchema();
console.log(schema.nodes); // [{label: "Person", properties: [...]}]
console.log(schema.relationships); // [{label: "KNOWS", sourceNodeLabel: "Person", targetNodeLabel: "Person", properties: [...]}]

gxr.getCategoryConfig(category)

Types

function getCategoryConfig(category: CategoryId): CategoryConfigType

Example

gxr.getCategoryConfig('Person');

gxr.getNode(id)

Types

function getNode(id: GxrNodeId): GxrNode | undefined

Example

gxr.getNode("A")

gxr.getRelationshipConfig(relationship)

Types

function getRelationshipConfig(relationship: RelationshipId): RelationshipConfigType

Example

gxr.getRelationshipConfig("RELATED_TO");

gxr.graph(maybePath)

Types

function getGraphSelection(maybePath?: PathFindingPath | PathFindingPath[]): GraphSelection

Example

// Add a node with id "A"
gxr.graph().add("A");

// Generate a random graph, run degree algorithm, and then run ego layout for a duration of 1 second.
gxr
.graph()
.clear()
.generate()
.degree()
.ego(
{
properties: { degree: (value) => value >= 3 },
depth: 5,
mode: "tree",
orientation: "down",
edgeLength: 0.5,
sortByProperty: "degree",
},
{ duration: 1000 }
);

gxr.makeGraph()

Types

function makeGraph(): GraphSelection

Example

gxr.makeGraph().add("A").add("B").add("C").add("A", "B").add("B", "C").add("C", "A");

gxr.nodes(options)

Get an IterableNodes object with an optional filter, sort, or reverse that can be used to iterate over the nodes in the graph.

Alias: gxr.nodes(...) is equivalent to gxr.graph().nodes(...)

Example

ids = gxr.nodes().ids();
gxr.nodes().forEach(console.log);
gxr.nodes().property('age', 24);
gxr.nodes().property('age', () => Math.random() * 100);
gxr.nodes({category: "Person"}).style('selected', true);
gxr.nodes({properties: {age: 24}}).style('selected', true);
gxr.nodes({properties: {age: (age) => age > 24}}).style('selected', true);

gxr.selectNodes(filter)

Select nodes in the graph based on a filter predicate or options.

Types

type NodePredicate = (node: GxrNode) => boolean
type SelectNodesOptions = GetNodesOptions | NodePredicate
function selectNodes(filter?: SelectNodesOptions): IterableNodes

Example

// Select nodes using a predicate function
gxr.selectNodes((n) => n.id === "hub");
gxr.selectNodes((n) => n.category === "Person");
gxr.selectNodes((n) => n.properties.age > 30);

// Select nodes by ID
gxr.selectNodes("nodeId");
gxr.selectNodes(["nodeId1", "nodeId2"]);

// Select nodes by category
gxr.selectNodes({ category: "Person" });

// Select nodes by properties
gxr.selectNodes({ properties: { name: "Alice" } });

// Select all nodes
gxr.selectNodes(() => true);

// Deselect all (select none)
gxr.selectNodes(() => false);

gxr.deselectNodes(filter)

Deselect nodes in the graph based on a filter predicate or options.

Types

type NodePredicate = (node: GxrNode) => boolean
type DeselectNodesOptions = GetNodesOptions | NodePredicate
function deselectNodes(filter?: DeselectNodesOptions): IterableNodes

Example

// Deselect all nodes
gxr.deselectNodes();

// Deselect nodes using a predicate function
gxr.deselectNodes((n) => n.id === "hub");
gxr.deselectNodes((n) => n.category === "Person");

// Deselect nodes by ID
gxr.deselectNodes("nodeId");
gxr.deselectNodes(["nodeId1", "nodeId2"]);

// Deselect nodes by category
gxr.deselectNodes({ category: "Person" });

gxr.invertSelectedNodes()

Invert node selection for currently visible nodes. Selected nodes become deselected, and unselected nodes become selected.

Types

function invertSelectedNodes(): IterableNodes

Example

gxr.invertSelectedNodes();

gxr.randomGraph(options)

Generate a random graph and add it to the canvas.

Types

type MakeRandomGraphOptions = {
nodeCount?: number;
edgeCount?: number;
category?: CategoryId | CategoryId[];
relationship?: RelationshipId | RelationshipId[];
}
function makeRandomGraph(options: MakeRandomGraphOptions = {}): GraphSelection

Example

gxr.randomGraph({nodeCount: 100, edgeCount: 200, categories: ["Person", "Company"], relationships: ["WORKS_FOR", "KNOWS"]});
gxr.forceLayout();

gxr.makeRandomGraph(options)

Generate an in-memory random graph.

Types

type MakeRandomGraphOptions = {
nodeCount?: number;
edgeCount?: number;
category?: CategoryId | CategoryId[];
relationship?: RelationshipId | RelationshipId[];
}
function makeRandomGraph(options: MakeRandomGraphOptions = {}): GraphSelection

Example

const randomGraph = gxr.makeRandomGraph({nodeCount: 100, edgeCount: 200, categories: ["Person", "Company"], relationships: ["WORKS_FOR", "KNOWS"]});
gxr.add(randomGraph);
gxr.forceLayout();

Layout

gxr.alignBy(options)

Given one of x, y, or z, find the center of that dimension and align all Nodes to that center on that dimension only.

Alias: gxr.alignBy(...) is equivalent to gxr.graph().alignBy(...)

Types

type AlignByOptions = {
dimension?: Dimension;
nodes?: GetNodesOptions;
tween?: TweenLayoutOptions;
}
function alignBy(options: AlignByOptions = {}): LayoutFunction

Example

await gxr.alignBy({
dimension: 'x',
})

gxr.circle(options)

All the nodes spread on a circle

Alias: gxr.circle(...) is equivalent to gxr.graph().circle(...)

Types

type CircleOptions = {
nodes?: GetNodesOptions
tween?: TweenLayoutOptions;
}
function circle(options?: CircleOptions)

Example

await gxr.circle();

gxr.cube(options)

All the nodes spread on a cube.

Alias: gxr.cube(...) is equivalent to gxr.graph().cube(...)

Types

type CubeOptions = {
nodes?: GetNodesOptions;
tween?: TweenLayoutOptions;
}
function cube(options?: CubeOptions): LayoutFunction

Example

await gxr.cube();

gxr.distributionBy(options)

Equally space Nodes on one of the x, y, or z axes while keeping the other two dimensions constant. Optionally bin the Nodes by a property value. Optionally scale the spacing by a "spread" factor (the higher the spread, the farther apart).

Alias: gxr.distributionBy(...) is equivalent to gxr.graph().distributionBy(...)

Types

type DistributionByOptions = AllDistributionByOptions | string
function distributionBy(options: DistributionByOptions = {}): LayoutFunction

Example

// Distribute nodes on the x-axis by a property
await gxr.distributionBy('similarity')

// Order nodes by a date property and spread them out
await gxr.distributionBy({
bin: 'episodeAirDate',
binType: 'date',
spread: 6,
})

// Equally space Nodes on the x-axis
await gxr.distributionBy({
dimension: 'x', // y, or z
})

// Equally space Nodes on the x-axis and bin the Nodes by "seasonNumber"
await gxr.distributionBy({
bin: 'seasonNumber',
dimension: 'x',
})

// Equally space Nodes on the x-axis and bin the Nodes by "seasonNumber" in descending order
await gxr.distributionBy({
bin: 'seasonNumber',
dimension: 'x',
reverse: true,
})

gxr.ego(options)

Ego reveals hierarchal data by arranging nodes in a tree, where a node's depth in the tree is equal to the length of the shortest path to the node. The tree projects linearly in one direction, or radially around the root[s].

Alias: gxr.ego(...) is equivalent to gxr.graph().ego(...)

Types

type EgoOptions = {
alongRelationships?: RelationshipId[];
depth?: number;
edgeLength?: number;
mode?: EgoMode;
nodes?: GetNodesOptions;
orientation?: EgoOrientation;
sortByProperty?: string;
tween?: TweenLayoutOptions;
}
function ego(options: EgoOptions = {}): LayoutFunction

Example

await gxr.nodes("a").ego({
depth: 3, // maximum depth of the tree; default 100
edgeLength: 1 // visual length of the edges in the tree; default 0.2
mode: 'rings' // 'tree' or 'rings'; default 'tree'
orientation: 'down' // 'up', 'down', 'left', or 'right'; default 'right'
sortByProperty: 'ComponentName' // arrange child nodes in ascending order by a property
[sortByProperty: sortByProperty({property: "ComponentName", ascending: false})] // same as above, but descending
}))

// Auto-select root nodes
await gxr.ego();

gxr.grid(options)

Equally space Nodes on the x-axis, y-axis, z=0.

Alias: gxr.grid(...) is equivalent to gxr.graph().grid(...)

Types

type GridOptions = {
nodes?: GetNodesOptions
tween?: TweenLayoutOptions;
}
function grid(options?: GridOptions): LayoutFunction

Example

await gxr.grid();

gxr.line(options)

Equally space Nodes on the x-axis, y=0, z=0.

Alias: gxr.line(...) is equivalent to gxr.graph().line(...)

Types

type LineOptions = {
nodes?: GetNodesOptions;
tween?: TweenLayoutOptions;
}
function line(options?: LineOptions): LayoutFunction

Example

await gxr.line();

// Animate the layout over 1 second
await gxr.line({
tween: {
duration: 1000,
},
});

gxr.parametric(options)

Map the x, y, and/or z dimensions to the range [-2, 2] by applying a linear scale to all or a subset of the domain of a property.

Alias: gxr.parametric(...) is equivalent to gxr.graph().parametric(...)

Types

type ParametricOptions = Partial<Pick<AxesOptions, "showAxes" | "showGrid" | "scale">> & {
nodes?: GetNodesOptions;
x?: string | ParametricDimension | number;
y?: string | ParametricDimension | number;
z?: string | ParametricDimension | number;
tween?: TweenLayoutOptions;
}
interface ParametricDimension {
property: string;
range: Interval;
}
function parametric(options: ParametricOptions = {}): LayoutFunction

Example

If a dimension is omitted, it is flattened to align with the grid.

// Line up Nodes on the x-axis, ordered by seasonNumber.
// Also set y and z to 0
await gxr.parametric({
x: 'seasonNumber',
y: 0,
z: 0,
})

// Line up Nodes on the x-axis, ordered by seasonNumber descending. Align y and z to the grid.
await gxr.parametric({
x: 'seasonNumber',
reverse: true,
})

// Linearly scale seasonNumber, episodeNumber, and millionViewers on the x, y, and z dimensions respectively
await gxr.parametric({
x: 'seasonNumber',
y: 'episodeNumber',
z: 'millionViewers',
})

gxr.rotate(options)

Given one of the x, y, or z dimensions, find the center point of all the Nodes and rotate all Nodes around the axis passing through the center point and lying on the dimension given.

Alias: gxr.rotate(...) is equivalent to gxr.graph().rotate(...)

Types

type RotateOptions = {
nodes?: GetNodesOptions;
dimension?: Dimension;
theta?: number;
tween?: TweenLayoutOptions;
}
function rotate(options: RotateOptions = {}): LayoutFunction

Example

await gxr.rotate({
dimension: 'x',
theta: 90,
})

await gxr.rotate({
dimension: 'z',
theta: 45
})

gxr.scale(options)

Scale the distance of each node from a computed center by a constant factor.

Alias: gxr.scale(...) is equivalent to gxr.graph().scale(...)

Types

type ScaleOptions = number | {
nodes?: GetNodesOptions
x?: number;
y?: number;
z?: number;
tween?: TweenLayoutOptions;
}
function scale(options: ScaleOptions = {}): LayoutFunction

Example

await gxr.scale({
x: 2,
y: 2,
z: 2,
})

gxr.scatter(options)

Set each node to a random point.

Alias: gxr.scatter(...) is equivalent to gxr.graph().scatter(...)

Types

type ScatterOptions = {
nodes?: GetNodesOptions
tween?: TweenLayoutOptions;
}
function scatter(options?: ScatterOptions): LayoutFunction

Example

await gxr.scatter()

gxr.shift(options)

Add a constant vector to the position of each node.

Alias: gxr.shift(...) is equivalent to gxr.graph().shift(...)

Types

type ShiftOptions = {
nodes?: GetNodesOptions
x?: number;
y?: number;
z?: number;
tween?: TweenLayoutOptions;
}
function shift(options: ShiftOptions = {}): LayoutFunction

Example

await gxr.shift({
x: 1,
})

gxr.toast(message)

Get the toast function

Types

type ToastReturnType = {
promise: (promise: Promise<unknown>, options?: {
pending?: string;
success?: string;
error?: string;
}) => Promise<unknown>;
success: (content: string) => void;
error: (content: string) => void;
info: (content: string) => void;
warn: (content: string) => void;
}
function toast(message: string): string;
function toast(): ToastReturnType;
function toast(message?: string): ToastReturnType | string

Example

gxr.toast("Hello, world!");
gxr.toast().info("Hello, world!");
gxr.toast().success("Hello, world!");
gxr.toast().error("Hello, world!");
gxr.toast().warn("Hello, world!");
await gxr.toast().promise(fetch(), "Hello, world!");

gxr.setParametricAxesOptions(options)

Types

function setParametricAxesOptions(options: Partial<AxesOptions>): void

Example

gxr.setParametricAxesOptions({
showAxes: false,
})

gxr.spiral(options)

All the nodes spread on a spiral

Alias: gxr.spiral(...) is equivalent to gxr.graph().spiral(...)

Types

type SpiralOptions = {
nodes?: GetNodesOptions;
tween?: TweenLayoutOptions;
}
function spiral(options?: SpiralOptions): LayoutFunction

Example

gxr.spiral()

gxr.sphere(options)

All the nodes spread on a sphere using Fibonacci sphere (golden spiral) algorithm

Alias: gxr.sphere(...) is equivalent to gxr.graph().sphere(...)

Types

type SphereOptions = {
nodes?: GetNodesOptions;
tween?: TweenLayoutOptions;
radius?: number;
density?: number;
}
function sphere(options?: SphereOptions): LayoutFunction

Example

await gxr.sphere();

// Custom radius and density
await gxr.sphere({
radius: 2,
density: 3,
tween: { duration: 1000 }
});

gxr.forceLayout()

Run a force layout on the graph.

Force Layout ignores pinned nodes. To unpin nodes, call gxr.nodes().pinned(false). If necessary, pass options to gxr.nodes() to select specific nodes to unpin.

Alias: gxr.forceLayout(...) is equivalent to gxr.graph().forceLayout(...)

Example

// Run force layout
gxr.forceLayout();

Neo4j

gxr.neo4j(query, options)

Types

type Neo4jData = Neo4jGraphData | Neo4jTableData
type Neo4jGraphData = {
nodes: Neo4jNode[];
relationships: Neo4jEdge[];
}
type Neo4jTableData = Array<string | number | null>[]
interface Neo4jOptions {
config?: Neo4jConfig;
projectId?: string;
saveToGraph?: boolean;
ignoreTips?: boolean;
params?: Record<string, unknown>;
skipLoadInnerRelationship?: boolean;
}
interface Neo4jConfig {
host: string;
boltPort: string;
username: string;
password: string;
database: string;
accessMode?: string;
}
interface Neo4jNode {
id: string;
labels: string[];
properties: Properties;
}
interface Neo4jEdge {
id: string;
startNodeId: string;
endNodeId: string;
type: string;
properties: Properties;
}
interface Neo4jResponseContent {
data: Neo4jData;
type: Neo4jResultType;
}
function neo4j(
query: string,
options: Neo4jOptions = {}
): Promise<void | Neo4jResult |

Example

await gxr.neo4j("MATCH (n) RETURN n LIMIT 10");

Query

gxr.query(query, options)

Types

type QueryOptions = Neo4jOptions
function query(query: string, options: QueryOptions = {}): void

Example

// Execute a query. Results appear in the graph workspace
await gxr.query("MATCH (n) RETURN n LIMIT 10");

// Execute a query. Results are not shown in the graph workspace
await gxr.query("MATCH (n) RETURN n LIMIT 10", { saveToGraph: false });

// Explicitly query a local Kuzu file
await gxr.query("MATCH (n) RETURN n LIMIT 10", { type: "localKuzuFile", name: "default" });

// Execute a query. Results are not shown in the graph workspace
const result = await gxr.query("MATCH (n) RETURN n LIMIT 10", { type: "localKuzuFile", name: "default", saveToGraph: false });
console.log(result);

Views

gxr.views

View management APIs for listing, saving, and loading views.

Example

// List all views
const views = await gxr.views.list();
console.log(views);

// Save a new view
const saved = await gxr.views.save({ name: "My View" });

// Update an existing view
await gxr.views.save({ id: saved._id });

// Load a view by id
await gxr.views.load({ id: saved._id });

gxr.views.list()

List all views for the current project. Fetches the latest views from the server.

Types

function listViews(): Promise<GxrView[]>

Example

const views = await gxr.views.list();
console.log(views.map(v => v.name));

gxr.views.save(options)

Save the current graph state as a view.

  • No args: overwrites the currently open view. If none is open, creates a new view with an auto-generated name.
  • { id }: overwrites a specific view by id.

Types

type SaveViewOptions = {
id?: string;
name?: string;
saveAvatarsView?: boolean;
shouldUpdateLocationWithPerspectiveId?: boolean;
}
function saveView({
id,
name,
saveAvatarsView = guiConfig?.saveAvatarsView ?? false,
shouldUpdateLocationWithPerspectiveId = true,
}: SaveViewOptions = {}): Promise<GxrView>

Example

// Overwrite the current view
await gxr.views.save();

// Overwrite a specific view
await gxr.views.save({ id: view._id });

gxr.views.saveAs(options)

Create a new view with the given name from the current graph state. Always creates a new view (never overwrites an existing one).

Types

type SaveViewOptions = {
id?: string;
name?: string;
saveAvatarsView?: boolean;
shouldUpdateLocationWithPerspectiveId?: boolean;
}
function saveView({
id,
name,
saveAvatarsView = guiConfig?.saveAvatarsView ?? false,
shouldUpdateLocationWithPerspectiveId = true,
}: SaveViewOptions = {}): Promise<GxrView>

Example

const view = await gxr.views.saveAs({ name: "My View" });

gxr.views.duplicate(options)

Duplicate an existing view by copying its saved state into a new view. The new view reuses the source view's saved .graphxr file and metadata.

Types

interface DuplicateViewOptions {
id: string;
name?: string;
}
function duplicateView({ id, name }: DuplicateViewOptions): Promise<GxrView>

Example

const copy = await gxr.views.duplicate({ id: original._id });
// or with a custom name:
const copy = await gxr.views.duplicate({ id: original._id, name: "My Copy" });

gxr.views.rename(options)

Rename a view. If id is omitted, uses the currently open view. Throws if no view is open.

Types

type RenameViewProps = {
id?: string;
name: string;
remark?: string;
}
function renameView({ id, name,remark }: RenameViewProps): Promise<GxrView>

Example

await gxr.views.rename({ id: view._id, name: "New Name" });
// or rename the current view:
await gxr.views.rename({ name: "New Name" });

gxr.views.delete(options)

Delete a view. If no id is provided, deletes the currently open view. After deletion the views list is refreshed and, when the deleted view was the active one, the URL is cleared.

Types

interface DeleteViewOptions {
/** View id to delete. If omitted, defaults to the currently open view. */
id?: string;
}
function deleteView({ id }: DeleteViewOptions = {}): Promise<void>

Example

await gxr.views.delete({ id: view._id });
// or delete the current view:
await gxr.views.delete();

gxr.views.getFileUrl(options)

Get the absolute URL to a view's stored .graphxr file. The URL can be fetched by anything with the right auth cookies/tokens. If id is omitted, uses the currently open view. Throws if no view is open.

Types

interface GetViewFileUrlOptions {
id?: string;
}
function getViewFileUrl({ id }: GetViewFileUrlOptions = {}): string

Example

const url = gxr.views.getFileUrl({ id: view._id });
// or use the current view:
const url = gxr.views.getFileUrl();

gxr.views.getFile(path)

Fetch a view's .graphxr file and return it as a Blob. If id is omitted, uses the currently open view. Throws if no view is open.

Types

function getFile(path: string): Promise<Response>

Example

const blob = await gxr.views.getFile({ id: view._id });
// or use the current view:
const blob = await gxr.views.getFile();

gxr.views.load(options)

Load a view by id.

Types

type LoadViewOptions = {
id: string;
}
function loadView({ id }: LoadViewOptions): Promise<GxrView>

Example

await gxr.views.load({ id: "123" });

gxr.views.getCurrent()

Get the currently loaded view, or undefined if no view is loaded.

Types

function getCurrentView(): void

Example

const current = gxr.views.getCurrent();
if (current) console.log(current.name);

gxr.views.getShareLink(options)

Get the share URL for a view. If id is omitted, uses the currently open view. Throws if no view is open.

Types

interface GetViewShareLinkOptions {
id?: string;
}
function getViewShareLink({ id }: GetViewShareLinkOptions = {}): string

Example

const link = gxr.views.getShareLink({ id: view._id });
// or use the current view:
const link = gxr.views.getShareLink();

gxr.views.setPassword(options)

Set or update the password on a view. If id is omitted, uses the currently open view. Throws if no view is open.

Types

interface SetViewPasswordOptions {
id?: string;
password: string;
}
function setViewPassword({ id, password }: SetViewPasswordOptions): Promise<GxrView>

Example

await gxr.views.setPassword({ id: view._id, password: "secret" });
// or use the current view:
await gxr.views.setPassword({ password: "secret" });

gxr.views.setRequireAuth(options)

Toggle "require authentication" on a view. If id is omitted, uses the currently open view. Throws if no view is open.

Types

interface SetViewRequireAuthOptions {
id?: string;
requireAuth: boolean;
}
function setViewRequireAuth({ id, requireAuth }: SetViewRequireAuthOptions): Promise<GxrView>

Example

await gxr.views.setRequireAuth({ id: view._id, requireAuth: true });
// or use the current view:
await gxr.views.setRequireAuth({ requireAuth: true });

gxr.loadView(options)

@deprecated Use gxr.views.load instead.

Types

type LoadViewOptions = {
id: string;
}
function loadView({ id }: LoadViewOptions): Promise<GxrView>

Example

await gxr.loadView({
id: "123",
})

Project

gxr.getProjectId()

Get the current project's id.

Types

function getProjectId(): void

Example

gxr.getProjectId();

gxr.getProjectName()

Get the current project's name.

Types

function getProjectName(): void

Example

gxr.getProjectName();

Version

gxr.getGxrVersion()

Get the current GraphXR version.

Types

function getGxrVersion(): string

Example

gxr.getGxrVersion(); // e.g. "2.15.0"

Settings

gxr.setTipsEnabled(value)

Types

function setTipsEnabled(value: boolean): void

Example

gxr.setTipsEnabled(false);

gxr.setAutoShowImage(value)

Types

function setAutoShowImage(value: boolean): boolean

Example

gxr.setAutoShowImage(true);

gxr.setEdgeScale(value)

Types

function setEdgeScale(value: number): number

Example

gxr.setEdgeScale(0.5);

gxr.setEdgeArrowVisibility(value)

Types

function setEdgeArrowVisibility(value: boolean): boolean

Example

gxr.setEdgeArrowVisibility(true);

gxr.setBlendEdge(value)

Types

function setBlendEdge(value: boolean): boolean

Example

gxr.setBlendEdge(false);

gxr.setAutoCaption(value)

Types

function setAutoCaption(value: boolean): boolean

Example

gxr.setAutoCaption(true);

gxr.setFullscreen(value)

Types

function setFullscreen(value: boolean): boolean

Example

gxr.setFullscreen(true);

gxr.setPinIconVisible(visible)

Types

function setPinIconVisible(visible: boolean): void

Example

gxr.setPinIconVisible(false);

gxr.setAlternateCaption(value)

Types

function setAlternateCaption(value: boolean): boolean

Example

gxr.setAlternateCaption(false);

gxr.setDashline(value)

Types

function setDashline(value: boolean): boolean

Example

gxr.setDashline(false);

gxr.setTheme(theme)

Types

function setTheme(theme: "light" | "dark"): void

Example

gxr.setTheme("light")
gxr.setTheme("dark")

gxr.setUseCurveLine(value)

Types

function setUseCurveLine(value: boolean): boolean

Example

//use curve line
gxr.setUseCurveLine(true)
//use straight line
gxr.setUseCurveLine(false)

gxr.setRelationshipNameVisibility(value)

Types

function setRelationshipNameVisibility(value: boolean): boolean

Example

gxr.setRelationshipNameVisibility(true)

gxr.setGraphMode(value)

Set the graph mode to 2D or 3D.

Types

function setGraphMode(value: string): string

Example

gxr.setGraphMode("2D")
gxr.setGraphMode("3D")

gxr.setCaptionScale(value)

Types

function setCaptionScale(value: number): number

Example

gxr.setCaptionScale(0.5)

Styles

gxr.colorNodesByProperty(options)

Types

type ColorNodesByPropertyOptions = {
category?: string;
property: string;
scale?: string;
colorMap?: Record<string, string>;
}
function colorNodesByProperty(options: ColorNodesByPropertyOptions): void

Example

// Color nodes by property using default scale
gxr.colorNodesByProperty('age');

// Color nodes by property using default scale (object syntax)
gxr.colorNodesByProperty({property: 'age'});

// Color nodes by property using a specific color scale
gxr.colorNodesByProperty({property: 'age', scale: 'BuGn'});

// Color specific property values with custom colors
gxr.colorNodesByProperty({
property: 'type',
colorMap: {
'Person': 'red',
'Company': 'blue',
'Location': 'green'
}
});

// Color nodes by status with hex colors
gxr.colorNodesByProperty({
property: 'status',
colorMap: {
'active': '#00FF00',
'inactive': '#FF0000',
'pending': '#FFA500'
}
});

// Combine color scale with specific value overrides
gxr.colorNodesByProperty({
property: 'category',
scale: 'Viridis',
colorMap: {
'important': '#FF0000' // Override specific values
}
});

gxr.getIcons()

Get a list of available icons

Types

function getIcons(): void

Example

const icons = await gxr.getIcons();

gxr.getIconByName(name)

Get an icon by name

Types

function getIconByName(name: string): void

Example

const icon = await gxr.getIconByName("person");

gxr.setCategoryColor(category, backgroundColor)

Set a category's color by hex

Types

function setCategoryColor(category: CategoryId, backgroundColor: string): void

Example

gxr.setCategoryColor("Person", "#00ff00");

gxr.setCategoryIcon(category, icon)

Set a category's icon

Types

function setCategoryIcon(category: CategoryId, icon: GxrIcon): void

Example

const icon = await gxr.getIconByName("person");
gxr.setCategoryIcon("Person", icon);

gxr.setCategoryIconByName(category, name)

Set a category's icon by name

Types

function setCategoryIcon(category: CategoryId, name: string): void

Example

gxr.setCategoryIconByName("Person", "person");

gxr.setCategoryVisibility(category, visible)

Types

function setCategoryVisibility(category: CategoryId, visible: boolean): void

Example

gxr.setCategoryVisibility("Person", false);

gxr.setRelationshipColor(relationship, color)

Types

function setRelationshipColor(relationship: RelationshipId, color: string): void

Example

gxr.setRelationshipColor("KNOWS", "#00ff00");

gxr.setRelationshipVisibility(relationship, visible)

Types

function setRelationshipVisibility(relationship: RelationshipId, visible: boolean): void

Example

gxr.setRelationshipVisibility("KNOWS", false);

gxr.sizeNodesByProperty(options)

Types

interface SizeNodesByProperty {
category: CategoryId;
property: string;
}
function sizeNodesByProperty({category, property}: SizeNodesByProperty): Promise<unknown>

Example

gxr.sizeNodesByProperty({category: "Person", property: 'age'});

gxr.traceNeighbor(options)

Types

type TraceNeighborOptions = TraverseOptions & {
depth: number;
}
function traceNeighbor(options: TraceNeighborOptions): GraphSelection

Example

gxr.traceNeighbor()

Transform

gxr.aggregate(config)

Pull data to root nodes from their neighborhoods up to a certain depth.

Alias: gxr.aggregate(...) is equivalent to gxr.graph().aggregate(...)

Types

type AggregateFormula = (values: PropertyValue[], options?: AggregateFormulaOptions) => PropertyValue | null
type AggregateFormulaKey = z.infer<typeof AggregateFormulaKeySchema>
type ConcatenateFormulaOptions = z.infer<typeof ConcatenateFormulaOptionsSchema>
type AggregateFormulaOptions = z.infer<typeof AggregateFormulaOptionsSchema>
type AggregateConfig = Omit<z.infer<typeof AggregateConfigSchema>, "formulaFn"> & {
formulaFn?: string | AggregateFormula;
}
type AggregateInputs = z.infer<typeof AggregateInputsSchema>
type AggregateOutputs = z.infer<typeof AggregateOutputsSchema>

Example

gxr.aggregate({
formula: 'sum',
property: "age",
})

gxr.aggregate({
formula: 'concatenate',
separator: ",",
property: "name",
along: "KNOWS",
startNodeId: "A",
depth: 3, // optional. Default is 1
})

gxr.aggregate({
// Formula can also be a function
formula: (values) => values.reduce((a, b) => a + b, 0),
property: "age",
}))

gxr.extract(config)

Alias: gxr.extract(...) is equivalent to gxr.graph().extract(...)

Types

type ExtractConfig = z.infer<typeof ExtractConfigSchema>
type ExtractInputs = z.infer<typeof ExtractInputsSchema>
type ExtractOutputs = z.infer<typeof ExtractOutputsSchema>
interface ExtractProperty {
name: string;
newName?: string;
isSplit?: boolean;
splitChar?: string;
isKey?: boolean;
}

Example

gxr.extract({
sourceCategory: "Episodes",
targetCategory: "Season",
props: [
{
name: "seasonNumber",
isKey: true,
},
{
name: "millionViewers",
},
{
name: "episodeAirDate",
},
],
relationship: "IN_SEASON",
})

gxr.link(config)

Create new edges between nodes which have matching values for the specified property.

Alias: gxr.link(...) is equivalent to gxr.graph().link(...)

Types

type MatchType = "case-insensitive" | "exact" | "function"
type MatchOptions = {
fn?: (valA: unknown, valB: unknown) => boolean; // For function match type
}
type RelationshipDirection = 'any' | 'forward' | 'reverse'
type RelationshipSpec = {
name: string;
direction?: RelationshipDirection;
}
type RelationshipOption = string | RelationshipSpec
type LinkConfig = z.infer<typeof LinkConfigSchema>
type LinkInputs = z.infer<typeof LinkInputsSchema>
type LinkOutputs = z.infer<typeof LinkOutputsSchema>

Example

// Exact match (default)
gxr.link({ sourceProperty: "id", targetProperty: "id" })

gxr.link({
sourceCategory: "Roles",
sourceProperty: "ParentName",
targetCategory: "Roles",
targetProperty: "ComponentName",
relationship: "IS_PARENT_OF"
})

// Case-insensitive match
gxr.link({
sourceCategory: "Person",
targetCategory: "Person",
sourceProperty: "email",
targetProperty: "email",
relationship: "SAME_EMAIL",
match: {
type: "case-insensitive"
}
})


// Custom function match
gxr.link({
sourceCategory: "Product",
targetCategory: "Product",
sourceProperty: "price",
targetProperty: "price",
relationship: "SIMILAR_PRICE",
match: {
type: "function",
options: {
fn: (priceA, priceB) => {
const diff = Math.abs(Number(priceA) - Number(priceB));
return diff <= 10; // Within $10
}
}
}
})

// Bidirectional linking (edges in both directions)
gxr.link({
sourceCategory: "Person",
targetCategory: "Person",
sourceProperty: "id",
targetProperty: "id",
relationship: { name: "CONNECTED", direction: "any" }
})

// Reverse direction (edges go from target to source)
gxr.link({
sourceCategory: "Person",
targetCategory: "Person",
sourceProperty: "id",
targetProperty: "id",
relationship: { name: "CONNECTED", direction: "reverse" }
})

gxr.merge(config)

Combine nodes or edges which have equivalent key properties.

@param options Merge options (category, relationship, keys, etc.)

Alias: gxr.merge(...) is equivalent to gxr.graph().merge(...)

Types

type MergeConfig = z.infer<typeof MergeConfigSchema>
type MergeInputs = z.infer<typeof MergeInputsSchema>
type MergeOutputs = z.infer<typeof MergeOutputsSchema>

Example

gxr.merge({
keys: ['seasonNumber'],
})

gxr.merge({
category: "Episode",
keys: ['seasonNumber'],
})

// Combine all emails between two persons sent on the same day (thus removing directionality)
gxr.merge({
relationship: "SENT_MAIL_TO"
keys: ['sendDate'],
})

// Combine all emails between two persons sent on the same day and preserve directionality
gxr.merge({
relationship: "SENT_MAIL_TO"
keys: ['sendDate'],
directional: true,
})

gxr.mergeNodes(options)

Create new nodes, or update existing nodes, based on the specified key properties.

Alias: gxr.mergeNodes(...) is equivalent to gxr.graph().mergeNodes(...)

Types

interface MergeNodesOptions {
category?: CategoryId;
keys?: string[];
data?: Properties[],
}
function mergeNodes(options: MergeNodesOptions): TransformFunction

Example

gxr.mergeNodes({
data: [{ name: "Flo", age: 32 }],
category: "Person",
keys: ["name"]
})

gxr.mergeRelationships(options)

Create new edges, or update existing edges, based on the specified key properties.

Alias: gxr.mergeRelationships(...) is equivalent to gxr.graph().mergeRelationships(...)

Types

type MergeRelationshipsData = {
source: Properties;
edge: Properties;
target: Properties;
}
interface MergeRelationshipsOptions {
source?: {
category: CategoryId;
keys?: string[];
};
edge: {
relationship: RelationshipId;
keys: string[];
};
target?: {
category: CategoryId;
keys?: string[];
};
data: MergeRelationshipsData[];
}
function mergeRelationships(options: MergeRelationshipsOptions): TransformFunction

Example

gxr.mergeRelationships({
data: [
{ source: {name: "Flo"}, edge: {since: 2010}, target: {name: "Aiden"} },
{ source: {name: "Flo"}, edge: {since: 2010}, target: {name: "Georgio"} },
],
source: { category: "Person", keys: ["name"] },
edge: { relationship: "KNOWS", keys: ["SINCE"] },
target: { category: "Person", keys: ["name"] },
})

gxr.quickInfoEnabled(enabled)

Enables/disables quick info

Types

function quickInfoEnabled(enabled: boolean): void

Example

gxr.quickInfoEnabled(true);

gxr.showQuickInfo(node)

Shows the quick info panel for the given node.

Types

function showQuickInfo(node: GxrNode): void

Example

gxr.showQuickInfo(gxr.nodes().at(0));

gxr.hideQuickInfo()

Hides the quick info panel

Types

function hideQuickInfo(): void

Example

gxr.showQuickInfo(gxr.nodes().at(0));

gxr.shortcut(config)

Given R1, B, and R2, Shortcut finds all unique paths from node A to node C, traveling first along R1, passing through B (center category), and travelling lastly through R2 to arrive at C. Once it finds all unique paths from A to C, Shortcut creates an edge A -> C (or C -> A if R3.direction is 'reverse') with properties aggregated from the center nodes.

More simply, A -R1-> [B] -R2-> C => A -R3-> C where R1 is the first relationship, B is centerCategory, R2 is the second relationship, and R3 is the new relationship. [B] means the set of all nodes B which are between A and C.

Options:

  • A (optional): constrain source nodes to this category
  • C (optional): constrain target nodes to this category
  • B (required): the center category

Direction options for R1, R2:

  • 'any' (default): follow edges regardless of direction
  • 'forward': only follow edges in their natural direction (source → target)
  • 'reverse': only follow edges in reverse direction (target ← source)

If antisymmetric is true, then if A-B-C, only A->C will be created in some total order (default by node.index ascending).

Alias: gxr.shortcut(...) is equivalent to gxr.graph().shortcut(...)

Types

type AggregateProperty = {
sourceProperty: string;
targetProperty?: string;
formula: AggregateFormulaKey;
formulaFn?: string | AggregateFormula;
}
type ShortcutConfig = z.infer<typeof ShortcutConfigSchema>
type ShortcutInputs = z.infer<typeof ShortcutInputsSchema>
type ShortcutOutputs = z.infer<typeof ShortcutOutputsSchema>

Example

shortcut({
A: 'Person',
R1: { name: 'IS_PARENT_OF', direction: 'forward' },
B: 'Node',
R2: { name: 'IS_PARENT_OF', direction: 'forward' },
C: 'Person',
R3: "IS_GRANDPARENT_OF",
antisymmetric: true,
aggregate: [
{
sourceProperty: "age",
targetProperty: "averageAge",
formula: "average",
},
],
countPaths: false,
})

Traversal

gxr.traverse(options)

Types

function traverse(options?: TraverseOptions): void

Example

for (const {node, edge, depth} of gxr.traverse({ startNodeId: "A", depth: 3 })) {
console.log(node, edge, depth);
}

Expand

gxr.expandFromDatabase()

Expand nodes by querying the database for their neighbors and adding the results to the graph. When nodeIds is not passed, expands from all nodes in the graph. Use gxr.nodes({...}).expandFromDatabase() to expand from filtered nodes.

Alias for gxr.graph().expandFromDatabase().

See also gxr.nodes().expandFromDatabase().

Alias: gxr.expandFromDatabase(...) is equivalent to gxr.graph().expandFromDatabase(...)

Example

// Expand all nodes in the graph
await gxr.expandFromDatabase();

// Expand specific nodes
await gxr.nodes(["1", "2", "3"]).expandFromDatabase();

// Expand along specific relationship types only
await gxr.expandFromDatabase({ relationships: ["KNOWS", "WORKS_AT"] });

// Expand with limit and direction
await gxr.expandFromDatabase({ relationships: ["KNOWS"], limit: 100, direction: "from" });

// Multi-hop expansion
await gxr.expandFromDatabase({ hops: 3, limit: 500 });

// Only expand between specified nodes
await gxr.expandFromDatabase({ onlyBetweenSelected: true, relationships: ["KNOWS"] });

// Page through results
let result = await gxr.expandFromDatabase({ limit: 100 });
while (result.hasMore) {
result = await gxr.expandFromDatabase({ limit: 100, skip: result.nextSkip });
}

UI

gxr.addContextMenuItem(item, options)

Add a custom menu item to the context menu.

Types

function addContextMenuItem(item: ContextMenuItem, {parent, after, index}: AddMenuItemOptions = {}): ContextMenuItem

Example

gxr.addContextMenuItem({
name: "Find Similar",
text: "Find Similar",
icon: "iconfont icon-similar",
hide: () => false,
enable: () => true,
action: (name, nodeId, edgeId, props) => {
console.log("Finding similar to", name, nodeId, edgeId, props);
},
})

Utility

gxr.dispatchGraphDataUpdate()

Force the UI to update. Sometimes necessary when using the API to update the graph.

Types

function dispatchGraphDataUpdate(): void

Example

gxr.dispatchGraphDataUpdate();

gxr.randomId()

Types

function makeRandomId(): string

Example

gxr.randomId() -> "lijfsleifjzlse";

gxr.sleep(ms)

Types

function sleep(ms: number): Promise<number>

Example

gxr.sleep(1000);

gxr.snapshot()

Get the graph as JSON, or apply a JSON snapshot to the current graph.

Alias: gxr.snapshot(...) is equivalent to gxr.graph().snapshot(...)

Example

// Get snapshot
const mySnapshot = gxr.snapshot()

// Apply snapshot
gxr.snapshot(mySnapshot)

gxr.vector(...args)

Types

function vector(
...args: unknown[]
): Vector2 | Vector3 | Vector4 | undefined

Example

gxr.vector() -> Vector3 {x: 0, y: 0, z: 0}
gxr.vector(1) -> undefined
gxr.vector(1, 2) -> Vector2 {x: 1, y: 2}
gxr.vector({x: 1, y: 2, z: 3}) -> Vector3 {x: 1, y: 2, z: 3}
gxr.vector([1, 2, 3]) -> Vector3 {x: 1, y: 2, z: 3}
gxr.vector(1, 2, 3) -> Vector3 {x: 1, y: 2, z: 3}
gxr.vector({x: 1, y: 2, z: 3, w: 4}) -> Vector4 {x: 1, y: 2, z: 3, w: 4}

User

gxr.getCurrentUser()

Types

function getCurrentUser(): CurrentUser

Example

const currentUser = gxr.getCurrentUser();
console.log(currentUser);

Undo / Redo

gxr.undo()

Types

function undo(): void

Example

gxr.undo();

gxr.redo()

Types

function redo(): void

Example

gxr.redo();

LLM

gxr.embed(inputMaybe, options)

Types

type EmbedOptions = | ({
provider: "transformerjs";
}
function embed(
inputMaybe: string | string[],
options: EmbedOptions = { provider: "gxr" },
): void

Example

// Call default embedding model with a string. Result is a vector.
const vector = await gxr.embed("Hello, world!");

// Call default embedding model with an array of strings. Result is an array of vectors.
const vector = await gxr.embed(["Hello, world!"]);

// Call local Ollama.
const vector = await gxr.embed(input, {provider: "ollama"});

// Call default embedding model configured in GraphXR backend.
const vector = await gxr.embed(input, {provider: "gxr"});

// Call a specific embedding model using the default LLM provider.
const vector = await gxr.embed(input, {provider: "gxr", model: "text-embedding-3-large"});

// Call a specific embedding model using a specific LLM provider.
const vector = await gxr.embed(input, {provider: "gxr", model: "text-embedding-3-small", llm: "my_openai"});

// Call a remote embedding model by providing config.
const vector = await gxr.embed(input, {provider: "gxr", model: "text-embedding-3-small", config: {provider: "openai", baseUrl: "https://api.openai.com/v1", apiKey: "sk-..."}})

gxr.llm(options)

Types

type ChatResponseSchema = {
type: string;
properties: Record<string, unknown>;
required?: string[];
additionalProperties?: boolean;
}
type OllamaResponseFormat = {
type: string;
properties?: {};
}
type ResponseFormat = OpenAIResponseFormat | OllamaResponseFormat
interface ChatMessage {
role: "system" | "user" | "assistant";
content: string;
}
interface LLMConfig {
name?: string;
provider?: string;
baseUrl?: string;
apiKey?: string;
organization?: string;
deployment?: string;
apiVersion?: string;
model?: string;
isLocal?: boolean;
}
interface OpenAIResponseFormat {
type: string;
json_schema?: {
name: string;
strict: boolean;
schema: ChatResponseSchema;
};
}
interface ChatOptions {
messages: ChatMessage[];
/**
* e.g. my_ollama
*/
llm?: string;
/**
* e.g. llama3.2
*/
model?: string;
/**
* config defines the provider and model, in case it's not defined on the server.
* e.g. { provider: 'ollama', model: 'llama3.2', baseUrl: 'http://localhost:11434' }
* optionally provide isLocal: true to call the LLM from your browser instead of GraphXR's backend.
*/
config?: LLMConfig;
stream?: boolean;
/**
* isTest is used by the admin portal to test run the LLM before adding it to the database.
*/
isTest?: boolean;
temperature?: number;
template?: string;
response_format?: ResponseFormat;
format?: ResponseFormat;
schema?: ChatResponseSchema;
injectGraphSchema?: boolean;
onStream?: (content: string) => void;
onError?: (error: string) => void;
onDone?: () => void;
}
function llmChat(options: ChatOptions): Promise<ChatMessage | null>

Example

const response = await gxr.llm({
messages: [{role: 'user', content: 'Hello, how are you?'}],
});
console.log(response);

gxr.ask(query, options)

Types

type AskOptions = Omit<ChatOptions, "messages"> & {
systemPrompt?: string;
}
function llmAsk(query: string, options: AskOptions = {}): void

Example

const response = await gxr.ask(
'Hello, how are you?',
);
console.log(response);

const response = await gxr.ask(
JSON.stringify(gxr.nodes("[[selected]]").properties()),
{
systemPrompt: 'Summarize the context.',
},
);
console.log(response);

Chat

gxr.chat

Chat API for managing conversation threads.

Example

// List all threads
const threads = gxr.chat.listThreads();

// Create a new thread
const newThread = gxr.chat.createThread("My Chat");

// Get messages from current thread
const messages = gxr.chat.getCurrentThread().messages;

// Add a message to the current thread
gxr.chat.addMessage(gxr.chat.getCurrentThreadId(), {
id: Date.now().toString(),
content: "Hello, AI!",
role: "user",
timestamp: Date.now()
});

Agent

gxr.agent

Agent helper APIs for attachment handling in chat UIs.

Example

const fileRef = await gxr.agent.attachFile("/notes/todo.md");
const screenshot = await gxr.agent.captureCanvasScreenshot();
const input = gxr.agent.buildMessageInput("Please summarize", [fileRef, screenshot]);

gxr.getDatabaseSchema()

Get schema from the connected database. Returns null if no database schema is available.

Types

interface GraphSchema {
nodes: NodeSchema[];
relationships: RelationshipSchema[];
}
interface NodeSchema {
label: string;
properties: PropertySchema[];
}
interface RelationshipSchema {
label: string;
sourceNodeLabel: string;
targetNodeLabel: string;
properties: PropertySchema[];
}
interface PropertySchema {
name: string;
type: 'string' | 'number' | 'boolean' | 'date';
isPrimaryKey?: boolean;
enum?: string[];
}
interface Neo4jMetaData {
labels: Record<string, {
keys: string[];
keysTypes: Record<string, string>;
name: string;
props: string[] | Record<string, string>;
propsTypes: Record<string, string>;
}>;
relationships: Record<string, {
endCategory: string;
keys: string[];
keysTypes: Record<string, string>;
name: string;
props: string[] | Record<string, string>;
propsTypes: Record<string, string>;
startCategory: string;
}>;
schema: {
labels: string[];
relationships: string[];
maps: Record<string, any>;
};
}
function getDatabaseSchema(): GraphSchema | null

Example

const schema = gxr.getDatabaseSchema();
if (schema) {
console.log(schema.nodes); // [{label: "Person", properties: [...]}]
console.log(schema.relationships); // [{label: "KNOWS", sourceNodeLabel: "Person", targetNodeLabel: "Person", properties: [...]}]
}

gxr.database

Database operation APIs

Prefer gxr.query(query, {saveToGraph: false}) instead of gxr.database.query(query).

Example

// Get database schema
const schema = await gxr.database.getSchema();

// Execute query
const results = await gxr.database.query("MATCH (n:Person) RETURN n LIMIT 10");

Info Panel

gxr.showNodeInfoPanel(nodeId)

Types

function showNodeInfoPanel(nodeId: string): void

Example

gxr.showNodeInfoPanel("A");

gxr.showEdgeInfoPanel(edgeId)

Types

function showEdgeInfoPanel(edgeId: string): void

Example

gxr.showEdgeInfoPanel("AB");

Tour

gxr.driver(options)

A wrapper for driver.js.

Types

function driver(options?: unknown): void

Example 1

// Create a simple tutorial with multiple steps
// The 'element' option accepts: CSS selector string, HTMLElement, or function
const tutorial = gxr.driver.createTutorial({
id: 'my-tutorial',
showProgress: true,
allowClose: true,
steps: [
{
element: '#menu-project', // CSS selector string
title: 'Project Menu',
description: 'Click here to open the project menu',
side: 'left',
align: 'start',
advanceOnError: true,
},
{
element: '.tour-extensions', // CSS selector string
title: 'Extension Tab',
description: 'Click here to view extensions',
side: 'top',
align: 'start',
advanceOnError: true,
},
],
});

// Run the tutorial
gxr.driver.runTutorial(tutorial);

Example 2

// All steps automatically use clickable proxies (transparent to user)
// Use a function for custom element finding
const tutorial = gxr.driver.createTutorial({
id: 'button-tutorial',
steps: [
{
element: (doc) => doc.querySelector('.my-button'), // Function
proxyId: 'my-button-proxy', // Optional: custom proxy ID
title: 'Click This Button',
description: 'Click the button to continue',
autoAdvance: false,
finishOnComplete: true,
},
],
});

gxr.driver.runTutorial(tutorial);

Example 3

// Create a tutorial with custom element finder (for iframes, etc.)
const findMyElement = (doc) => {
const iframe = doc.querySelector('iframe.share-extension-iframe');
const iframeDoc = iframe?.contentDocument || iframe?.contentWindow?.document;
return iframeDoc?.querySelector('.target-element') || null;
};

const tutorial = gxr.driver.createTutorial({
id: 'custom-finder-tutorial',
steps: [
{
element: findMyElement, // Custom function
title: 'Custom Element',
description: 'This element is found using a custom function',
},
],
});

gxr.driver.runTutorial(tutorial);

Path Finding

gxr.dijkstra(...args)

Example

// Find the shortest path between nodes A and B, and select the nodes in the path
const paths = gxr.dijkstra("A", "B");
gxr.graph(paths).nodes().select()

gxr.yens(...args)

Example

// Find k shortest paths between nodes A and B, and select the nodes in the paths
const paths = gxr.yens("A", "B");
gxr.graph(paths).nodes().select()

Canvas

gxr.isCanvasLoaded()

Types

function isCanvasLoaded(): boolean

Example

gxr.isCanvasLoaded();

gxr.onCanvasLoaded()

Example

gxr.onCanvasLoaded(() => {
console.log("Canvas loaded");
});

gxr.screenshot(options)

Take a screenshot of the graph canvas.

Do not use hidePanels option. Use include* options instead.

Options:

  • frameNodes (default: true) — fly out to frame all nodes before capturing
  • hidePanels (default: false) — DEPRECATED! Use include* options instead.
  • includeTitleBar (default: false) — include the title bar
  • includeLeftGroup (default: false) — include the left sidebar group
  • includeNavigationTools (default: false) — include the navigation tools
  • includeTools (default: false) — include the bottom toolbar
  • includeExportButton (default: false) — include the export dropdown button
  • includeCategoryStylesButtons (default: false) — include the category styles (paint brush) buttons
  • includeLegends (default: true) — include GraphXR legends (Category, Tag, Property, Relationship)
  • includeFloatingPanels (default: false) — include floating panels (e.g. workspace panels)
  • includeContextMenu (default: false) — include the right-click context menu
  • includeInfoPanel (default: true) — include the node/edge info panel
  • ignoreSelectors — additional CSS selectors whose matching elements should be excluded
  • quality (default: 1.0) — image quality for JPEG format (0-1)
  • format (default: 'png') — output image format ('png' | 'jpeg')

Types

interface ScreenshotOptions {
/**
* Whether to call flyOut() to frame all nodes before taking the screenshot
* @default true
*/
frameNodes?: boolean;

/**
* Whether to hide all UI panels. When true, overrides all include* options to false.
* @default false
*/
hidePanels?: boolean;

/**
* Whether to include the title bar in the screenshot
* @default false
*/
includeTitleBar?: boolean;

/**
* Whether to include the left sidebar group in the screenshot
* @default false
*/
includeLeftGroup?: boolean;

/**
* Whether to include the navigation tools in the screenshot
* @default false
*/
includeNavigationTools?: boolean;

/**
* Whether to include the bottom toolbar in the screenshot
* @default false
*/
includeTools?: boolean;

/**
* Whether to include the export dropdown button in the screenshot
* @default false
*/
includeExportButton?: boolean;

/**
* Whether to include the category styles (paint brush) buttons in the screenshot
* @default false
*/
includeCategoryStylesButtons?: boolean;

/**
* Whether to include GraphXR legends (Category, Tag, Property, Relationship) in the screenshot
* @default true
*/
includeLegends?: boolean;

/**
* Whether to include floating panels (e.g. workspace panels) in the screenshot
* @default false
*/
includeFloatingPanels?: boolean;

/**
* Whether to include the right-click context menu in the screenshot
* @default false
*/
includeContextMenu?: boolean;

/**
* Whether to include the node/edge info panel in the screenshot
* @default true
*/
includeInfoPanel?: boolean;

/**
* Additional CSS selectors whose matching elements should be excluded from the screenshot.
* These are appended to the selectors derived from the include* options.
*/
ignoreSelectors?: string[];

/**
* Image quality for JPEG format (0-1)
* @default 1.0
*/
quality?: number;

/**
* Output image format
* @default 'png'
*/
format?: 'png' | 'jpeg';
}
function screenshot(options: ScreenshotOptions = {}): Promise<Blob>

Example

// Basic usage - frames all nodes and captures canvas only (no UI panels)
const blob = await gxr.screenshot();

// Capture with specific UI elements visible
const blob = await gxr.screenshot({
frameNodes: true,
includeLegends: true,
includeInfoPanel: true,
includeTitleBar: true,
});

// Canvas-only screenshot as JPEG with custom quality
const blob = await gxr.screenshot({
frameNodes: false,
format: 'jpeg',
quality: 0.8,
});

// Exclude specific elements by CSS selector
const blob = await gxr.screenshot({
ignoreSelectors: ['.my-custom-overlay', '#watermark'],
});

// Download the screenshot
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'graph-screenshot.png';
link.click();
URL.revokeObjectURL(url);

Workspace

gxr.workspace

Workspace API for managing panel registrations and state.

Example

// Register a panel
gxr.workspace.registerPanel({
id: "transform.extract",
target: "transform",
title: "Extract",
render: () => <ExtractPanel />
});

// Get panels for a target
const transformPanels = gxr.workspace.usePanelsByTarget('transform');

// Get a specific registration
const reg = gxr.workspace.getPanelRegistration('transform.extract');