Search in sources :

Example 26 with LGraph

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);
}
Also used : LNode(org.eclipse.elk.alg.layered.graph.LNode) LGraph(org.eclipse.elk.alg.layered.graph.LGraph)

Example 27 with LGraph

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;
        }
    }
}
Also used : LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) SelfLoopPort(org.eclipse.elk.alg.layered.intermediate.loops.SelfLoopPort) LGraph(org.eclipse.elk.alg.layered.graph.LGraph)

Example 28 with LGraph

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();
}
Also used : Layer(org.eclipse.elk.alg.layered.graph.Layer) InternalProperties(org.eclipse.elk.alg.layered.options.InternalProperties) LGraph(org.eclipse.elk.alg.layered.graph.LGraph) KVector(org.eclipse.elk.core.math.KVector) IElkProgressMonitor(org.eclipse.elk.core.util.IElkProgressMonitor) Optional(java.util.Optional) LNode(org.eclipse.elk.alg.layered.graph.LNode) ILayoutProcessor(org.eclipse.elk.core.alg.ILayoutProcessor) NodeType(org.eclipse.elk.alg.layered.graph.LNode.NodeType) LayeredOptions(org.eclipse.elk.alg.layered.options.LayeredOptions) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 29 with LGraph

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();
}
Also used : Iterables(com.google.common.collect.Iterables) Layer(org.eclipse.elk.alg.layered.graph.Layer) PortSide(org.eclipse.elk.core.options.PortSide) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) Function(java.util.function.Function) LayeredOptions(org.eclipse.elk.alg.layered.options.LayeredOptions) ElkRectangle(org.eclipse.elk.core.math.ElkRectangle) Lists(com.google.common.collect.Lists) CGraph(org.eclipse.elk.alg.common.compaction.oned.CGraph) InternalProperties(org.eclipse.elk.alg.layered.options.InternalProperties) Map(java.util.Map) StreamSupport(java.util.stream.StreamSupport) Pair(org.eclipse.elk.core.util.Pair) EnumSet(java.util.EnumSet) NodeType(org.eclipse.elk.alg.layered.graph.LNode.NodeType) Iterator(java.util.Iterator) CGroup(org.eclipse.elk.alg.common.compaction.oned.CGroup) KVector(org.eclipse.elk.core.math.KVector) CompareFuzzy(org.eclipse.elk.alg.common.compaction.oned.CompareFuzzy) Set(java.util.Set) Maps(com.google.common.collect.Maps) Sets(com.google.common.collect.Sets) CNode(org.eclipse.elk.alg.common.compaction.oned.CNode) Objects(java.util.Objects) List(java.util.List) Quadruplet(org.eclipse.elk.alg.common.compaction.oned.Quadruplet) LGraph(org.eclipse.elk.alg.layered.graph.LGraph) Direction(org.eclipse.elk.core.options.Direction) Entry(java.util.Map.Entry) LPort(org.eclipse.elk.alg.layered.graph.LPort) EdgeRouting(org.eclipse.elk.core.options.EdgeRouting) LNode(org.eclipse.elk.alg.layered.graph.LNode) SplineSegment(org.eclipse.elk.alg.layered.p5edges.splines.SplineSegment) Collections(java.util.Collections) CNode(org.eclipse.elk.alg.common.compaction.oned.CNode) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector)

Example 30 with LGraph

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);
            }
        }
    }
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LNode(org.eclipse.elk.alg.layered.graph.LNode) LGraph(org.eclipse.elk.alg.layered.graph.LGraph) Layer(org.eclipse.elk.alg.layered.graph.Layer) TestAfterProcessor(org.eclipse.elk.alg.test.framework.annotations.TestAfterProcessor)

Aggregations

LGraph (org.eclipse.elk.alg.layered.graph.LGraph)115 LNode (org.eclipse.elk.alg.layered.graph.LNode)90 LPort (org.eclipse.elk.alg.layered.graph.LPort)49 Layer (org.eclipse.elk.alg.layered.graph.Layer)38 Test (org.junit.Test)36 TestAfterProcessor (org.eclipse.elk.alg.test.framework.annotations.TestAfterProcessor)19 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)17 KVector (org.eclipse.elk.core.math.KVector)15 InternalProperties (org.eclipse.elk.alg.layered.options.InternalProperties)14 LayeredOptions (org.eclipse.elk.alg.layered.options.LayeredOptions)13 List (java.util.List)11 ILayoutProcessor (org.eclipse.elk.core.alg.ILayoutProcessor)11 IElkProgressMonitor (org.eclipse.elk.core.util.IElkProgressMonitor)10 NodeType (org.eclipse.elk.alg.layered.graph.LNode.NodeType)9 Lists (com.google.common.collect.Lists)7 Set (java.util.Set)7 GraphProperties (org.eclipse.elk.alg.layered.options.GraphProperties)7 GraphInfoHolder (org.eclipse.elk.alg.layered.p3order.GraphInfoHolder)7 PortSide (org.eclipse.elk.core.options.PortSide)7 ElkNode (org.eclipse.elk.graph.ElkNode)7