Skip to content
This repository has been archived by the owner on Nov 13, 2020. It is now read-only.

Commit

Permalink
Merge pull request #72 from vpanfilov/master
Browse files Browse the repository at this point in the history
Fix issue #71 (endless loop in mxHierarchicalLayout)
  • Loading branch information
davidjgraph committed May 28, 2020
2 parents 7949678 + b1d35b9 commit bae5d39
Showing 1 changed file with 49 additions and 7 deletions.
56 changes: 49 additions & 7 deletions src/com/mxgraph/layout/hierarchical/mxHierarchicalLayout.java
Expand Up @@ -18,6 +18,7 @@
import com.mxgraph.layout.hierarchical.stage.mxHierarchicalLayoutStage;
import com.mxgraph.layout.hierarchical.stage.mxMedianHybridCrossingReduction;
import com.mxgraph.layout.hierarchical.stage.mxMinimumCycleRemover;
import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxGraphModel;
import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.view.mxCellState;
Expand Down Expand Up @@ -404,13 +405,22 @@ public Set<Object> filterDescendants(Object cell)
for (int i = 0; i < childCount; i++)
{
Object child = model.getChildAt(cell, i);
result.addAll(filterDescendants(child));

// Ignore ports in the layout vertex list, they are dealt with
// in the traversal mechanisms
if (!isPort((mxCell) child)) {
result.addAll(filterDescendants(child));
}
}
}

return result;
}

private boolean isPort(mxCell cell) {
return cell.getGeometry().isRelative();
}

/**
* Traverses the (directed) graph invoking the given function for each
* visited vertex and edge. The function is invoked with the current vertex
Expand Down Expand Up @@ -451,19 +461,51 @@ protected void traverse(Object vertex, boolean directed, Object edge,

int edgeCount = model.getEdgeCount(vertex);

boolean[] edgeIsSource = new boolean[edgeCount];
if (edgeCount > 0) {
for (int i = 0; i < edgeCount; i++) {
Object e = model.getEdgeAt(vertex, i);
edgeIsSource[i] = view.getVisibleTerminal(e, true) == vertex;
}
}

if (edgeCount > 0)
{
for (int i = 0; i < edgeCount; i++)
{
Object e = model.getEdgeAt(vertex, i);
boolean isSource = view.getVisibleTerminal(e, true) == vertex;

if (!directed || isSource)
if (!directed || edgeIsSource[i])
{
Object next = view.getVisibleTerminal(e, !isSource);
traverse(next, directed, e, allVertices,
currentComp, hierarchyVertices,
filledVertexSet);
Object next = view.getVisibleTerminal(e, !edgeIsSource[i]);

// Check whether there are more edges incoming from the target vertex than outgoing
// The hierarchical model treats bi-directional parallel edges as being sourced
// from the more "sourced" terminal. If the directions are equal in number, the direction
// is that of the natural direction from the roots of the layout.
// The checks below are slightly more verbose than need be for performance reasons
int netCount = 1;

for (int j = 0; j < edgeCount; j++) {
if (j != i) {
boolean isSorce2 = edgeIsSource[j];
Object e2 = model.getEdgeAt(vertex, j);
Object otherTerm = view.getVisibleTerminal(e2, !isSorce2);
if (otherTerm == next) {
if (isSorce2) {
netCount++;
} else {
netCount--;
}
}
}
}

if (netCount >= 0){
traverse(next, directed, e, allVertices,
currentComp, hierarchyVertices,
filledVertexSet);
}
}
}
}
Expand Down

0 comments on commit bae5d39

Please sign in to comment.