Browse Source

fixed self referencing edges during clustering

webworkersNetwork
Alex de Mulder 9 years ago
parent
commit
bb0104bacf
3 changed files with 7642 additions and 82 deletions
  1. +35
    -34
      dist/vis.js
  2. +36
    -35
      lib/network/modules/Clustering.js
  3. +7571
    -13
      test/networkTest.html

+ 35
- 34
dist/vis.js View File

@ -35104,7 +35104,7 @@ return /******/ (function(modules) { // webpackBootstrap
edges = undefined, edges = undefined,
node = undefined, node = undefined,
nodeId = undefined, nodeId = undefined,
visibleEdges = undefined;
relevantEdgeCount = undefined;
// collect the nodes that will be in the cluster // collect the nodes that will be in the cluster
for (var i = 0; i < this.body.nodeIndices.length; i++) { for (var i = 0; i < this.body.nodeIndices.length; i++) {
var childNodesObj = {}; var childNodesObj = {};
@ -35113,46 +35113,42 @@ return /******/ (function(modules) { // webpackBootstrap
// if this node is already used in another cluster this session, we do not have to re-evaluate it. // if this node is already used in another cluster this session, we do not have to re-evaluate it.
if (usedNodes[nodeId] === undefined) { if (usedNodes[nodeId] === undefined) {
visibleEdges = 0;
relevantEdgeCount = 0;
node = this.body.nodes[nodeId]; node = this.body.nodes[nodeId];
edges = []; edges = [];
for (var j = 0; j < node.edges.length; j++) { for (var j = 0; j < node.edges.length; j++) {
edge = node.edges[j]; edge = node.edges[j];
if (edge.hiddenByCluster !== true) { if (edge.hiddenByCluster !== true) {
if (edge.toId !== edge.fromId) {
relevantEdgeCount++;
}
edges.push(edge); edges.push(edge);
} }
} }
// this node qualifies, we collect its neighbours to start the clustering process. // this node qualifies, we collect its neighbours to start the clustering process.
if (edges.length === edgeCount) {
if (relevantEdgeCount === edgeCount) {
var gatheringSuccessful = true; var gatheringSuccessful = true;
for (var j = 0; j < edges.length; j++) { for (var j = 0; j < edges.length; j++) {
edge = edges[j]; edge = edges[j];
var childNodeId = this._getConnectedId(edge, nodeId); var childNodeId = this._getConnectedId(edge, nodeId);
// if unused and if not referencing itself
if (childNodeId !== nodeId && usedNodes[nodeId] === undefined) {
// add the nodes to the list by the join condition.
if (options.joinCondition === undefined) {
// add the nodes to the list by the join condition.
if (options.joinCondition === undefined) {
childEdgesObj[edge.id] = edge;
childNodesObj[nodeId] = this.body.nodes[nodeId];
childNodesObj[childNodeId] = this.body.nodes[childNodeId];
usedNodes[nodeId] = true;
} else {
var clonedOptions = this._cloneOptions(this.body.nodes[nodeId]);
if (options.joinCondition(clonedOptions) === true) {
childEdgesObj[edge.id] = edge; childEdgesObj[edge.id] = edge;
childNodesObj[nodeId] = this.body.nodes[nodeId]; childNodesObj[nodeId] = this.body.nodes[nodeId];
childNodesObj[childNodeId] = this.body.nodes[childNodeId];
usedNodes[nodeId] = true; usedNodes[nodeId] = true;
} else { } else {
var clonedOptions = this._cloneOptions(this.body.nodes[nodeId]);
if (options.joinCondition(clonedOptions) === true) {
childEdgesObj[edge.id] = edge;
childNodesObj[nodeId] = this.body.nodes[nodeId];
usedNodes[nodeId] = true;
} else {
// this node does not qualify after all.
gatheringSuccessful = false;
break;
}
// this node does not qualify after all.
gatheringSuccessful = false;
break;
} }
} else {
// this node does not qualify after all.
gatheringSuccessful = false;
break;
} }
} }
@ -35302,7 +35298,7 @@ return /******/ (function(modules) { // webpackBootstrap
*/ */
}, { }, {
key: '_createClusterEdges', key: '_createClusterEdges',
value: function _createClusterEdges(childNodesObj, clusterNodeProperties, clusterEdgeProperties) {
value: function _createClusterEdges(childNodesObj, childEdgesObj, clusterNodeProperties, clusterEdgeProperties) {
var edge = undefined, var edge = undefined,
childNodeId = undefined, childNodeId = undefined,
childNode = undefined, childNode = undefined,
@ -35323,16 +35319,21 @@ return /******/ (function(modules) { // webpackBootstrap
edge = childNode.edges[j]; edge = childNode.edges[j];
// we only handle edges that are visible to the system, not the disabled ones from the clustering process. // we only handle edges that are visible to the system, not the disabled ones from the clustering process.
if (edge.hiddenByCluster !== true) { if (edge.hiddenByCluster !== true) {
// set up the from and to.
if (edge.toId == childNodeId) {
// this is a double equals because ints and strings can be interchanged here.
toId = clusterNodeProperties.id;
fromId = edge.fromId;
otherNodeId = fromId;
// self-referencing edges will be added to the "hidden" list
if (edge.toId == edge.fromId) {
childEdgesObj[edge.id] = edge;
} else { } else {
toId = edge.toId;
fromId = clusterNodeProperties.id;
otherNodeId = toId;
// set up the from and to.
if (edge.toId == childNodeId) {
// this is a double equals because ints and strings can be interchanged here.
toId = clusterNodeProperties.id;
fromId = edge.fromId;
otherNodeId = fromId;
} else {
toId = edge.toId;
fromId = clusterNodeProperties.id;
otherNodeId = toId;
}
} }
// Only edges from the cluster outwards are being replaced. // Only edges from the cluster outwards are being replaced.
@ -35489,8 +35490,8 @@ return /******/ (function(modules) { // webpackBootstrap
// finally put the cluster node into global // finally put the cluster node into global
this.body.nodes[clusterNodeProperties.id] = clusterNode; this.body.nodes[clusterNodeProperties.id] = clusterNode;
// create the new edges that will connect to the cluster
this._createClusterEdges(childNodesObj, clusterNodeProperties, options.clusterEdgeProperties);
// create the new edges that will connect to the cluster, all self-referencing edges will be added to childEdgesObject here.
this._createClusterEdges(childNodesObj, childEdgesObj, clusterNodeProperties, options.clusterEdgeProperties);
// disable the childEdges // disable the childEdges
for (var edgeId in childEdgesObj) { for (var edgeId in childEdgesObj) {

+ 36
- 35
lib/network/modules/Clustering.js View File

@ -95,7 +95,7 @@ class ClusterEngine {
options = this._checkOptions(options); options = this._checkOptions(options);
let clusters = []; let clusters = [];
let usedNodes = {}; let usedNodes = {};
let edge, edges, node, nodeId, visibleEdges;
let edge, edges, node, nodeId, relevantEdgeCount;
// collect the nodes that will be in the cluster // collect the nodes that will be in the cluster
for (let i = 0; i < this.body.nodeIndices.length; i++) { for (let i = 0; i < this.body.nodeIndices.length; i++) {
let childNodesObj = {}; let childNodesObj = {};
@ -104,50 +104,45 @@ class ClusterEngine {
// if this node is already used in another cluster this session, we do not have to re-evaluate it. // if this node is already used in another cluster this session, we do not have to re-evaluate it.
if (usedNodes[nodeId] === undefined) { if (usedNodes[nodeId] === undefined) {
visibleEdges = 0;
relevantEdgeCount = 0;
node = this.body.nodes[nodeId]; node = this.body.nodes[nodeId];
edges = []; edges = [];
for (let j = 0; j < node.edges.length; j++) { for (let j = 0; j < node.edges.length; j++) {
edge = node.edges[j]; edge = node.edges[j];
if (edge.hiddenByCluster !== true) { if (edge.hiddenByCluster !== true) {
if (edge.toId !== edge.fromId) {
relevantEdgeCount++;
}
edges.push(edge); edges.push(edge);
} }
} }
// this node qualifies, we collect its neighbours to start the clustering process. // this node qualifies, we collect its neighbours to start the clustering process.
if (edges.length === edgeCount) {
if (relevantEdgeCount === edgeCount) {
let gatheringSuccessful = true; let gatheringSuccessful = true;
for (let j = 0; j < edges.length; j++) { for (let j = 0; j < edges.length; j++) {
edge = edges[j]; edge = edges[j];
let childNodeId = this._getConnectedId(edge, nodeId); let childNodeId = this._getConnectedId(edge, nodeId);
// if unused and if not referencing itself
if (childNodeId !== nodeId && usedNodes[nodeId] === undefined) {
// add the nodes to the list by the join condition.
if (options.joinCondition === undefined) {
// add the nodes to the list by the join condition.
if (options.joinCondition === undefined) {
childEdgesObj[edge.id] = edge;
childNodesObj[nodeId] = this.body.nodes[nodeId];
childNodesObj[childNodeId] = this.body.nodes[childNodeId];
usedNodes[nodeId] = true;
}
else {
let clonedOptions = this._cloneOptions(this.body.nodes[nodeId]);
if (options.joinCondition(clonedOptions) === true) {
childEdgesObj[edge.id] = edge; childEdgesObj[edge.id] = edge;
childNodesObj[nodeId] = this.body.nodes[nodeId]; childNodesObj[nodeId] = this.body.nodes[nodeId];
childNodesObj[childNodeId] = this.body.nodes[childNodeId];
usedNodes[nodeId] = true; usedNodes[nodeId] = true;
} }
else { else {
let clonedOptions = this._cloneOptions(this.body.nodes[nodeId]);
if (options.joinCondition(clonedOptions) === true) {
childEdgesObj[edge.id] = edge;
childNodesObj[nodeId] = this.body.nodes[nodeId];
usedNodes[nodeId] = true;
}
else {
// this node does not qualify after all.
gatheringSuccessful = false;
break;
}
// this node does not qualify after all.
gatheringSuccessful = false;
break;
} }
} }
else {
// this node does not qualify after all.
gatheringSuccessful = false;
break;
}
} }
// add to the cluster queue // add to the cluster queue
@ -280,7 +275,7 @@ class ClusterEngine {
* @param options * @param options
* @private * @private
*/ */
_createClusterEdges (childNodesObj, clusterNodeProperties, clusterEdgeProperties) {
_createClusterEdges (childNodesObj, childEdgesObj, clusterNodeProperties, clusterEdgeProperties) {
let edge, childNodeId, childNode, toId, fromId, otherNodeId; let edge, childNodeId, childNode, toId, fromId, otherNodeId;
// loop over all child nodes and their edges to find edges going out of the cluster // loop over all child nodes and their edges to find edges going out of the cluster
@ -296,16 +291,22 @@ class ClusterEngine {
edge = childNode.edges[j]; edge = childNode.edges[j];
// we only handle edges that are visible to the system, not the disabled ones from the clustering process. // we only handle edges that are visible to the system, not the disabled ones from the clustering process.
if (edge.hiddenByCluster !== true) { if (edge.hiddenByCluster !== true) {
// set up the from and to.
if (edge.toId == childNodeId) { // this is a double equals because ints and strings can be interchanged here.
toId = clusterNodeProperties.id;
fromId = edge.fromId;
otherNodeId = fromId;
// self-referencing edges will be added to the "hidden" list
if (edge.toId == edge.fromId) {
childEdgesObj[edge.id] = edge;
} }
else { else {
toId = edge.toId;
fromId = clusterNodeProperties.id;
otherNodeId = toId;
// set up the from and to.
if (edge.toId == childNodeId) { // this is a double equals because ints and strings can be interchanged here.
toId = clusterNodeProperties.id;
fromId = edge.fromId;
otherNodeId = fromId;
}
else {
toId = edge.toId;
fromId = clusterNodeProperties.id;
otherNodeId = toId;
}
} }
// Only edges from the cluster outwards are being replaced. // Only edges from the cluster outwards are being replaced.
@ -446,8 +447,8 @@ class ClusterEngine {
// finally put the cluster node into global // finally put the cluster node into global
this.body.nodes[clusterNodeProperties.id] = clusterNode; this.body.nodes[clusterNodeProperties.id] = clusterNode;
// create the new edges that will connect to the cluster
this._createClusterEdges(childNodesObj, clusterNodeProperties, options.clusterEdgeProperties);
// create the new edges that will connect to the cluster, all self-referencing edges will be added to childEdgesObject here.
this._createClusterEdges(childNodesObj, childEdgesObj, clusterNodeProperties, options.clusterEdgeProperties);
// disable the childEdges // disable the childEdges
for (let edgeId in childEdgesObj) { for (let edgeId in childEdgesObj) {

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


Loading…
Cancel
Save