Reference

GraphXR API Reference

Camera

flyToCenter

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

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

flyToPosition

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

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

flyOut

Zoom out until all nodes are visible

gxr.flyOut();

setCameraOptions

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

setCameraRotating

gxr.setCameraRotating(true);

Captions

captionNodesByProperties

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

Events

onGraphDataUpdate

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

onSelect

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

Graph

add

Add nodes and edges to the graph.

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"

clear

Clear the graph

gxr.clear();

edges

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);

getCategoryConfig

gxr.getCategoryConfig('Person');

getNode

gxr.getNode("A")

getRelationshipConfig

gxr.getRelationshipConfig("RELATED_TO");

graph

// Add a node with id "A"
gxr.graph().add("A");
 
// Select nodes in shortest path from A -> B, including A and B
gxr.graph().shortestPath("A", "B").nodes().select()
 
// 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 }
  );

makeGraph

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

nodes

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);

randomGraph

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

select

gxr.select('age > 30')

Layout

alignBy

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

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

circle

All the nodes spread on a circle

gxr.circle();

cube

All the nodes spread on a cube.

gxr.cube();

distributionBy

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).

// Distribute nodes on the x-axis by a property
gxr.distributionBy('similarity')
 
// Equally space Nodes on the x-axis
gxr.distributionBy({
  dimension: 'x', // y, or z
})
 
// Equally space Nodes on the x-axis and bin the Nodes by "seasonNumber"
gxr.distributionBy({
  bin: 'seasonNumber',
  dimension: 'x',
})
 
// Equally space Nodes on the x-axis and bin the Nodes by "seasonNumber" in descending order
gxr.distributionBy({
  bin: 'seasonNumber',
  dimension: 'x',
  reverse: true,
})

ego

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].

gxr.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
}))

grid

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

gxr.grid();

line

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

gxr.line();

parametric

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.

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
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.
gxr.parametric({
  x: 'seasonNumber',
  reverse: true,
})
 
// Linearly scale seasonNumber, episodeNumber, and millionViewers on the x, y, and z dimensions respectively
gxr.parametric({
  x: 'seasonNumber',
  y: 'episodeNumber',
  z: 'millionViewers',
})

rotate

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.

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

scale

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

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

scatter

Set each node to a random point.

gxr.scatter()

shift

Add a constant vector to the position of each node.

gxr.shift({
  x: 1,
})

setParametricAxesOptions

gxr.setParametricAxesOptions({
  showAxes: false,
})

spiral

All the nodes spread on a spiral

gxr.spiral()

forceLayout

Run a force layout on the graph.

// Run force layout
gxr.forceLayout();

Neo4j

neo4j

 nodes(): IterableNodes;
gxr.neo4j("MATCH (n) RETURN n LIMIT 10");

Settings

setTipsEnabled

gxr.setTipsEnabled(false);

setAutoShowImage

gxr.setAutoShowImage(true);

setEdgeScale

gxr.setEdgeScale(0.5);

setFullscreen

gxr.setFullscreen(true);

setPinIconVisible

gxr.setPinIconVisible(false);

setTheme

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

Styles

colorNodesByProperty

gxr.colorNodesByProperty('age');
gxr.colorNodesByProperty({property: 'age'});
gxr.colorNodesByProperty({property: 'age', scale: 'BuGn'});

getIcons

Get a list of available icons

const icons = await gxr.getIcons();

getIconByName

Get an icon by name

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

setCategoryColor

Set a category's color by hex

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

setCategoryIcon

Set a category's icon

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

setCategoryIconByName

Set a category's icon by name

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

setCategoryVisibility

gxr.setCategoryVisibility("Person", false);

setRelationshipColor

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

setRelationshipVisibility

gxr.setRelationshipVisibility("KNOWS", false);

sizeNodesByProperty

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

Transform

aggregate

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

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),
  ...
}))

extract

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

link

Create new edges between nodes which have the same value for the specified property.

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

merge

Combine nodes or edges which have equivalent key properties.

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,
})

mergeNodes

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

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

mergeRelationships

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

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"] },
})

quickInfoEnabled

Enables/disables quick info

gxr.quickInfoEnabled(true);

showQuickInfo

Shows the quick info panel for the given node.

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

hideQuickInfo

Hides the quick info panel

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

shortcut

Convert A -> B -> C to A -> C

gxr.shortcut({
  incoming: 'IS_PARENT_OF',
  center: 'Node',
  outgoing: 'IS_PARENT_OF',
  shortcut: "IS_GRANDPARENT_OF",
  directional: true,
  aggregate: [
    {
      sourceProperty: "age",
      targetProperty: "averageAge",
      formula: "average",
    },
  ],
  countLinks: false,
})

Traversal

traverse

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

UI

addContextMenuItem

Add a custom menu item to the context menu.

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

dispatchGraphDataUpdate

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

gxr.dispatchGraphDataUpdate();

randomId

gxr.randomId() -> "lijfsleifjzlse";

sleep

gxr.sleep(1000);

snapshot

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

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

vector

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}