From 5e8d670e5e073076dd06798646a4d498e8ec56f6 Mon Sep 17 00:00:00 2001 From: Alex de Mulder Date: Wed, 8 Jan 2014 16:46:22 +0100 Subject: [PATCH] refined clustering --- src/graph/Graph.js | 131 ++++++++++++++++++++++++++++++-------------- src/graph/Node.js | 2 +- vis.js | 133 +++++++++++++++++++++++++++++++-------------- 3 files changed, 182 insertions(+), 84 deletions(-) diff --git a/src/graph/Graph.js b/src/graph/Graph.js index 2c35bbd7..fdef88d9 100644 --- a/src/graph/Graph.js +++ b/src/graph/Graph.js @@ -41,11 +41,11 @@ function Graph (container, data, options) { background: '#D2E5FF' }, cluster: { - border: '#000000', - background: '#F0F0F0', + border: '#256a2d', + background: '#2cd140', highlight: { - border: '#FF0FFF', - background: '#FF000F' + border: '#899539', + background: '#c5dc29' } } }, @@ -148,40 +148,9 @@ function Graph (container, data, options) { // draw data this.setData(data); -}; +} -/** - * This function checks if the zoom action is in or out. - * If out, check if we can form clusters, if in, check if we can open clusters. - * This function is only called from _zoom() - * - * @private - */ -Graph.prototype._updateClusters = function() { - var moving_before_clustering = this.moving; - - if (this.previous_scale > this.scale) { // zoom out - this._formClusters(false); - } - else if (this.previous_scale < this.scale) { // zoom out - this._openClusters(); - } - - // update node labels - for (var nid in this.nodes) { - var node = this.nodes[nid]; - node.label = String(node.remaining_edges).concat(":",String(node.cluster_size)); - } - - this.previous_scale = this.scale; - - // if the simulation was settled, we restart the simulation if a cluster has been formed or expanded - if (this.moving != moving_before_clustering) { - this.start(); - } -}; - /** * This function can be called to increase the cluster level. This means that the nodes with only one edge connection will * be clustered with their connected node. This can be repeated as many times as needed. @@ -189,7 +158,7 @@ Graph.prototype._updateClusters = function() { */ Graph.prototype.collapseClusterLevel = function() { this._formClusters(true); -} +}; /** * This function can be called to decrease the cluster level. This means that the nodes with only one edge connection will @@ -204,7 +173,7 @@ Graph.prototype.expandClusterLevel = function() { } } this._updateNodeIndexList(); -} +}; /** @@ -216,7 +185,8 @@ Graph.prototype.expandClusterLevel = function() { Graph.prototype.fullyOpenCluster = function(node) { this._expandClusterNode(node,true,true); this._updateNodeIndexList(); -} +}; + /** * This function can be called to open up a specific cluster. @@ -227,7 +197,81 @@ Graph.prototype.fullyOpenCluster = function(node) { Graph.prototype.openCluster = function(node) { this._expandClusterNode(node,false,true); this._updateNodeIndexList(); -} +}; + + +/** + * This function checks if the zoom action is in or out. + * If out, check if we can form clusters, if in, check if we can open clusters. + * This function is only called from _zoom() + * + * @private + */ +Graph.prototype._updateClusters = function() { + var moving_before_clustering = this.moving; + + if (this.previous_scale > this.scale) { // zoom out + this._formClusters(false); + } + else if (this.previous_scale < this.scale) { // zoom out + this._openClusters(); + } + + this._updateClusterLabels(); + this._updateNodeLabels(); + + this.previous_scale = this.scale; + + // if the simulation was settled, we restart the simulation if a cluster has been formed or expanded + if (this.moving != moving_before_clustering) { + this.start(); + } +}; + +/** + * This updates the node labels for all nodes (for debugging purposes) + * @private + */ +Graph.prototype._updateLabels = function() { + // update node labels + for (var node_id in this.nodes) { + if (this.nodes.hasOwnProperty(node_id)) { + var node = this.nodes[node_id]; + node.label = String(node.remaining_edges).concat(":",String(node.cluster_size)); + } + } +}; + +/** + * This updates the node labels for all clusters + * @private + */ +Graph.prototype._updateClusterLabels = function() { + // update node labels + for (var node_id in this.nodes) { + if (this.nodes.hasOwnProperty(node_id)) { + var node = this.nodes[node_id]; + if (node.cluster_size > 1) { + node.label = "[".concat(String(node.cluster_size),"]"); + } + } + } +}; + +/** + * This updates the node labels for all nodes that are NOT clusters + * @private + */ +Graph.prototype._updateNodeLabels = function() { + // update node labels + for (var node_id in this.nodes) { + var node = this.nodes[node_id]; + if (node.cluster_size == 1) { + node.label = "[".concat(String(node.cluster_size),"]"); + } + } +}; + /** * This function loops over all nodes in the node_indices list. For each node it checks if it is a cluster and if it @@ -244,6 +288,7 @@ Graph.prototype._openClusters = function() { this._updateNodeIndexList(); }; + /** * This function checks if a node has to be opened. This is done by checking the zoom level. * If the node contains child nodes, this function is recursively called on the child nodes as well. @@ -295,6 +340,7 @@ Graph.prototype._expandClusterNode = function(node, recursive, force_expand) { } }; + /** * This function will expel a child_node from a parent_node. This is to de-cluster the node. This function will remove * the child node from the parent contained_node object and put it back into the global nodes object. @@ -339,6 +385,7 @@ Graph.prototype._expelChildFromParent = function(node, contained_node_id, recurs }; + /** * This function checks if any nodes at the end of their trees have edges below a threshold length * This function is called only from _updateClusters() @@ -409,7 +456,7 @@ Graph.prototype._formClusters = function(force_level_collapse) { /** - * This function adds the childnode to the parentnode, creating a cluster if it is not already. + * This function adds the child node to the parent node, creating a cluster if it is not already. * This function is called only from _updateClusters() * * @param parent_node | Node object: this is the node that will house the child node @@ -445,6 +492,7 @@ Graph.prototype._addToCluster = function(parent_node, child_node, edge, edge_id, this.moving = true; }; + /** * This function will apply the changes made to the remaining_edges during the formation of the clusters. * This is a seperate function to allow for level-wise collapsing of the node tree. @@ -473,6 +521,7 @@ Graph.prototype._updateNodeIndexList = function() { } }; + /** * Set nodes and edges, and optionally options as well. * diff --git a/src/graph/Node.js b/src/graph/Node.js index b4bebe1e..fd6b974b 100644 --- a/src/graph/Node.js +++ b/src/graph/Node.js @@ -66,7 +66,7 @@ function Node(properties, imagelist, grouplist, constants) { this.vy = 0.0; // velocity y this.minForce = constants.minForce; this.damping = 0.9; // damping factor -}; +} /** * (re)setting the clustering variables and objects diff --git a/vis.js b/vis.js index fc0b086c..e65cbeef 100644 --- a/vis.js +++ b/vis.js @@ -12513,7 +12513,7 @@ function Node(properties, imagelist, grouplist, constants) { this.vy = 0.0; // velocity y this.minForce = constants.minForce; this.damping = 0.9; // damping factor -}; +} /** * (re)setting the clustering variables and objects @@ -14096,11 +14096,11 @@ function Graph (container, data, options) { background: '#D2E5FF' }, cluster: { - border: '#000000', - background: '#F0F0F0', + border: '#256a2d', + background: '#2cd140', highlight: { - border: '#FF0FFF', - background: '#FF000F' + border: '#899539', + background: '#c5dc29' } } }, @@ -14203,39 +14203,8 @@ function Graph (container, data, options) { // draw data this.setData(data); -}; - - -/** - * This function checks if the zoom action is in or out. - * If out, check if we can form clusters, if in, check if we can open clusters. - * This function is only called from _zoom() - * - * @private - */ -Graph.prototype._updateClusters = function() { - var moving_before_clustering = this.moving; - - if (this.previous_scale > this.scale) { // zoom out - this._formClusters(false); - } - else if (this.previous_scale < this.scale) { // zoom out - this._openClusters(); - } - - // update node labels - for (var nid in this.nodes) { - var node = this.nodes[nid]; - node.label = String(node.remaining_edges).concat(":",String(node.cluster_size)); - } - - this.previous_scale = this.scale; +} - // if the simulation was settled, we restart the simulation if a cluster has been formed or expanded - if (this.moving != moving_before_clustering) { - this.start(); - } -}; /** * This function can be called to increase the cluster level. This means that the nodes with only one edge connection will @@ -14244,7 +14213,7 @@ Graph.prototype._updateClusters = function() { */ Graph.prototype.collapseClusterLevel = function() { this._formClusters(true); -} +}; /** * This function can be called to decrease the cluster level. This means that the nodes with only one edge connection will @@ -14259,7 +14228,7 @@ Graph.prototype.expandClusterLevel = function() { } } this._updateNodeIndexList(); -} +}; /** @@ -14271,7 +14240,8 @@ Graph.prototype.expandClusterLevel = function() { Graph.prototype.fullyOpenCluster = function(node) { this._expandClusterNode(node,true,true); this._updateNodeIndexList(); -} +}; + /** * This function can be called to open up a specific cluster. @@ -14282,7 +14252,81 @@ Graph.prototype.fullyOpenCluster = function(node) { Graph.prototype.openCluster = function(node) { this._expandClusterNode(node,false,true); this._updateNodeIndexList(); -} +}; + + +/** + * This function checks if the zoom action is in or out. + * If out, check if we can form clusters, if in, check if we can open clusters. + * This function is only called from _zoom() + * + * @private + */ +Graph.prototype._updateClusters = function() { + var moving_before_clustering = this.moving; + + if (this.previous_scale > this.scale) { // zoom out + this._formClusters(false); + } + else if (this.previous_scale < this.scale) { // zoom out + this._openClusters(); + } + + this._updateClusterLabels(); + this._updateNodeLabels(); + + this.previous_scale = this.scale; + + // if the simulation was settled, we restart the simulation if a cluster has been formed or expanded + if (this.moving != moving_before_clustering) { + this.start(); + } +}; + +/** + * This updates the node labels for all nodes (for debugging purposes) + * @private + */ +Graph.prototype._updateLabels = function() { + // update node labels + for (var node_id in this.nodes) { + if (this.nodes.hasOwnProperty(node_id)) { + var node = this.nodes[node_id]; + node.label = String(node.remaining_edges).concat(":",String(node.cluster_size)); + } + } +}; + +/** + * This updates the node labels for all clusters + * @private + */ +Graph.prototype._updateClusterLabels = function() { + // update node labels + for (var node_id in this.nodes) { + if (this.nodes.hasOwnProperty(node_id)) { + var node = this.nodes[node_id]; + if (node.cluster_size > 1) { + node.label = "[".concat(String(node.cluster_size),"]"); + } + } + } +}; + +/** + * This updates the node labels for all nodes that are NOT clusters + * @private + */ +Graph.prototype._updateNodeLabels = function() { + // update node labels + for (var node_id in this.nodes) { + var node = this.nodes[node_id]; + if (node.cluster_size == 1) { + node.label = "[".concat(String(node.cluster_size),"]"); + } + } +}; + /** * This function loops over all nodes in the node_indices list. For each node it checks if it is a cluster and if it @@ -14299,6 +14343,7 @@ Graph.prototype._openClusters = function() { this._updateNodeIndexList(); }; + /** * This function checks if a node has to be opened. This is done by checking the zoom level. * If the node contains child nodes, this function is recursively called on the child nodes as well. @@ -14350,6 +14395,7 @@ Graph.prototype._expandClusterNode = function(node, recursive, force_expand) { } }; + /** * This function will expel a child_node from a parent_node. This is to de-cluster the node. This function will remove * the child node from the parent contained_node object and put it back into the global nodes object. @@ -14394,6 +14440,7 @@ Graph.prototype._expelChildFromParent = function(node, contained_node_id, recurs }; + /** * This function checks if any nodes at the end of their trees have edges below a threshold length * This function is called only from _updateClusters() @@ -14464,7 +14511,7 @@ Graph.prototype._formClusters = function(force_level_collapse) { /** - * This function adds the childnode to the parentnode, creating a cluster if it is not already. + * This function adds the child node to the parent node, creating a cluster if it is not already. * This function is called only from _updateClusters() * * @param parent_node | Node object: this is the node that will house the child node @@ -14500,6 +14547,7 @@ Graph.prototype._addToCluster = function(parent_node, child_node, edge, edge_id, this.moving = true; }; + /** * This function will apply the changes made to the remaining_edges during the formation of the clusters. * This is a seperate function to allow for level-wise collapsing of the node tree. @@ -14528,6 +14576,7 @@ Graph.prototype._updateNodeIndexList = function() { } }; + /** * Set nodes and edges, and optionally options as well. *