Search in sources :

Example 46 with LPort

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

the class CuttingUtils method insertDummies.

/**
 * Inserts two in-layer dummies and a varying number of long edge dummies for the passed edge.
 *
 * Let {@code originalEdge = e = (u,v)}. In-layer dummies {@code il_1} and {@code il_2} are inserted into layers
 * {@code L(u)} and {@code L(v)}. Long edge dummies {@code d_1, ..., d_m} are inserted into the layers
 * {@code L(u)+1, ..., L(v)-1}.
 *
 * The resulting chain of edges looks as follows (if {@code offsetFirstInLayerDummy} is 1).
 *
 * <pre>
 *                               v
 *                               î
 * il_1 -> d_1 -> ... -> d_m -> il_2
 *  î
 *  u
 * </pre>
 *
 * @param layeredGraph
 *            the underlying graph with a given layering.
 * @param originalEdge
 *            the edge to be split
 * @param offsetFirstInLayerDummy
 *            the dummy nodes are inserted at the end of each layer. For the first in-layer dummy this is not always
 *            desired and can be modified using this offset.
 */
public static List<LEdge> insertDummies(final LGraph layeredGraph, final LEdge originalEdge, final int offsetFirstInLayerDummy) {
    // to visually separate the backward wrapping edges, add some additional spacing
    double edgeNodeSpacing = layeredGraph.getProperty(LayeredOptions.SPACING_EDGE_NODE);
    double additionalSpacing = layeredGraph.getProperty(LayeredOptions.WRAPPING_ADDITIONAL_EDGE_SPACING);
    IndividualSpacings is = new IndividualSpacings();
    is.setProperty(LayeredOptions.SPACING_EDGE_NODE, edgeNodeSpacing + additionalSpacing);
    LEdge edge = originalEdge;
    LPort targetPort = edge.getTarget();
    LNode src = edge.getSource().getNode();
    LNode tgt = edge.getTarget().getNode();
    int srcIndex = src.getLayer().getIndex();
    int tgtIndex = tgt.getLayer().getIndex();
    List<LEdge> createdEdges = Lists.newArrayList();
    for (int i = srcIndex; i <= tgtIndex; i++) {
        // Create dummy node
        LNode dummyNode = new LNode(layeredGraph);
        dummyNode.setType(NodeType.LONG_EDGE);
        dummyNode.setProperty(InternalProperties.ORIGIN, edge);
        dummyNode.setProperty(LayeredOptions.PORT_CONSTRAINTS, PortConstraints.FIXED_POS);
        dummyNode.setProperty(LayeredOptions.SPACING_INDIVIDUAL, is);
        Layer nextLayer = layeredGraph.getLayers().get(i);
        if (i == srcIndex) {
            dummyNode.setLayer(nextLayer.getNodes().size() - offsetFirstInLayerDummy, nextLayer);
        } else {
            dummyNode.setLayer(nextLayer);
        }
        // Set thickness of the edge
        double thickness = edge.getProperty(LayeredOptions.EDGE_THICKNESS);
        if (thickness < 0) {
            thickness = 0;
            edge.setProperty(LayeredOptions.EDGE_THICKNESS, thickness);
        }
        dummyNode.getSize().y = thickness;
        double portPos = Math.floor(thickness / 2);
        // Create dummy input and output ports
        LPort dummyInput = new LPort();
        dummyInput.setSide(PortSide.WEST);
        dummyInput.setNode(dummyNode);
        dummyInput.getPosition().y = portPos;
        LPort dummyOutput = new LPort();
        dummyOutput.setSide(PortSide.EAST);
        dummyOutput.setNode(dummyNode);
        dummyOutput.getPosition().y = portPos;
        edge.setTarget(dummyInput);
        // Create a dummy edge
        LEdge dummyEdge = new LEdge();
        dummyEdge.copyProperties(edge);
        dummyEdge.setProperty(LayeredOptions.JUNCTION_POINTS, null);
        dummyEdge.setSource(dummyOutput);
        dummyEdge.setTarget(targetPort);
        setDummyProperties(dummyNode, edge, dummyEdge);
        createdEdges.add(dummyEdge);
        edge = dummyEdge;
    }
    return createdEdges;
}
Also used : IndividualSpacings(org.eclipse.elk.core.util.IndividualSpacings) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 47 with LPort

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

the class GreedyPortDistributor method distributePortsOnNode.

/**
 * Distribute ports greedily on a single node.
 */
private boolean distributePortsOnNode(final LNode node, final PortSide side, final boolean useHierarchicalCrosscounter) {
    List<LPort> ports = node.getPortSideView(side);
    if (side == PortSide.SOUTH || side == PortSide.WEST) {
        ports = Lists.reverse(ports);
    }
    boolean improved = false;
    boolean continueSwitching;
    do {
        continueSwitching = false;
        for (int i = 0; i < ports.size() - 1; i++) {
            LPort upperPort = ports.get(i);
            LPort lowerPort = ports.get(i + 1);
            if (switchingDecreasesCrossings(upperPort, lowerPort, node, useHierarchicalCrosscounter)) {
                improved = true;
                switchPorts(ports, node, i, i + 1);
                continueSwitching = true;
            }
        }
    } while (continueSwitching);
    return improved;
}
Also used : LPort(org.eclipse.elk.alg.layered.graph.LPort)

Example 48 with LPort

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

the class GreedyCycleBreaker method updateNeighbors.

/**
 * Updates indegree and outdegree values of the neighbors of the given node,
 * simulating its removal from the graph. the sources and sinks lists are
 * also updated.
 *
 * @param node node for which neighbors are updated
 */
private void updateNeighbors(final LNode node) {
    for (LPort port : node.getPorts()) {
        for (LEdge edge : port.getConnectedEdges()) {
            LPort connectedPort = edge.getSource() == port ? edge.getTarget() : edge.getSource();
            LNode endpoint = connectedPort.getNode();
            // exclude self-loops
            if (node == endpoint) {
                continue;
            }
            int priority = edge.getProperty(LayeredOptions.PRIORITY_DIRECTION);
            if (priority < 0) {
                priority = 0;
            }
            int index = endpoint.id;
            if (mark[index] == 0) {
                if (edge.getTarget() == connectedPort) {
                    indeg[index] -= priority + 1;
                    if (indeg[index] <= 0 && outdeg[index] > 0) {
                        sources.add(endpoint);
                    }
                } else {
                    outdeg[index] -= priority + 1;
                    if (outdeg[index] <= 0 && indeg[index] > 0) {
                        sinks.add(endpoint);
                    }
                }
            }
        }
    }
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode)

Example 49 with LPort

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

the class InteractiveCycleBreaker method process.

@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor) {
    monitor.begin("Interactive cycle breaking", 1);
    // gather edges that point to the wrong direction
    List<LEdge> revEdges = Lists.newArrayList();
    for (LNode source : layeredGraph.getLayerlessNodes()) {
        source.id = 1;
        double sourcex = source.getInteractiveReferencePoint().x;
        for (LPort port : source.getPorts(PortType.OUTPUT)) {
            for (LEdge edge : port.getOutgoingEdges()) {
                LNode target = edge.getTarget().getNode();
                if (target != source) {
                    double targetx = target.getInteractiveReferencePoint().x;
                    if (targetx < sourcex) {
                        revEdges.add(edge);
                    }
                }
            }
        }
    }
    // reverse the gathered edges
    for (LEdge edge : revEdges) {
        edge.reverse(layeredGraph, true);
    }
    // perform an additional check for cycles - maybe we missed something
    // (could happen if some nodes have the same horizontal position)
    revEdges.clear();
    for (LNode node : layeredGraph.getLayerlessNodes()) {
        // unvisited nodes have id = 1
        if (node.id > 0) {
            findCycles(node, revEdges);
        }
    }
    // again, reverse the edges that were marked
    for (LEdge edge : revEdges) {
        edge.reverse(layeredGraph, true);
    }
    revEdges.clear();
    monitor.done();
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode)

Example 50 with LPort

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

the class SweepCopy method assertCorrectPortSides.

/**
 * Corrects the {@link PortSide} of dummy's origin.
 * @return The {@link LNode} ('origin') whose port {@code dummy} represents.
 */
private LNode assertCorrectPortSides(final LNode dummy) {
    assert dummy.getType() == NodeType.NORTH_SOUTH_PORT;
    LNode origin = dummy.getProperty(InternalProperties.IN_LAYER_LAYOUT_UNIT);
    // a north south port dummy has exactly one port
    List<LPort> dummyPorts = dummy.getPorts();
    LPort dummyPort = dummyPorts.get(0);
    // find the corresponding port on the regular node
    for (LPort port : origin.getPorts()) {
        if (port.equals(dummyPort.getProperty(InternalProperties.ORIGIN))) {
            // switch the port's side if necessary
            if ((port.getSide() == PortSide.NORTH) && (dummy.id > origin.id)) {
                port.setSide(PortSide.SOUTH);
                if (port.isExplicitlySuppliedPortAnchor()) {
                    // Set new coordinates for port anchor since it was switched from NORTH to SOUTH.
                    // The y coordinate is updated by mirroring the y coordinate
                    double portHeight = port.getSize().y;
                    double anchorY = port.getAnchor().y;
                    port.getAnchor().y = portHeight - anchorY;
                }
            } else if ((port.getSide() == PortSide.SOUTH) && (origin.id > dummy.id)) {
                port.setSide(PortSide.NORTH);
                if (port.isExplicitlySuppliedPortAnchor()) {
                    // Set new coordinates for port anchor since it was switched from NORTH to SOUTH.
                    // The y coordinate is updated by mirroring the y coordinate
                    double portHeight = port.getSize().y;
                    double anchorY = port.getAnchor().y;
                    port.getAnchor().y = -(portHeight - anchorY);
                }
            }
            break;
        }
    }
    return origin;
}
Also used : LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode)

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