Search in sources :

Example 81 with LEdge

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

the class DummySelfLoopProcessor method process.

@Override
public void process(final LGraph layeredGraph, final IElkProgressMonitor monitor) {
    monitor.begin("Self-loop processing", 1);
    // Iterate through all nodes
    List<LNode> createdDummies = Lists.newArrayList();
    for (Layer layer : layeredGraph) {
        createdDummies.clear();
        for (LNode node : layer) {
            for (LPort port : node.getPorts()) {
                // Go through the port's outgoing edges
                LEdge[] edges = LGraphUtil.toEdgeArray(port.getOutgoingEdges());
                for (LEdge edge : edges) {
                    // We're only interested in edges whose source and target node are identical
                    if (edge.getSource().getNode() != edge.getTarget().getNode()) {
                        continue;
                    }
                    LPort sourcePort = edge.getSource();
                    LPort targetPort = edge.getTarget();
                    PortSide sourcePortSide = sourcePort.getSide();
                    PortSide targetPortSide = targetPort.getSide();
                    // First, let's deal with the cases where edges have to be reversed
                    if ((sourcePortSide == PortSide.NORTH || sourcePortSide == PortSide.SOUTH) && targetPortSide == PortSide.WEST) {
                        edge.reverse(layeredGraph, false);
                    } else if (sourcePortSide == PortSide.SOUTH && targetPortSide == PortSide.NORTH) {
                        edge.reverse(layeredGraph, false);
                    } else if (sourcePortSide == PortSide.EAST && targetPortSide != PortSide.EAST) {
                        edge.reverse(layeredGraph, false);
                    }
                    // Now, let's see if a dummy has to be inserted
                    if (sourcePortSide == PortSide.EAST && targetPortSide == PortSide.WEST) {
                        // Note that the edge was reversed, so source and target port have switched
                        createdDummies.add(createDummy(layeredGraph, edge, targetPort, sourcePort));
                    } else if (sourcePortSide == PortSide.WEST && targetPortSide == PortSide.EAST) {
                        createdDummies.add(createDummy(layeredGraph, edge, sourcePort, targetPort));
                    }
                }
            }
        }
        // Add the dummies, if any
        for (LNode dummy : createdDummies) {
            dummy.setLayer(layer);
        }
    }
    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) PortSide(org.eclipse.elk.core.options.PortSide) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 82 with LEdge

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

the class EdgeAndLayerConstraintEdgeReverser method handleInnerNodes.

// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Inner Nodes
/**
 * @param remainingNodes
 */
private void handleInnerNodes(final LGraph layeredGraph, final List<LNode> remainingNodes) {
    // Iterate over the remaining nodes
    for (LNode node : remainingNodes) {
        // Check if there is a layer constraint
        LayerConstraint layerConstraint = node.getProperty(LayeredOptions.LAYERING_LAYER_CONSTRAINT);
        EdgeConstraint edgeConstraint = null;
        switch(layerConstraint) {
            case FIRST:
            case FIRST_SEPARATE:
                edgeConstraint = EdgeConstraint.OUTGOING_ONLY;
                break;
            case LAST:
            case LAST_SEPARATE:
                edgeConstraint = EdgeConstraint.INCOMING_ONLY;
                break;
        }
        if (edgeConstraint != null) {
            // Set the edge constraint on the node
            node.setProperty(InternalProperties.EDGE_CONSTRAINT, EdgeConstraint.OUTGOING_ONLY);
            if (edgeConstraint == EdgeConstraint.INCOMING_ONLY) {
                reverseEdges(layeredGraph, node, layerConstraint, PortType.INPUT);
            } else if (edgeConstraint == EdgeConstraint.OUTGOING_ONLY) {
                reverseEdges(layeredGraph, node, layerConstraint, PortType.OUTPUT);
            }
        } else {
            // port dummy with FIRST_SEPARATE and an inverted ports on the target node's EAST side.
            if (node.getProperty(LayeredOptions.PORT_CONSTRAINTS).isSideFixed() && !node.getPorts().isEmpty()) {
                boolean allPortsReversed = true;
                for (LPort port : node.getPorts()) {
                    // reversed.
                    if (!(port.getSide() == PortSide.EAST && port.getNetFlow() > 0 || port.getSide() == PortSide.WEST && port.getNetFlow() < 0)) {
                        allPortsReversed = false;
                        break;
                    }
                    // no LAST or LAST_SEPARATE allowed for the target of outgoing edges
                    for (LEdge e : port.getOutgoingEdges()) {
                        LayerConstraint lc = e.getTarget().getNode().getProperty(LayeredOptions.LAYERING_LAYER_CONSTRAINT);
                        if (lc == LayerConstraint.LAST || lc == LayerConstraint.LAST_SEPARATE) {
                            allPortsReversed = false;
                            break;
                        }
                    }
                    // no FIRST or FIRST_SEPARATE allowed for the source of incoming edgs
                    for (LEdge e : port.getIncomingEdges()) {
                        LayerConstraint lc = e.getSource().getNode().getProperty(LayeredOptions.LAYERING_LAYER_CONSTRAINT);
                        if (lc == LayerConstraint.FIRST || lc == LayerConstraint.FIRST_SEPARATE) {
                            allPortsReversed = false;
                            break;
                        }
                    }
                }
                if (allPortsReversed) {
                    // Reverse all kinds of edges
                    reverseEdges(layeredGraph, node, layerConstraint, PortType.UNDEFINED);
                }
            }
        }
    }
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) EdgeConstraint(org.eclipse.elk.alg.layered.options.EdgeConstraint) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) LayerConstraint(org.eclipse.elk.alg.layered.options.LayerConstraint)

Example 83 with LEdge

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

the class FinalSplineBendpointsCalculator method calculateBezierBendPoints.

/**
 * Collects all NUB control points computed for a spline segment and converts them to bezier control points.
 * Note that additional NUB control points <em>may</em> be added before the conversion is performed.
 */
private void calculateBezierBendPoints(final List<LEdge> edgeChain, final LEdge survivingEdge) {
    if (edgeChain.isEmpty()) {
        return;
    }
    // in this chain we will put all NURBS control points.
    final KVectorChain allCP = new KVectorChain();
    // add the computed bendpoints to the specified edge (default to the first edge in the edge chain)
    final LEdge edge = survivingEdge != null ? survivingEdge : edgeChain.get(0);
    // Process the source end of the edge-chain.
    final LPort sourcePort = edge.getSource();
    // edge must be the first edge of a chain of edges
    if (!SplineEdgeRouter.isQualifiedAsStartingNode(sourcePort.getNode())) {
        throw new IllegalArgumentException("The target node of the edge must be a normal node " + "or a northSouthPort.");
    }
    // add the source as the very first control point.
    allCP.addLast(sourcePort.getAbsoluteAnchor());
    // add an additional control point if the source port is a north or south port
    if (PortSide.SIDES_NORTH_SOUTH.contains(sourcePort.getSide())) {
        double y = sourcePort.getProperty(InternalProperties.SPLINE_NS_PORT_Y_COORD);
        KVector northSouthCP = new KVector(sourcePort.getAbsoluteAnchor().x, y);
        allCP.addLast(northSouthCP);
    }
    // copy the calculated control points for all spline segments,
    // possibly adding additional control points halfway between computed ones
    KVector lastCP = null;
    boolean addMidPoint = false;
    Iterator<LEdge> edgeIterator = edgeChain.iterator();
    while (edgeIterator.hasNext()) {
        LEdge currentEdge = edgeIterator.next();
        // read the stored bend-points for vertical segments, calculated by calculateNUBSBendPoint.
        final KVectorChain currentBendPoints = currentEdge.getBendPoints();
        if (!currentBendPoints.isEmpty()) {
            // get a more straight horizontal segment
            if (addMidPoint) {
                KVector halfway = lastCP.add(currentBendPoints.getFirst()).scale(ONE_HALF);
                allCP.addLast(halfway);
                addMidPoint = false;
            } else {
                addMidPoint = true;
            }
            lastCP = currentBendPoints.getLast().clone();
            allCP.addAll(currentBendPoints);
            currentBendPoints.clear();
        }
    }
    // finalize the spline
    LPort targetPort = edge.getTarget();
    // again, add an additional control point if the target port is a north or sout port
    if (PortSide.SIDES_NORTH_SOUTH.contains(targetPort.getSide())) {
        double y = targetPort.getProperty(InternalProperties.SPLINE_NS_PORT_Y_COORD);
        KVector northSouthCP = new KVector(targetPort.getAbsoluteAnchor().x, y);
        allCP.addLast(northSouthCP);
    }
    // finish with the target as last control point.
    allCP.addLast(targetPort.getAbsoluteAnchor());
    // insert straightening control points (if desired)
    if (splineRoutingMode == SplineRoutingMode.CONSERVATIVE) {
        // Add a control point for a straight segment at the very start and at the very end of a spline to prevent
        // the edge from colliding with self-loops or the like inside the margin of the node.
        // This also ensures the correct initial direction of the edge
        insertStraighteningControlPoints(allCP, sourcePort, targetPort);
    }
    // convert list of NUB control points to bezier control points
    final NubSpline nubSpline = new NubSpline(true, SplineEdgeRouter.SPLINE_DIMENSION, allCP);
    // ... and set them as bendpoints of the edge
    edge.getBendPoints().addAll(nubSpline.getBezierCP());
}
Also used : KVectorChain(org.eclipse.elk.core.math.KVectorChain) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) NubSpline(org.eclipse.elk.alg.layered.p5edges.splines.NubSpline) KVector(org.eclipse.elk.core.math.KVector)

Example 84 with LEdge

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

the class GraphTransformer method transpose.

// /////////////////////////////////////////////////////////////////////////////
// Transpose
/**
 * Transpose the x and y coordinates of the given graph.
 *
 * @param nodes the nodes of the graph to transpose
 */
private void transpose(final List<LNode> nodes) {
    // Transpose nodes
    for (LNode node : nodes) {
        transpose(node.getPosition());
        transpose(node.getSize());
        transpose(node.getPadding());
        transposeNodeLabelPlacement(node);
        transposeProperties(node);
        // Transpose ports
        for (LPort port : node.getPorts()) {
            transpose(port.getPosition());
            transpose(port.getAnchor());
            transpose(port.getSize());
            transposePortSide(port);
            reverseIndex(port);
            // Transpose edges
            for (LEdge edge : port.getOutgoingEdges()) {
                // Transpose bend points
                for (KVector bendPoint : edge.getBendPoints()) {
                    transpose(bendPoint);
                }
                // Transpose junction points
                KVectorChain junctionPoints = edge.getProperty(LayeredOptions.JUNCTION_POINTS);
                if (junctionPoints != null) {
                    for (KVector jp : junctionPoints) {
                        transpose(jp);
                    }
                }
                // Transpose edge labels
                for (LLabel label : edge.getLabels()) {
                    transpose(label.getPosition());
                    transpose(label.getSize());
                }
            }
            // Transpose port labels
            for (LLabel label : port.getLabels()) {
                transpose(label.getPosition());
                transpose(label.getSize());
            }
        }
        // External port dummy?
        if (node.getType() == NodeType.EXTERNAL_PORT) {
            transposeExternalPortSide(node);
            transposeLayerConstraint(node);
        }
        // Transpose node labels
        for (LLabel label : node.getLabels()) {
            transposeNodeLabelPlacement(label);
            transpose(label.getSize());
            transpose(label.getPosition());
        }
    }
}
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 85 with LEdge

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

the class BKAligner method verticalAlignment.

// ///////////////////////////////////////////////////////////////////////////////////////////////////
// Block Building and Inner Shifting
/**
 * The graph is traversed in the given directions and nodes a grouped into blocks. The nodes in these
 * blocks will later be placed such that the edges connecting them will be straight lines.
 *
 * <p>Type 1 conflicts are resolved, so that the dummy nodes of a long edge share the same block if
 * possible, such that the long edge is drawn straightly.</p>
 *
 * @param bal One of the four layouts which shall be used in this step
 * @param markedEdges List with all edges that were marked as type 1 conflicts
 */
public void verticalAlignment(final BKAlignedLayout bal, final Set<LEdge> markedEdges) {
    // Initialize root and align maps
    for (Layer layer : layeredGraph.getLayers()) {
        for (LNode v : layer.getNodes()) {
            bal.root[v.id] = v;
            bal.align[v.id] = v;
            bal.innerShift[v.id] = 0.0;
        }
    }
    List<Layer> layers = layeredGraph.getLayers();
    // right to left, thus a reverse iterator is needed
    if (bal.hdir == HDirection.LEFT) {
        layers = Lists.reverse(layers);
    }
    for (Layer layer : layers) {
        // r denotes the position in layer order where the last block was found
        // It is initialized with -1, since nothing is found and the ordering starts with 0
        int r = -1;
        List<LNode> nodes = layer.getNodes();
        if (bal.vdir == VDirection.UP) {
            // If the alignment direction is UP, the nodes in a layer are traversed
            // reversely, thus we start at INT_MAX and with the reversed list of nodes.
            r = Integer.MAX_VALUE;
            nodes = Lists.reverse(nodes);
        }
        // CHECKSTYLEOFF Local Variable Names
        for (LNode v_i_k : nodes) {
            List<Pair<LNode, LEdge>> neighbors = null;
            if (bal.hdir == HDirection.LEFT) {
                neighbors = ni.rightNeighbors.get(v_i_k.id);
            } else {
                neighbors = ni.leftNeighbors.get(v_i_k.id);
            }
            if (neighbors.size() > 0) {
                // When a node has many upper neighbors, consider only the (two) nodes in the
                // middle.
                int d = neighbors.size();
                int low = ((int) Math.floor(((d + 1.0) / 2.0))) - 1;
                int high = ((int) Math.ceil(((d + 1.0) / 2.0))) - 1;
                if (bal.vdir == VDirection.UP) {
                    // Check, whether v_i_k can be added to a block of its upper/lower neighbor(s)
                    for (int m = high; m >= low; m--) {
                        if (bal.align[v_i_k.id].equals(v_i_k)) {
                            Pair<LNode, LEdge> u_m_pair = neighbors.get(m);
                            LNode u_m = u_m_pair.getFirst();
                            // ensures that at least one edge exists
                            if (!markedEdges.contains(u_m_pair.getSecond()) && r > ni.nodeIndex[u_m.id]) {
                                bal.align[u_m.id] = v_i_k;
                                bal.root[v_i_k.id] = bal.root[u_m.id];
                                bal.align[v_i_k.id] = bal.root[v_i_k.id];
                                bal.od[bal.root[v_i_k.id].id] &= v_i_k.getType() == NodeType.LONG_EDGE;
                                r = ni.nodeIndex[u_m.id];
                            }
                        }
                    }
                } else {
                    // Check, whether vik can be added to a block of its upper/lower neighbor(s)
                    for (int m = low; m <= high; m++) {
                        if (bal.align[v_i_k.id].equals(v_i_k)) {
                            Pair<LNode, LEdge> um_pair = neighbors.get(m);
                            LNode um = um_pair.getFirst();
                            if (!markedEdges.contains(um_pair.getSecond()) && r < ni.nodeIndex[um.id]) {
                                bal.align[um.id] = v_i_k;
                                bal.root[v_i_k.id] = bal.root[um.id];
                                bal.align[v_i_k.id] = bal.root[v_i_k.id];
                                bal.od[bal.root[v_i_k.id].id] &= v_i_k.getType() == NodeType.LONG_EDGE;
                                r = ni.nodeIndex[um.id];
                            }
                        }
                    }
                }
            }
        }
    // CHECKSTYLEON Local Variable Names
    }
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LNode(org.eclipse.elk.alg.layered.graph.LNode) Layer(org.eclipse.elk.alg.layered.graph.Layer) Pair(org.eclipse.elk.core.util.Pair)

Aggregations

LEdge (org.eclipse.elk.alg.layered.graph.LEdge)148 LNode (org.eclipse.elk.alg.layered.graph.LNode)107 LPort (org.eclipse.elk.alg.layered.graph.LPort)80 Layer (org.eclipse.elk.alg.layered.graph.Layer)41 KVector (org.eclipse.elk.core.math.KVector)34 KVectorChain (org.eclipse.elk.core.math.KVectorChain)20 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)17 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)16 PortSide (org.eclipse.elk.core.options.PortSide)11 ArrayList (java.util.ArrayList)9 List (java.util.List)9 InternalProperties (org.eclipse.elk.alg.layered.options.InternalProperties)8 Set (java.util.Set)7 LayeredOptions (org.eclipse.elk.alg.layered.options.LayeredOptions)7 Map (java.util.Map)6 IElkProgressMonitor (org.eclipse.elk.core.util.IElkProgressMonitor)6 Lists (com.google.common.collect.Lists)5 Iterator (java.util.Iterator)5 ElkRectangle (org.eclipse.elk.core.math.ElkRectangle)5 Pair (org.eclipse.elk.core.util.Pair)5