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