Skip to content

Commit

Permalink
Allow multiple edges to be hidden by a clustered edge.
Browse files Browse the repository at this point in the history
Fix for almende#3245.

This fix adjusts the clustering edges so that theyi can refer to multiple edges instead of just one.

This API method is now insufficient, since multiple base edges can be returned.

- Added replacing method `clustering.getBaseEdges()`
- Adjusted example `changingClusteredEdgeNodes` for the new method. This is the *only* place where `getBaseEdge()` was used
- Adjusted documentation for new method and deprecation old method.

Method `getbaseEdge()` should now be considered `deprecated`, and in due time should be removed.
  • Loading branch information
wimrijnders committed Jul 18, 2017
1 parent 48686fd commit e05b676
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 14 deletions.
15 changes: 14 additions & 1 deletion docs/network/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -644,10 +644,23 @@ <h2 id="methods">Methods</h2>
</tr>
<tr class="hidden" parent="getBaseEdge">
<td class="midMethods">Returns: Value</td>
<td>When a clusteredEdgeId is available, this method will return the original baseEdgeId provided in <code>data.edges</code><br/>
<td><b>This method is deprecated</b>. Use <code>getBaseEdges()</code> instead.<br><br>
When a clusteredEdgeId is available, this method will return the original baseEdgeId provided in <code>data.edges</code><br/>
ie. After clustering the 'SelectEdge' event is fired but provides only the clustered edge. This method can then be used to return the baseEdgeId.
</td>
</tr>
<tr class="collapsible toggle" onclick="toggleTable('methodTable','getBaseEdges', this);">
<td colspan="2"><span parent="getBaseEdges" class="right-caret" id="method_getBaseEdges"></span>
getBaseEdges(<code>String clusteredEdgeId</code>)
</td>
</tr>
<tr class="hidden" parent="getBaseEdges">
<td class="midMethods">Returns: Array</td>
<td>For the given <code>clusteredEdgeId</code>, this method will return all the original base edge id's provided in <code>data.edges</code>.
For a non-clustered (i.e. 'base') edge, <code>clusteredEdgeId</code> is returned.<br/><br/>
Only the base edge id's are returned. All clustered edges id's under <code>clusteredEdgeId</code> are skipped, but scanned recursively to return their base id's.<br/>
</td>
</tr>
<tr class="collapsible toggle" onclick="toggleTable('methodTable','updateEdge', this);">
<td colspan="2"><span parent="updateEdge" class="right-caret" id="method_updateEdge"></span> updateEdge(
<code>String startEdgeId, Object options</code>)
Expand Down
2 changes: 1 addition & 1 deletion examples/network/other/changingClusteredEdgesNodes.html
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
var obj = {};
obj.clicked_id = params.edges[0];
network.clustering.updateEdge(params.edges[0], {color : '#aa0000'});
obj.base_edge = network.clustering.getBaseEdge(params.edges[0]);
obj.base_edges = network.clustering.getBaseEdges(params.edges[0]);
obj.all_clustered_edges = network.clustering.getClusteredEdges(params.edges[0]);
document.getElementById('eventSpan').innerHTML = '<h2>selectEdge event:</h2>' + JSON.stringify(obj, null, 4);
}
Expand Down
68 changes: 56 additions & 12 deletions lib/network/modules/Clustering.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,11 @@ class ClusterEngine {
for (let j = 0; j < newEdges.length; j++) {
let newEdge = newEdges[j];

if (createdEdge.fromId === newEdge.fromId
&& createdEdge.toId === newEdge.toId ) {
// We replace both to and from edges with a single cluster edge
let matchToDirection = (createdEdge.fromId === newEdge.fromId && createdEdge.toId === newEdge.toId);
let matchFromDirection = (createdEdge.fromId === newEdge.toId && createdEdge.toId === newEdge.fromId);

if (matchToDirection || matchFromDirection ) {
return newEdge;
}
}
Expand Down Expand Up @@ -631,10 +634,13 @@ class ClusterEngine {
let edge = edgesToBeDeleted[i];
let otherNodeId = this._getConnectedId(edge, clusterNodeId);
let otherNode = this.clusteredNodes[otherNodeId];
let transferEdge = this.body.edges[edge.clusteringEdgeReplacingId];

// if the other node is in another cluster, we transfer ownership of this edge to the other cluster
if (transferEdge !== undefined) {
for (let j = 0; j < edge.clusteringEdgeReplacingIds.length; j++) {
let transferId = edge.clusteringEdgeReplacingIds[j];
let transferEdge = this.body.edges[transferId];
if (transferEdge === undefined) continue;

// if the other node is in another cluster, we transfer ownership of this edge to the other cluster
if (otherNode !== undefined) {
// transfer ownership:
let otherCluster = this.body.nodes[otherNode.clusterId];
Expand Down Expand Up @@ -787,22 +793,60 @@ class ClusterEngine {
* Get the base edge id of clusterEdgeId. cluster edge (clusteredEdgeId) -> cluster edge B -> cluster edge C -> base edge
* @param clusteredEdgeId
* @returns baseEdgeId
* @deprecated
*/
getBaseEdge(clusteredEdgeId) {
let baseEdgeId = clusteredEdgeId;
let max = 100;
// Just kludge this by returning the first base edge id found
return this.getBaseEdges(clusteredEdgeId)[0];
}


/**
* Get all regular edges for this clustered edge id.
*
* @param {Number} clusteredEdgeId
* @returns {Array[Number} all baseEdgeId's under this clustered edge
*/
getBaseEdges(clusteredEdgeId) {
let IdsToHandle = [clusteredEdgeId];
let doneIds = [];
let foundIds = [];
let max = 100;
let counter = 0;

while (clusteredEdgeId !== undefined && this.body.edges[clusteredEdgeId] !== undefined && counter < max) {
clusteredEdgeId = this.body.edges[clusteredEdgeId].clusteringEdgeReplacingId;
while (IdsToHandle.length > 0 && counter < max) {
let nextId = IdsToHandle.pop();
if (nextId === undefined) continue; // Paranoia here and onwards
let nextEdge = this.body.edges[nextId];
if (nextEdge === undefined) continue;
counter++;
if (clusteredEdgeId !== undefined) {
baseEdgeId = clusteredEdgeId;

let replacingIds = nextEdge.clusteringEdgeReplacingIds;
if (replacingIds === undefined) {
// nextId is a base id
foundIds.push(nextId);
} else {
// Another cluster edge, unravel this one as well
for (let i = 0; i < replacingIds.length; ++i) {
let replacingId = replacingIds[i];

// Don't add if already handled
// TODO: never triggers; find a test-case which does
if (IdsToHandle.indexOf(replacingIds) !== -1 || doneIds.indexOf(replacingIds) !== -1) {
continue;
}

IdsToHandle.push(replacingId);
}
}

doneIds.push(nextId);
}
return baseEdgeId;

return foundIds;
}


/**
* Get the Id the node is connected to
* @param edge
Expand Down

0 comments on commit e05b676

Please sign in to comment.