use of org.eclipse.elk.alg.layered.graph.LGraph in project elk by eclipse.
the class CrossHierarchyEdgeComparator method hierarchyLevel.
/**
* Compute the hierarchy level of the given nested graph.
*
* @param nestedGraph a nested graph
* @param topLevelGraph the top-level graph
* @return the hierarchy level (higher number means the node is nested deeper)
*/
private static int hierarchyLevel(final LGraph nestedGraph, final LGraph topLevelGraph) {
LGraph currentGraph = nestedGraph;
int level = 0;
do {
if (currentGraph == topLevelGraph) {
return level;
}
LNode currentNode = currentGraph.getParentNode();
if (currentNode == null) {
// the given node is not an ancestor of the graph node
throw new IllegalArgumentException();
}
currentGraph = currentNode.getGraph();
level++;
} while (true);
}
use of org.eclipse.elk.alg.layered.graph.LGraph in project elk by eclipse.
the class SelfLoopPreProcessor method hidePorts.
/**
* Possibly hides all ports whose only incident edges are self loops. This is only done if port constraints are not
* at least {@link PortConstraints#FIXED_ORDER}.
*/
private void hidePorts(final SelfLoopHolder slHolder) {
LNode lNode = slHolder.getLNode();
LGraph nestedGraph = lNode.getNestedGraph();
/* There are two cases in which we want to refrain from hiding ports:
* 1. The port order is already fixed. Then the code that would compute a proper port order won't be confused by
* the self-loop ports, so there's no need to hide them.
* 2. The self loop holder has another graph inside of it which contains external ports. In that case, the
* crossing minimization will compute proper port orders. The self loop holder will have the port order
* applied and its port constraints set to FIXED_POS, so this is basically the first case with extra steps.
*/
boolean orderFixed = lNode.getProperty(LayeredOptions.PORT_CONSTRAINTS).isOrderFixed();
boolean hierarchyMode = nestedGraph != null && nestedGraph.getProperty(InternalProperties.GRAPH_PROPERTIES).contains(GraphProperties.EXTERNAL_PORTS);
if (orderFixed || hierarchyMode) {
// No need to hide any ports
return;
}
for (SelfLoopPort slPort : slHolder.getSLPortMap().values()) {
if (slPort.hadOnlySelfLoops()) {
// Hide the port
LPort lPort = slPort.getLPort();
lPort.setNode(null);
// Remember that we actually did so
slPort.setHidden(true);
slHolder.setPortsHidden(true);
// run into this case.
assert lPort.getProperty(InternalProperties.PORT_DUMMY) == null;
}
}
}
use of org.eclipse.elk.alg.layered.graph.LGraph in project elk by eclipse.
the class SemiInteractiveCrossMinProcessor method process.
@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor progressMonitor) {
progressMonitor.begin("Semi-Interactive Crossing Minimization Processor", 1);
boolean addedConstraints = false;
for (Layer l : layeredGraph) {
// #1 extract relevant nodes
// #2 sort them with ascending y coordinate
// #3 introduce pair-wise in-layer constraints
Optional<LNode> reduced = l.getNodes().stream().filter(n -> n.getType() == NodeType.NORMAL).filter(n -> n.getAllProperties().containsKey(LayeredOptions.POSITION)).sorted((n1, n2) -> {
KVector origPos1 = n1.getProperty(LayeredOptions.POSITION);
KVector origPos2 = n2.getProperty(LayeredOptions.POSITION);
return Double.compare(origPos1.y, origPos2.y);
}).reduce((prev, cur) -> {
prev.getProperty(InternalProperties.IN_LAYER_SUCCESSOR_CONSTRAINTS).add(cur);
return cur;
});
addedConstraints |= reduced.isPresent();
}
// If we added in-layer successor constraints, make subsequent phases aware
if (addedConstraints) {
layeredGraph.setProperty(InternalProperties.IN_LAYER_SUCCESSOR_CONSTRAINTS_BETWEEN_NON_DUMMIES, true);
}
progressMonitor.done();
}
use of org.eclipse.elk.alg.layered.graph.LGraph in project elk by eclipse.
the class LGraphToCGraphTransformer method applyLayout.
/**
* Apply the layout from the internal constraint graph back to the original lgraph.
*/
public void applyLayout() {
// apply the compacted positions to nodes
cGraph.cNodes.stream().filter(cNode -> cNode.origin instanceof LNode).forEach(cNode -> {
LNode lNode = (LNode) cNode.origin;
lNode.getPosition().x = cNode.hitbox.x + lNode.getMargin().left;
});
// adjust comment boxes
applyCommentPositions();
// apply new positions to vertical segments
cGraph.cNodes.stream().filter(cNode -> cNode.origin instanceof VerticalSegment).forEach(cNode -> {
double deltaX = cNode.hitbox.x - cNode.hitboxPreCompaction.x;
VerticalSegment vs = (VerticalSegment) cNode.origin;
vs.affectedBends.forEach(b -> b.x += deltaX);
vs.affectedBoundingBoxes.forEach(bb -> bb.x += deltaX);
vs.junctionPoints.forEach(jp -> jp.x += deltaX);
});
// be properly located in between non-straight parts
if (edgeRouting == EdgeRouting.SPLINES) {
// offset selfloops of splines
nodesMap.keySet().stream().flatMap(n -> StreamSupport.stream(n.getOutgoingEdges().spliterator(), false)).filter(e -> e.isSelfLoop()).forEach(sl -> {
LNode lNode = sl.getSource().getNode();
CNode cNode = nodesMap.get(lNode);
double deltaX = cNode.hitbox.x - cNode.hitboxPreCompaction.x;
sl.getBendPoints().offset(deltaX, 0);
});
// offset straight segments
layeredGraph.getLayers().stream().flatMap(l -> l.getNodes().stream()).flatMap(n -> StreamSupport.stream(n.getOutgoingEdges().spliterator(), false)).map(e -> e.getProperty(InternalProperties.SPLINE_ROUTE_START)).filter(chain -> chain != null && !chain.isEmpty()).forEach(spline -> adjustSplineControlPoints(spline));
}
// calculating new graph size and offset
KVector topLeft = new KVector(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
KVector bottomRight = new KVector(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
for (CNode cNode : cGraph.cNodes) {
topLeft.x = Math.min(topLeft.x, cNode.hitbox.x);
topLeft.y = Math.min(topLeft.y, cNode.hitbox.y);
bottomRight.x = Math.max(bottomRight.x, cNode.hitbox.x + cNode.hitbox.width);
bottomRight.y = Math.max(bottomRight.y, cNode.hitbox.y + cNode.hitbox.height);
}
layeredGraph.getOffset().reset().add(topLeft.clone().negate());
layeredGraph.getSize().reset().add(bottomRight.clone().sub(topLeft));
// external port dummies may have been moved ... put them back
applyExternalPortPositions(topLeft, bottomRight);
cleanup();
}
use of org.eclipse.elk.alg.layered.graph.LGraph in project elk by eclipse.
the class BasicLayerAssignmentTest method testEdgesPointTowardsNextLayers.
@TestAfterProcessor(CoffmanGrahamLayerer.class)
@TestAfterProcessor(InteractiveLayerer.class)
@TestAfterProcessor(LongestPathLayerer.class)
@TestAfterProcessor(MinWidthLayerer.class)
@TestAfterProcessor(NetworkSimplexLayerer.class)
@TestAfterProcessor(StretchWidthLayerer.class)
public void testEdgesPointTowardsNextLayers(final Object graph) {
LGraph lGraph = (LGraph) graph;
// Assign increasing IDs to the layers
int nextLayerId = 0;
for (Layer layer : lGraph) {
layer.id = nextLayerId++;
}
for (Layer layer : lGraph) {
for (LNode node : layer) {
int nodeLayerId = node.getLayer().id;
for (LEdge edge : node.getOutgoingEdges()) {
assertTrue(nodeLayerId < edge.getTarget().getNode().getLayer().id);
}
}
}
}
Aggregations