diff --git a/dist/vis.js b/dist/vis.js
index 49849530..e48df784 100644
--- a/dist/vis.js
+++ b/dist/vis.js
@@ -12131,7 +12131,9 @@ var HierarchicalLayoutMixin = {
*/
_setupHierarchicalLayout : function() {
if (this.constants.hierarchicalLayout.enabled == true) {
-
+ if (this.constants.hierarchicalLayout.direction == "RL" || this.constants.hierarchicalLayout.direction == "DU") {
+ this.constants.hierarchicalLayout.levelSeparation *= -1;
+ }
// get the size of the largest hubs and check if the user has defined a level for a node.
var hubsize = 0;
var node, nodeId;
@@ -12195,10 +12197,21 @@ var HierarchicalLayoutMixin = {
for (nodeId in distribution[0].nodes) {
if (distribution[0].nodes.hasOwnProperty(nodeId)) {
node = distribution[0].nodes[nodeId];
- if (node.xFixed) {
- node.x = distribution[0].minPos;
- distribution[0].minPos += distribution[0].nodeSpacing;
- node.xFixed = false;
+ if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
+ if (node.xFixed) {
+ node.x = distribution[0].minPos;
+ node.xFixed = false;
+
+ distribution[0].minPos += distribution[0].nodeSpacing;
+ }
+ }
+ else {
+ if (node.yFixed) {
+ node.y = distribution[0].minPos;
+ node.yFixed = false;
+
+ distribution[0].minPos += distribution[0].nodeSpacing;
+ }
}
this._placeBranchNodes(node.edges,node.id,distribution,node.level);
}
@@ -12226,7 +12239,12 @@ var HierarchicalLayoutMixin = {
node = this.nodes[nodeId];
node.xFixed = true;
node.yFixed = true;
- node.y = this.constants.hierarchicalLayout.levelSeparation*node.level;
+ if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
+ node.y = this.constants.hierarchicalLayout.levelSeparation*node.level;
+ }
+ else {
+ node.x = this.constants.hierarchicalLayout.levelSeparation*node.level;
+ }
if (!distribution.hasOwnProperty(node.level)) {
distribution[node.level] = {amount: 0, nodes: {}, minPos:0, nodeSpacing:0};
}
@@ -12329,9 +12347,23 @@ var HierarchicalLayoutMixin = {
}
// if a node is conneceted to another node on the same level (or higher (means lower level))!, this is not handled here.
- if (childNode.xFixed && childNode.level > parentLevel) {
- childNode.xFixed = false;
- childNode.x = distribution[childNode.level].minPos;
+ var nodeMoved = false;
+ if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
+ if (childNode.xFixed && childNode.level > parentLevel) {
+ childNode.xFixed = false;
+ childNode.x = distribution[childNode.level].minPos;
+ nodeMoved = true;
+ }
+ }
+ else {
+ if (childNode.yFixed && childNode.level > parentLevel) {
+ childNode.yFixed = false;
+ childNode.y = distribution[childNode.level].minPos;
+ nodeMoved = true;
+ }
+ }
+
+ if (nodeMoved == true) {
distribution[childNode.level].minPos += distribution[childNode.level].nodeSpacing;
if (childNode.edges.length > 1) {
this._placeBranchNodes(childNode.edges,childNode.id,distribution,childNode.level);
@@ -15606,7 +15638,8 @@ function Graph (container, data, options) {
hierarchicalLayout: {
enabled:false,
levelSeparation: 150,
- nodeSpacing: 100
+ nodeSpacing: 100,
+ direction: "UD" // UD, DU, LR, RL
},
smoothCurves: true,
maxVelocity: 10,
@@ -15716,7 +15749,6 @@ function Graph (container, data, options) {
}
}
-
// if clustering is disabled, the simulation will have started in the setData function
if (this.constants.clustering.enabled) {
this.startWithClustering();
@@ -16389,7 +16421,6 @@ Graph.prototype._onTap = function (event) {
Graph.prototype._onDoubleTap = function (event) {
var pointer = this._getPointer(event.gesture.center);
this._handleDoubleTap(pointer);
-
};
@@ -17404,12 +17435,6 @@ Graph.prototype._initializeMixinLoaders = function () {
-
-
-
-
-
-
/**
* vis.js module exports
*/
diff --git a/docs/graph.html b/docs/graph.html
index 2ba9951c..407977cb 100644
--- a/docs/graph.html
+++ b/docs/graph.html
@@ -1663,12 +1663,20 @@ var options: {
hierarchicalLayout: true
}
-// advanced configuration for keyboard controls
+// advanced configuration for hierarchical layout
var options: {
hierarchicalLayout: {
enabled:false,
levelSeparation: 150,
- nodeSpacing: 100
+ nodeSpacing: 100,
+ direction: "UD"
+ }
+}
+// partial configuration automatically sets enabled to true
+var options: {
+ hierarchicalLayout: {
+ nodeSpacing: 100,
+ direction: "UD"
}
}
@@ -1692,13 +1700,20 @@ var options: {
levelSeparation
Number
150
-
This defines the space between levels (in the Y-direction).
+
This defines the space between levels (in the Y-direction, considering UP-DOWN direction).
nodeSpacing
Number
100
-
This defines the space between nodes in the same level (in the X-direction).
+
This defines the space between nodes in the same level (in the X-direction, considering UP-DOWN direction).
+
+
+
direction
+
String
+
UD
+
This defines the direction the graph is drawn in. The supported directions are: Up-Down (UD), Down-Up (DU), Left-Right (LR) and Right-Left (RL).
+ These need to be supplied by the acronyms in parentheses.
Methods
diff --git a/examples/graph/23_hierarchical_layout.html b/examples/graph/23_hierarchical_layout.html
index 2545dbbc..508c9de6 100644
--- a/examples/graph/23_hierarchical_layout.html
+++ b/examples/graph/23_hierarchical_layout.html
@@ -21,6 +21,8 @@
var edges = null;
var graph = null;
+
+
function draw() {
nodes = [];
edges = [];
@@ -75,12 +77,14 @@
nodes: nodes,
edges: edges
};
-
+ var directionInput = document.getElementById("direction");
var options = {
edges: {
},
stabilize: false,
- hierarchicalLayout:true
+ hierarchicalLayout: {
+ direction: directionInput.value
+ }
};
graph = new vis.Graph(container, data, options);
@@ -89,6 +93,7 @@
document.getElementById('selection').innerHTML = 'Selection: ' + params.nodes;
});
}
+
@@ -104,6 +109,35 @@
+
+
+
+
+
+
+
diff --git a/src/graph/Graph.js b/src/graph/Graph.js
index cb51a28a..8e13055c 100644
--- a/src/graph/Graph.js
+++ b/src/graph/Graph.js
@@ -138,7 +138,8 @@ function Graph (container, data, options) {
hierarchicalLayout: {
enabled:false,
levelSeparation: 150,
- nodeSpacing: 100
+ nodeSpacing: 100,
+ direction: "UD" // UD, DU, LR, RL
},
smoothCurves: true,
maxVelocity: 10,
@@ -248,7 +249,6 @@ function Graph (container, data, options) {
}
}
-
// if clustering is disabled, the simulation will have started in the setData function
if (this.constants.clustering.enabled) {
this.startWithClustering();
@@ -921,7 +921,6 @@ Graph.prototype._onTap = function (event) {
Graph.prototype._onDoubleTap = function (event) {
var pointer = this._getPointer(event.gesture.center);
this._handleDoubleTap(pointer);
-
};
@@ -1935,9 +1934,3 @@ Graph.prototype._initializeMixinLoaders = function () {
-
-
-
-
-
-
diff --git a/src/graph/graphMixins/HierarchicalLayoutMixin.js b/src/graph/graphMixins/HierarchicalLayoutMixin.js
index 922e9757..63ebf556 100644
--- a/src/graph/graphMixins/HierarchicalLayoutMixin.js
+++ b/src/graph/graphMixins/HierarchicalLayoutMixin.js
@@ -9,7 +9,9 @@ var HierarchicalLayoutMixin = {
*/
_setupHierarchicalLayout : function() {
if (this.constants.hierarchicalLayout.enabled == true) {
-
+ if (this.constants.hierarchicalLayout.direction == "RL" || this.constants.hierarchicalLayout.direction == "DU") {
+ this.constants.hierarchicalLayout.levelSeparation *= -1;
+ }
// get the size of the largest hubs and check if the user has defined a level for a node.
var hubsize = 0;
var node, nodeId;
@@ -73,10 +75,21 @@ var HierarchicalLayoutMixin = {
for (nodeId in distribution[0].nodes) {
if (distribution[0].nodes.hasOwnProperty(nodeId)) {
node = distribution[0].nodes[nodeId];
- if (node.xFixed) {
- node.x = distribution[0].minPos;
- distribution[0].minPos += distribution[0].nodeSpacing;
- node.xFixed = false;
+ if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
+ if (node.xFixed) {
+ node.x = distribution[0].minPos;
+ node.xFixed = false;
+
+ distribution[0].minPos += distribution[0].nodeSpacing;
+ }
+ }
+ else {
+ if (node.yFixed) {
+ node.y = distribution[0].minPos;
+ node.yFixed = false;
+
+ distribution[0].minPos += distribution[0].nodeSpacing;
+ }
}
this._placeBranchNodes(node.edges,node.id,distribution,node.level);
}
@@ -104,7 +117,12 @@ var HierarchicalLayoutMixin = {
node = this.nodes[nodeId];
node.xFixed = true;
node.yFixed = true;
- node.y = this.constants.hierarchicalLayout.levelSeparation*node.level;
+ if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
+ node.y = this.constants.hierarchicalLayout.levelSeparation*node.level;
+ }
+ else {
+ node.x = this.constants.hierarchicalLayout.levelSeparation*node.level;
+ }
if (!distribution.hasOwnProperty(node.level)) {
distribution[node.level] = {amount: 0, nodes: {}, minPos:0, nodeSpacing:0};
}
@@ -207,9 +225,23 @@ var HierarchicalLayoutMixin = {
}
// if a node is conneceted to another node on the same level (or higher (means lower level))!, this is not handled here.
- if (childNode.xFixed && childNode.level > parentLevel) {
- childNode.xFixed = false;
- childNode.x = distribution[childNode.level].minPos;
+ var nodeMoved = false;
+ if (this.constants.hierarchicalLayout.direction == "UD" || this.constants.hierarchicalLayout.direction == "DU") {
+ if (childNode.xFixed && childNode.level > parentLevel) {
+ childNode.xFixed = false;
+ childNode.x = distribution[childNode.level].minPos;
+ nodeMoved = true;
+ }
+ }
+ else {
+ if (childNode.yFixed && childNode.level > parentLevel) {
+ childNode.yFixed = false;
+ childNode.y = distribution[childNode.level].minPos;
+ nodeMoved = true;
+ }
+ }
+
+ if (nodeMoved == true) {
distribution[childNode.level].minPos += distribution[childNode.level].nodeSpacing;
if (childNode.edges.length > 1) {
this._placeBranchNodes(childNode.edges,childNode.id,distribution,childNode.level);