Search in sources :

Example 1 with LPort

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

the class HierarchicalPortOrthogonalEdgeRouter method connectNodeToDummy.

/**
 * Adds a port to the given node and connects that to the given dummy node.
 *
 * @param node the node to connect to the dummy.
 * @param dummy the external port dummy to connect the node to.
 */
private void connectNodeToDummy(final LGraph layeredGraph, final LNode node, final LNode dummy) {
    // First, add a port to the node. The port side depends on the node's hierarchical port side
    LPort outPort = new LPort();
    outPort.setNode(node);
    PortSide extPortSide = node.getProperty(InternalProperties.EXT_PORT_SIDE);
    outPort.setSide(extPortSide);
    // Find the dummy node's port
    LPort inPort = dummy.getPorts().get(0);
    // Connect the two nodes
    LEdge edge = new LEdge();
    edge.setSource(outPort);
    edge.setTarget(inPort);
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) PortSide(org.eclipse.elk.core.options.PortSide)

Example 2 with LPort

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

the class HierarchicalPortOrthogonalEdgeRouter method correctSlantedEdgeSegments.

/**
 * Goes over the eastern and western hierarchical dummy nodes in the given layer and checks
 * whether their incident edges have slanted segments. Note that only the first and last
 * segment needs to be checked.
 *
 * @param layer the layer.
 */
private void correctSlantedEdgeSegments(final Layer layer) {
    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);
        if (extPortSide == PortSide.EAST || extPortSide == PortSide.WEST) {
            for (LEdge edge : node.getConnectedEdges()) {
                KVectorChain bendPoints = edge.getBendPoints();
                if (bendPoints.isEmpty()) {
                    // TODO: The edge has no bend points yet, but may still be slanted. Handle that!
                    continue;
                }
                // Correct a slanted segment connected to the source port if it belongs to our node
                LPort sourcePort = edge.getSource();
                if (sourcePort.getNode() == node) {
                    KVector firstBendPoint = bendPoints.getFirst();
                    firstBendPoint.y = sourcePort.getAbsoluteAnchor().y;
                }
                // Correct a slanted segment connected to the target port if it belongs to our node
                LPort targetPort = edge.getTarget();
                if (targetPort.getNode() == node) {
                    KVector lastBendPoint = bendPoints.getLast();
                    lastBendPoint.y = targetPort.getAbsoluteAnchor().y;
                }
            }
        }
    }
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) KVectorChain(org.eclipse.elk.core.math.KVectorChain) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) PortSide(org.eclipse.elk.core.options.PortSide) KVector(org.eclipse.elk.core.math.KVector)

Example 3 with LPort

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

the class HierarchicalPortOrthogonalEdgeRouter method removeTemporaryNorthSouthDummies.

// /////////////////////////////////////////////////////////////////////////////
// STEP 4: REMOVE TEMPORARY DUMMIES
/**
 * Removes the temporary hierarchical port dummies, reconnecting their incoming and outgoing
 * edges to the original dummies and setting the appropriate bend points.
 *
 * @param layeredGraph the layered graph.
 */
private void removeTemporaryNorthSouthDummies(final LGraph layeredGraph) {
    List<LNode> nodesToRemove = Lists.newArrayList();
    // Iterate through all layers
    for (Layer layer : layeredGraph) {
        for (LNode node : layer) {
            if (node.getType() != NodeType.EXTERNAL_PORT) {
                // We're only looking for hierarchical port dummies
                continue;
            }
            if (!node.hasProperty(InternalProperties.EXT_PORT_REPLACED_DUMMY)) {
                // We're only looking for temporary north / south dummies
                continue;
            }
            // There must be a port where all edges come in, another port where edges go out, and
            // a port with an edge connecting node and origin (that one was added previously by
            // this processor)
            LPort nodeInPort = null;
            LPort nodeOutPort = null;
            LPort nodeOriginPort = null;
            for (LPort port : node.getPorts()) {
                switch(port.getSide()) {
                    case WEST:
                        nodeInPort = port;
                        break;
                    case EAST:
                        nodeOutPort = port;
                        break;
                    default:
                        nodeOriginPort = port;
                }
            }
            // Find the edge connecting this dummy to the original external port dummy that we
            // restored just a while ago
            LEdge nodeToOriginEdge = nodeOriginPort.getOutgoingEdges().get(0);
            // Compute bend points for incoming edges
            KVectorChain incomingEdgeBendPoints = new KVectorChain(nodeToOriginEdge.getBendPoints());
            KVector firstBendPoint = new KVector(nodeOriginPort.getPosition());
            firstBendPoint.add(node.getPosition());
            incomingEdgeBendPoints.add(0, firstBendPoint);
            // Compute bend points for outgoing edges
            KVectorChain outgoingEdgeBendPoints = KVectorChain.reverse(nodeToOriginEdge.getBendPoints());
            KVector lastBendPoint = new KVector(nodeOriginPort.getPosition());
            lastBendPoint.add(node.getPosition());
            outgoingEdgeBendPoints.add(lastBendPoint);
            // Retrieve the original hierarchical port dummy
            LNode replacedDummy = (LNode) node.getProperty(InternalProperties.EXT_PORT_REPLACED_DUMMY);
            LPort replacedDummyPort = replacedDummy.getPorts().get(0);
            // Reroute all the input port's edges
            LEdge[] edges = nodeInPort.getIncomingEdges().toArray(new LEdge[0]);
            for (LEdge edge : edges) {
                edge.setTarget(replacedDummyPort);
                edge.getBendPoints().addAllAsCopies(edge.getBendPoints().size(), incomingEdgeBendPoints);
            }
            // Reroute all the output port's edges
            edges = LGraphUtil.toEdgeArray(nodeOutPort.getOutgoingEdges());
            for (LEdge edge : edges) {
                edge.setSource(replacedDummyPort);
                edge.getBendPoints().addAllAsCopies(0, outgoingEdgeBendPoints);
            }
            // Remove connection between node and original hierarchical port dummy
            nodeToOriginEdge.setSource(null);
            nodeToOriginEdge.setTarget(null);
            // Remember the temporary node for removal
            nodesToRemove.add(node);
        }
    }
    // Remove nodes
    for (LNode node : nodesToRemove) {
        node.setLayer(null);
    }
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) KVectorChain(org.eclipse.elk.core.math.KVectorChain) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 4 with LPort

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

the class HierarchicalPortOrthogonalEdgeRouter method restoreDummy.

/**
 * Restores the given dummy.
 */
private void restoreDummy(final LNode dummy, final LGraph graph) {
    // Depending on the hierarchical port's side, we set the port side of the dummy's ports
    // to be able to route properly (northern dummies must have a southern port)
    PortSide portSide = dummy.getProperty(InternalProperties.EXT_PORT_SIDE);
    LPort dummyPort = dummy.getPorts().get(0);
    if (portSide == PortSide.NORTH) {
        dummyPort.setSide(PortSide.SOUTH);
    } else if (portSide == PortSide.SOUTH) {
        dummyPort.setSide(PortSide.NORTH);
    }
    // are not set acoordingly. That needs to be fixed (if port labels are to be taken into consideration)
    if (graph.getProperty(LayeredOptions.NODE_SIZE_CONSTRAINTS).contains(SizeConstraint.PORT_LABELS)) {
        // The ElkGraphImporter has set the relevant spacings on the dummy node
        double portLabelSpacing = dummy.getProperty(LayeredOptions.SPACING_LABEL_PORT);
        double labelLabelSpacing = dummy.getProperty(LayeredOptions.SPACING_LABEL_LABEL);
        Set<PortLabelPlacement> portLabelPlacement = graph.getProperty(LayeredOptions.PORT_LABELS_PLACEMENT);
        if (portLabelPlacement.contains(PortLabelPlacement.INSIDE)) {
            double currentY = portLabelSpacing;
            double xCenterRelativeToPort = dummy.getSize().x / 2 - dummyPort.getPosition().x;
            for (LLabel label : dummyPort.getLabels()) {
                label.getPosition().y = currentY;
                label.getPosition().x = xCenterRelativeToPort - label.getSize().x / 2;
                currentY += label.getSize().y + labelLabelSpacing;
            }
        } else if (portLabelPlacement.contains(PortLabelPlacement.OUTSIDE)) {
            // Port labels have a vertical size of 0, but we need to set their x coordinate
            for (LLabel label : dummyPort.getLabels()) {
                label.getPosition().x = portLabelSpacing + dummy.getSize().x - dummyPort.getPosition().x;
            }
        }
        // Calculate margins
        NodeDimensionCalculation.getNodeMarginCalculator(LGraphAdapters.adapt(graph, false)).processNode(LGraphAdapters.adapt(dummy, false));
    }
}
Also used : PortLabelPlacement(org.eclipse.elk.core.options.PortLabelPlacement) LLabel(org.eclipse.elk.alg.layered.graph.LLabel) LPort(org.eclipse.elk.alg.layered.graph.LPort) PortSide(org.eclipse.elk.core.options.PortSide)

Example 5 with LPort

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

the class InvertedPortProcessor method createEastPortSideDummies.

/**
 * Creates the necessary dummy nodes for an input port on the east side of a node, provided that
 * the edge connects two different nodes.
 *
 * @param layeredGraph
 *            the layered graph.
 * @param eastwardPort
 *            the offending port.
 * @param edge
 *            the edge connected to the port.
 * @param layerNodeList
 *            list of unassigned nodes belonging to the layer of the node the port belongs to.
 *            The new dummy node is added to this list and must be assigned to the layer later.
 */
private void createEastPortSideDummies(final LGraph layeredGraph, final LPort eastwardPort, final LEdge edge, final List<LNode> layerNodeList) {
    assert edge.getTarget() == eastwardPort;
    // Ignore self loops
    if (edge.getSource().getNode() == eastwardPort.getNode()) {
        return;
    }
    // Dummy node in the same layer
    LNode dummy = new LNode(layeredGraph);
    dummy.setType(NodeType.LONG_EDGE);
    dummy.setProperty(InternalProperties.ORIGIN, edge);
    dummy.setProperty(LayeredOptions.PORT_CONSTRAINTS, PortConstraints.FIXED_POS);
    layerNodeList.add(dummy);
    LPort dummyInput = new LPort();
    dummyInput.setNode(dummy);
    dummyInput.setSide(PortSide.WEST);
    LPort dummyOutput = new LPort();
    dummyOutput.setNode(dummy);
    dummyOutput.setSide(PortSide.EAST);
    // Reroute the original edge
    edge.setTarget(dummyInput);
    // Connect the dummy with the original port
    LEdge dummyEdge = new LEdge();
    dummyEdge.copyProperties(edge);
    dummyEdge.setProperty(LayeredOptions.JUNCTION_POINTS, null);
    dummyEdge.setSource(dummyOutput);
    dummyEdge.setTarget(eastwardPort);
    // Set LONG_EDGE_SOURCE and LONG_EDGE_TARGET properties on the LONG_EDGE dummy
    setLongEdgeSourceAndTarget(dummy, dummyInput, dummyOutput, eastwardPort);
    // Move head labels from the old edge over to the new one
    ListIterator<LLabel> labelIterator = edge.getLabels().listIterator();
    while (labelIterator.hasNext()) {
        LLabel label = labelIterator.next();
        EdgeLabelPlacement labelPlacement = label.getProperty(LayeredOptions.EDGE_LABELS_PLACEMENT);
        if (labelPlacement == EdgeLabelPlacement.HEAD) {
            // Remember which edge the label originally belonged to, unless it already knows
            if (!label.hasProperty(InternalProperties.END_LABEL_EDGE)) {
                label.setProperty(InternalProperties.END_LABEL_EDGE, edge);
            }
            labelIterator.remove();
            dummyEdge.getLabels().add(label);
        }
    }
}
Also used : LLabel(org.eclipse.elk.alg.layered.graph.LLabel) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) EdgeLabelPlacement(org.eclipse.elk.core.options.EdgeLabelPlacement)

Aggregations

LPort (org.eclipse.elk.alg.layered.graph.LPort)270 LNode (org.eclipse.elk.alg.layered.graph.LNode)187 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)78 Test (org.junit.Test)66 Layer (org.eclipse.elk.alg.layered.graph.Layer)62 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)46 KVector (org.eclipse.elk.core.math.KVector)36 PortSide (org.eclipse.elk.core.options.PortSide)29 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)23 KVectorChain (org.eclipse.elk.core.math.KVectorChain)18 GraphInfoHolder (org.eclipse.elk.alg.layered.p3order.GraphInfoHolder)15 List (java.util.List)12 ArrayList (java.util.ArrayList)8 InternalProperties (org.eclipse.elk.alg.layered.options.InternalProperties)8 PortConstraints (org.eclipse.elk.core.options.PortConstraints)7 Set (java.util.Set)6 ElkLabel (org.eclipse.elk.graph.ElkLabel)6 EnumSet (java.util.EnumSet)5 SelfHyperLoop (org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop)5 Lists (com.google.common.collect.Lists)4