Graph Layout

29 min read

Introduction

Graph layouts are the algorithms arranging the node positions to obtain a understandable visualizaiton. According to the differences of data strucutre, the layouts can be categorized into: general graph layout and tree graph layout. There are several layout algorithms for them respectively. By utilizing the built-in layouts, Translating the layouts and their configurations, translating the data can be achieved. Besides, G6 provides the Web-Worker for general graph layout in case layout calculation takes too long to block page interaction.

Besides, G6 supports Custom Layout mechanism for users to design their own layout algorithm.

In fact, 'layout' is a free mechanism in G6. The built-in layouts only calculate and manipulate the x and y in node data. In other word, users can assign x and y to nodes by any other ways including the algorithms from the third-party libraries. Once G6 find the x and y information on data, it will render the graph according to it.

In this ducoment, we will introduce the layout algorithms in detail.

G6 Layouts Overview

Configure the Graph

Configure layout to the Graph instance to assign the layout methods and their configurations. The following code assigns the layout with type: 'force', which means the classical force-directed layout algorithm. The configurations preventOverlap: true and nodeSize: 30 are assigned to prevent node overlappings, where the nodeSize is used for collide detection. More layout configurations can be found in the following sections.

const graph = new G6.Graph({
  // ...                      // Other configurations for the graph
  layout: {
    // Object, the layout configuration. Random layout by default
    type: 'force',
    preventOverlap: true,
    nodeSize: 30,
    // workerEnabled: true, // Whether enable webworker
    // gpuEnabled: true // Whether enable GPU version. supported by G6 4.0, and only support gForce and fruchterman layout
    // ...                    // Other configurations for the layout
  },
});

Different layout algorithms have different configurations. For all the general graph layout algorithms in G6, you can enable the web-worker by configure workerEnabled: true in the layout configuration above. With web-worker, layout algorithms performed on large data with high cost will not block the web page.

When the layout is not assigned:

  • If there is position information with x and y in node data, G6 renders the graph with them;
  • If the position information does not exist in the node data, Random Layout will take effect by default.

Layouts for Graph

General graph layout API: General Graph Layout API.

Random

img


Description: Randomizes the node positions.
API: Random API
Configuration:

NameTypeExampleDefaultDescription
centerArray[ 0, 0 ]The center of the graphThe center of the layout
widthNumber300The width of the graph
heightNumber300The height of the graph
workerEnabledBooleantrue / falsefalseWhether to enable the web-worker in case layout calculation takes too long to block page interaction

GForce

img


Description: GForce implements the classical force-directed layout algorithm by G6 4.0. It supports assign different masses and center gravities for different nodes freedomly. More importantly, it supports GPU parallel acceleration. If you want to fix the positions for some nodes during calculation, assign fx and fy for the nodes as fixing positions. Demo for fixing node.
API: GForce API
Configuration:

NameTypeExampleDefaultDescription
centerArray[ 0, 0 ]The center of the graphThe center of the layout
linkDistanceNumber / FunctionExample 1: 50 
Example 2:
d => {
  // d is an edge
  if (d.id === 'edge1') {
    return 100;
  }
  return 50;
}
1The edge length. It can be a function to define the different edge lengths for different edges (Example 2)
nodeStrengthNumber / FunctionExmaple 1: -30 
Exmaple 2:
d => {
  // d is a node
  if (d.id === 'node1') {
    return -100;
  }
  return -30;
} / 1000
1000The strength of node force. Positive value means repulsive force, negative value means attractive force (it is different from 'force')(As example 2)
edgeStrengthNumber / FunctionExample 1: 1 
Example 2:
d => {
  // d is a node
  if (d.id === 'node1') {
    return 10;
  }
  return 1;
}
200The strength of edge force. Calculated according to the degree of nodes by default (As Example 2)
preventOverlapBooleanfalsefalseWhether to prevent node overlappings. To activate preventing node overlappings, nodeSize is required, which is used for collide detection. The size in the node data will take effect if nodeSize is not assigned
nodeSizeArray / Number20undefinedThe diameter of the node. It is used for preventing node overlappings. If nodeSize is not assigned, the size property in node data will take effect. If the size in node data does not exist either, nodeSize is assigned to 10 by default
nodeSpacing

Number / FunctionExample 1 : 10
Example 2 : 
d => {
  // d is a node
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0img
Takes effect when preventOverlap is true. It is the minimum distance between nodes to prevent node overlappings. It can be a function to define different distances for different nodes (example 2)
minMovementNumber0.10.5When the average movement of nodes in one iteration is smaller than minMovement, terminate the layout
maxIterationNumber5001000The max number of iterations. If the average movement do not reach minMovement but the iteration number is over maxIteration, terminate the layout
dampingNumber0.990.9Range [0, 1], affect the speed of decreasing node moving speed. Large the number, slower the decreasing
maxSpeedNumber101000The max speed in each iteration
coulombDisScaleNumber0.0030.005A parameter for repulsive force between nodes. Large the number, larger the repulsion
getMassFunctiond => {
  // d 是一个节点
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
undefinedIt is a callback returns the mass of each node. If it is not assigned, the degree of each node will takes effect. The usage is similar to nodeSpacing
getCenterFunction(d, degree) => {
  // d is a node, degree is the degree of the node
  if (d.degree === 0') {
    return [100, 100, 10]; // x, y, strength
  }
  return [210, 150, 5]; // x, y, strength
}
undefinedIt is a callback returns gravity center and the gravity strength for each node
gravityNumber2010The gravity strength to the center for all the nodes. Larger the number, more compact the nodes
onTickFunctionundefinedThe callback function of each iteration
onLayoutEndFunctionundefinedThe callback function after layout
workerEnabledBooleantrue / falsefalseWhether to enable the web-worker in case layout calculation takes too long to block page interaction
gpuEnabledBooleantrue / falsefalseWhether to enable the GPU parallel computing, supported by G6 4.0. If the machine or browser does not support GPU computing, it will be degraded to CPU computing automatically.

Force

imggraphLayout/guide


Description: Classical force-directed layout algorithm. If you want to fix the positions for some nodes during calculation, assign fx and fy for the nodes as fixing positions. Demo for fixing the dragged node with force layout.
API: Force API
Configuration: Corresponds to the configurations in force-directed algorithm in d3.js

NameTypeExampleDefaultDescription
centerArray[ 0, 0 ]The center of the graphThe center of the layout
linkDistanceNumber / FunctionExample 1: 50 
Example 2:
d => {
  // d is an edge
  if (d.id === 'edge1') {
    return 100;
  }
  return 50;
}
50The edge length. It can be a function to define the different edge lengths for different edges (Example 2)
nodeStrengthNumber / FunctionExample 1: -30 
Example 2:
d => {
  // d is a node
  if (d.id === 'node1') {
    return -100;
  }
  return -30;
}
nullThe strength of node force. Positive value means attractive force, negative value means repulsive force (Example 2)
edgeStrengthNumberExample 1: 1 
Example 2:
d => {
  // d is a node
  if (d.id === 'node1') {
    return 10;
  }
  return 1;
}
nullThe strength of edge force, ranges from 0 to 1. Calculated according to the degree of nodes by default (Example 2)
preventOverlapBooleanfalsefalseWhether to prevent node overlappings. To activate preventing node overlappings, nodeSize is required, which is used for collide detection. The size in the node data will take effect if nodeSize is not assigned. If the nodeSize and size in data are both undefiend, nodeSize will be assigned to 10 by default
nodeSizeArray / Number20undefinedThe diameter of the node. It is used for preventing node overlappings. If nodeSize is not assigned, the size property in node data will take effect. If the size in node data does not exist either, nodeSize is assigned to 10 by default
nodeSpacing

Number / FunctionExample 1: 10
Example 2:  
d => {
  // d is a node
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0img
Takes effect when preventOverlap is true. It is the minimum distance between nodes to prevent node overlappings. It can be a function to define different distances for different nodes (example 2)
alphaDecayNumber0.030.028The decay ratio of alpha for convergence. THe range is [0, 1]. 0.028 corresponds to 300 times iteration
alphaMinNumber0.030.001The threshold to stop the iteration
alphaNumber0.10.3The current alpha of convergence
collideStrengthNumber0.81The strength of force for preventing node overlappings. The range is [0, 1]
clusteringBooleanfalsefalseWhether run the force layout with clustering
clusterNodeStrengthNumber-1-0.8The force between nodes. It will be repulsive force while it is negative
clusterEdgeStrengthNumber0.10.2The force along the edge
clusterEdgeDistanceNumber10050The edge length between the clusters
clusterNodeSizeNumber1015The node size(diameter) for clustering
clusterFociStrengthNumber0.80.5The force for the clustering foci
forceSimulationObjectnullCustomed force simulation. If it is not assigned, the force simulation of d3.js will take effect
onTickFunction{}The callback function of each iteration
onLayoutEndFunction{}The callback function after layout
workerEnabledBooleantrue / falsefalseWhether to enable the web-worker in case layout calculation takes too long to block page interaction

Fruchterman

img


Description: Fruchterman is a kind of force-directed layout. If you want to fix the positions for some nodes during calculation, assign fx and fy for the nodes as fixing positions. Demo for fixing node.
API: Fruchterman API
Configuration:

NameTypeExampleDefaultDescription
centerArray[ 0, 0 ]The center of the graphThe center of the layout
maxIterationNumber10001000The maximum interation number
gravityNumber1010The gravity, which affects the compactness of the layout
speedNumber11The moving speed in each iteration. Large value might lead to violent swing
clusteringBooleanfalsefalseWhether to layout by clustering
clusterGravityNumber3010The gravity of each clusterm which affects the compactness of each cluster
workerEnabledBooleantrue / falsefalseWhether to enable the web-worker in case layout calculation takes too long to block page interaction
gpuEnabledBooleantrue / falsefalseWhether to enable the GPU parallel computing, supported by G6 4.0

Circular

img img img


Description: Arranges the nodes on a circle.
API: Circular API
Configuration:

NameTypeExample/OptionsDefaultDescription
centerArray[ 0, 0 ]The center of the graphThe center of the layout
radiusNumber50nullThe radius of the circle. If the raidus exists, startRadius and endRadius do not take effect.
startRadiusNumber10nullThe start radius of spiral layout
endRadiusNumber100nullThe end radius of spiral layout
clockwiseBooleantruetrueWhether to layout clockwisely
divisionsNumber31The division number of the nodes on the circle. Takes effect when endRadius - startRadius !== 0
orderingStringnull'topology''degree'nullThe ordering method for nodes. null by default, which means the nodes are arranged in data order. 'topology' means in topology order; 'degree' means in degree order.
angleRatioNumber11How many 2*PIs Between the first node and the last node
workerEnabledBooleantrue / falsefalseWhether to enable the web-worker in case layout calculation takes too long to block page interaction

Radial

img


Description: Arranges the nodes to concentrics centered at a focus node according to their shortest path length to the focus node.
API: Radial API
Configuration:

NameTypeExampleDefaultDescription
centerArray[ 0, 0 ]The center of the graphThe center of the layout
linkDistanceNumber5050The edge length
maxIterationNumber10001000The max iteration number.
focusNodeString / Object'node1'nullThe focus node of the radial layout. The first node of the data is the default value. It can be the id of a node or the node item.
unitRadiusNumber10100The separation between adjacent circles. If unitRadius is not assigned, the layout will fill the canvas automatically.
preventOverlapBooleanfalsefalseWhether to prevent node overlappings. To activate preventing node overlappings, nodeSize is required, which is used for collide detection. The size in the node data will take effect if nodeSize is not assigned.
maxPreventOverlapIterationNumber500200The maximum iteration number of preventing node overlappings
nodeSizeNumber1010The diameter of the node. It is used for preventing node overlappings.
:
The size in the node data will take effect if nodeSize is not assigned. If the size in node data does not exist either, nodeSize is assigned to 10 by default
nodeSpacing
Number / FunctionExample 1: 10
Example 2:  
d => {
  // d is a node
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0img
Takes effect when preventOverlap is true. It is the minimum distance between nodes to prevent node overlappings. It can be a function to define different distances for different nodes (example 2)
strictRadialBooleantruefalseWhether to layout the graph as strict radial, which means the nodes will be arranged on each circle strictly. Takes effect only when preventOverlap is true. Refer to Radial-strictRadial API
- When preventOverlap is true, and strictRadial is false, the overlapped nodes are arranged along their circles strictly. But for the situation that there are too many nodes on a circle to be arranged, the overlappings might not be eliminated completely
- When preventOverlap is true, and strictRadial is true , the overlapped nodes can be arranged around their circle with small offsets.
sortByString'data' / 'cluster'undefinedSort the nodes of the same level. undefined by default, which means place the nodes with connections as close as possible; 'data' means place the node according to the ordering in data, the closer the nodes in data ordering, the closer the nodes will be placed. sortBy also can be assigned to any name of property in nodes data, such as 'cluster', 'name' and so on (make sure the property exists in the data)
sortStrengthNumber1010The strength to sort the nodes in the same circle. Larger number means place the nodes with smaller distance of sortBy more closely. Takes effect only when sortBy is not undefined
workerEnabledBooleantrue / falsefalseWhether to enable the web-worker in case layout calculation takes too long to block page interaction

MDS

img
Description: MDS (Multidimensional scaling) is used for project high dimensional data onto low dimensional space.
API: MDS API
Configuration:

NameTypeExampleDefaultDescription
centerArray[ 0, 0 ]The center of the graphThe center of the layout
linkDistanceNumber5050The edge length
workerEnabledBooleantrue / falsefalseWhether to enable the web-worker in case layout calculation takes too long to block page interaction

Dagre

img
Description: An hierarchical layout.
API: Dagre API
Configuration:

NameTypeExample/OptionsDefaultDescription
rankdirString'TB' / 'BT' / 'LR' / 'RL''TB'The layout direction. T: top; B: bottom; L: left; R: right
alignString'UL' / 'UR' / 'DL' / 'DR' / undefinedundefinedThe alignment of the nodes. undefined by default, align to the center. U: upper; D: down; L: left; R: right
nodesepNumber4050The separation between nodes with unit px. When rankdir is 'TB' or 'BT', nodesep represents the horizontal separations between nodes; When rankdir is 'LR' or 'RL', nodesep represents the vertical separations between nodes
ranksepNumber4050The separations between adjacent levels with unit px. When rankdir is 'TB' or 'BT', ranksep represents the vertical separations between adjacent levels; when rankdir is 'LR' or 'RL', rankdir represents the horizontal separations between adjacent levels
nodesepFunc

Functiond => {
  // d is a node
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
undefinedThe function for node separation with unit px. You can adjust the separations between different node pairs by using this function instead of nodesep. When rankdir is 'LR' or 'RL', nodesep represents the vertical separations between nodes. The priority of nodesepFunc is lower than nodesep, which means if nodesep is assigned, the nodesepFunc will not take effect
ranksepFunc

Functiond => {
  // d is a node
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
undefinedThe function for level separation with unit px. You can adjust the separations between different adjacent levels by using this function instead of ranksep. When rankdir is 'TB' or 'BT', ranksep represents the vertical separations between adjacent levels; when rankdir is 'LR' or 'RL', rankdir represents the horizontal separations between adjacent levels. The priority of ranksepFunc is lower than ranksep, which means if ranksep is assigned, the ranksepFunc will not take effect
controlPointsBooleantruetrueWhether to keep the control points of layout
workerEnabledBooleantrue / falsefalseWhether to enable the web-worker in case layout calculation takes too long to block page interaction
sortByComboBooleantrue / falsefalseWhether to sort the nodes in a level according to the comboId in their data. Enable sortByCombo to avoid combo overlappings

Concentric

img
Tips: Concentric layout in G6 refers to cytoscape.js, we obey the MIT license
Description: Arranges the nodes on several concentric circles.
API: Concentric API
Configuration:
NameTypeExample/OptionsDefaultDescription
centerArray[ 0, 0 ]The center of the graphThe center of the layout
nodeSizeNumber3030The diameter of the node. It is used for preventing node overlappings
minNodeSpacingNumber1010The minimum separation between adjacent circles
preventOverlapBooleanfalsefalseWhether to prevent node overlappings. To activate preventing node overlappings, nodeSize is required, which is used for collide detection. The size in the node data will take effect if nodeSize is not assigned. If the size in node data does not exist either, nodeSize is assigned to 30 by default
sweepNumberMath.PIundefinedHow many radians should be between the first and last node (defaults to full circle). If it is undefined, 2 _ Math.PI _ (1 - 1 /level.nodes) will be used, where level.nodes is nodes set of each level,level.nodesis the number of nodes of the level
equidistantBooleanfalsefalseWhether levels have an equal radial distance between them, may cause bounding box overflow
startAngleNumber3.143 / 2 * Math.PIWhere nodes start in radians
clockwiseBooleanfalsefalsePlace the nodes in clockwise or not
maxLevelDiffNumber0.5undefinedThe sum of concentric values in each level. If it is undefined, maxValue / 4 will take place, where maxValue is the max value of ordering properties. For example, if sortBy='degree', maxValue is the max degree value of all the nodes
sortByString'property1' / 'weight' / ...undefinedOrder the nodes according to this parameter. It is the property's name of node. The node with higher value will be placed to the center. If it is undefined, the algorithm will order the nodes by their degree
workerEnabledBooleantrue / falsefalseWhether to enable the web-worker in case layout calculation takes too long to block page interaction

Grid

img
Tips: Concentric layout in G6 refers to cytoscape.js, we obey the MIT license.
Description: Orders the nodes according to the configurations and arranged them onto grid.
API: Grid API
Configuration:
NameTypeExample/OptionsDefaultDescription
beginArray[ 0, 0 ][ 0, 0 ]网格开始位置(左上角)
preventOverlapBooleanfalsefalseWhether to prevent node overlappings. To activate preventing node overlappings, nodeSize is required, which is used for collide detection. The size in the node data will take effect if nodeSize is not assigned. If the size in node data does not exist either, nodeSize is assigned to 30 by default
preventOverlapPaddingNumber1010The minimum padding between nodes to prevent node overlappings. Takes effect when preventOverlap is true
nodeSizeNumber3030The diameter of the node. It is used for preventing node overlappings.
condenseBooleanfalsefalseWheter to utilize the minimum space of the canvas. false means utilizing the full space, true means utilizing the minimum space.
rowsNumber5undefinedThe row number of the grid. If rows is undefined, the algorithm will calculate it according to the space and node numbers automatically
colsNumber5undefinedThe column number of the grid. If cols is undefined, the algorithm will calculate it according to the space and node numbers automatically
sortByString'property1' / 'weight' / ...'degree'The ordering method for nodes. Smaller the index in the ordered array, more center the node will be placed. If sortBy is undefined, the algorithm order the nodes according to their degrees
workerEnabledBooleantrue / falsefalseWhether to enable the web-worker in case layout calculation takes too long to block page interaction

Combo Force

img
APICombo Force API
Parameters

NameTypeExample/OptionsDefaultDescription
centerArray[ 0, 0 ]The center of the graphThe center of the layout
maxIterationNumber100100The maximum iteration number
linkDistanceNumber / Functione.g. 1: 50 
e.g. 2:
d => {
  // d is an edge
  if (d.id === 'edge1') {
    return 100;
  }
  return 50;
}
10The edge length
nodeStrengthNumber / Functione.g. 1: 10 
e.g. 2:
d => {
  // d is a node
  if (d.id === 'node1') {
    return 10;
  }
  return 30;
} / null
30The strength of node force
edgeStrengthNumber / Functione.g. 1: 1 
e.g. 2:
d => {
  // d is a node
  if (d.id === 'node1') {
    return 10;
  }
  return 1;
}
0.2The strength of edge force
preventOverlapBooleanfalsefalseWhether to prevent node overlappings and combo overlappings. If it is assign true, preventNodeOverlap and preventComboOverlap will be set to true. See the API of preventNodeOverlap and preventComboOverlap for more detail
preventNodeOverlapBooleanfalsetrueWhether to prevent node overlappings. To activate preventing node overlappings, nodeSize is required, which is used for collide detection. The size in the node data will take effect if nodeSize is not assigned
preventComboOverlapBooleanfalsetrueWhether to prevent combo overlappings
collideStrengthNumber0.1undefinedThe unified strength of force for preventing node overlappings and combo overlappings. The range is [0, 1]. If it is not undefined, the nodeCollideStrength and comboCollideStrength will be set to the same value
nodeCollideStrengthNumber0.40.5The strength of force for preventing node overlappings. The range is [0, 1]
comboCollideStrengthNumber0.40.5The strength of force for preventing combo overlappings. The range is [0, 1]
nodeSizeArray / Number1010The diameter of the node. It is used for preventing node overlappings. If nodeSize is not assigned, the size property in node data will take effect. If the size in node data does not exist either, nodeSize is assigned to 10 by default
nodeSpacing

Number / Functione.g. 1 : 10
e.g. 2 : 
d => {
  // d is a node
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0img
Takes effect when preventNodeOverlap or preventOverlap is true. It is the minimum distance between nodes to prevent node overlappings. It can be a function to define different distances for different nodes (example 2)
comboSpacing

Number / Functione.g. 1 : 10
e.g. 2 : 
d => {
  // d is a node
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0Takes effect when preventComboOverlap or preventOverlap is true. It is the minimum distance between combos to prevent combo overlappings. It can be a function to define different distances for different combos (example 2)
comboPadding

Number / Functione.g. 1 : 10
e.g. 2 : 
d => {
  // d is a node
  if (d.id === 'node1') {
    return 100;
  }
  return 10;
}
0The padding value inside each combo. It is not about rendering, only used for force calculation
alphaDecayNumber0.030.028The decay ratio of alpha for convergence. The range is [0, 1]. 0.028 corresponds to 300 iterations
alphaMinNumber0.030.001The threshold to stop the iteration
alphaNumber0.11The current alpha of convergence
onTickFunction{}The callback function of each iteration
onLayoutEndFunction{}The callback function after layout
gravityNumber10The gravity, which will affect the compactness of the layout
comboGravityNumber30The gravity of each combo, which will affect the compactness of each combo
optimizeRangeFactorNumber1When the distance between two nodes is larger than optimizeRangeFactor * width, the forces between them will not be calculated any more. A proper value for optimizeRangeFactor will lead to less calculation to optimize the performance of the layout
depthAttractiveForceScaleNumber0.5The scale for adjusting the strength of attractive force between nodes with different depths. The range is [0, 1]. Lager the depth difference, smaller the attractive force strength
depthRepulsiveForceScaleNumber2The scale for adjusting the strength of repulsive force between nodes with different depths. The range is [1, Infinity]. Lager the depth difference, larger the attractive force strength
velocityDecayNumber0.20.6The decay speed of the moving velocity of nodes for each iteration
workerEnabledBooleantrue / falsefalseWhether to enable the web-worker in case layout calculation takes too long to block page interaction