Search in sources :

Example 16 with LNode

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

the class LayerConstraintPostprocessor method restoreHiddenNodes.

/**
 * Restores nodes hidden by {@link LayerConstraintPreprocessor}.
 */
private void restoreHiddenNodes(final LGraph layeredGraph, final Layer firstSeparateLayer, final Layer lastSeparateLayer) {
    for (LNode hiddenNode : layeredGraph.getProperty(InternalProperties.HIDDEN_NODES)) {
        // Add the node to the appropriate layer
        switch(hiddenNode.getProperty(LayeredOptions.LAYERING_LAYER_CONSTRAINT)) {
            case FIRST_SEPARATE:
                hiddenNode.setLayer(firstSeparateLayer);
                break;
            case LAST_SEPARATE:
                hiddenNode.setLayer(lastSeparateLayer);
                break;
            default:
                // Only *_SEPARATE nodes should be in the list
                assert false;
        }
        // Restore the node's edges
        for (LEdge hiddenEdge : hiddenNode.getConnectedEdges()) {
            // responsible for hiding it. Thus, we may find an edge here that is already restored!
            if (hiddenEdge.getSource() != null && hiddenEdge.getTarget() != null) {
                continue;
            }
            // One end point is the hidden node, the other is null
            boolean isOutgoing = hiddenEdge.getTarget() == null;
            LPort originalOppositePort = hiddenEdge.getProperty(InternalProperties.ORIGINAL_OPPOSITE_PORT);
            if (isOutgoing) {
                hiddenEdge.setTarget(originalOppositePort);
            } else {
                hiddenEdge.setSource(originalOppositePort);
            }
        }
    }
}
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 17 with LNode

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

the class InteractiveExternalPortPositioner method findNorthSouthPortXCoordinate.

private Optional<Double> findNorthSouthPortXCoordinate(final LNode dummy) {
    // external port dummies must have exactly one port
    assert dummy.getPorts().size() == 1;
    LPort port = dummy.getPorts().get(0);
    if (!port.getOutgoingEdges().isEmpty() && !port.getIncomingEdges().isEmpty()) {
        throw new IllegalStateException("Interactive layout does not support " + "NORTH/SOUTH ports with incoming _and_ outgoing edges.");
    }
    if (!port.getOutgoingEdges().isEmpty()) {
        // find the minimum position
        double min = Double.POSITIVE_INFINITY;
        for (LEdge e : port.getOutgoingEdges()) {
            LNode n = e.getTarget().getNode();
            ElkMargin margins = n.getProperty(LayeredOptions.MARGINS);
            min = Math.min(min, n.getPosition().x - margins.left);
        }
        return Optional.of(min);
    }
    if (!port.getIncomingEdges().isEmpty()) {
        // find the maximum value
        double max = Double.NEGATIVE_INFINITY;
        for (LEdge e : port.getIncomingEdges()) {
            LNode n = e.getSource().getNode();
            ElkMargin margins = n.getProperty(LayeredOptions.MARGINS);
            max = Math.max(max, n.getPosition().x + n.getSize().x + margins.right);
        }
        return Optional.of(max);
    }
    // we should never reach here
    return Optional.absent();
}
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) ElkMargin(org.eclipse.elk.core.math.ElkMargin)

Example 18 with LNode

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

the class GraphTransformer method mirrorX.

// /////////////////////////////////////////////////////////////////////////////
// Mirror Horizontally
/**
 * Mirror the x coordinates of the given graph.
 *
 * @param nodes the nodes of the graph to transpose
 * @param graph the graph the nodes are part of
 */
private void mirrorX(final List<LNode> nodes, final LGraph graph) {
    /* Assuming that no nodes extend into negative x coordinates, mirroring a node means that the
         * space left to its left border equals the space right to its right border when mirrored. In
         * mathematical terms:
         *     oldPosition.x = graphWidth - newPosition.x - nodeWidth
         * We use the offset variable to store graphWidth, since that's the constant offset against which
         * we calculate the new node positions.
         * This, however, stops to work once nodes are allowed to extend into negative coordinates. Then,
         * we have to subtract from the graphWidth the amount of space the graph extends into negative
         * coordinates. This amount is saved in the graph's graphOffset. Thus, our offset here becomes:
         *     offset = graphWidth - graphOffset.x 
         */
    double offset = 0;
    // over its nodes
    if (graph.getSize().x == 0) {
        for (LNode node : nodes) {
            offset = Math.max(offset, node.getPosition().x + node.getSize().x + node.getMargin().right);
        }
    } else {
        offset = graph.getSize().x - graph.getOffset().x;
    }
    offset -= graph.getOffset().x;
    // mirror all nodes, ports, edges, and labels
    for (LNode node : nodes) {
        mirrorX(node.getPosition(), offset - node.getSize().x);
        mirrorX(node.getPadding());
        mirrorNodeLabelPlacementX(node);
        // mirror position
        if (node.getAllProperties().containsKey(LayeredOptions.POSITION)) {
            mirrorX(node.getProperty(LayeredOptions.POSITION), offset - node.getSize().x);
        }
        // mirror the alignment
        switch(node.getProperty(LayeredOptions.ALIGNMENT)) {
            case LEFT:
                node.setProperty(LayeredOptions.ALIGNMENT, Alignment.RIGHT);
                break;
            case RIGHT:
                node.setProperty(LayeredOptions.ALIGNMENT, Alignment.LEFT);
                break;
        }
        KVector nodeSize = node.getSize();
        for (LPort port : node.getPorts()) {
            mirrorX(port.getPosition(), nodeSize.x - port.getSize().x);
            mirrorX(port.getAnchor(), port.getSize().x);
            mirrorPortSideX(port);
            reverseIndex(port);
            for (LEdge edge : port.getOutgoingEdges()) {
                // Mirror bend points
                for (KVector bendPoint : edge.getBendPoints()) {
                    mirrorX(bendPoint, offset);
                }
                // Mirror junction points
                KVectorChain junctionPoints = edge.getProperty(LayeredOptions.JUNCTION_POINTS);
                if (junctionPoints != null) {
                    for (KVector jp : junctionPoints) {
                        mirrorX(jp, offset);
                    }
                }
                // Mirror edge label positions
                for (LLabel label : edge.getLabels()) {
                    mirrorX(label.getPosition(), offset - label.getSize().x);
                }
            }
            // Mirror port label positions
            for (LLabel label : port.getLabels()) {
                mirrorX(label.getPosition(), port.getSize().x - label.getSize().x);
            }
        }
        // External port dummy?
        if (node.getType() == NodeType.EXTERNAL_PORT) {
            mirrorExternalPortSideX(node);
            mirrorLayerConstraintX(node);
        }
        // Mirror node labels
        for (LLabel label : node.getLabels()) {
            mirrorNodeLabelPlacementX(label);
            mirrorX(label.getPosition(), nodeSize.x - label.getSize().x);
        }
    }
}
Also used : LLabel(org.eclipse.elk.alg.layered.graph.LLabel) 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)

Example 19 with LNode

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

the class GraphTransformer method process.

@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor) {
    monitor.begin("Graph transformation (" + mode + ")", 1);
    // We need to add all layerless nodes as well as all nodes in layers since this processor
    // is run twice -- once before layering, and once afterwards
    List<LNode> nodes = Lists.newArrayList(layeredGraph.getLayerlessNodes());
    for (Layer layer : layeredGraph.getLayers()) {
        nodes.addAll(layer.getNodes());
    }
    // graph transformations for unusual layout directions
    DirectionCongruency congruency = layeredGraph.getProperty(LayeredOptions.DIRECTION_CONGRUENCY);
    if (congruency == DirectionCongruency.READING_DIRECTION) {
        // --------------------------------------------------------------
        switch(layeredGraph.getProperty(LayeredOptions.DIRECTION)) {
            case LEFT:
                mirrorAllX(layeredGraph, nodes);
                break;
            case DOWN:
                transposeAll(layeredGraph, nodes);
                break;
            case UP:
                if (mode == Mode.TO_INTERNAL_LTR) {
                    transposeAll(layeredGraph, nodes);
                    mirrorAllY(layeredGraph, nodes);
                } else {
                    mirrorAllY(layeredGraph, nodes);
                    transposeAll(layeredGraph, nodes);
                }
                break;
        }
    } else {
        if (mode == Mode.TO_INTERNAL_LTR) {
            // --------------------------------------------------------------
            switch(layeredGraph.getProperty(LayeredOptions.DIRECTION)) {
                case LEFT:
                    mirrorAllX(layeredGraph, nodes);
                    mirrorAllY(layeredGraph, nodes);
                    break;
                case DOWN:
                    rotate90Clockwise(layeredGraph, nodes);
                    break;
                case UP:
                    rotate90CounterClockwise(layeredGraph, nodes);
                    break;
            }
        } else {
            // --------------------------------------------------------------
            switch(layeredGraph.getProperty(LayeredOptions.DIRECTION)) {
                case LEFT:
                    mirrorAllX(layeredGraph, nodes);
                    mirrorAllY(layeredGraph, nodes);
                    break;
                case DOWN:
                    rotate90CounterClockwise(layeredGraph, nodes);
                    break;
                case UP:
                    rotate90Clockwise(layeredGraph, nodes);
                    break;
            }
        }
    }
    monitor.done();
}
Also used : LNode(org.eclipse.elk.alg.layered.graph.LNode) DirectionCongruency(org.eclipse.elk.alg.layered.options.DirectionCongruency) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 20 with LNode

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

the class GraphTransformer method mirrorY.

// /////////////////////////////////////////////////////////////////////////////
// Mirror Vertically
/**
 * Mirror the y coordinates of the given graph.
 *
 * @param nodes the nodes of the graph to transpose
 * @param graph the graph the nodes are part of
 */
private void mirrorY(final List<LNode> nodes, final LGraph graph) {
    // See mirrorX for an explanation of how the offset is calculated
    double offset = 0;
    if (graph.getSize().y == 0) {
        for (LNode node : nodes) {
            offset = Math.max(offset, node.getPosition().y + node.getSize().y + node.getMargin().bottom);
        }
    } else {
        offset = graph.getSize().y - graph.getOffset().y;
    }
    offset -= graph.getOffset().y;
    // mirror all nodes, ports, edges, and labels
    for (LNode node : nodes) {
        mirrorY(node.getPosition(), offset - node.getSize().y);
        mirrorY(node.getPadding());
        mirrorNodeLabelPlacementY(node);
        // mirror position
        if (node.getAllProperties().containsKey(LayeredOptions.POSITION)) {
            mirrorY(node.getProperty(LayeredOptions.POSITION), offset - node.getSize().y);
        }
        // mirror the alignment
        switch(node.getProperty(LayeredOptions.ALIGNMENT)) {
            case TOP:
                node.setProperty(LayeredOptions.ALIGNMENT, Alignment.BOTTOM);
                break;
            case BOTTOM:
                node.setProperty(LayeredOptions.ALIGNMENT, Alignment.TOP);
                break;
        }
        KVector nodeSize = node.getSize();
        for (LPort port : node.getPorts()) {
            mirrorY(port.getPosition(), nodeSize.y - port.getSize().y);
            mirrorY(port.getAnchor(), port.getSize().y);
            mirrorPortSideY(port);
            reverseIndex(port);
            for (LEdge edge : port.getOutgoingEdges()) {
                // Mirror bend points
                for (KVector bendPoint : edge.getBendPoints()) {
                    mirrorY(bendPoint, offset);
                }
                // Mirror junction points
                KVectorChain junctionPoints = edge.getProperty(LayeredOptions.JUNCTION_POINTS);
                if (junctionPoints != null) {
                    for (KVector jp : junctionPoints) {
                        mirrorY(jp, offset);
                    }
                }
                // Mirror edge label positions
                for (LLabel label : edge.getLabels()) {
                    mirrorY(label.getPosition(), offset - label.getSize().y);
                }
            }
            // Mirror port label positions
            for (LLabel label : port.getLabels()) {
                mirrorY(label.getPosition(), port.getSize().y - label.getSize().y);
            }
        }
        // External port dummy?
        if (node.getType() == NodeType.EXTERNAL_PORT) {
            mirrorExternalPortSideY(node);
            mirrorInLayerConstraintY(node);
        }
        // Mirror node labels
        for (LLabel label : node.getLabels()) {
            mirrorNodeLabelPlacementY(label);
            mirrorY(label.getPosition(), nodeSize.y - label.getSize().y);
        }
    }
}
Also used : LLabel(org.eclipse.elk.alg.layered.graph.LLabel) 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)

Aggregations

LNode (org.eclipse.elk.alg.layered.graph.LNode)471 LPort (org.eclipse.elk.alg.layered.graph.LPort)189 Layer (org.eclipse.elk.alg.layered.graph.Layer)185 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)110 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)91 Test (org.junit.Test)85 KVector (org.eclipse.elk.core.math.KVector)38 PortSide (org.eclipse.elk.core.options.PortSide)28 List (java.util.List)23 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)22 GraphInfoHolder (org.eclipse.elk.alg.layered.p3order.GraphInfoHolder)16 TestAfterProcessor (org.eclipse.elk.alg.test.framework.annotations.TestAfterProcessor)16 KVectorChain (org.eclipse.elk.core.math.KVectorChain)15 NodeType (org.eclipse.elk.alg.layered.graph.LNode.NodeType)14 ArrayList (java.util.ArrayList)13 InternalProperties (org.eclipse.elk.alg.layered.options.InternalProperties)13 LayeredOptions (org.eclipse.elk.alg.layered.options.LayeredOptions)13 PortConstraints (org.eclipse.elk.core.options.PortConstraints)13 Set (java.util.Set)12 CrossingsCounter (org.eclipse.elk.alg.layered.p3order.counting.CrossingsCounter)10