Search in sources :

Example 6 with PortConstraints

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

the class ComponentsProcessor method split.

/**
 * Split the given graph into its connected components.
 *
 * @param graph an input graph with layerless nodes
 * @return a list of components that can be processed one by one
 */
public List<LGraph> split(final LGraph graph) {
    List<LGraph> result;
    // Default to the simple graph placer
    graphPlacer = simpleRowGraphPlacer;
    // Whether separate components processing is requested
    Boolean separateProperty = graph.getProperty(LayeredOptions.SEPARATE_CONNECTED_COMPONENTS);
    boolean separate = separateProperty == null || separateProperty.booleanValue();
    // Whether the graph contains external ports
    boolean extPorts = graph.getProperty(InternalProperties.GRAPH_PROPERTIES).contains(GraphProperties.EXTERNAL_PORTS);
    // The graph's external port constraints
    PortConstraints extPortConstraints = graph.getProperty(LayeredOptions.PORT_CONSTRAINTS);
    boolean compatiblePortConstraints = !extPortConstraints.isOrderFixed();
    // FREE or FIXED_SIDES.
    if (separate && (compatiblePortConstraints || !extPorts)) {
        // Set id of all nodes to 0
        for (LNode node : graph.getLayerlessNodes()) {
            node.id = 0;
        }
        // Perform DFS starting on each node, collecting connected components
        result = Lists.newArrayList();
        for (LNode node : graph.getLayerlessNodes()) {
            Pair<List<LNode>, Set<PortSide>> componentData = dfs(node, null);
            if (componentData != null) {
                LGraph newGraph = new LGraph();
                newGraph.copyProperties(graph);
                newGraph.setProperty(InternalProperties.EXT_PORT_CONNECTIONS, componentData.getSecond());
                newGraph.getPadding().copy(graph.getPadding());
                // If a minimum size was set on the original graph, setting it on the seperated graphs as well
                // might enlarge them although their combined area might not actually have fallen below the minimum
                // size; thus, remove the minimum size
                newGraph.setProperty(LayeredOptions.NODE_SIZE_MINIMUM, null);
                for (LNode n : componentData.getFirst()) {
                    newGraph.getLayerlessNodes().add(n);
                    n.setGraph(newGraph);
                }
                result.add(newGraph);
            }
        }
        if (extPorts) {
            // With external port connections, we want to use the more complex components
            // placement algorithm
            graphPlacer = componentGroupGraphPlacer;
        }
    } else {
        result = Arrays.asList(graph);
    }
    // The component with the node with the smallest order should be first.
    if (graph.getProperty(LayeredOptions.CONSIDER_MODEL_ORDER_STRATEGY) != OrderingStrategy.NONE) {
        Collections.sort(result, (g1, g2) -> {
            int g1Order = Integer.MAX_VALUE;
            for (LNode node : g1.getLayerlessNodes()) {
                if (node.hasProperty(InternalProperties.MODEL_ORDER)) {
                    g1Order = Math.min(g1Order, node.getProperty(InternalProperties.MODEL_ORDER));
                }
            }
            int g2Order = Integer.MAX_VALUE;
            for (LNode node : g2.getLayerlessNodes()) {
                if (node.hasProperty(InternalProperties.MODEL_ORDER)) {
                    g2Order = Math.min(g2Order, node.getProperty(InternalProperties.MODEL_ORDER));
                }
            }
            return Integer.compare(g1Order, g2Order);
        });
    }
    return result;
}
Also used : Set(java.util.Set) EnumSet(java.util.EnumSet) LNode(org.eclipse.elk.alg.layered.graph.LNode) List(java.util.List) LGraph(org.eclipse.elk.alg.layered.graph.LGraph) PortConstraints(org.eclipse.elk.core.options.PortConstraints)

Example 7 with PortConstraints

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

the class ElkGraphImporter method transformNode.

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Node Transformation
/**
 * Transforms the given node and its contained ports.
 *
 * @param elknode
 *            the node to transform
 * @param lgraph
 *            the layered graph into which the transformed node is put
 * @return the transformed node
 */
private LNode transformNode(final ElkNode elknode, final LGraph lgraph) {
    // add a new node to the layered graph, copying its position
    LNode lnode = new LNode(lgraph);
    lnode.copyProperties(elknode);
    lnode.setProperty(InternalProperties.ORIGIN, elknode);
    lnode.getSize().x = elknode.getWidth();
    lnode.getSize().y = elknode.getHeight();
    lnode.getPosition().x = elknode.getX();
    lnode.getPosition().y = elknode.getY();
    lgraph.getLayerlessNodes().add(lnode);
    nodeAndPortMap.put(elknode, lnode);
    // check if the node is a compound node in the original graph
    if (!elknode.getChildren().isEmpty() || elknode.getProperty(LayeredOptions.INSIDE_SELF_LOOPS_ACTIVATE)) {
        lnode.setProperty(InternalProperties.COMPOUND_NODE, true);
    }
    Set<GraphProperties> graphProperties = lgraph.getProperty(InternalProperties.GRAPH_PROPERTIES);
    // port constraints and sides cannot be undefined
    PortConstraints portConstraints = lnode.getProperty(LayeredOptions.PORT_CONSTRAINTS);
    if (portConstraints == PortConstraints.UNDEFINED) {
        lnode.setProperty(LayeredOptions.PORT_CONSTRAINTS, PortConstraints.FREE);
    } else if (portConstraints != PortConstraints.FREE) {
        // if the port constraints are not free, set the appropriate graph property
        graphProperties.add(GraphProperties.NON_FREE_PORTS);
    }
    // transform the ports
    Direction direction = lgraph.getProperty(LayeredOptions.DIRECTION);
    for (ElkPort elkport : elknode.getPorts()) {
        if (!elkport.getProperty(LayeredOptions.NO_LAYOUT)) {
            transformPort(elkport, lnode, graphProperties, direction, portConstraints);
        }
    }
    // add the node's labels
    for (ElkLabel elklabel : elknode.getLabels()) {
        if (!elklabel.getProperty(LayeredOptions.NO_LAYOUT) && !Strings.isNullOrEmpty(elklabel.getText())) {
            lnode.getLabels().add(transformLabel(elklabel));
        }
    }
    if (lnode.getProperty(LayeredOptions.COMMENT_BOX)) {
        graphProperties.add(GraphProperties.COMMENTS);
    }
    // if we have a hypernode without ports, create a default input and output port
    if (lnode.getProperty(LayeredOptions.HYPERNODE)) {
        graphProperties.add(GraphProperties.HYPERNODES);
        graphProperties.add(GraphProperties.HYPEREDGES);
        lnode.setProperty(LayeredOptions.PORT_CONSTRAINTS, PortConstraints.FREE);
    }
    return lnode;
}
Also used : GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) ElkLabel(org.eclipse.elk.graph.ElkLabel) ElkPort(org.eclipse.elk.graph.ElkPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) PortConstraints(org.eclipse.elk.core.options.PortConstraints) Direction(org.eclipse.elk.core.options.Direction)

Example 8 with PortConstraints

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

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

the class PortListSorter method process.

@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor) {
    monitor.begin("Port order processing", 1);
    PortSortingStrategy pss = layeredGraph.getProperty(LayeredOptions.PORT_SORTING_STRATEGY);
    // Iterate through the nodes of all layers
    for (Layer layer : layeredGraph) {
        for (LNode node : layer) {
            PortConstraints portConstraints = node.getProperty(LayeredOptions.PORT_CONSTRAINTS);
            List<LPort> ports = node.getPorts();
            // We need to sort the port list according to port constraints
            if (portConstraints.isOrderFixed()) {
                Collections.sort(ports, CMP_COMBINED);
            } else if (portConstraints.isSideFixed()) {
                // by default try to preserve the input order
                Collections.sort(ports, CMP_PORT_SIDE);
                reverseWestAndSouthSide(ports);
                if (pss == PortSortingStrategy.PORT_DEGREE) {
                    Collections.sort(ports, CMP_PORT_DEGREE_EAST_WEST);
                }
            }
            node.cachePortSides();
        }
    }
    monitor.done();
}
Also used : PortSortingStrategy(org.eclipse.elk.alg.layered.options.PortSortingStrategy) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) Layer(org.eclipse.elk.alg.layered.graph.Layer) PortConstraints(org.eclipse.elk.core.options.PortConstraints)

Example 10 with PortConstraints

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

the class HierarchicalPortOrthogonalEdgeRouter method fixCoordinates.

// /////////////////////////////////////////////////////////////////////////////
// STEP 5: FIX DUMMY COORDINATES
/**
 * Fixes all hierarchical port dummy coordinates. For east / west external port dummies, this
 * means setting the x coordinate appropriately, and, in case of {@code FIXED_RATIO},
 * checking that the ratio is respected. For north / south hierarchical port dummies, this
 * means setting the y coordinate appropriately.
 *
 * @param layeredGraph the layered graph.
 */
private void fixCoordinates(final LGraph layeredGraph) {
    PortConstraints constraints = layeredGraph.getProperty(LayeredOptions.PORT_CONSTRAINTS);
    // East port dummies are in the first layer; all other dummies are in the last layer
    List<Layer> layers = layeredGraph.getLayers();
    fixCoordinates(layers.get(0), constraints, layeredGraph);
    fixCoordinates(layers.get(layers.size() - 1), constraints, layeredGraph);
}
Also used : PortConstraints(org.eclipse.elk.core.options.PortConstraints) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Aggregations

PortConstraints (org.eclipse.elk.core.options.PortConstraints)18 LNode (org.eclipse.elk.alg.layered.graph.LNode)9 PortSide (org.eclipse.elk.core.options.PortSide)8 Direction (org.eclipse.elk.core.options.Direction)6 LPort (org.eclipse.elk.alg.layered.graph.LPort)5 KVector (org.eclipse.elk.core.math.KVector)5 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)5 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)4 ElkLabel (org.eclipse.elk.graph.ElkLabel)4 ElkNode (org.eclipse.elk.graph.ElkNode)4 ElkPort (org.eclipse.elk.graph.ElkPort)4 EnumSet (java.util.EnumSet)3 List (java.util.List)3 Map (java.util.Map)3 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)3 Layer (org.eclipse.elk.alg.layered.graph.Layer)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 Set (java.util.Set)2 LPadding (org.eclipse.elk.alg.layered.graph.LPadding)2