Browse Source

improvements on hierarchical layout

fixDataView
Alex de Mulder 8 years ago
parent
commit
1330708f63
4 changed files with 122 additions and 2575 deletions
  1. +1
    -0
      HISTORY.md
  2. +37
    -3
      dist/vis.js
  3. +35
    -2
      lib/network/modules/LayoutEngine.js
  4. +49
    -2570
      test/networkTest.html

+ 1
- 0
HISTORY.md View File

@ -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

+ 37
- 3
dist/vis.js View File

@ -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;
}

+ 35
- 2
lib/network/modules/LayoutEngine.js View File

@ -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;
}

+ 49
- 2570
test/networkTest.html
File diff suppressed because it is too large
View File


Loading…
Cancel
Save