Browse Source

refined clustering

css_transitions
Alex de Mulder 11 years ago
parent
commit
5e8d670e5e
3 changed files with 182 additions and 84 deletions
  1. +90
    -41
      src/graph/Graph.js
  2. +1
    -1
      src/graph/Node.js
  3. +91
    -42
      vis.js

+ 90
- 41
src/graph/Graph.js View File

@ -41,11 +41,11 @@ function Graph (container, data, options) {
background: '#D2E5FF' background: '#D2E5FF'
}, },
cluster: { cluster: {
border: '#000000',
background: '#F0F0F0',
border: '#256a2d',
background: '#2cd140',
highlight: { highlight: {
border: '#FF0FFF',
background: '#FF000F'
border: '#899539',
background: '#c5dc29'
} }
} }
}, },
@ -148,40 +148,9 @@ function Graph (container, data, options) {
// draw data // draw data
this.setData(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 * 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. * 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() { Graph.prototype.collapseClusterLevel = function() {
this._formClusters(true); this._formClusters(true);
}
};
/** /**
* This function can be called to decrease the cluster level. This means that the nodes with only one edge connection will * 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(); this._updateNodeIndexList();
}
};
/** /**
@ -216,7 +185,8 @@ Graph.prototype.expandClusterLevel = function() {
Graph.prototype.fullyOpenCluster = function(node) { Graph.prototype.fullyOpenCluster = function(node) {
this._expandClusterNode(node,true,true); this._expandClusterNode(node,true,true);
this._updateNodeIndexList(); this._updateNodeIndexList();
}
};
/** /**
* This function can be called to open up a specific cluster. * 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) { Graph.prototype.openCluster = function(node) {
this._expandClusterNode(node,false,true); this._expandClusterNode(node,false,true);
this._updateNodeIndexList(); 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 * 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._updateNodeIndexList();
}; };
/** /**
* This function checks if a node has to be opened. This is done by checking the zoom level. * 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. * 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 * 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. * 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 checks if any nodes at the end of their trees have edges below a threshold length
* This function is called only from _updateClusters() * 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() * This function is called only from _updateClusters()
* *
* @param parent_node | Node object: this is the node that will house the child node * @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.moving = true;
}; };
/** /**
* This function will apply the changes made to the remaining_edges during the formation of the clusters. * 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. * 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. * Set nodes and edges, and optionally options as well.
* *

+ 1
- 1
src/graph/Node.js View File

@ -66,7 +66,7 @@ function Node(properties, imagelist, grouplist, constants) {
this.vy = 0.0; // velocity y this.vy = 0.0; // velocity y
this.minForce = constants.minForce; this.minForce = constants.minForce;
this.damping = 0.9; // damping factor this.damping = 0.9; // damping factor
};
}
/** /**
* (re)setting the clustering variables and objects * (re)setting the clustering variables and objects

+ 91
- 42
vis.js View File

@ -12513,7 +12513,7 @@ function Node(properties, imagelist, grouplist, constants) {
this.vy = 0.0; // velocity y this.vy = 0.0; // velocity y
this.minForce = constants.minForce; this.minForce = constants.minForce;
this.damping = 0.9; // damping factor this.damping = 0.9; // damping factor
};
}
/** /**
* (re)setting the clustering variables and objects * (re)setting the clustering variables and objects
@ -14096,11 +14096,11 @@ function Graph (container, data, options) {
background: '#D2E5FF' background: '#D2E5FF'
}, },
cluster: { cluster: {
border: '#000000',
background: '#F0F0F0',
border: '#256a2d',
background: '#2cd140',
highlight: { highlight: {
border: '#FF0FFF',
background: '#FF000F'
border: '#899539',
background: '#c5dc29'
} }
} }
}, },
@ -14203,39 +14203,8 @@ function Graph (container, data, options) {
// draw data // draw data
this.setData(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 * 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() { Graph.prototype.collapseClusterLevel = function() {
this._formClusters(true); this._formClusters(true);
}
};
/** /**
* This function can be called to decrease the cluster level. This means that the nodes with only one edge connection will * 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(); this._updateNodeIndexList();
}
};
/** /**
@ -14271,7 +14240,8 @@ Graph.prototype.expandClusterLevel = function() {
Graph.prototype.fullyOpenCluster = function(node) { Graph.prototype.fullyOpenCluster = function(node) {
this._expandClusterNode(node,true,true); this._expandClusterNode(node,true,true);
this._updateNodeIndexList(); this._updateNodeIndexList();
}
};
/** /**
* This function can be called to open up a specific cluster. * 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) { Graph.prototype.openCluster = function(node) {
this._expandClusterNode(node,false,true); this._expandClusterNode(node,false,true);
this._updateNodeIndexList(); 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 * 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._updateNodeIndexList();
}; };
/** /**
* This function checks if a node has to be opened. This is done by checking the zoom level. * 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. * 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 * 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. * 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 checks if any nodes at the end of their trees have edges below a threshold length
* This function is called only from _updateClusters() * 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() * This function is called only from _updateClusters()
* *
* @param parent_node | Node object: this is the node that will house the child node * @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.moving = true;
}; };
/** /**
* This function will apply the changes made to the remaining_edges during the formation of the clusters. * 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. * 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. * Set nodes and edges, and optionally options as well.
* *

Loading…
Cancel
Save