Search in sources :

Example 66 with LEdge

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

the class SortByInputModelProcessor method getTargetNode.

/**
 * Returns the target node of a port considering long edges.
 * @param port The port
 * @return the target node of the long edge connecting to the port or null if none exist.
 */
public static LNode getTargetNode(final LPort port) {
    LNode node = null;
    LEdge edge = port.getOutgoingEdges().get(0);
    do {
        node = edge.getTarget().getNode();
        // If the dummy node has a target return it.
        if (node.hasProperty(InternalProperties.LONG_EDGE_TARGET)) {
            return node.getProperty(InternalProperties.LONG_EDGE_TARGET).getNode();
        }
        // It not the current node might be the target node or one has to iterate manually through to it.
        if (node.getType() != NodeType.NORMAL && node.getOutgoingEdges().iterator().hasNext()) {
            edge = node.getOutgoingEdges().iterator().next();
        } else if (node.getType() != NodeType.NORMAL) {
            return null;
        }
    } while (node != null && node.getType() != NodeType.NORMAL);
    return node;
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LNode(org.eclipse.elk.alg.layered.graph.LNode)

Example 67 with LEdge

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

the class LGraphToCGraphTransformer method verticalSegmentToCNode.

private void verticalSegmentToCNode(final VerticalSegment verticalSegment) {
    // create CNode representation for the last segment
    CNode cNode = CNode.of().origin(verticalSegment).type("vs").hitbox(new ElkRectangle(verticalSegment.hitbox)).toStringDelegate(VS_TO_STRING_DELEGATE).create(cGraph);
    // assumption: during creation of LNode representing CNodes, these CNodes have been fitted with their own group
    if (!verticalSegment.potentialGroupParents.isEmpty()) {
        verticalSegment.potentialGroupParents.get(0).cGroup.addCNode(cNode);
    }
    Quadruplet vsLock = new Quadruplet();
    lockMap.put(cNode, vsLock);
    // segments belonging to multiple edges should be locked
    // in the direction that fewer different ports are connected in
    // (only used if LEFT_RIGHT_CONNECTION_LOCKING is active)
    Set<LPort> inc = Sets.newHashSet();
    Set<LPort> out = Sets.newHashSet();
    for (LEdge e : verticalSegment.representedLEdges) {
        inc.add(e.getSource());
        out.add(e.getTarget());
    }
    int difference = inc.size() - out.size();
    if (difference < 0) {
        vsLock.set(true, Direction.LEFT);
        vsLock.set(false, Direction.RIGHT);
    } else if (difference > 0) {
        vsLock.set(false, Direction.LEFT);
        vsLock.set(true, Direction.RIGHT);
    }
    verticalSegment.joined.forEach(other -> verticalSegmentsMap.put(other, cNode));
    verticalSegmentsMap.put(verticalSegment, cNode);
}
Also used : CNode(org.eclipse.elk.alg.common.compaction.oned.CNode) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) Quadruplet(org.eclipse.elk.alg.common.compaction.oned.Quadruplet) LPort(org.eclipse.elk.alg.layered.graph.LPort) ElkRectangle(org.eclipse.elk.core.math.ElkRectangle)

Example 68 with LEdge

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

the class LGraphToCGraphTransformer method transformNodes.

private void transformNodes() {
    for (Layer layer : layeredGraph) {
        for (LNode node : layer) {
            // of other nodes overlapping them after compaction
            if (node.getProperty(LayeredOptions.COMMENT_BOX)) {
                if (!Iterables.isEmpty(node.getConnectedEdges())) {
                    LEdge e = Iterables.get(node.getConnectedEdges(), 0);
                    LNode other = e.getSource().getNode();
                    if (other == node) {
                        other = e.getTarget().getNode();
                    }
                    Pair<LNode, KVector> p = Pair.of(other, node.getPosition().clone().sub(other.getPosition()));
                    commentOffsets.put(node, p);
                    continue;
                }
            }
            ElkRectangle hitbox = new ElkRectangle(node.getPosition().x - node.getMargin().left, node.getPosition().y - node.getMargin().top, node.getSize().x + node.getMargin().left + node.getMargin().right, node.getSize().y + node.getMargin().top + node.getMargin().bottom);
            // create the node in the compaction graph
            CNode cNode = CNode.of().origin(node).hitbox(hitbox).toStringDelegate(NODE_TO_STRING_DELEGATE).create(cGraph);
            // the node lives in its own group
            CGroup.of().nodes(cNode).master(cNode).create(cGraph);
            Quadruplet nodeLock = new Quadruplet();
            lockMap.put(cNode, nodeLock);
            // locking the node for directions that fewer edges are connected in
            // (only used if LEFT_RIGHT_CONNECTION_LOCKING is used)
            int difference = Iterables.size(node.getIncomingEdges()) - Iterables.size(node.getOutgoingEdges());
            if (difference < 0) {
                nodeLock.set(true, Direction.LEFT);
            } else if (difference > 0) {
                nodeLock.set(true, Direction.RIGHT);
            }
            // excluding external port dummies
            if (node.getType() == NodeType.EXTERNAL_PORT) {
                nodeLock.set(false, false, false, false);
            }
            nodesMap.put(node, cNode);
        }
    }
}
Also used : CNode(org.eclipse.elk.alg.common.compaction.oned.CNode) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) Quadruplet(org.eclipse.elk.alg.common.compaction.oned.Quadruplet) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) ElkRectangle(org.eclipse.elk.core.math.ElkRectangle) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 69 with LEdge

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

the class LGraphToCGraphTransformer method collectVerticalSegmentsOrthogonal.

private List<VerticalSegment> collectVerticalSegmentsOrthogonal() {
    List<VerticalSegment> verticalSegments = Lists.newArrayList();
    for (Layer layer : layeredGraph) {
        for (LNode node : layer) {
            final CNode cNode = nodesMap.get(node);
            // add vertical edge segments
            for (LEdge edge : node.getOutgoingEdges()) {
                Iterator<KVector> bends = edge.getBendPoints().iterator();
                boolean first = true;
                VerticalSegment lastSegment = null;
                // infer vertical segments from positions of bendpoints
                if (bends.hasNext()) {
                    KVector bend1 = bends.next();
                    KVector bend2 = null;
                    // get segment of source n/s port of outgoing segment
                    if (edge.getSource().getSide() == PortSide.NORTH) {
                        VerticalSegment vs = new VerticalSegment(bend1, new KVector(bend1.x, cNode.hitbox.y), cNode, edge);
                        vs.ignoreSpacing.down = true;
                        vs.aPort = edge.getSource();
                        verticalSegments.add(vs);
                    }
                    if (edge.getSource().getSide() == PortSide.SOUTH) {
                        VerticalSegment vs = new VerticalSegment(bend1, new KVector(bend1.x, cNode.hitbox.y + cNode.hitbox.height), cNode, edge);
                        vs.ignoreSpacing.up = true;
                        vs.aPort = edge.getSource();
                        verticalSegments.add(vs);
                    }
                    // get regular segments
                    while (bends.hasNext()) {
                        bend2 = bends.next();
                        if (!CompareFuzzy.eq(bend1.y, bend2.y)) {
                            lastSegment = new VerticalSegment(bend1, bend2, null, edge);
                            verticalSegments.add(lastSegment);
                            // the first vertical segment of an outgoing edge
                            if (first) {
                                first = false;
                                // to route the edges away from the nodes, does not become an issue
                                if (bend2.y < cNode.hitbox.y) {
                                    lastSegment.ignoreSpacing.down = true;
                                } else if (bend2.y > cNode.hitbox.y + cNode.hitbox.height) {
                                    lastSegment.ignoreSpacing.up = true;
                                } else {
                                    // completely surrounded
                                    lastSegment.ignoreSpacing.up = true;
                                    lastSegment.ignoreSpacing.down = true;
                                }
                            }
                        }
                        if (bends.hasNext()) {
                            bend1 = bend2;
                        }
                    }
                    // handle last vertical segment
                    if (lastSegment != null) {
                        CNode cTargetNode = nodesMap.get(edge.getTarget().getNode());
                        if (bend1.y < cTargetNode.hitbox.y) {
                            lastSegment.ignoreSpacing.down = true;
                        } else if (bend1.y > cTargetNode.hitbox.y + cTargetNode.hitbox.height) {
                            lastSegment.ignoreSpacing.up = true;
                        } else {
                            // completely surrounded
                            lastSegment.ignoreSpacing.up = true;
                            lastSegment.ignoreSpacing.down = true;
                        }
                    }
                }
            }
            // same for incoming edges to get north/south segments on target side
            for (LEdge edge : node.getIncomingEdges()) {
                if (!edge.getBendPoints().isEmpty()) {
                    // get segment of target n/s port
                    KVector bend1 = edge.getBendPoints().getLast();
                    if (edge.getTarget().getSide() == PortSide.NORTH) {
                        VerticalSegment vs = new VerticalSegment(bend1, new KVector(bend1.x, cNode.hitbox.y), cNode, edge);
                        vs.ignoreSpacing.down = true;
                        vs.aPort = edge.getTarget();
                        verticalSegments.add(vs);
                    }
                    if (edge.getTarget().getSide() == PortSide.SOUTH) {
                        VerticalSegment vs = new VerticalSegment(bend1, new KVector(bend1.x, cNode.hitbox.y + cNode.hitbox.height), cNode, edge);
                        vs.ignoreSpacing.up = true;
                        vs.aPort = edge.getTarget();
                        verticalSegments.add(vs);
                    }
                }
            }
        }
    }
    return verticalSegments;
}
Also used : CNode(org.eclipse.elk.alg.common.compaction.oned.CNode) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) Layer(org.eclipse.elk.alg.layered.graph.Layer)

Example 70 with LEdge

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

the class LongEdgeSplitter method splitEdge.

/**
 * Does the actual work of splitting a given edge by rerouting it to the given dummy node and
 * introducing a new edge. Two ports are added to the dummy node and long edge properties are
 * configured for it. Also, any head labels the old edge has are moved to the new edge.
 *
 * @param edge
 *            the edge to be split.
 * @param dummyNode
 *            the dummy node to split the edge with.
 * @return the new edge.
 */
public static LEdge splitEdge(final LEdge edge, final LNode dummyNode) {
    LPort oldEdgeTarget = edge.getTarget();
    // 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(oldEdgeTarget);
    setDummyNodeProperties(dummyNode, edge, dummyEdge);
    moveHeadLabels(edge, dummyEdge);
    return dummyEdge;
}
Also used : LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort)

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