|
|
@ -113,8 +113,8 @@ class ClusterEngine { |
|
|
|
|
|
|
|
/** |
|
|
|
* |
|
|
|
* @param hubsize |
|
|
|
* @param options |
|
|
|
* @param {Number} hubsize |
|
|
|
* @param {Object} options |
|
|
|
*/ |
|
|
|
clusterByHubsize(hubsize, options) { |
|
|
|
if (hubsize === undefined) { |
|
|
@ -142,10 +142,10 @@ class ClusterEngine { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* loop over all nodes, check if they adhere to the condition and cluster if needed. |
|
|
|
* @param options |
|
|
|
* @param refreshData |
|
|
|
*/ |
|
|
|
* loop over all nodes, check if they adhere to the condition and cluster if needed. |
|
|
|
* @param {Object} options |
|
|
|
* @param {Boolean} [refreshData=true] |
|
|
|
*/ |
|
|
|
cluster(options = {}, refreshData = true) { |
|
|
|
if (options.joinCondition === undefined) {throw new Error("Cannot call clusterByNodeData without a joinCondition function in the options.");} |
|
|
|
|
|
|
@ -180,9 +180,9 @@ class ClusterEngine { |
|
|
|
|
|
|
|
/** |
|
|
|
* Cluster all nodes in the network that have only X edges |
|
|
|
* @param edgeCount |
|
|
|
* @param options |
|
|
|
* @param refreshData |
|
|
|
* @param {Number} edgeCount |
|
|
|
* @param {Object} options |
|
|
|
* @param {Boolean} [refreshData=true] |
|
|
|
*/ |
|
|
|
clusterByEdgeCount(edgeCount, options, refreshData = true) { |
|
|
|
options = this._checkOptions(options); |
|
|
@ -256,18 +256,18 @@ class ClusterEngine { |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Cluster all nodes in the network that have only 1 edge |
|
|
|
* @param options |
|
|
|
* @param refreshData |
|
|
|
*/ |
|
|
|
* Cluster all nodes in the network that have only 1 edge |
|
|
|
* @param {Object} options |
|
|
|
* @param {Boolean} [refreshData=true] |
|
|
|
*/ |
|
|
|
clusterOutliers(options, refreshData = true) { |
|
|
|
this.clusterByEdgeCount(1,options,refreshData); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Cluster all nodes in the network that have only 2 edge |
|
|
|
* @param options |
|
|
|
* @param refreshData |
|
|
|
* @param {Object} options |
|
|
|
* @param {Boolean} [refreshData=true] |
|
|
|
*/ |
|
|
|
clusterBridges(options, refreshData = true) { |
|
|
|
this.clusterByEdgeCount(2,options,refreshData); |
|
|
@ -277,9 +277,9 @@ class ClusterEngine { |
|
|
|
|
|
|
|
/** |
|
|
|
* suck all connected nodes of a node into the node. |
|
|
|
* @param nodeId |
|
|
|
* @param options |
|
|
|
* @param refreshData |
|
|
|
* @param {vis.Node.id} nodeId |
|
|
|
* @param {Object} options |
|
|
|
* @param {Boolean} [refreshData=true] |
|
|
|
*/ |
|
|
|
clusterByConnection(nodeId, options, refreshData = true) { |
|
|
|
// kill conditions
|
|
|
@ -353,10 +353,10 @@ class ClusterEngine { |
|
|
|
* This function creates the edges that will be attached to the cluster |
|
|
|
* It looks for edges that are connected to the nodes from the "outside' of the cluster. |
|
|
|
* |
|
|
|
* @param childNodesObj |
|
|
|
* @param childEdgesObj |
|
|
|
* @param clusterNodeProperties |
|
|
|
* @param clusterEdgeProperties |
|
|
|
* @param {{vis.Node.id: vis.Node}} childNodesObj |
|
|
|
* @param {{vis.Edge.id: vis.Edge}} childEdgesObj |
|
|
|
* @param {Object} clusterNodeProperties |
|
|
|
* @param {Object} clusterEdgeProperties |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
_createClusterEdges (childNodesObj, childEdgesObj, clusterNodeProperties, clusterEdgeProperties) { |
|
|
@ -414,6 +414,8 @@ class ClusterEngine { |
|
|
|
|
|
|
|
/** |
|
|
|
* Find a cluster edge which matches the given created edge. |
|
|
|
* @param {vis.Edge} createdEdge |
|
|
|
* @returns {vis.Edge} |
|
|
|
*/ |
|
|
|
var getNewEdge = function(createdEdge) { |
|
|
|
for (let j = 0; j < newEdges.length; j++) { |
|
|
@ -462,7 +464,7 @@ class ClusterEngine { |
|
|
|
/** |
|
|
|
* This function checks the options that can be supplied to the different cluster functions |
|
|
|
* for certain fields and inserts defaults if needed |
|
|
|
* @param options |
|
|
|
* @param {Object} options |
|
|
|
* @returns {*} |
|
|
|
* @private |
|
|
|
*/ |
|
|
@ -590,7 +592,7 @@ class ClusterEngine { |
|
|
|
|
|
|
|
/** |
|
|
|
* Check if a node is a cluster. |
|
|
|
* @param nodeId |
|
|
|
* @param {vis.Node.id} nodeId |
|
|
|
* @returns {*} |
|
|
|
*/ |
|
|
|
isCluster(nodeId) { |
|
|
@ -631,10 +633,11 @@ class ClusterEngine { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* Open a cluster by calling this function. |
|
|
|
* @param {String} clusterNodeId | the ID of the cluster node |
|
|
|
* @param {Boolean} refreshData | wrap up afterwards if not true |
|
|
|
*/ |
|
|
|
* Open a cluster by calling this function. |
|
|
|
* @param {vis.Edge.id} clusterNodeId | the ID of the cluster node |
|
|
|
* @param {Object} options |
|
|
|
* @param {Boolean} refreshData | wrap up afterwards if not true |
|
|
|
*/ |
|
|
|
openCluster(clusterNodeId, options, refreshData = true) { |
|
|
|
// kill conditions
|
|
|
|
if (clusterNodeId === undefined) {throw new Error("No clusterNodeId supplied to openCluster.");} |
|
|
@ -811,7 +814,7 @@ class ClusterEngine { |
|
|
|
|
|
|
|
/** |
|
|
|
* Using a clustered nodeId, update with the new options |
|
|
|
* @param clusteredNodeId |
|
|
|
* @param {vis.Edge.id} clusteredNodeId |
|
|
|
* @param {object} newOptions |
|
|
|
*/ |
|
|
|
updateClusteredNode(clusteredNodeId, newOptions) { |
|
|
@ -825,7 +828,7 @@ class ClusterEngine { |
|
|
|
|
|
|
|
/** |
|
|
|
* Using a base edgeId, update all related clustered edges with the new options |
|
|
|
* @param startEdgeId |
|
|
|
* @param {vis.Edge.id} startEdgeId |
|
|
|
* @param {object} newOptions |
|
|
|
*/ |
|
|
|
updateEdge(startEdgeId, newOptions) { |
|
|
@ -843,8 +846,8 @@ class ClusterEngine { |
|
|
|
|
|
|
|
/** |
|
|
|
* Get a stack of clusterEdgeId's (+base edgeid) that a base edge is the same as. cluster edge C -> cluster edge B -> cluster edge A -> base edge(edgeId) |
|
|
|
* @param edgeId |
|
|
|
* @returns {Array} |
|
|
|
* @param {vis.Edge.id} edgeId |
|
|
|
* @returns {Array<vis.Edge.id>} |
|
|
|
*/ |
|
|
|
getClusteredEdges(edgeId) { |
|
|
|
let stack = []; |
|
|
@ -862,8 +865,8 @@ class ClusterEngine { |
|
|
|
|
|
|
|
/** |
|
|
|
* Get the base edge id of clusterEdgeId. cluster edge (clusteredEdgeId) -> cluster edge B -> cluster edge C -> base edge |
|
|
|
* @param clusteredEdgeId |
|
|
|
* @returns baseEdgeId |
|
|
|
* @param {vis.Edge.id} clusteredEdgeId |
|
|
|
* @returns {vis.Edge.id} baseEdgeId |
|
|
|
* |
|
|
|
* TODO: deprecate in 5.0.0. Method getBaseEdges() is the correct one to use. |
|
|
|
*/ |
|
|
@ -876,8 +879,8 @@ class ClusterEngine { |
|
|
|
/** |
|
|
|
* Get all regular edges for this clustered edge id. |
|
|
|
* |
|
|
|
* @param {Number} clusteredEdgeId |
|
|
|
* @returns {Array[Number} all baseEdgeId's under this clustered edge |
|
|
|
* @param {vis.Edge.id} clusteredEdgeId |
|
|
|
* @returns {Array<vis.Edge.id>} all baseEdgeId's under this clustered edge |
|
|
|
*/ |
|
|
|
getBaseEdges(clusteredEdgeId) { |
|
|
|
let IdsToHandle = [clusteredEdgeId]; |
|
|
@ -921,8 +924,8 @@ class ClusterEngine { |
|
|
|
|
|
|
|
/** |
|
|
|
* Get the Id the node is connected to |
|
|
|
* @param edge |
|
|
|
* @param nodeId |
|
|
|
* @param {vis.Edge} edge |
|
|
|
* @param {vis.Node.id} nodeId |
|
|
|
* @returns {*} |
|
|
|
* @private |
|
|
|
*/ |
|
|
@ -942,6 +945,7 @@ class ClusterEngine { |
|
|
|
* We determine how many connections denote an important hub. |
|
|
|
* We take the mean + 2*std as the important hub size. (Assuming a normal distribution of data, ~2.2%) |
|
|
|
* |
|
|
|
* @returns {Number} |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
_getHubSize() { |
|
|
@ -979,7 +983,12 @@ class ClusterEngine { |
|
|
|
/** |
|
|
|
* Create an edge for the cluster representation. |
|
|
|
* |
|
|
|
* @return {Edge} newly created clustered edge |
|
|
|
* @param {vis.Node.id} fromId |
|
|
|
* @param {vis.Node.id} toId |
|
|
|
* @param {vis.Edge} baseEdge |
|
|
|
* @param {Object} clusterEdgeProperties |
|
|
|
* @param {Object} extraOptions |
|
|
|
* @returns {Edge} newly created clustered edge |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
_createClusteredEdge(fromId, toId, baseEdge, clusterEdgeProperties, extraOptions) { |
|
|
@ -1012,9 +1021,10 @@ class ClusterEngine { |
|
|
|
/** |
|
|
|
* Add the passed child nodes and edges to the given cluster node. |
|
|
|
* |
|
|
|
* @param childNodes {Object|Node} hash of nodes or single node to add in cluster |
|
|
|
* @param childEdges {Object|Edge} hash of edges or single edge to take into account when clustering |
|
|
|
* @param clusterNode {Node} cluster node to add nodes and edges to |
|
|
|
* @param {Object|Node} childNodes hash of nodes or single node to add in cluster |
|
|
|
* @param {Object|Edge} childEdges hash of edges or single edge to take into account when clustering |
|
|
|
* @param {Node} clusterNode cluster node to add nodes and edges to |
|
|
|
* @param {Object} [clusterEdgeProperties] |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
_clusterEdges(childNodes, childEdges, clusterNode, clusterEdgeProperties) { |
|
|
@ -1075,7 +1085,8 @@ class ClusterEngine { |
|
|
|
* |
|
|
|
* NOTE: If you know a cleaner way to do this, please enlighten me (wimrijnders). |
|
|
|
* |
|
|
|
* @return {Node|undefined} Node instance for cluster, if present |
|
|
|
* @param {vis.Node.id} nodeId |
|
|
|
* @returns {Node|undefined} Node instance for cluster, if present |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
_getClusterNodeForNode(nodeId) { |
|
|
@ -1095,6 +1106,10 @@ class ClusterEngine { |
|
|
|
* Internal helper function for conditionally removing items in array |
|
|
|
* |
|
|
|
* Done like this because Array.filter() is not fully supported by all IE's. |
|
|
|
* |
|
|
|
* @param {Array} arr |
|
|
|
* @param {function} callback |
|
|
|
* @returns {Array} |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
_filter(arr, callback) { |
|
|
@ -1276,6 +1291,7 @@ class ClusterEngine { |
|
|
|
/** |
|
|
|
* Determine if node with given id is part of a cluster. |
|
|
|
* |
|
|
|
* @param {vis.Node.id} nodeId |
|
|
|
* @return {boolean} true if part of a cluster. |
|
|
|
*/ |
|
|
|
_isClusteredNode(nodeId) { |
|
|
@ -1290,6 +1306,7 @@ class ClusterEngine { |
|
|
|
* - it is directly replaced by a clustering edge |
|
|
|
* - any of its connecting nodes is in a cluster |
|
|
|
* |
|
|
|
* @param {vis.Edge.id} edgeId |
|
|
|
* @return {boolean} true if part of a cluster. |
|
|
|
*/ |
|
|
|
_isClusteredEdge(edgeId) { |
|
|
|