visjs-network
Version:
A dynamic, browser-based network visualization library.
95 lines (83 loc) • 2.89 kB
JavaScript
let util = require('../../../../util')
let Node = require('../Node').default
/**
* A Cluster is a special Node that allows a group of Nodes positioned closely together
* to be represented by a single Cluster Node.
*
* @extends Node
*/
class Cluster extends Node {
/**
* @param {Object} options
* @param {Object} body
* @param {Array.<HTMLImageElement>}imagelist
* @param {Array} grouplist
* @param {Object} globalOptions
* @param {Object} defaultOptions Global default options for nodes
*/
constructor(
options,
body,
imagelist,
grouplist,
globalOptions,
defaultOptions
) {
super(options, body, imagelist, grouplist, globalOptions, defaultOptions)
this.isCluster = true
this.containedNodes = {}
this.containedEdges = {}
}
/**
* Transfer child cluster data to current and disconnect the child cluster.
*
* Please consult the header comment in 'Clustering.js' for the fields set here.
*
* @param {string|number} childClusterId id of child cluster to open
*/
_openChildCluster(childClusterId) {
let childCluster = this.body.nodes[childClusterId]
if (this.containedNodes[childClusterId] === undefined) {
throw new Error(
'node with id: ' + childClusterId + ' not in current cluster'
)
}
if (!childCluster.isCluster) {
throw new Error('node with id: ' + childClusterId + ' is not a cluster')
}
// Disconnect child cluster from current cluster
delete this.containedNodes[childClusterId]
util.forEach(childCluster.edges, edge => {
delete this.containedEdges[edge.id]
})
// Transfer nodes and edges
util.forEach(childCluster.containedNodes, (node, nodeId) => {
this.containedNodes[nodeId] = node
})
childCluster.containedNodes = {}
util.forEach(childCluster.containedEdges, (edge, edgeId) => {
this.containedEdges[edgeId] = edge
})
childCluster.containedEdges = {}
// Transfer edges within cluster edges which are clustered
util.forEach(childCluster.edges, clusterEdge => {
util.forEach(this.edges, parentClusterEdge => {
// Assumption: a clustered edge can only be present in a single clustering edge
// Not tested here
let index = parentClusterEdge.clusteringEdgeReplacingIds.indexOf(
clusterEdge.id
)
if (index === -1) return
util.forEach(clusterEdge.clusteringEdgeReplacingIds, srcId => {
parentClusterEdge.clusteringEdgeReplacingIds.push(srcId)
// Maintain correct bookkeeping for transferred edge
this.body.edges[srcId].edgeReplacedById = parentClusterEdge.id
})
// Remove cluster edge from parent cluster edge
parentClusterEdge.clusteringEdgeReplacingIds.splice(index, 1)
})
})
childCluster.edges = []
}
}
export default Cluster