Search in sources :

Example 1 with EdgeRouting

use of org.eclipse.elk.core.options.EdgeRouting in project elk by eclipse.

the class ElkGraphLayoutTransferrer method applyLayout.

/**
 * Applies the layout information contained in the given LGraph to the ElkGraph elements it was
 * created from. All source ElkGraph elements are expected to be accessible through their LGraph
 * counterparts through the {@link InternalProperties#ORIGIN} property.
 *
 * @param lgraph the LGraph whose layout information to apply.
 */
public void applyLayout(final LGraph lgraph) {
    Object graphOrigin = lgraph.getProperty(InternalProperties.ORIGIN);
    if (!(graphOrigin instanceof ElkNode)) {
        return;
    }
    // The ElkNode that represents this graph in the original ElkGraph
    ElkNode parentElkNode = (ElkNode) graphOrigin;
    // The LNode that represents this graph in the upper hierarchy level, if any
    LNode parentLNode = (LNode) lgraph.getParentNode();
    // Get the offset to be added to all coordinates
    KVector offset = new KVector(lgraph.getOffset());
    // Adjust offset (and with it the positions) by the requested padding
    LPadding lPadding = lgraph.getPadding();
    offset.x += lPadding.left;
    offset.y += lPadding.top;
    // Set node padding, if it was computed during layout
    final EnumSet<SizeOptions> sizeOptions = parentElkNode.getProperty(LayeredOptions.NODE_SIZE_OPTIONS);
    if (sizeOptions.contains(SizeOptions.COMPUTE_PADDING)) {
        ElkPadding padding = parentElkNode.getProperty(LayeredOptions.PADDING);
        padding.setBottom(lPadding.bottom);
        padding.setTop(lPadding.top);
        padding.setLeft(lPadding.left);
        padding.setRight(lPadding.right);
    }
    // Along the way, we collect the list of edges to be processed later
    List<LEdge> edgeList = Lists.newArrayList();
    // Process the nodes
    for (LNode lnode : lgraph.getLayerlessNodes()) {
        if (representsNode(lnode)) {
            applyNodeLayout(lnode, offset);
        } else if (representsExternalPort(lnode) && parentLNode == null) {
            // We have an external port here on the top-most hierarchy level of the current (possibly
            // hierarchical) layout run; set its position
            ElkPort elkport = (ElkPort) lnode.getProperty(InternalProperties.ORIGIN);
            KVector portPosition = LGraphUtil.getExternalPortPosition(lgraph, lnode, elkport.getWidth(), elkport.getHeight());
            elkport.setLocation(portPosition.x, portPosition.y);
        }
        // correctly)
        for (LPort port : lnode.getPorts()) {
            port.getOutgoingEdges().stream().filter(edge -> !LGraphUtil.isDescendant(edge.getTarget().getNode(), lnode)).forEach(edge -> edgeList.add(edge));
        }
    }
    // Collect edges that go from the current graph's representing LNode down into its descendants
    if (parentLNode != null) {
        for (LPort port : parentLNode.getPorts()) {
            port.getOutgoingEdges().stream().filter(edge -> LGraphUtil.isDescendant(edge.getTarget().getNode(), parentLNode)).forEach(edge -> edgeList.add(edge));
        }
    }
    // Iterate through all edges
    EdgeRouting routing = parentElkNode.getProperty(LayeredOptions.EDGE_ROUTING);
    for (LEdge ledge : edgeList) {
        applyEdgeLayout(ledge, routing, offset, lPadding);
    }
    // Setup the parent node
    applyParentNodeLayout(lgraph);
    // Process nested subgraphs
    for (LNode lnode : lgraph.getLayerlessNodes()) {
        LGraph nestedGraph = lnode.getNestedGraph();
        if (nestedGraph != null) {
            applyLayout(nestedGraph);
        }
    }
}
Also used : GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) LLabel(org.eclipse.elk.alg.layered.graph.LLabel) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) ElkNode(org.eclipse.elk.graph.ElkNode) ElkPort(org.eclipse.elk.graph.ElkPort) PortLabelPlacement(org.eclipse.elk.core.options.PortLabelPlacement) LayeredOptions(org.eclipse.elk.alg.layered.options.LayeredOptions) KVectorChain(org.eclipse.elk.core.math.KVectorChain) ElkUtil(org.eclipse.elk.core.util.ElkUtil) Lists(com.google.common.collect.Lists) LabelDummySwitcher(org.eclipse.elk.alg.layered.intermediate.LabelDummySwitcher) InternalProperties(org.eclipse.elk.alg.layered.options.InternalProperties) ElkPadding(org.eclipse.elk.core.math.ElkPadding) EnumSet(java.util.EnumSet) NodePlacementStrategy(org.eclipse.elk.alg.layered.options.NodePlacementStrategy) NodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility) PortConstraints(org.eclipse.elk.core.options.PortConstraints) ElkLabel(org.eclipse.elk.graph.ElkLabel) KVector(org.eclipse.elk.core.math.KVector) SizeOptions(org.eclipse.elk.core.options.SizeOptions) Set(java.util.Set) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint) LGraphUtil(org.eclipse.elk.alg.layered.graph.LGraphUtil) LPadding(org.eclipse.elk.alg.layered.graph.LPadding) List(java.util.List) LGraph(org.eclipse.elk.alg.layered.graph.LGraph) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) LPort(org.eclipse.elk.alg.layered.graph.LPort) EdgeRouting(org.eclipse.elk.core.options.EdgeRouting) LNode(org.eclipse.elk.alg.layered.graph.LNode) ElkEdge(org.eclipse.elk.graph.ElkEdge) ElkGraphUtil(org.eclipse.elk.graph.util.ElkGraphUtil) ElkNode(org.eclipse.elk.graph.ElkNode) SizeOptions(org.eclipse.elk.core.options.SizeOptions) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) ElkPort(org.eclipse.elk.graph.ElkPort) LPadding(org.eclipse.elk.alg.layered.graph.LPadding) EdgeRouting(org.eclipse.elk.core.options.EdgeRouting) LGraph(org.eclipse.elk.alg.layered.graph.LGraph) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Example 2 with EdgeRouting

use of org.eclipse.elk.core.options.EdgeRouting in project elk by eclipse.

the class FixedLayoutProvider method layout.

@Override
public void layout(final ElkNode layoutNode, final IElkProgressMonitor progressMonitor) {
    progressMonitor.begin("Fixed Layout", 1);
    EdgeRouting edgeRouting = layoutNode.getProperty(CoreOptions.EDGE_ROUTING);
    double maxx = 0;
    double maxy = 0;
    for (ElkNode node : layoutNode.getChildren()) {
        // set the fixed position of the node, or leave it as it is
        KVector pos = node.getProperty(FixedLayouterOptions.POSITION);
        if (pos != null) {
            node.setLocation(pos.x, pos.y);
            // set the fixed size of the node
            if (node.getProperty(FixedLayouterOptions.NODE_SIZE_CONSTRAINTS).contains(SizeConstraint.MINIMUM_SIZE)) {
                KVector minSize = node.getProperty(FixedLayouterOptions.NODE_SIZE_MINIMUM);
                if (minSize.x > 0 && minSize.y > 0) {
                    ElkUtil.resizeNode(node, minSize.x, minSize.y, true, true);
                }
            }
        }
        maxx = Math.max(maxx, node.getX() + node.getWidth());
        maxy = Math.max(maxy, node.getY() + node.getHeight());
        // set the fixed position of the node labels, or leave them as they are
        for (ElkLabel label : node.getLabels()) {
            pos = label.getProperty(FixedLayouterOptions.POSITION);
            if (pos != null) {
                label.setLocation(pos.x, pos.y);
            }
            maxx = Math.max(maxx, node.getX() + label.getX() + label.getWidth());
            maxy = Math.max(maxy, node.getY() + label.getY() + label.getHeight());
        }
        // set the fixed position of the ports, or leave them as they are
        for (ElkPort port : node.getPorts()) {
            pos = port.getProperty(FixedLayouterOptions.POSITION);
            if (pos != null) {
                port.setLocation(pos.x, pos.y);
            }
            double portx = node.getX() + port.getX();
            double porty = node.getY() + port.getY();
            maxx = Math.max(maxx, portx + port.getWidth());
            maxy = Math.max(maxy, porty + port.getHeight());
            // set the fixed position of the port labels, or leave them as they are
            for (ElkLabel label : port.getLabels()) {
                pos = label.getProperty(FixedLayouterOptions.POSITION);
                if (pos != null) {
                    label.setLocation(pos.x, pos.y);
                }
                maxx = Math.max(maxx, portx + label.getX() + label.getWidth());
                maxy = Math.max(maxy, porty + label.getY() + label.getHeight());
            }
        }
        // set fixed routing for the node's outgoing edges (both simple and hierarchical), or leave them as they are
        for (ElkEdge edge : ElkGraphUtil.allOutgoingEdges(node)) {
            KVector maxv = processEdge(edge, edgeRouting);
            maxx = Math.max(maxx, maxv.x);
            maxy = Math.max(maxy, maxv.y);
        }
        // note that this potentially results in hierarchical edges being handled twice
        for (ElkEdge edge : ElkGraphUtil.allIncomingEdges(node)) {
            if (ElkGraphUtil.getSourceNode(edge).getParent() != layoutNode) {
                KVector maxv = processEdge(edge, edgeRouting);
                maxx = Math.max(maxx, maxv.x);
                maxy = Math.max(maxy, maxv.y);
            }
        }
    }
    // if orthogonal routing is selected, determine the junction points
    if (edgeRouting == EdgeRouting.ORTHOGONAL) {
        for (ElkNode node : layoutNode.getChildren()) {
            for (ElkEdge edge : ElkGraphUtil.allOutgoingEdges(node)) {
                generateJunctionPoints(edge);
            }
        }
    }
    // set size of the parent node unless its size should be fixed as well
    if (!layoutNode.getProperty(FixedLayouterOptions.NODE_SIZE_FIXED_GRAPH_SIZE)) {
        ElkPadding padding = layoutNode.getProperty(FixedLayouterOptions.PADDING);
        double newWidth = maxx + padding.getLeft() + padding.getRight();
        double newHeight = maxy + padding.getTop() + padding.getBottom();
        ElkUtil.resizeNode(layoutNode, newWidth, newHeight, true, true);
    }
    progressMonitor.done();
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) ElkLabel(org.eclipse.elk.graph.ElkLabel) ElkPort(org.eclipse.elk.graph.ElkPort) EdgeRouting(org.eclipse.elk.core.options.EdgeRouting) KVector(org.eclipse.elk.core.math.KVector) ElkPadding(org.eclipse.elk.core.math.ElkPadding) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Example 3 with EdgeRouting

use of org.eclipse.elk.core.options.EdgeRouting 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 4 with EdgeRouting

use of org.eclipse.elk.core.options.EdgeRouting in project elk by eclipse.

the class NorthSouthPortPostprocessor method process.

@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor) {
    monitor.begin("Odd port side processing", 1);
    // Spline edge routing manages bend points in the edge router. Differentiate behaviour
    // depending on edge router.
    EdgeRouting routing = layeredGraph.getProperty(LayeredOptions.EDGE_ROUTING);
    // Iterate through the layers
    for (Layer layer : layeredGraph) {
        // Iterate through the nodes (use an array to avoid concurrent modification exceptions)
        LNode[] nodeArray = LGraphUtil.toNodeArray(layer.getNodes());
        for (LNode node : nodeArray) {
            // We only care for North/South Port dummy nodes
            if (node.getType() != NodeType.NORTH_SOUTH_PORT) {
                continue;
            }
            if (routing == EdgeRouting.SPLINES) {
                // Iterate through ports
                for (LPort port : node.getPorts()) {
                    if (!port.getIncomingEdges().isEmpty()) {
                        processSplineInputPort(port);
                    }
                    if (!port.getOutgoingEdges().isEmpty()) {
                        processSplineOutputPort(port);
                    }
                }
            } else if (node.getProperty(InternalProperties.ORIGIN) instanceof LEdge) {
                // It's a self-loop
                processSelfLoop(node);
            } else {
                // Check if all ports were created for the same origin port
                boolean sameOriginPort;
                if (node.getPorts().size() >= 2) {
                    // Iterate over the dummy's ports to find out whether the origin is always the same
                    sameOriginPort = true;
                    Iterator<LPort> portIterator = node.getPorts().iterator();
                    LPort currentPort = portIterator.next();
                    LPort previousPort = null;
                    while (portIterator.hasNext()) {
                        previousPort = currentPort;
                        currentPort = portIterator.next();
                        if (!previousPort.getProperty(InternalProperties.ORIGIN).equals(currentPort.getProperty(InternalProperties.ORIGIN))) {
                            // The two ports don't have the same origin
                            sameOriginPort = false;
                            break;
                        }
                    }
                } else {
                    sameOriginPort = false;
                }
                // Iterate through the ports
                for (LPort port : node.getPorts()) {
                    if (!port.getIncomingEdges().isEmpty()) {
                        processInputPort(port, sameOriginPort);
                    }
                    if (!port.getOutgoingEdges().isEmpty()) {
                        processOutputPort(port, sameOriginPort);
                    }
                }
            }
            // Remove the node
            node.setLayer(null);
        }
    }
    monitor.done();
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) Iterator(java.util.Iterator) EdgeRouting(org.eclipse.elk.core.options.EdgeRouting) LNode(org.eclipse.elk.alg.layered.graph.LNode) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 5 with EdgeRouting

use of org.eclipse.elk.core.options.EdgeRouting in project elk by eclipse.

the class LGraphToCGraphTransformer method transformEdges.

private void transformEdges() {
    EdgeRouting style = layeredGraph.getProperty(LayeredOptions.EDGE_ROUTING);
    List<VerticalSegment> verticalSegments;
    switch(style) {
        case ORTHOGONAL:
            verticalSegments = collectVerticalSegmentsOrthogonal();
            break;
        case SPLINES:
            verticalSegments = collectVerticalSegmentsSplines();
            break;
        default:
            throw new IllegalStateException("Compaction not supported for " + style + " edges.");
    }
    // merge them
    mergeVerticalSegments(verticalSegments);
    // create precomputed constraints
    verticalSegmentsMap.keySet().forEach(vs -> {
        CNode vsNode = verticalSegmentsMap.get(vs);
        vs.constraints.forEach(other -> {
            CNode otherNode = verticalSegmentsMap.get(other);
            cGraph.predefinedHorizontalConstraints.add(Pair.of(vsNode, otherNode));
        });
    });
}
Also used : CNode(org.eclipse.elk.alg.common.compaction.oned.CNode) EdgeRouting(org.eclipse.elk.core.options.EdgeRouting)

Aggregations

EdgeRouting (org.eclipse.elk.core.options.EdgeRouting)6 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)3 LNode (org.eclipse.elk.alg.layered.graph.LNode)3 LPort (org.eclipse.elk.alg.layered.graph.LPort)3 KVector (org.eclipse.elk.core.math.KVector)3 Lists (com.google.common.collect.Lists)2 EnumSet (java.util.EnumSet)2 Iterator (java.util.Iterator)2 List (java.util.List)2 Set (java.util.Set)2 CNode (org.eclipse.elk.alg.common.compaction.oned.CNode)2 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)2 Layer (org.eclipse.elk.alg.layered.graph.Layer)2 InternalProperties (org.eclipse.elk.alg.layered.options.InternalProperties)2 LayeredOptions (org.eclipse.elk.alg.layered.options.LayeredOptions)2 ElkPadding (org.eclipse.elk.core.math.ElkPadding)2 ElkEdge (org.eclipse.elk.graph.ElkEdge)2 ElkLabel (org.eclipse.elk.graph.ElkLabel)2 ElkNode (org.eclipse.elk.graph.ElkNode)2 ElkPort (org.eclipse.elk.graph.ElkPort)2