Search in sources :

Example 1 with LPadding

use of org.eclipse.elk.alg.layered.graph.LPadding in project elk by eclipse.

the class HierarchicalPortOrthogonalEdgeRouter method setNorthSouthDummyCoordinates.

// /////////////////////////////////////////////////////////////////////////////
// STEP 2: SET NORTH / SOUTH DUMMY COORDINATES
/**
 * Set coordinates for northern and southern external port dummy nodes.
 *
 * @param layeredGraph the layered graph.
 * @param northSouthDummies dummy nodes whose position to set.
 */
private void setNorthSouthDummyCoordinates(final LGraph layeredGraph, final List<LNode> northSouthDummies) {
    PortConstraints constraints = layeredGraph.getProperty(LayeredOptions.PORT_CONSTRAINTS);
    KVector graphSize = layeredGraph.getSize();
    LPadding graphPadding = layeredGraph.getPadding();
    double graphWidth = graphSize.x + graphPadding.left + graphPadding.right;
    double northY = 0 - graphPadding.top - layeredGraph.getOffset().y;
    double southY = graphSize.y + graphPadding.top + graphPadding.bottom - layeredGraph.getOffset().y;
    // Lists of northern and southern external port dummies
    List<LNode> northernDummies = Lists.newArrayList();
    List<LNode> southernDummies = Lists.newArrayList();
    for (LNode dummy : northSouthDummies) {
        // Set x coordinate
        switch(constraints) {
            case FREE:
            case FIXED_SIDE:
            case FIXED_ORDER:
                calculateNorthSouthDummyPositions(dummy);
                break;
            case FIXED_RATIO:
                applyNorthSouthDummyRatio(dummy, graphWidth);
                dummy.borderToContentAreaCoordinates(true, false);
                break;
            case FIXED_POS:
                applyNorthSouthDummyPosition(dummy);
                dummy.borderToContentAreaCoordinates(true, false);
                // Ensure that the graph is wide enough to hold the port
                graphSize.x = Math.max(graphSize.x, dummy.getPosition().x + dummy.getSize().x / 2.0);
                break;
        }
        // Set y coordinates and add the dummy to its respective list
        switch(dummy.getProperty(InternalProperties.EXT_PORT_SIDE)) {
            case NORTH:
                dummy.getPosition().y = northY;
                northernDummies.add((dummy));
                break;
            case SOUTH:
                dummy.getPosition().y = southY;
                southernDummies.add(dummy);
                break;
        }
    }
    // have been put on top of one another
    switch(constraints) {
        case FREE:
        case FIXED_SIDE:
            ensureUniquePositions(northernDummies, layeredGraph);
            ensureUniquePositions(southernDummies, layeredGraph);
            break;
        case FIXED_ORDER:
            restoreProperOrder(northernDummies, layeredGraph);
            restoreProperOrder(southernDummies, layeredGraph);
            break;
    }
}
Also used : LPadding(org.eclipse.elk.alg.layered.graph.LPadding) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) PortConstraints(org.eclipse.elk.core.options.PortConstraints)

Example 2 with LPadding

use of org.eclipse.elk.alg.layered.graph.LPadding in project elk by eclipse.

the class HierarchicalPortOrthogonalEdgeRouter method fixCoordinates.

/**
 * Fixes the coordinates of the nodes in the given layer.
 *
 * @param layer the layer.
 * @param constraints external port constraints.
 * @param graph the graph.
 */
private void fixCoordinates(final Layer layer, final PortConstraints constraints, final LGraph graph) {
    // Get some geometric values from the graph
    LPadding padding = graph.getPadding();
    KVector offset = graph.getOffset();
    KVector graphActualSize = graph.getActualSize();
    double newActualGraphHeight = graphActualSize.y;
    // of the graph, so we're setting y coordinates of NORTH and SOUTH dummies in a second iteration
    for (LNode node : layer) {
        if (node.getType() != NodeType.EXTERNAL_PORT) {
            // We're only looking for hierarchical port dummies
            continue;
        }
        PortSide extPortSide = node.getProperty(InternalProperties.EXT_PORT_SIDE);
        KVector extPortSize = node.getProperty(InternalProperties.EXT_PORT_SIZE);
        KVector nodePosition = node.getPosition();
        // Set x coordinate
        switch(extPortSide) {
            case EAST:
                nodePosition.x = graph.getSize().x + padding.right - offset.x;
                break;
            case WEST:
                nodePosition.x = -offset.x - padding.left;
                break;
        }
        // Set y coordinate
        double requiredActualGraphHeight = 0.0;
        switch(extPortSide) {
            case EAST:
            case WEST:
                if (constraints == PortConstraints.FIXED_RATIO) {
                    double ratio = node.getProperty(InternalProperties.PORT_RATIO_OR_POSITION);
                    nodePosition.y = graphActualSize.y * ratio - node.getProperty(LayeredOptions.PORT_ANCHOR).y;
                    requiredActualGraphHeight = nodePosition.y + extPortSize.y;
                    node.borderToContentAreaCoordinates(false, true);
                } else if (constraints == PortConstraints.FIXED_POS) {
                    nodePosition.y = node.getProperty(InternalProperties.PORT_RATIO_OR_POSITION) - node.getProperty(LayeredOptions.PORT_ANCHOR).y;
                    requiredActualGraphHeight = nodePosition.y + extPortSize.y;
                    node.borderToContentAreaCoordinates(false, true);
                }
                break;
        }
        newActualGraphHeight = Math.max(newActualGraphHeight, requiredActualGraphHeight);
    }
    // Make the graph larger, if necessary
    graph.getSize().y += newActualGraphHeight - graphActualSize.y;
    // Iterate over NORTH and SOUTH dummies now that the graph's height is fixed
    for (LNode node : layer) {
        if (node.getType() != NodeType.EXTERNAL_PORT) {
            // We're only looking for hierarchical port dummies
            continue;
        }
        PortSide extPortSide = node.getProperty(InternalProperties.EXT_PORT_SIDE);
        KVector nodePosition = node.getPosition();
        // Set y coordinate
        switch(extPortSide) {
            case NORTH:
                nodePosition.y = -offset.y - padding.top;
                break;
            case SOUTH:
                nodePosition.y = graph.getSize().y + padding.bottom - offset.y;
                break;
        }
    }
}
Also used : LPadding(org.eclipse.elk.alg.layered.graph.LPadding) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) PortSide(org.eclipse.elk.core.options.PortSide)

Example 3 with LPadding

use of org.eclipse.elk.alg.layered.graph.LPadding in project elk by eclipse.

the class HierarchicalNodeResizingProcessor method resizeGraphNoReallyIMeanIt.

/**
 * Applies a new effective size to a graph that previously had an old size calculated by the layout algorithm. This
 * method takes care of adjusting content alignments as well as external ports that would be misplaced if the new
 * size is larger than the old one.
 *
 * @param lgraph
 *            the graph to apply the size to.
 * @param oldSize
 *            old size as calculated by the layout algorithm.
 * @param newSize
 *            new size that may be larger than the old one.
 */
private void resizeGraphNoReallyIMeanIt(final LGraph lgraph, final KVector oldSize, final KVector newSize) {
    // obey to specified alignment constraints
    Set<ContentAlignment> contentAlignment = lgraph.getProperty(LayeredOptions.CONTENT_ALIGNMENT);
    // horizontal alignment
    if (newSize.x > oldSize.x) {
        if (contentAlignment.contains(ContentAlignment.H_CENTER)) {
            lgraph.getOffset().x += (newSize.x - oldSize.x) / 2f;
        } else if (contentAlignment.contains(ContentAlignment.H_RIGHT)) {
            lgraph.getOffset().x += newSize.x - oldSize.x;
        }
    }
    // vertical alignment
    if (newSize.y > oldSize.y) {
        if (contentAlignment.contains(ContentAlignment.V_CENTER)) {
            lgraph.getOffset().y += (newSize.y - oldSize.y) / 2f;
        } else if (contentAlignment.contains(ContentAlignment.V_BOTTOM)) {
            lgraph.getOffset().y += newSize.y - oldSize.y;
        }
    }
    // correct the position of eastern and southern hierarchical ports, if necessary
    if (lgraph.getProperty(InternalProperties.GRAPH_PROPERTIES).contains(GraphProperties.EXTERNAL_PORTS) && (newSize.x > oldSize.x || newSize.y > oldSize.y)) {
        // (at this point, the graph's nodes are not divided into layers anymore)
        for (LNode node : lgraph.getLayerlessNodes()) {
            // we're only looking for external port dummies
            if (node.getType() == NodeType.EXTERNAL_PORT) {
                // check which side the external port is on
                PortSide extPortSide = node.getProperty(InternalProperties.EXT_PORT_SIDE);
                if (extPortSide == PortSide.EAST) {
                    node.getPosition().x += newSize.x - oldSize.x;
                } else if (extPortSide == PortSide.SOUTH) {
                    node.getPosition().y += newSize.y - oldSize.y;
                }
            }
        }
    }
    // Actually apply the new size
    LPadding padding = lgraph.getPadding();
    lgraph.getSize().x = newSize.x - padding.left - padding.right;
    lgraph.getSize().y = newSize.y - padding.top - padding.bottom;
}
Also used : ContentAlignment(org.eclipse.elk.core.options.ContentAlignment) LPadding(org.eclipse.elk.alg.layered.graph.LPadding) LNode(org.eclipse.elk.alg.layered.graph.LNode) PortSide(org.eclipse.elk.core.options.PortSide)

Example 4 with LPadding

use of org.eclipse.elk.alg.layered.graph.LPadding 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 5 with LPadding

use of org.eclipse.elk.alg.layered.graph.LPadding in project elk by eclipse.

the class ElkGraphImporter method createLGraph.

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Graph Transformation
/**
 * Create an LGraph from the given node.
 *
 * @param elkgraph
 *            the parent node from which to create the LGraph
 * @return a new LGraph instance
 */
private LGraph createLGraph(final ElkNode elkgraph) {
    LGraph lgraph = new LGraph();
    // Copy the properties of the KGraph to the layered graph
    lgraph.copyProperties(elkgraph);
    if (lgraph.getProperty(LayeredOptions.DIRECTION) == Direction.UNDEFINED) {
        lgraph.setProperty(LayeredOptions.DIRECTION, LGraphUtil.getDirection(lgraph));
    }
    // The root may have a label manager installed
    if (lgraph.getProperty(LabelManagementOptions.LABEL_MANAGER) == null) {
        ElkGraphElement root = (ElkGraphElement) EcoreUtil.getRootContainer(elkgraph);
        lgraph.setProperty(LabelManagementOptions.LABEL_MANAGER, root.getProperty(LabelManagementOptions.LABEL_MANAGER));
    }
    // Remember the KGraph parent the LGraph was created from
    lgraph.setProperty(InternalProperties.ORIGIN, elkgraph);
    // Initialize the graph properties discovered during the transformations
    lgraph.setProperty(InternalProperties.GRAPH_PROPERTIES, EnumSet.noneOf(GraphProperties.class));
    // Adjust the padding to respect inside labels (if the graph has a parent, we need to supply that as well
    // since size information stored there may apply to the current graph node)
    ElkPadding nodeLabelpadding = NodeLabelAndSizeCalculator.computeInsideNodeLabelPadding(elkgraph.getParent() == null ? null : ElkGraphAdapters.adapt(elkgraph.getParent()), ElkGraphAdapters.adaptSingleNode(elkgraph), Direction.RIGHT);
    ElkPadding nodePadding = lgraph.getProperty(LayeredOptions.PADDING);
    // Setup the graph's padding
    LPadding lPadding = lgraph.getPadding();
    lPadding.add(nodePadding);
    lPadding.add(nodeLabelpadding);
    return lgraph;
}
Also used : GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) LPadding(org.eclipse.elk.alg.layered.graph.LPadding) LGraph(org.eclipse.elk.alg.layered.graph.LGraph) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) ElkPadding(org.eclipse.elk.core.math.ElkPadding)

Aggregations

LPadding (org.eclipse.elk.alg.layered.graph.LPadding)6 LNode (org.eclipse.elk.alg.layered.graph.LNode)5 KVector (org.eclipse.elk.core.math.KVector)3 PortSide (org.eclipse.elk.core.options.PortSide)3 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)2 GraphProperties (org.eclipse.elk.alg.layered.options.GraphProperties)2 ElkPadding (org.eclipse.elk.core.math.ElkPadding)2 ContentAlignment (org.eclipse.elk.core.options.ContentAlignment)2 PortConstraints (org.eclipse.elk.core.options.PortConstraints)2 Lists (com.google.common.collect.Lists)1 EnumSet (java.util.EnumSet)1 List (java.util.List)1 Set (java.util.Set)1 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)1 LGraphUtil (org.eclipse.elk.alg.layered.graph.LGraphUtil)1 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)1 LPort (org.eclipse.elk.alg.layered.graph.LPort)1 LabelDummySwitcher (org.eclipse.elk.alg.layered.intermediate.LabelDummySwitcher)1 InternalProperties (org.eclipse.elk.alg.layered.options.InternalProperties)1 LayeredOptions (org.eclipse.elk.alg.layered.options.LayeredOptions)1