vis.js is a dynamic, browser-based visualization library
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 lines
2.7 KiB

  1. let util = require("../../../../util");
  2. let Node = require("../Node").default;
  3. /**
  4. * A Cluster is a special Node that allows a group of Nodes positioned closely together
  5. * to be represented by a single Cluster Node.
  6. *
  7. * @extends Node
  8. */
  9. class Cluster extends Node {
  10. /**
  11. * @param {Object} options
  12. * @param {Object} body
  13. * @param {Array.<HTMLImageElement>}imagelist
  14. * @param {Array} grouplist
  15. * @param {Object} globalOptions
  16. */
  17. constructor(options, body, imagelist, grouplist, globalOptions) {
  18. super(options, body, imagelist, grouplist, globalOptions);
  19. this.isCluster = true;
  20. this.containedNodes = {};
  21. this.containedEdges = {};
  22. }
  23. /**
  24. * Transfer child cluster data to current and disconnect the child cluster.
  25. *
  26. * Please consult the header comment in 'Clustering.js' for the fields set here.
  27. *
  28. * @param {string|number} childClusterId id of child cluster to open
  29. */
  30. _openChildCluster(childClusterId) {
  31. let childCluster = this.body.nodes[childClusterId];
  32. if (this.containedNodes[childClusterId] === undefined) {
  33. throw new Error('node with id: ' + childClusterId + ' not in current cluster');
  34. }
  35. if (!childCluster.isCluster) {
  36. throw new Error('node with id: ' + childClusterId + ' is not a cluster');
  37. }
  38. // Disconnect child cluster from current cluster
  39. delete this.containedNodes[childClusterId];
  40. util.forEach(childCluster.edges, (edge) => {
  41. delete this.containedEdges[edge.id];
  42. });
  43. // Transfer nodes and edges
  44. util.forEach(childCluster.containedNodes, (node, nodeId) => {
  45. this.containedNodes[nodeId] = node;
  46. });
  47. childCluster.containedNodes = {};
  48. util.forEach(childCluster.containedEdges, (edge, edgeId) => {
  49. this.containedEdges[edgeId] = edge;
  50. });
  51. childCluster.containedEdges = {};
  52. // Transfer edges within cluster edges which are clustered
  53. util.forEach(childCluster.edges, (clusterEdge) => {
  54. util.forEach(this.edges, (parentClusterEdge) => {
  55. // Assumption: a clustered edge can only be present in a single clustering edge
  56. // Not tested here
  57. let index = parentClusterEdge.clusteringEdgeReplacingIds.indexOf(clusterEdge.id);
  58. if (index === -1) return;
  59. util.forEach(clusterEdge.clusteringEdgeReplacingIds, (srcId) => {
  60. parentClusterEdge.clusteringEdgeReplacingIds.push(srcId);
  61. // Maintain correct bookkeeping for transferred edge
  62. this.body.edges[srcId].edgeReplacedById = parentClusterEdge.id;
  63. });
  64. // Remove cluster edge from parent cluster edge
  65. parentClusterEdge.clusteringEdgeReplacingIds.splice(index, 1);
  66. });
  67. });
  68. childCluster.edges = [];
  69. }
  70. }
  71. export default Cluster;