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());
Navigation
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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.graph().addEdges(...)
Example
gxr.addEdges([{ sourceId: "A", targetId: "B" }, { sourceId: "B", targetId: "C" }]);
gxr.clear()
Clear the graph
Alias:
gxr.clear(...)is equivalent togxr.graph().clear(...)
Example
gxr.clear();
gxr.edges(options)
Alias:
gxr.edges(...)is equivalent togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 togxr.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 capturinghidePanels(default: false) — DEPRECATED! Useinclude*options instead.includeTitleBar(default: false) — include the title barincludeLeftGroup(default: false) — include the left sidebar groupincludeNavigationTools(default: false) — include the navigation toolsincludeTools(default: false) — include the bottom toolbarincludeExportButton(default: false) — include the export dropdown buttonincludeCategoryStylesButtons(default: false) — include the category styles (paint brush) buttonsincludeLegends(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 menuincludeInfoPanel(default: true) — include the node/edge info panelignoreSelectors— additional CSS selectors whose matching elements should be excludedquality(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');