@ -44,6 +44,7 @@ class ClusterEngine {
for ( let i = 0 ; i < nodesToCluster . length ; i ++ ) {
for ( let i = 0 ; i < nodesToCluster . length ; i ++ ) {
this . clusterByConnection ( nodesToCluster [ i ] , options , false ) ;
this . clusterByConnection ( nodesToCluster [ i ] , options , false ) ;
}
}
this . body . emitter . emit ( '_dataChanged' ) ;
this . body . emitter . emit ( '_dataChanged' ) ;
}
}
@ -83,11 +84,12 @@ class ClusterEngine {
/ * *
/ * *
* Cluster all nodes in the network that have only 1 edge
* @ param options
* @ param refreshData
* /
clusterOutliers ( options , refreshData = true ) {
* Cluster all nodes in the network that have only X edges
* @ param edgeCount
* @ param options
* @ param refreshData
* /
clusterByEdgeCount ( edgeCount , options , refreshData = true ) {
options = this . _checkOptions ( options ) ;
options = this . _checkOptions ( options ) ;
let clusters = [ ] ;
let clusters = [ ] ;
@ -105,8 +107,8 @@ class ClusterEngine {
}
}
}
}
if ( visibleEdges === 1 ) {
// this is an outlier
if ( visibleEdges === edgeCount ) {
// this is a qualifying node
let childNodeId = this . _getConnectedId ( edge , nodeId ) ;
let childNodeId = this . _getConnectedId ( edge , nodeId ) ;
if ( childNodeId !== nodeId ) {
if ( childNodeId !== nodeId ) {
if ( options . joinCondition === undefined ) {
if ( options . joinCondition === undefined ) {
@ -145,6 +147,24 @@ class ClusterEngine {
}
}
}
}
/ * *
* Cluster all nodes in the network that have only 1 edge
* @ param options
* @ param refreshData
* /
clusterOutliers ( options , refreshData = true ) {
this . clusterByEdgeCount ( 1 , options , refreshData ) ;
}
/ * *
* Cluster all nodes in the network that have only 2 edge
* @ param options
* @ param refreshData
* /
clusterBridges ( options , refreshData = true ) {
this . clusterByEdgeCount ( 2 , options , refreshData ) ;
}
_checkIfUsed ( clusters , nodeId , edgeId ) {
_checkIfUsed ( clusters , nodeId , edgeId ) {
for ( let i = 0 ; i < clusters . length ; i ++ ) {
for ( let i = 0 ; i < clusters . length ; i ++ ) {
@ -189,25 +209,26 @@ class ClusterEngine {
let edge = node . edges [ i ] ;
let edge = node . edges [ i ] ;
let childNodeId = this . _getConnectedId ( edge , parentNodeId ) ;
let childNodeId = this . _getConnectedId ( edge , parentNodeId ) ;
if ( childNodeId !== parentNodeId ) {
if ( options . joinCondition === undefined ) {
childEdgesObj [ edge . id ] = edge ;
childNodesObj [ childNodeId ] = this . body . nodes [ childNodeId ] ;
}
else {
// clone the options and insert some additional parameters that could be interesting.
let childClonedOptions = this . _cloneOptions ( this . body . nodes [ childNodeId ] ) ;
if ( options . joinCondition ( parentClonedOptions , childClonedOptions ) === true ) {
if ( this . clusteredNodes [ childNodeId ] === undefined ) {
if ( childNodeId !== parentNodeId ) {
if ( options . joinCondition === undefined ) {
childEdgesObj [ edge . id ] = edge ;
childEdgesObj [ edge . id ] = edge ;
childNodesObj [ childNodeId ] = this . body . nodes [ childNodeId ] ;
childNodesObj [ childNodeId ] = this . body . nodes [ childNodeId ] ;
}
}
else {
// clone the options and insert some additional parameters that could be interesting.
let childClonedOptions = this . _cloneOptions ( this . body . nodes [ childNodeId ] ) ;
if ( options . joinCondition ( parentClonedOptions , childClonedOptions ) === true ) {
childEdgesObj [ edge . id ] = edge ;
childNodesObj [ childNodeId ] = this . body . nodes [ childNodeId ] ;
}
}
}
else {
childEdgesObj [ edge . id ] = edge ;
}
}
}
else {
childEdgesObj [ edge . id ] = edge ;
}
}
}
}
this . _cluster ( childNodesObj , childEdgesObj , options , refreshData ) ;
this . _cluster ( childNodesObj , childEdgesObj , options , refreshData ) ;
}
}
@ -304,9 +325,19 @@ class ClusterEngine {
* @ private
* @ private
* /
* /
_cluster ( childNodesObj , childEdgesObj , options , refreshData = true ) {
_cluster ( childNodesObj , childEdgesObj , options , refreshData = true ) {
// kill condition: no children so cant cluster
// kill condition: no children so can' t cluster
if ( Object . keys ( childNodesObj ) . length === 0 ) { return ; }
if ( Object . keys ( childNodesObj ) . length === 0 ) { return ; }
// check if this cluster call is not trying to cluster anything that is in another cluster.
for ( let nodeId in childNodesObj ) {
if ( childNodesObj . hasOwnProperty ( nodeId ) ) {
if ( this . clusteredNodes [ nodeId ] !== undefined ) {
return ;
}
}
}
let clusterNodeProperties = util . deepExtend ( { } , options . clusterNodeProperties ) ;
let clusterNodeProperties = util . deepExtend ( { } , options . clusterNodeProperties ) ;
// construct the clusterNodeProperties
// construct the clusterNodeProperties
@ -314,17 +345,21 @@ class ClusterEngine {
// get the childNode options
// get the childNode options
let childNodesOptions = [ ] ;
let childNodesOptions = [ ] ;
for ( let nodeId in childNodesObj ) {
for ( let nodeId in childNodesObj ) {
let clonedOptions = this . _cloneOptions ( childNodesObj [ nodeId ] ) ;
childNodesOptions . push ( clonedOptions ) ;
if ( childNodesObj . hasOwnProperty ( nodeId ) ) {
let clonedOptions = this . _cloneOptions ( childNodesObj [ nodeId ] ) ;
childNodesOptions . push ( clonedOptions ) ;
}
}
}
// get clusterproperties based on childNodes
// get clusterproperties based on childNodes
let childEdgesOptions = [ ] ;
let childEdgesOptions = [ ] ;
for ( let edgeId in childEdgesObj ) {
for ( let edgeId in childEdgesObj ) {
// these cluster edges will be removed on creation of the cluster.
if ( edgeId . substr ( 0 , 12 ) !== "clusterEdge:" ) {
let clonedOptions = this . _cloneOptions ( childEdgesObj [ edgeId ] , 'edge' ) ;
childEdgesOptions . push ( clonedOptions ) ;
if ( childEdgesObj . hasOwnProperty ( edgeId ) ) {
// these cluster edges will be removed on creation of the cluster.
if ( edgeId . substr ( 0 , 12 ) !== "clusterEdge:" ) {
let clonedOptions = this . _cloneOptions ( childEdgesObj [ edgeId ] , 'edge' ) ;
childEdgesOptions . push ( clonedOptions ) ;
}
}
}
}
}