Search in sources :

Example 16 with ElkPadding

use of org.eclipse.elk.core.math.ElkPadding 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 17 with ElkPadding

use of org.eclipse.elk.core.math.ElkPadding in project elk by eclipse.

the class ElkGraphImporter method applyLayout.

// /////////////////////////////////////////////////////////////////////////////
// Apply Layout Results
@Override
public void applyLayout(final TGraph tGraph) {
    // get the corresponding kGraph
    ElkNode elkgraph = (ElkNode) tGraph.getProperty(InternalProperties.ORIGIN);
    // calculate the offset from border spacing and node distribution
    double minXPos = Integer.MAX_VALUE;
    double minYPos = Integer.MAX_VALUE;
    double maxXPos = Integer.MIN_VALUE;
    double maxYPos = Integer.MIN_VALUE;
    for (TNode tNode : tGraph.getNodes()) {
        KVector pos = tNode.getPosition();
        KVector size = tNode.getSize();
        minXPos = Math.min(minXPos, pos.x - size.x / 2);
        minYPos = Math.min(minYPos, pos.y - size.y / 2);
        maxXPos = Math.max(maxXPos, pos.x + size.x / 2);
        maxYPos = Math.max(maxYPos, pos.y + size.y / 2);
    }
    ElkPadding padding = elkgraph.getProperty(MrTreeOptions.PADDING);
    KVector offset = new KVector(padding.getLeft() - minXPos, padding.getTop() - minYPos);
    // process the nodes
    for (TNode tNode : tGraph.getNodes()) {
        Object object = tNode.getProperty(InternalProperties.ORIGIN);
        if (object instanceof ElkNode) {
            // set the node position
            ElkNode elknode = (ElkNode) object;
            KVector nodePos = tNode.getPosition().add(offset);
            elknode.setLocation(nodePos.x - elknode.getWidth() / 2, nodePos.y - elknode.getHeight() / 2);
        }
    }
    // process the edges
    for (TEdge tEdge : tGraph.getEdges()) {
        ElkEdge elkedge = (ElkEdge) tEdge.getProperty(InternalProperties.ORIGIN);
        if (elkedge != null) {
            KVectorChain bendPoints = tEdge.getBendPoints();
            // add the source port and target points to the vector chain
            KVector sourcePoint = new KVector(tEdge.getSource().getPosition());
            bendPoints.addFirst(sourcePoint);
            KVector targetPoint = new KVector(tEdge.getTarget().getPosition());
            bendPoints.addLast(targetPoint);
            // correct the source and target points
            toNodeBorder(sourcePoint, bendPoints.get(1), tEdge.getSource().getSize());
            toNodeBorder(targetPoint, bendPoints.get(bendPoints.size() - 2), tEdge.getTarget().getSize());
            ElkEdgeSection edgeSection = ElkGraphUtil.firstEdgeSection(elkedge, true, true);
            ElkUtil.applyVectorChain(bendPoints, edgeSection);
        }
    }
    // set up the graph
    double width = maxXPos - minXPos + padding.getHorizontal();
    double height = maxYPos - minYPos + padding.getVertical();
    ElkUtil.resizeNode(elkgraph, width, height, false, false);
}
Also used : TEdge(org.eclipse.elk.alg.mrtree.graph.TEdge) TNode(org.eclipse.elk.alg.mrtree.graph.TNode) ElkNode(org.eclipse.elk.graph.ElkNode) KVectorChain(org.eclipse.elk.core.math.KVectorChain) KVector(org.eclipse.elk.core.math.KVector) ElkPadding(org.eclipse.elk.core.math.ElkPadding) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Example 18 with ElkPadding

use of org.eclipse.elk.core.math.ElkPadding in project elk by eclipse.

the class BoxLayoutProvider method mergeAndPlaceInc.

/**
 * In increasing node area order: pick nodes until the next node's half size is larger than
 * the current cumulated area. Problematic for certain graphs, where
 * the cumulation becomes quite large early.
 */
private List<Group> mergeAndPlaceInc(final List<Group> groups, final double objSpacing, final double minWidth, final double minHeight, final boolean expandNodes, final double aspectRatio) {
    // sort increasingly
    Collections.sort(groups, (g1, g2) -> Double.compare(g1.area(), g2.area()));
    ListIterator<Group> groupIterator = groups.listIterator();
    List<Group> toBePlaced = Lists.newArrayList();
    double commonArea = 0;
    while (groupIterator.hasNext()) {
        Group g = groupIterator.next();
        if (!toBePlaced.isEmpty() && g.area() > (commonArea * 2)) {
            // merge the current set of groups into a common group
            Group merged = new Group(toBePlaced);
            double innerAspectRatio = g.getWidth() / g.getHeight();
            // place the nodes in the group
            KVector groupSize = placeInnerBoxes(merged, objSpacing, new ElkPadding(), minWidth, minHeight, expandNodes, innerAspectRatio);
            merged.size.reset().add(groupSize);
            // reset
            toBePlaced.clear();
            commonArea = 0;
            // add the merged group and the current group to
            // the active list
            toBePlaced.add(merged);
            toBePlaced.add(g);
            commonArea = merged.area() + g.area();
        } else {
            // add the group to the active set
            toBePlaced.add(g);
            commonArea += g.area();
        }
    }
    return toBePlaced;
}
Also used : KVector(org.eclipse.elk.core.math.KVector) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Example 19 with ElkPadding

use of org.eclipse.elk.core.math.ElkPadding 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 20 with ElkPadding

use of org.eclipse.elk.core.math.ElkPadding in project elk by eclipse.

the class RandomLayoutProvider method layout.

@Override
public void layout(final ElkNode parentNode, final IElkProgressMonitor progressMonitor) {
    progressMonitor.begin("Random Layout", 1);
    if (parentNode.getChildren().isEmpty()) {
        progressMonitor.done();
        return;
    }
    // initialize random seed
    Random random;
    Integer randomSeed = parentNode.getProperty(RandomLayouterOptions.RANDOM_SEED);
    if (randomSeed != null && randomSeed != 0) {
        random = new Random(randomSeed);
    } else {
        random = new Random();
    }
    // retrieve some layout option values
    float aspectRatio = parentNode.getProperty(RandomLayouterOptions.ASPECT_RATIO).floatValue();
    float spacing = parentNode.getProperty(RandomLayouterOptions.SPACING_NODE_NODE).floatValue();
    ElkPadding padding = parentNode.getProperty(RandomLayouterOptions.PADDING);
    // randomize the layout
    randomize(parentNode, random, aspectRatio, spacing, padding);
    progressMonitor.done();
}
Also used : Random(java.util.Random) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Aggregations

ElkPadding (org.eclipse.elk.core.math.ElkPadding)73 ElkNode (org.eclipse.elk.graph.ElkNode)34 KVector (org.eclipse.elk.core.math.KVector)25 Test (org.junit.Test)18 BasicProgressMonitor (org.eclipse.elk.core.util.BasicProgressMonitor)15 ElkLabel (org.eclipse.elk.graph.ElkLabel)10 ElkRectangle (org.eclipse.elk.core.math.ElkRectangle)9 ElkEdge (org.eclipse.elk.graph.ElkEdge)9 KLabel (de.cau.cs.kieler.klighd.kgraph.KLabel)5 KContainerRendering (de.cau.cs.kieler.klighd.krendering.KContainerRendering)5 KText (de.cau.cs.kieler.klighd.krendering.KText)5 ArrayList (java.util.ArrayList)5 HashMap (java.util.HashMap)5 ElkEdgeSection (org.eclipse.elk.graph.ElkEdgeSection)5 LabelDecorationConfigurator (de.cau.cs.kieler.klighd.labels.decoration.LabelDecorationConfigurator)4 List (java.util.List)4 ElkPort (org.eclipse.elk.graph.ElkPort)4 KPolyline (de.cau.cs.kieler.klighd.krendering.KPolyline)3 HashSet (java.util.HashSet)3 NodeStatement (org.eclipse.elk.alg.graphviz.dot.dot.NodeStatement)3