Search in sources :

Example 1 with NodeFlexibility

use of org.eclipse.elk.alg.layered.options.NodeFlexibility in project elk by eclipse.

the class NetworkSimplexPlacer method applyPositions.

// ------------------------------------------------------------------------------------------------
// Apply Layout
// ------------------------------------------------------------------------------------------------
private void applyPositions() {
    for (Layer l : lGraph) {
        for (LNode lNode : l) {
            // find the node's corners
            NodeRep nodeRep = nodeReps[lNode.id];
            double minY = nodeRep.head.layer;
            double maxY = nodeRep.tail.layer;
            // set new position and size
            lNode.getPosition().y = minY;
            double sizeDelta = (maxY - minY) - lNode.getSize().y;
            boolean flexibleNode = isFlexibleNode(lNode);
            NodeFlexibility nf = getNodeFlexibility(lNode);
            // modify the size?
            if (flexibleNode && nf.isFlexibleSizeWhereSpacePermits()) {
                lNode.getSize().y += sizeDelta;
            }
            // reposition ports if allowed
            if (flexibleNode && nf.isFlexiblePorts()) {
                for (LPort p : lNode.getPorts()) {
                    if (PortSide.SIDES_EAST_WEST.contains(p.getSide())) {
                        NNode nNode = portMap.get(p);
                        p.getPosition().y = nNode.layer - minY;
                    }
                }
                // when the node got resized, the positions of labels and south ports have to be adjusted
                for (LLabel label : lNode.getLabels()) {
                    adjustLabelPosition(lNode, label, sizeDelta);
                }
                if (nf.isFlexibleSizeWhereSpacePermits()) {
                    lNode.getPortSideView(PortSide.SOUTH).forEach(p -> p.getPosition().y += sizeDelta);
                }
            }
        }
    }
}
Also used : NNode(org.eclipse.elk.alg.common.networksimplex.NNode) LLabel(org.eclipse.elk.alg.layered.graph.LLabel) LPort(org.eclipse.elk.alg.layered.graph.LPort) NodeFlexibility.getNodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility.getNodeFlexibility) NodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility) LNode(org.eclipse.elk.alg.layered.graph.LNode) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 2 with NodeFlexibility

use of org.eclipse.elk.alg.layered.options.NodeFlexibility in project elk by eclipse.

the class NetworkSimplexPlacer method isFlexibleNode.

// ------------------------------------------------------------------------------------------------
// Flexible Ports
// ------------------------------------------------------------------------------------------------
/**
 * A node is <em>flexible</em> if
 * <ul>
 *  <li>its port constraints are <b>not</b> {@link PortConstraints#FIXED_POS}, and</li>
 *  <li>the node's height is large enough to give the ports
 *      on both sides (WEST and EAST) enough room to potentially alter their position.</li>
 * </ul>
 *
 * The rationale for the latter case is the following:
 * if the height of a node is not enough to accommodate all ports
 * and we are not allowed to change the node's size,
 * we simply use the port positions that have been computed by the {@link LabelAndNodeSizeProcessor}.
 * The processor is able to handle this situation properly.
 *
 * @param lNode a node
 * @return whether the node is regarded flexible.
 */
public static boolean isFlexibleNode(final LNode lNode) {
    // dummies are not flexible!
    if (lNode.getType() != NodeType.NORMAL) {
        return false;
    }
    // at least two ports are required ...
    if (lNode.getPorts().size() <= 1) {
        return false;
    }
    // if ports may not be moved there's no use in enlarging the node
    PortConstraints pc = lNode.getProperty(LayeredOptions.PORT_CONSTRAINTS);
    if (pc.isPosFixed()) {
        return false;
    }
    NodeFlexibility nf = getNodeFlexibility(lNode);
    if (nf == NodeFlexibility.NONE) {
        return false;
    }
    // all ports, reuse the existing port positions
    if (!nf.isFlexibleSizeWhereSpacePermits()) {
        // we are not allowed to increase the node's size
        double portSpacing = Spacings.getIndividualOrDefault(lNode, LayeredOptions.SPACING_PORT_PORT);
        ElkMargin additionalPortSpacing = lNode.getProperty(LayeredOptions.SPACING_PORTS_SURROUNDING);
        if (additionalPortSpacing == null) {
            additionalPortSpacing = new ElkMargin(portSpacing, portSpacing, portSpacing, portSpacing);
        }
        // check west side
        List<LPort> westPorts = lNode.getPortSideView(PortSide.WEST);
        double requiredWestHeight = additionalPortSpacing.top + additionalPortSpacing.bottom + (westPorts.size() - 1) * portSpacing;
        if (requiredWestHeight > lNode.getSize().y) {
            return false;
        }
        // check east side
        List<LPort> eastPorts = lNode.getPortSideView(PortSide.EAST);
        double requiredEastHeight = additionalPortSpacing.top + additionalPortSpacing.bottom + (eastPorts.size() - 1) * portSpacing;
        if (requiredEastHeight > lNode.getSize().y) {
            return false;
        }
    }
    return true;
}
Also used : LPort(org.eclipse.elk.alg.layered.graph.LPort) NodeFlexibility.getNodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility.getNodeFlexibility) NodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility) PortConstraints(org.eclipse.elk.core.options.PortConstraints) ElkMargin(org.eclipse.elk.core.math.ElkMargin)

Example 3 with NodeFlexibility

use of org.eclipse.elk.alg.layered.options.NodeFlexibility in project elk by eclipse.

the class NetworkSimplexPlacer method insertFlexibleWhereSpaceAuxiliaryEdges.

/**
 * Inserts auxiliary edges for the case that {@link NodeFlexibility#NODE_SIZE_WHERE_SPACE_PERMITS} node exist.
 */
private void insertFlexibleWhereSpaceAuxiliaryEdges() {
    int minLayer = nGraph.nodes.stream().map(n -> n.layer).min(Integer::compare).get();
    int maxLayer = nGraph.nodes.stream().map(n -> n.layer).max(Integer::compare).get();
    int usedLayers = maxLayer - minLayer;
    NNode globalSource = NNode.of().create(nGraph);
    NNode globalSink = NNode.of().create(nGraph);
    // make sure the distance between source and sink is preserved
    NEdge.of().weight(NODE_SIZE_WEIGHT_STATIC * 2).delta(usedLayers).source(globalSource).target(globalSink).create();
    // fix the position of most non-flexible nodes and make sure the flexible nodes
    // can only increase in size
    Arrays.stream(nodeReps).filter(nr -> nr.origin.getType() == NodeType.NORMAL).filter(// allow leaves to move
    nr -> nr.origin.getPorts().size() > 1).forEach(nr -> {
        NEdge.of().weight(0).delta(nr.tail.layer - minLayer).source(globalSource).target(nr.tail).create();
        NEdge.of().weight(0).delta(usedLayers - nr.head.layer).source(nr.head).target(globalSink).create();
    });
}
Also used : NNode(org.eclipse.elk.alg.common.networksimplex.NNode) Arrays(java.util.Arrays) ElkMargin(org.eclipse.elk.core.math.ElkMargin) Iterables(com.google.common.collect.Iterables) GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) Layer(org.eclipse.elk.alg.layered.graph.Layer) ListIterator(java.util.ListIterator) LLabel(org.eclipse.elk.alg.layered.graph.LLabel) NorthSouthPortPreprocessor(org.eclipse.elk.alg.layered.intermediate.NorthSouthPortPreprocessor) PortSide(org.eclipse.elk.core.options.PortSide) IElkProgressMonitor(org.eclipse.elk.core.util.IElkProgressMonitor) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) NGraph(org.eclipse.elk.alg.common.networksimplex.NGraph) Stack(java.util.Stack) LayeredOptions(org.eclipse.elk.alg.layered.options.LayeredOptions) ArrayList(java.util.ArrayList) Spacings(org.eclipse.elk.alg.layered.options.Spacings) IntermediateProcessorStrategy(org.eclipse.elk.alg.layered.intermediate.IntermediateProcessorStrategy) Lists(com.google.common.collect.Lists) InternalProperties(org.eclipse.elk.alg.layered.options.InternalProperties) Map(java.util.Map) NodeFlexibility.getNodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility.getNodeFlexibility) StreamSupport(java.util.stream.StreamSupport) NetworkSimplex(org.eclipse.elk.alg.common.networksimplex.NetworkSimplex) NodeType(org.eclipse.elk.alg.layered.graph.LNode.NodeType) LayoutProcessorConfiguration(org.eclipse.elk.core.alg.LayoutProcessorConfiguration) NNode(org.eclipse.elk.alg.common.networksimplex.NNode) DoubleMath(com.google.common.math.DoubleMath) NodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility) Iterator(java.util.Iterator) PortConstraints(org.eclipse.elk.core.options.PortConstraints) Predicate(java.util.function.Predicate) NEdge(org.eclipse.elk.alg.common.networksimplex.NEdge) Set(java.util.Set) ILayoutPhase(org.eclipse.elk.core.alg.ILayoutPhase) Maps(com.google.common.collect.Maps) Sets(com.google.common.collect.Sets) LGraphElement(org.eclipse.elk.alg.layered.graph.LGraphElement) List(java.util.List) LGraph(org.eclipse.elk.alg.layered.graph.LGraph) NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement) LayeredPhases(org.eclipse.elk.alg.layered.LayeredPhases) LabelAndNodeSizeProcessor(org.eclipse.elk.alg.layered.intermediate.LabelAndNodeSizeProcessor) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) Queue(java.util.Queue)

Example 4 with NodeFlexibility

use of org.eclipse.elk.alg.layered.options.NodeFlexibility in project elk by eclipse.

the class NetworkSimplexPlacer method transformFixedOrderNode.

/**
 * @return the corners that were created for {@link LNode}.
 */
private NodeRep transformFixedOrderNode(final LNode lNode) {
    // -----------------------------------
    // corner creation
    // -----------------------------------
    NNode topLeft = NNode.of().origin(lNode).type("flexible-head").create(nGraph);
    NNode bottomLeft = NNode.of().origin(lNode).type("flexible-tail").create(nGraph);
    NodeRep corners = new NodeRep(lNode, true, topLeft, bottomLeft);
    // -----------------------------------
    // weight & minimum length
    // -----------------------------------
    // the LabelAndNodeSizeProcessor ensures that any node size constraint is satisfied,
    // i.e. the node's size is at least the specified minimum size and, if desired,
    // the node is resized according to owned ports and labels
    // as such we can safely use the current height as minimum height
    double minHeight = lNode.getSize().y;
    NodeFlexibility nf = getNodeFlexibility(lNode);
    double sizeWeight = NODE_SIZE_WEIGHT_STATIC;
    if (nf.isFlexibleSize()) {
        // we are allowed to enlarge to node
        // nevertheless, a little weight is good, otherwise the node can become arbitrarily tall
        // especially since the edges that connect the node's do not carry nay weight
        sizeWeight = NODE_SIZE_WEIGHT_FLEXIBLE;
    }
    NEdge nodeSizeEdge = NEdge.of().weight(sizeWeight).delta((int) Math.ceil(minHeight)).source(topLeft).target(bottomLeft).create();
    if (nf == NodeFlexibility.NODE_SIZE_WHERE_SPACE_PERMITS) {
        flexibleWhereSpacePermitsEdges.add(nodeSizeEdge);
    }
    // -----------------------------------
    // port transformation
    // -----------------------------------
    // convert the ports to NNodes, note that the list of westward ports
    // must be reversed since their original order is from bottom to top
    transformPorts(Lists.reverse(lNode.getPortSideView(PortSide.WEST)), corners);
    transformPorts(lNode.getPortSideView(PortSide.EAST), corners);
    // return the corners for further processing
    return corners;
}
Also used : NNode(org.eclipse.elk.alg.common.networksimplex.NNode) NEdge(org.eclipse.elk.alg.common.networksimplex.NEdge) NodeFlexibility.getNodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility.getNodeFlexibility) NodeFlexibility(org.eclipse.elk.alg.layered.options.NodeFlexibility)

Aggregations

NodeFlexibility (org.eclipse.elk.alg.layered.options.NodeFlexibility)4 NodeFlexibility.getNodeFlexibility (org.eclipse.elk.alg.layered.options.NodeFlexibility.getNodeFlexibility)4 NNode (org.eclipse.elk.alg.common.networksimplex.NNode)3 LPort (org.eclipse.elk.alg.layered.graph.LPort)3 NEdge (org.eclipse.elk.alg.common.networksimplex.NEdge)2 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)2 LNode (org.eclipse.elk.alg.layered.graph.LNode)2 Layer (org.eclipse.elk.alg.layered.graph.Layer)2 ElkMargin (org.eclipse.elk.core.math.ElkMargin)2 PortConstraints (org.eclipse.elk.core.options.PortConstraints)2 Iterables (com.google.common.collect.Iterables)1 Lists (com.google.common.collect.Lists)1 Maps (com.google.common.collect.Maps)1 Sets (com.google.common.collect.Sets)1 DoubleMath (com.google.common.math.DoubleMath)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Iterator (java.util.Iterator)1 List (java.util.List)1 ListIterator (java.util.ListIterator)1