Browse Source

cleaned up hierarchical view to work with multiple unconnected sets

flowchartTest
Alex de Mulder 9 years ago
parent
commit
26357c22df
3 changed files with 91 additions and 63 deletions
  1. +45
    -32
      dist/vis.js
  2. +4
    -1
      examples/network/32_hierarchicaLayoutMethods.html
  3. +42
    -30
      lib/network/modules/LayoutEngine.js

+ 45
- 32
dist/vis.js View File

@ -35148,7 +35148,6 @@ return /******/ (function(modules) { // webpackBootstrap
} else { } else {
undefinedLevel = true; undefinedLevel = true;
} }
hubsize = hubsize < node.edges.length ? node.edges.length : hubsize;
} }
} }
@ -35163,12 +35162,12 @@ return /******/ (function(modules) { // webpackBootstrap
// define levels if undefined by the users. Based on hubsize // define levels if undefined by the users. Based on hubsize
if (undefinedLevel == true) { if (undefinedLevel == true) {
if (this.options.hierarchical.sortMethod == "hubsize") { if (this.options.hierarchical.sortMethod == "hubsize") {
this._determineLevels(hubsize);
this._determineLevelsByHubsize();
} else if (this.options.hierarchical.sortMethod == "directed" || "direction") { } else if (this.options.hierarchical.sortMethod == "directed" || "direction") {
this._determineLevelsDirected(); this._determineLevelsDirected();
} }
} }
console.log(this.hierarchicalLevels);
// check the distribution of the nodes per level. // check the distribution of the nodes per level.
var distribution = this._getDistribution(); var distribution = this._getDistribution();
@ -35259,7 +35258,7 @@ return /******/ (function(modules) { // webpackBootstrap
writable: true, writable: true,
configurable: true configurable: true
}, },
_determineLevels: {
_determineLevelsByHubsize: {
/** /**
@ -35268,29 +35267,41 @@ return /******/ (function(modules) { // webpackBootstrap
* @param hubsize * @param hubsize
* @private * @private
*/ */
value: function _determineLevels(hubsize) {
value: function _determineLevelsByHubsize() {
var nodeId = undefined, var nodeId = undefined,
node = undefined; node = undefined;
var hubSize = 1;
// determine hubs
for (nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) {
node = this.body.nodes[nodeId];
if (node.edges.length == hubsize) {
this.hierarchicalLevels[nodeId] = 0;
while (hubSize > 0) {
// determine hubs
hubSize = this._getHubSize();
if (hubSize == 0) break;
for (nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) {
node = this.body.nodes[nodeId];
if (node.edges.length == hubSize) {
this._setLevel(0, node);
}
} }
} }
} }
// branch from hubs
for (nodeId in this.body.nodes) {
},
writable: true,
configurable: true
},
_getHubSize: {
value: function _getHubSize() {
var hubSize = 0;
for (var nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) { if (this.body.nodes.hasOwnProperty(nodeId)) {
node = this.body.nodes[nodeId];
if (this.hierarchicalLevels[nodeId] == 0) {
this._setLevel(1, node.edges, node.id);
var node = this.body.nodes[nodeId];
if (this.hierarchicalLevels[nodeId] === undefined) {
hubSize = node.edges.length < hubSize ? hubSize : node.edges.length;
} }
} }
} }
return hubSize;
}, },
writable: true, writable: true,
configurable: true configurable: true
@ -35305,20 +35316,18 @@ return /******/ (function(modules) { // webpackBootstrap
* @param parentId * @param parentId
* @private * @private
*/ */
value: function _setLevel(level, edges, parentId) {
for (var i = 0; i < edges.length; i++) {
var childNode = undefined;
if (edges[i].toId == parentId) {
childNode = edges[i].from;
value: function _setLevel(level, node) {
if (this.hierarchicalLevels[node.id] !== undefined) {
return;
}var childNode = undefined;
this.hierarchicalLevels[node.id] = level;
for (var i = 0; i < node.edges.length; i++) {
if (node.edges[i].toId == node.id) {
childNode = node.edges[i].from;
} else { } else {
childNode = edges[i].to;
}
if (this.hierarchicalLevels[childNode.id] === undefined || this.hierarchicalLevels[childNode.id] > level) {
this.hierarchicalLevels[childNode.id] = level;
if (childNode.edges.length > 1) {
this._setLevel(level + 1, childNode.edges, childNode.id);
}
childNode = node.edges[i].to;
} }
this._setLevel(level + 1, childNode);
} }
}, },
writable: true, writable: true,
@ -35336,12 +35345,16 @@ return /******/ (function(modules) { // webpackBootstrap
*/ */
value: function _determineLevelsDirected() { value: function _determineLevelsDirected() {
var nodeId = undefined, var nodeId = undefined,
firstNode = undefined;
node = undefined;
var minLevel = 10000; var minLevel = 10000;
// set first node to source // set first node to source
firstNode = this.body.nodes[this.body.nodeIndices[0]];
this._setLevelDirected(minLevel, firstNode);
for (nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) {
node = this.body.nodes[nodeId];
this._setLevelDirected(minLevel, node);
}
}
// get the minimum level // get the minimum level
for (nodeId in this.body.nodes) { for (nodeId in this.body.nodes) {

+ 4
- 1
examples/network/32_hierarchicaLayoutMethods.html View File

@ -34,7 +34,7 @@
var nodes = []; var nodes = [];
var edges = []; var edges = [];
// randomly create some nodes and edges // randomly create some nodes and edges
for (var i = 0; i < 15; i++) {
for (var i = 0; i < 19; i++) {
nodes.push({id: i, label: String(i)}); nodes.push({id: i, label: String(i)});
} }
edges.push({from: 0, to: 1}); edges.push({from: 0, to: 1});
@ -51,6 +51,9 @@
edges.push({from: 2, to: 9}); edges.push({from: 2, to: 9});
edges.push({from: 3, to: 14}); edges.push({from: 3, to: 14});
edges.push({from: 1, to: 12}); edges.push({from: 1, to: 12});
edges.push({from: 16, to: 15});
edges.push({from: 15, to: 17});
edges.push({from: 18, to: 17});
// create a network // create a network
var container = document.getElementById('mynetwork'); var container = document.getElementById('mynetwork');

+ 42
- 30
lib/network/modules/LayoutEngine.js View File

@ -126,7 +126,6 @@ class LayoutEngine {
else { else {
undefinedLevel = true; undefinedLevel = true;
} }
hubsize = hubsize < node.edges.length ? node.edges.length : hubsize;
} }
} }
@ -142,13 +141,13 @@ class LayoutEngine {
// define levels if undefined by the users. Based on hubsize // define levels if undefined by the users. Based on hubsize
if (undefinedLevel == true) { if (undefinedLevel == true) {
if (this.options.hierarchical.sortMethod == "hubsize") { if (this.options.hierarchical.sortMethod == "hubsize") {
this._determineLevels(hubsize);
this._determineLevelsByHubsize();
} }
else if (this.options.hierarchical.sortMethod == "directed" || "direction") { else if (this.options.hierarchical.sortMethod == "directed" || "direction") {
this._determineLevelsDirected(); this._determineLevelsDirected();
} }
} }
console.log(this.hierarchicalLevels)
// check the distribution of the nodes per level. // check the distribution of the nodes per level.
let distribution = this._getDistribution(); let distribution = this._getDistribution();
@ -233,28 +232,38 @@ class LayoutEngine {
* @param hubsize * @param hubsize
* @private * @private
*/ */
_determineLevels(hubsize) {
_determineLevelsByHubsize() {
let nodeId, node; let nodeId, node;
let hubSize = 1;
// determine hubs
for (nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) {
node = this.body.nodes[nodeId];
if (node.edges.length == hubsize) {
this.hierarchicalLevels[nodeId] = 0;
while (hubSize > 0) {
// determine hubs
hubSize = this._getHubSize();
if (hubSize == 0)
break;
for (nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) {
node = this.body.nodes[nodeId];
if (node.edges.length == hubSize) {
this._setLevel(0, node);
}
} }
} }
} }
}
// branch from hubs
for (nodeId in this.body.nodes) {
_getHubSize() {
let hubSize = 0;
for (let nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) { if (this.body.nodes.hasOwnProperty(nodeId)) {
node = this.body.nodes[nodeId];
if (this.hierarchicalLevels[nodeId] == 0) {
this._setLevel(1,node.edges,node.id);
let node = this.body.nodes[nodeId];
if (this.hierarchicalLevels[nodeId] === undefined) {
hubSize = node.edges.length < hubSize ? hubSize : node.edges.length;
} }
} }
} }
return hubSize;
} }
/** /**
@ -265,21 +274,20 @@ class LayoutEngine {
* @param parentId * @param parentId
* @private * @private
*/ */
_setLevel(level, edges, parentId) {
for (let i = 0; i < edges.length; i++) {
let childNode;
if (edges[i].toId == parentId) {
childNode = edges[i].from;
_setLevel(level, node) {
if (this.hierarchicalLevels[node.id] !== undefined)
return;
let childNode;
this.hierarchicalLevels[node.id] = level;
for (let i = 0; i < node.edges.length; i++) {
if (node.edges[i].toId == node.id) {
childNode = node.edges[i].from;
} }
else { else {
childNode = edges[i].to;
}
if (this.hierarchicalLevels[childNode.id] === undefined || this.hierarchicalLevels[childNode.id] > level) {
this.hierarchicalLevels[childNode.id] = level;
if (childNode.edges.length > 1) {
this._setLevel(level+1, childNode.edges, childNode.id);
}
childNode = node.edges[i].to;
} }
this._setLevel(level + 1, childNode);
} }
} }
@ -292,12 +300,16 @@ class LayoutEngine {
* @private * @private
*/ */
_determineLevelsDirected() { _determineLevelsDirected() {
let nodeId, firstNode;
let nodeId, node;
let minLevel = 10000; let minLevel = 10000;
// set first node to source // set first node to source
firstNode = this.body.nodes[this.body.nodeIndices[0]];
this._setLevelDirected(minLevel,firstNode);
for (nodeId in this.body.nodes) {
if (this.body.nodes.hasOwnProperty(nodeId)) {
node = this.body.nodes[nodeId];
this._setLevelDirected(minLevel,node);
}
}
// get the minimum level // get the minimum level
for (nodeId in this.body.nodes) { for (nodeId in this.body.nodes) {

Loading…
Cancel
Save