Table of Contents

1. Virtual properties in the Detail tab

Virtual properties in visualization can be created or modified in the Detail tab. Virtual properties are small javascript functions (called formulas) that can be used to create properties based on values stored in an element or in the elements in its neighborhood. This formula has to return a single value (string or number) which represents the value of this virtual property for the particular element.

1.1. Create or unhide virtual property (1)

With this menu, you can create a new virtual property that will be created on every element (nodes, relationships, or merged relationships). With this menu, you can also hide and unhide hidden virtual properties.

1.2. Edit, hide or delete virtual property (2)

With this menu, you can

  • edit virtual property (change title or formula) or 

  • hide virtual property (it will be not shown in the Virtual properties list but you can unhide it anytime) or

  • delete virtual property (it will no longer be available and you can't restore it)

2. Creating a virtual property

Virtual property is created for every element in a group. Group is formed by nodes, relationships, merged relationships, and direction merged relationships. So when you create a virtual property on the Detail tab of a node, this property is added to every node in the visualization.

When creating a virtual property:

  • define a title for property (mandatory)

  • define formula (mandatory). Only valid formulas can be created - you can test your formula with the Test formula button. You can write your own formula or you can insert one of the built-in formula templates and change it to suit your purpose.

2.1. Context of a virtual property

Every group of elements has a different context when creating a virtual property. Context is a set of variables available in the formula by default. The formula, that is entered in the modal window is evaluated using this syntax:

function (context_var_1, context_var_2, ...){
...your formula...
}

2.1.1. Node's virtual property context

Virtual property on a node can use these variables in the virtual property's code:

  • node: an object with node's data. When you want to use a particular DB property of this node in the formula, use syntax node.data.name_of_property.

  • nodes: an array of node objects connected to the node for which the virtual property is being calculated.

  • edges: array of objects with data of node's relationships (all relationships in node's neighborhood). When you want to use a particular DB property of the first relationship in the formula, use edges[0].data.name_of_property.

  • numOfHiddenRelationships: number of all node's relationships stored in DB (incoming or outgoing) minus the number of node's relationships already in visualization

2.1.2. Relationship's virtual property context

Virtual property on a relationship can use these variables in the virtual property's code:

  • edge: an object with relationship's data. When you want to use a particular DB property of a relationship in the formula, use edge.data.name_of_property.

  • source: relationship's source (start) node. When you want to use a particular DB property of the source (start) node in the formula, use source.data.name_of_property.

  • target: relationship's target (end) node. When you want to use a particular DB property of the target (end) node in the formula, use target.data.name_of_property.

2.1.3. Merged relationship's virtual property context

Virtual property on a merged relationship can use these variables in the virtual property's code:

  • edges: array of objects with data of relationships that are merged to a particular merged relationship. When you want to use a particular DB property of the first relationship in the formula, use edges[0].data.name_of_property.

  • source: relationship's source (start) node. When you want to use a particular DB property of the source (start) node in the formula, use source.data.name_of_property.

  • target: relationship's target (end) node. When you want to use a particular DB property of the target (end) node in the formula, use target.data.name_of_property.

2.1.4. Direction merged relationship's virtual property context

Virtual property on a direction merged relationship can use these variables in the virtual property's code:

  • edges: array of objects with data of relationships that are merged to a particular merged relationship. When you want to use a particular DB property of the first relationship in the formula, use edges[0].data.name_of_property.

  • source: relationship's source (start) node. When you want to use a particular DB property of the source (start) node in the formula, use source.data.name_of_property.

  • target: relationship's target (end) node. When you want to use a particular DB property of the target (end) node in the formula, use target.data.name_of_property.

2.2. Data structures of graph elements

Every graph element in the virtual property context is represented by a JS object that contains

  • System properties - calculated by Graphlytic of by the rendering library (Cytoscape.js). The full list of System properties is in the table below.

  • Database properties - properties loaded from the graph database

System properties:

Property

Values

Description

group

"nodes", "edges"

Cytoscape.js group property.

position

Object

Cytoscape.js position object. Contains "x" and "y" position values.

This property exists only for nodes. When the position is updated the virtual property is not recalculated.

data

Object

Cytoscape.js data object.

data.id

String

Cytoscape.js element ID.

data.source

String

Cytoscape.js relationship's source node ID. Exists only for relationships.

data.target

String

Cytoscape.js relationship's target node ID. Exists only for relationships.

data._dbId

String

Element ID in the graph database. Exists only for nodes and unmerged relationships.

data._gl_group

"nodes", "edges",

"mergedEdges",

"dirMergedEdges"

Graphlytic group of the elements. 

data._dbLabels

Array

An array of node's labels (strings) in the graph database. Exists only for nodes.

data._dbRelType

String

Relationship type from the graph database. Exists only for relationships.

data._created

Number (epoch ms)

Created by Graphlytic when the element is created using the UI or import features of Graphlytic.

data._updated

Number (epoch ms)

Created/updated by Graphlytic every time when the element is updated using the UI or import features of Graphlytic.

data._numOfHiddenRelationships

Number

System property calculated by Graphlytic representing the number of not rendered relationships (_numOfHiddenRelationships = _numOfRelations - <number of rendered relationships>).

Exists only for nodes.

data._numOfRelatedNodes

Number

The number of node's related nodes in the graph database.

Exists only for nodes.

data._numOfRelations

Number

The number of node relationships (incoming and outgoing) in the graph database.

Exists only for nodes.

2.2.1. Example data structure of a node

An example data structure of a node:

{
"group":"nodes",
"data":{
"id":"0",
"_dbId":"0",
"_gl_group":"nodes",
"_dbLabels":["node_label_1", "node_label_2"],
"_created":1607958614713,
"_updated":1615797599879
"_numOfHiddenRelationships":0,
"_numOfRelatedNodes":9,
"_numOfRelations":9,
<prop_1>: <value_1>,
...
<prop_n>: <value_n>
},
"position":{
"x":-11.266923121409485,
"y":-39.89026192275111
}
}

2.2.2. Example data structure of a relationship

An example data structure of a relationship:

{
"group":"edges",
"data":{
"id":"edge0",
"source":"0",
"target":"6",
"_dbId":"0",
"_gl_group":"edges",
"_dbRelType":"FREE",
"_created":1608450451999,
"_updated":1608477685120,
<prop_1>: <value_1>,
...
<prop_n>: <value_n>
}
}

2.2.3. Example data structure of a direction merged relationship

An example data structure of a direction merged relationship:

{
"group":"edges",
"data":{
"id":"dme_0_2",
"source":"0",
"target":"2",
"_gl_group":"dirMergedEdges",
"<prop_1>":"<value_1>",
...
"<prop_n>":"<value_n>"
}
}

2.2.4. Example data structure of a merged relationship

An example data structure of a merged relationship:

{
"group":"edges",
"data":{
"id":"me_0_2",
"source":"0",
"target":"2",
"_gl_group":"mergedEdges",
"<prop_1>":"<value_1>",
...
"<prop_n>":"<value_n>"
}
}

3. Graph API

For more advanced cases there’s a Graph API available in the virtual property’s context. This API can be used to traverse the graph and access graph elements by their IDs. This gives great flexibility but can be more performance demanding.

3.1. Method “Model.getNodeById(nodeId)”

Returns node from the Model based on its ID value.

Example:

let someNode = Model.getNodeById(nodeId);

3.2. Method “Model.getEdgeById(edgeId)”

Returns edge (relationship) from the Model based on its ID value.

Example:

let someEdge = Model.getEdgeById(edgeId);

3.3. Method “Model.getNodeNeighbors(nodeId, direction)”

Returns nodes from the Model that are connected to a specific node identified by its node ID value.

A direction can be specified to get only outgoing, incoming, or both types of nodes. Available values for direction are:

  • “IN” - returns only nodes with relationships ending in the nodeId node.

  • “OUT” - returns only nodes with relationships starting in the nodeId node.

  • “BOTH” or undefined - returns all neighboring nodes of the nodeId node.

Example:

let neighbors = Model.getNodeNeighbors(nodeId, "BOTH");

3.4. Method “Model.getNodeRelationships(nodeId, direction)”

Returns relationships from the Model that are connected to a specific node identified by its node ID value.

A direction can be specified to get only outgoing, incoming, or both types of relationships. Available values for direction are:

  • “IN” - returns only relationships that end in the nodeId node.

  • “OUT” - returns only relationships that start in the nodeId node.

  • “BOTH” or undefined - returns all relationships connected to the nodeId node.

Example:

let neighbors = Model.getNodeRelationships(nodeId, "BOTH");

4. Examples

4.1. Title by node labels

If you want to, for instance, use different property values as titles of nodes for different node labels, you can create a virtual property on nodes (example below) and then use this virtual property as the node title to show the values in the visualization.

for (var i = 0; i < node.data._dbLabels.length; i++){
var label = node.data._dbLabels[i];
switch (label){
case "Person":
return node.data.name;
break;
case "Company":
return node.data.title;
break;
case "Address":
return node.data.street + ", " + node.data.city;
break;
default:
return node.data.uuid;
}
}

4.2. Average of property values

This formula can be used to calculate an average value of some property stored on the relationships of a node. This virtual property can be then used for styling the nodes in the visualization, e.g. size or color can be linearly mapped to numerical intervals.

if (edges == undefined || edges.length == 0){return 0;}
var sum = 0;
var count = 0;
for (var i = 0; i < edges.length; i++){
var edge = edges[i];
var value = parseFloat(edge.data.property);
if (!isNaN(value)){
sum += value;
count++;
}
}
var avg = sum/count;
return avg;