|
@ -14945,6 +14945,7 @@ Images.prototype.load = function(url) { |
|
|
*/ |
|
|
*/ |
|
|
function Cluster() { |
|
|
function Cluster() { |
|
|
this.clusterSession = 0; |
|
|
this.clusterSession = 0; |
|
|
|
|
|
this.hubThreshold = 5; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
@ -15312,11 +15313,14 @@ Cluster.prototype._forceClustersByZoom = function() { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* this functions starts clustering by hubs |
|
|
|
|
|
* The minimum hub threshold is set globally |
|
|
|
|
|
*/ |
|
|
Cluster.prototype.aggregateHubs = function() { |
|
|
Cluster.prototype.aggregateHubs = function() { |
|
|
var isMovingBeforeClustering = this.moving; |
|
|
var isMovingBeforeClustering = this.moving; |
|
|
|
|
|
|
|
|
var hubThreshold = 4; |
|
|
|
|
|
this._forceClustersByHub(hubThreshold); |
|
|
|
|
|
|
|
|
this._forceClustersByHub(); |
|
|
|
|
|
|
|
|
// if the simulation was settled, we restart the simulation if a cluster has been formed or expanded
|
|
|
// if the simulation was settled, we restart the simulation if a cluster has been formed or expanded
|
|
|
if (this.moving != isMovingBeforeClustering) { |
|
|
if (this.moving != isMovingBeforeClustering) { |
|
@ -15325,23 +15329,39 @@ Cluster.prototype.aggregateHubs = function() { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Cluster.prototype._getHubSize = function() { |
|
|
|
|
|
var distribution = {}; |
|
|
|
|
|
for (var i = 0; i < this.nodeIndices.length; i++) { |
|
|
|
|
|
// TODO get the distribution
|
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* |
|
|
* |
|
|
* @param hubThreshold |
|
|
* @param hubThreshold |
|
|
* @private |
|
|
* @private |
|
|
*/ |
|
|
*/ |
|
|
Cluster.prototype._forceClustersByHub = function(hubThreshold) { |
|
|
|
|
|
for (var nodeID = 0; nodeID < this.nodeIndices.length; nodeID++) { |
|
|
|
|
|
if (this.nodes.hasOwnProperty(this.nodeIndices[nodeID])) { |
|
|
|
|
|
var hubNode = this.nodes[this.nodeIndices[nodeID]]; |
|
|
|
|
|
if (hubNode.dynamicEdges.length >= hubThreshold) { |
|
|
|
|
|
|
|
|
Cluster.prototype._forceClustersByHub = function() { |
|
|
|
|
|
// we loop over all nodes in the list
|
|
|
|
|
|
for (var i = 0; i < this.nodeIndices.length; i++) { |
|
|
|
|
|
// we check if it is still available since it can be used by the clustering in this loop
|
|
|
|
|
|
if (this.nodes.hasOwnProperty(this.nodeIndices[i])) { |
|
|
|
|
|
var hubNode = this.nodes[this.nodeIndices[i]]; |
|
|
|
|
|
|
|
|
|
|
|
// we decide if the node is a hub
|
|
|
|
|
|
// TODO: check if dynamicEdgesLength is required
|
|
|
|
|
|
if (hubNode.dynamicEdges.length >= this.hubThreshold) { |
|
|
|
|
|
|
|
|
|
|
|
// we create a list of edges because the dynamicEdges change over the course of this loop
|
|
|
var edgesIDarray = [] |
|
|
var edgesIDarray = [] |
|
|
var amountOfInitialEdges = hubNode.dynamicEdges.length; |
|
|
var amountOfInitialEdges = hubNode.dynamicEdges.length; |
|
|
for (var i = 0; i < amountOfInitialEdges; i++) { |
|
|
|
|
|
edgesIDarray.push(hubNode.dynamicEdges[i].id); |
|
|
|
|
|
|
|
|
for (var j = 0; j < amountOfInitialEdges; j++) { |
|
|
|
|
|
edgesIDarray.push(hubNode.dynamicEdges[j].id); |
|
|
} |
|
|
} |
|
|
for (var i = 0; i < amountOfInitialEdges; i++) { |
|
|
|
|
|
var edge = this.edges[edgesIDarray[i]]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// we loop over all edges INITIALLY connected to this hub
|
|
|
|
|
|
for (var j = 0; j < amountOfInitialEdges; j++) { |
|
|
|
|
|
var edge = this.edges[edgesIDarray[j]]; |
|
|
var childNode = this.nodes[(edge.fromId == hubNode.id) ? edge.toId : edge.fromId]; |
|
|
var childNode = this.nodes[(edge.fromId == hubNode.id) ? edge.toId : edge.fromId]; |
|
|
this._addToCluster(hubNode,childNode,true); |
|
|
this._addToCluster(hubNode,childNode,true); |
|
|
} |
|
|
} |
|
@ -15350,13 +15370,8 @@ Cluster.prototype._forceClustersByHub = function(hubThreshold) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
this._updateNodeIndexList(); |
|
|
this._updateNodeIndexList(); |
|
|
this._updateDynamicEdges(); |
|
|
|
|
|
|
|
|
//this._updateDynamicEdges();
|
|
|
this._updateLabels(); |
|
|
this._updateLabels(); |
|
|
|
|
|
|
|
|
if (this.moving != isMovingBeforeClustering) { |
|
|
|
|
|
this.start(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -15374,9 +15389,11 @@ Cluster.prototype._addToCluster = function(parentNode, childNode, forceLevelColl |
|
|
// join child node in the parent node
|
|
|
// join child node in the parent node
|
|
|
parentNode.containedNodes[childNode.id] = childNode; |
|
|
parentNode.containedNodes[childNode.id] = childNode; |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
if (forceLevelCollapse == false) { |
|
|
if (forceLevelCollapse == false) { |
|
|
parentNode.dynamicEdgesLength += childNode.dynamicEdges.length - 2; |
|
|
parentNode.dynamicEdgesLength += childNode.dynamicEdges.length - 2; |
|
|
} |
|
|
} |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
for (var i = 0; i < childNode.dynamicEdges.length; i++) { |
|
|
for (var i = 0; i < childNode.dynamicEdges.length; i++) { |
|
|
var edge = childNode.dynamicEdges[i]; |
|
|
var edge = childNode.dynamicEdges[i]; |
|
@ -15384,7 +15401,6 @@ Cluster.prototype._addToCluster = function(parentNode, childNode, forceLevelColl |
|
|
this._addToContainedEdges(parentNode,childNode,edge); |
|
|
this._addToContainedEdges(parentNode,childNode,edge); |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
console.log('connecting edge to cluster'); |
|
|
|
|
|
this._connectEdgeToCluster(parentNode,childNode,edge); |
|
|
this._connectEdgeToCluster(parentNode,childNode,edge); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -15405,9 +15421,10 @@ Cluster.prototype._addToCluster = function(parentNode, childNode, forceLevelColl |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
parentNode.formationScale = this.scale; // The latest child has been added on this scale
|
|
|
parentNode.formationScale = this.scale; // The latest child has been added on this scale
|
|
|
parentNode.dynamicEdgesLength = parentNode.dynamicEdges.length; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
parentNode.dynamicEdgesLength = parentNode.dynamicEdges.length; |
|
|
|
|
|
|
|
|
// recalculate the size of the node on the next time the node is rendered
|
|
|
// recalculate the size of the node on the next time the node is rendered
|
|
|
parentNode.clearSizeCache(); |
|
|
parentNode.clearSizeCache(); |
|
|
|
|
|
|
|
@ -15641,7 +15658,7 @@ function Graph (container, data, options) { |
|
|
edges: { |
|
|
edges: { |
|
|
widthMin: 1, |
|
|
widthMin: 1, |
|
|
widthMax: 15, |
|
|
widthMax: 15, |
|
|
width: 1, |
|
|
|
|
|
|
|
|
width: 10, |
|
|
style: 'line', |
|
|
style: 'line', |
|
|
color: '#343434', |
|
|
color: '#343434', |
|
|
fontColor: '#343434', |
|
|
fontColor: '#343434', |
|
|