diff --git a/HISTORY.md b/HISTORY.md index 67f1fcdc..8601dcc9 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -21,6 +21,7 @@ http://visjs.org - Fixed #1408: Unclustering without release function respects fixed positions now. - Fixed #1358: Fixed example for clustering on zoom. - Fixed #1416: Fixed error in improvedLayout. +- Improvements on hierarchical layout. ### Timeline diff --git a/dist/vis.js b/dist/vis.js index 63d427d1..9bdb0f20 100644 --- a/dist/vis.js +++ b/dist/vis.js @@ -5,7 +5,7 @@ * A dynamic, browser-based visualization library. * * @version 4.9.1-SNAPSHOT - * @date 2015-11-26 + * @date 2015-11-27 * * @license * Copyright (C) 2011-2015 Almende B.V, http://almende.com @@ -39644,12 +39644,45 @@ return /******/ (function(modules) { // webpackBootstrap // check the distribution of the nodes per level. var distribution = this._getDistribution(); + // add offset to distribution + this._addOffsetsToDistribution(distribution); + // place the nodes on the canvas. this._placeNodesByHierarchy(distribution); } } } + /** + * center align the nodes in the hierarchy for quicker display. + * @param distribution + * @private + */ + }, { + key: '_addOffsetsToDistribution', + value: function _addOffsetsToDistribution(distribution) { + var maxDistances = 0; + // get the maximum amount of distances between nodes over all levels + for (var level in distribution) { + if (distribution.hasOwnProperty(level)) { + if (maxDistances < distribution[level].amount) { + maxDistances = distribution[level].amount; + } + } + } + // o---o---o : 3 nodes, 2 disances. hence -1 + maxDistances -= 1; + + // set the distances for all levels but normalize on the first level (0) + var zeroLevelDistance = distribution[0].amount - 1 - maxDistances; + for (var level in distribution) { + if (distribution.hasOwnProperty(level)) { + var distances = distribution[level].amount - 1 - zeroLevelDistance; + distribution[level].distance = (maxDistances - distances) * 0.5 * this.nodeSpacing; + } + } + } + /** * This function places the nodes on the canvas based on the hierarchial distribution. * @@ -39674,6 +39707,7 @@ return /******/ (function(modules) { // webpackBootstrap if (node.x === undefined) { node.x = distribution[level].distance; } + // since the placeBranchNodes can make this process not exactly sequential, we have to avoid overlap by either spacing from the node, or simply adding distance. distribution[level].distance = Math.max(distribution[level].distance + this.nodeSpacing, node.x + this.nodeSpacing); } else { @@ -39896,13 +39930,13 @@ return /******/ (function(modules) { // webpackBootstrap if (childNodeLevel > parentLevel) { if (this.options.hierarchical.direction === 'UD' || this.options.hierarchical.direction === 'DU') { if (childNode.x === undefined) { - childNode.x = Math.max(distribution[childNodeLevel].distance, parentNode.x); + childNode.x = Math.max(distribution[childNodeLevel].distance); } distribution[childNodeLevel].distance = childNode.x + this.nodeSpacing; this.positionedNodes[childNode.id] = true; } else { if (childNode.y === undefined) { - childNode.y = Math.max(distribution[childNodeLevel].distance, parentNode.y); + childNode.y = Math.max(distribution[childNodeLevel].distance); } distribution[childNodeLevel].distance = childNode.y + this.nodeSpacing; } diff --git a/lib/network/modules/LayoutEngine.js b/lib/network/modules/LayoutEngine.js index 12de04fd..236be584 100644 --- a/lib/network/modules/LayoutEngine.js +++ b/lib/network/modules/LayoutEngine.js @@ -325,12 +325,44 @@ class LayoutEngine { // check the distribution of the nodes per level. let distribution = this._getDistribution(); + // add offset to distribution + this._addOffsetsToDistribution(distribution); + // place the nodes on the canvas. this._placeNodesByHierarchy(distribution); } } } + + /** + * center align the nodes in the hierarchy for quicker display. + * @param distribution + * @private + */ + _addOffsetsToDistribution(distribution) { + let maxDistances = 0; + // get the maximum amount of distances between nodes over all levels + for (let level in distribution) { + if (distribution.hasOwnProperty(level)) { + if (maxDistances < distribution[level].amount) { + maxDistances = distribution[level].amount; + } + } + } + // o---o---o : 3 nodes, 2 disances. hence -1 + maxDistances -= 1; + + // set the distances for all levels but normalize on the first level (0) + var zeroLevelDistance = distribution[0].amount - 1 - maxDistances; + for (let level in distribution) { + if (distribution.hasOwnProperty(level)) { + var distances = distribution[level].amount - 1 - zeroLevelDistance; + distribution[level].distance = ((maxDistances - distances) * 0.5) * this.nodeSpacing; + } + } + } + /** * This function places the nodes on the canvas based on the hierarchial distribution. * @@ -350,6 +382,7 @@ class LayoutEngine { if (this.options.hierarchical.direction === 'UD' || this.options.hierarchical.direction === 'DU') { if (node.x === undefined) {node.x = distribution[level].distance;} + // since the placeBranchNodes can make this process not exactly sequential, we have to avoid overlap by either spacing from the node, or simply adding distance. distribution[level].distance = Math.max(distribution[level].distance + this.nodeSpacing, node.x + this.nodeSpacing); } @@ -570,14 +603,14 @@ class LayoutEngine { if (childNodeLevel > parentLevel) { if (this.options.hierarchical.direction === 'UD' || this.options.hierarchical.direction === 'DU') { if (childNode.x === undefined) { - childNode.x = Math.max(distribution[childNodeLevel].distance, parentNode.x); + childNode.x = Math.max(distribution[childNodeLevel].distance); } distribution[childNodeLevel].distance = childNode.x + this.nodeSpacing; this.positionedNodes[childNode.id] = true; } else { if (childNode.y === undefined) { - childNode.y = Math.max(distribution[childNodeLevel].distance, parentNode.y) + childNode.y = Math.max(distribution[childNodeLevel].distance) } distribution[childNodeLevel].distance = childNode.y + this.nodeSpacing; } diff --git a/test/networkTest.html b/test/networkTest.html index 7ab14016..a35753df 100644 --- a/test/networkTest.html +++ b/test/networkTest.html @@ -1,2583 +1,62 @@ - + - - - + body { + font: 10pt sans; + } + #mynetwork { + width: 1600px; + height: 900px; + border: 1px solid lightgray; + } + + + - - - -
- -