Search in sources :

Example 11 with LLabel

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

the class ElkGraphImporter method transformEdge.

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Edge Transformation
/**
 * Transforms the given edge if it's not a hyperedge. If it is a hyperedge, throws an exception.
 *
 * @param elkedge the edge to transform
 * @param elkparent the node in the original graph which currently gets transformed into {@code lgraph}
 * @param lgraph the layered graph
 * @return the transformed edge, or {@code null} if it cannot be transformed
 * @throws UnsupportedGraphException if the edge is a hyperedge.
 */
private LEdge transformEdge(final ElkEdge elkedge, final ElkNode elkparent, final LGraph lgraph) {
    checkEdgeValidity(elkedge);
    // Get a few basic information about the edge
    ElkConnectableShape elkSourceShape = elkedge.getSources().get(0);
    ElkConnectableShape elkTargetShape = elkedge.getTargets().get(0);
    ElkNode elkSourceNode = ElkGraphUtil.connectableShapeToNode(elkSourceShape);
    ElkNode elkTargetNode = ElkGraphUtil.connectableShapeToNode(elkTargetShape);
    ElkEdgeSection edgeSection = elkedge.getSections().isEmpty() ? null : elkedge.getSections().get(0);
    // Find the transformed source and target nodes
    LNode sourceLNode = (LNode) nodeAndPortMap.get(elkSourceNode);
    LNode targetLNode = (LNode) nodeAndPortMap.get(elkTargetNode);
    LPort sourceLPort = null;
    LPort targetLPort = null;
    // Find the transformed source port, if any
    if (elkSourceShape instanceof ElkPort) {
        // If the ElkPort is a regular port, it will map to an LPort; if it's an external port, it
        // will map to an LNode
        LGraphElement sourceElem = nodeAndPortMap.get(elkSourceShape);
        if (sourceElem instanceof LPort) {
            sourceLPort = (LPort) sourceElem;
        } else if (sourceElem instanceof LNode) {
            sourceLNode = (LNode) sourceElem;
            sourceLPort = sourceLNode.getPorts().get(0);
        }
    }
    // Find the transformed target port, if any
    if (elkTargetShape instanceof ElkPort) {
        // If the ElkPort is a regular port, it will map to an LPort; if it's an external port, it
        // will map to an LNode
        LGraphElement targetElem = nodeAndPortMap.get(elkTargetShape);
        if (targetElem instanceof LPort) {
            targetLPort = (LPort) targetElem;
        } else if (targetElem instanceof LNode) {
            targetLNode = (LNode) targetElem;
            targetLPort = targetLNode.getPorts().get(0);
        }
    }
    // reason, we back out
    if (sourceLNode == null || targetLNode == null) {
        throw new UnsupportedGraphException("The source or the target of edge " + elkedge + " could not be found. " + "This usually happens when an edge connects a node laid out by ELK Layered to a node in " + "another level of hierarchy laid out by either another instance of ELK Layered or another " + "layout algorithm alltogether. The former can be solved by setting the hierarchyHandling " + "option to INCLUDE_CHILDREN.");
    }
    // Create a layered edge
    LEdge ledge = new LEdge();
    ledge.copyProperties(elkedge);
    ledge.setProperty(InternalProperties.ORIGIN, elkedge);
    // Clear junction points, since they are recomputed from scratch
    ledge.setProperty(LayeredOptions.JUNCTION_POINTS, null);
    // If we have a self-loop, set the appropriate graph property
    Set<GraphProperties> graphProperties = lgraph.getProperty(InternalProperties.GRAPH_PROPERTIES);
    if (sourceLNode == targetLNode) {
        graphProperties.add(GraphProperties.SELF_LOOPS);
    }
    // Create source and target ports if they do not exist yet
    if (sourceLPort == null) {
        PortType portType = PortType.OUTPUT;
        KVector sourcePoint = null;
        if (edgeSection != null && sourceLNode.getProperty(LayeredOptions.PORT_CONSTRAINTS).isSideFixed()) {
            sourcePoint = new KVector(edgeSection.getStartX(), edgeSection.getStartY());
            // The coordinates need to be relative to us
            ElkUtil.toAbsolute(sourcePoint, elkedge.getContainingNode());
            ElkUtil.toRelative(sourcePoint, elkparent);
            // source), we may need to adjust the coordinates
            if (ElkGraphUtil.isDescendant(elkTargetNode, elkSourceNode)) {
                // External source port: put it on the west side
                portType = PortType.INPUT;
                sourcePoint.add(sourceLNode.getPosition());
            }
        }
        sourceLPort = LGraphUtil.createPort(sourceLNode, sourcePoint, portType, lgraph);
    }
    if (targetLPort == null) {
        PortType portType = PortType.INPUT;
        KVector targetPoint = null;
        if (edgeSection != null && targetLNode.getProperty(LayeredOptions.PORT_CONSTRAINTS).isSideFixed()) {
            targetPoint = new KVector(edgeSection.getEndX(), edgeSection.getEndY());
            // Adjust the coordinates
            // MIGRATE Not sure yet if this really does what we want it to do
            ElkUtil.toAbsolute(targetPoint, elkedge.getContainingNode());
            ElkUtil.toRelative(targetPoint, elkparent);
        }
        targetLPort = LGraphUtil.createPort(targetLNode, targetPoint, portType, targetLNode.getGraph());
    }
    // Finally set the source and target of the edge
    ledge.setSource(sourceLPort);
    ledge.setTarget(targetLPort);
    // If the ports have multiple incoming or outgoing edges, the HYPEREDGE property needs to be set
    if (sourceLPort.getIncomingEdges().size() > 1 || sourceLPort.getOutgoingEdges().size() > 1 || targetLPort.getIncomingEdges().size() > 1 || targetLPort.getOutgoingEdges().size() > 1) {
        graphProperties.add(GraphProperties.HYPEREDGES);
    }
    // Transform the edge's labels
    for (ElkLabel elklabel : elkedge.getLabels()) {
        if (!elklabel.getProperty(LayeredOptions.NO_LAYOUT) && !Strings.isNullOrEmpty(elklabel.getText())) {
            LLabel llabel = transformLabel(elklabel);
            ledge.getLabels().add(llabel);
            // edge label placement is actually properly defined
            switch(llabel.getProperty(LayeredOptions.EDGE_LABELS_PLACEMENT)) {
                case HEAD:
                case TAIL:
                    graphProperties.add(GraphProperties.END_LABELS);
                    break;
                case CENTER:
                    graphProperties.add(GraphProperties.CENTER_LABELS);
                    llabel.setProperty(LayeredOptions.EDGE_LABELS_PLACEMENT, EdgeLabelPlacement.CENTER);
            }
        }
    }
    // Copy the original bend points of the edge in case they are required
    CrossingMinimizationStrategy crossMinStrat = lgraph.getProperty(LayeredOptions.CROSSING_MINIMIZATION_STRATEGY);
    NodePlacementStrategy nodePlaceStrat = lgraph.getProperty(LayeredOptions.NODE_PLACEMENT_STRATEGY);
    boolean bendPointsRequired = crossMinStrat == CrossingMinimizationStrategy.INTERACTIVE || nodePlaceStrat == NodePlacementStrategy.INTERACTIVE;
    if (edgeSection != null && !edgeSection.getBendPoints().isEmpty() && bendPointsRequired) {
        KVectorChain originalBendpoints = ElkUtil.createVectorChain(edgeSection);
        KVectorChain importedBendpoints = new KVectorChain();
        // MIGRATE We may have to do some coordinate conversion here
        for (KVector point : originalBendpoints) {
            importedBendpoints.add(new KVector(point));
        }
        ledge.setProperty(InternalProperties.ORIGINAL_BENDPOINTS, importedBendpoints);
    }
    return ledge;
}
Also used : UnsupportedGraphException(org.eclipse.elk.core.UnsupportedGraphException) NodePlacementStrategy(org.eclipse.elk.alg.layered.options.NodePlacementStrategy) ElkNode(org.eclipse.elk.graph.ElkNode) LLabel(org.eclipse.elk.alg.layered.graph.LLabel) GraphProperties(org.eclipse.elk.alg.layered.options.GraphProperties) ElkPort(org.eclipse.elk.graph.ElkPort) LGraphElement(org.eclipse.elk.alg.layered.graph.LGraphElement) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) KVectorChain(org.eclipse.elk.core.math.KVectorChain) ElkConnectableShape(org.eclipse.elk.graph.ElkConnectableShape) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) ElkLabel(org.eclipse.elk.graph.ElkLabel) LPort(org.eclipse.elk.alg.layered.graph.LPort) CrossingMinimizationStrategy(org.eclipse.elk.alg.layered.options.CrossingMinimizationStrategy) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) PortType(org.eclipse.elk.alg.layered.options.PortType)

Example 12 with LLabel

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

the class ComponentsCompactor method addLGraphElementBounds.

private void addLGraphElementBounds(final List<Point> pts, final LShape element, final KVector offset) {
    // extract the relevant margins object.
    // there's LayoutOptions.MARGINS as well,
    // however, this is only used outside of elk layered.
    LMargin margins = null;
    if (element instanceof LNode) {
        margins = ((LNode) element).getMargin();
    } else if (element instanceof LPort) {
        margins = ((LPort) element).getMargin();
    } else if (element instanceof LLabel) {
        margins = new LMargin();
    }
    // add bounding box of the node
    pts.add(new Point(element.getPosition().x - margins.left + offset.x, element.getPosition().y - margins.top + offset.y));
    pts.add(new Point(element.getPosition().x - margins.left + offset.x, element.getPosition().y + element.getSize().y + margins.bottom + offset.y));
    pts.add(new Point(element.getPosition().x + element.getSize().x + margins.right + offset.x, element.getPosition().y - margins.top + offset.y));
    pts.add(new Point(element.getPosition().x + element.getSize().x + margins.right + offset.x, element.getPosition().y + element.getSize().y + margins.bottom + offset.y));
}
Also used : LMargin(org.eclipse.elk.alg.layered.graph.LMargin) LLabel(org.eclipse.elk.alg.layered.graph.LLabel) LPort(org.eclipse.elk.alg.layered.graph.LPort) LNode(org.eclipse.elk.alg.layered.graph.LNode) Point(org.eclipse.elk.alg.layered.compaction.recthull.Point)

Example 13 with LLabel

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

the class CompoundGraphPreprocessor method moveLabelsAndRemoveOriginalEdges.

/**
 * Moves all labels of the original edges to the appropriate dummy edges and removes the
 * original edges from the graph.
 *
 * @param graph
 *            the top-level graph.
 */
private void moveLabelsAndRemoveOriginalEdges(final LGraph graph) {
    // edges from the graph
    for (LEdge origEdge : crossHierarchyMap.keySet()) {
        // segments
        if (origEdge.getLabels().size() > 0) {
            // retrieve and sort the edge segments introduced for the original edge
            List<CrossHierarchyEdge> edgeSegments = new ArrayList<CrossHierarchyEdge>(crossHierarchyMap.get(origEdge));
            Collections.sort(edgeSegments, new CrossHierarchyEdgeComparator(graph));
            // iterate over the labels and move them to the edge segments
            Iterator<LLabel> labelIterator = origEdge.getLabels().listIterator();
            while (labelIterator.hasNext()) {
                LLabel currLabel = labelIterator.next();
                // find the index of the dummy edge we will move the label to
                int targetDummyEdgeIndex = -1;
                switch(currLabel.getProperty(LayeredOptions.EDGE_LABELS_PLACEMENT)) {
                    case HEAD:
                        targetDummyEdgeIndex = edgeSegments.size() - 1;
                        break;
                    case CENTER:
                        targetDummyEdgeIndex = getShallowestEdgeSegment(edgeSegments);
                        break;
                    case TAIL:
                        targetDummyEdgeIndex = 0;
                        break;
                    default:
                }
                // move the label if we were lucky enough to find a new home for it
                if (targetDummyEdgeIndex != -1) {
                    CrossHierarchyEdge targetSegment = edgeSegments.get(targetDummyEdgeIndex);
                    targetSegment.getEdge().getLabels().add(currLabel);
                    targetSegment.getEdge().getSource().getNode().getGraph().getProperty(InternalProperties.GRAPH_PROPERTIES).add(GraphProperties.END_LABELS);
                    targetSegment.getEdge().getSource().getNode().getGraph().getProperty(InternalProperties.GRAPH_PROPERTIES).add(GraphProperties.CENTER_LABELS);
                    labelIterator.remove();
                    currLabel.setProperty(InternalProperties.ORIGINAL_LABEL_EDGE, origEdge);
                }
            }
        }
        // remove original edge
        origEdge.setSource(null);
        origEdge.setTarget(null);
    }
}
Also used : LLabel(org.eclipse.elk.alg.layered.graph.LLabel) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) ArrayList(java.util.ArrayList)

Example 14 with LLabel

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

the class AbstractGraphPlacer method moveGraph.

/**
 * Move the source graph into the destination graph using a specified offset. This method should
 * only be called once per graph, since it also applies the graph's set offset in addition to the
 * one given in the methods of this argument.
 *
 * @param destGraph the destination graph.
 * @param sourceGraph the source graph.
 * @param offsetx x coordinate offset.
 * @param offsety y coordinate offset.
 */
protected void moveGraph(final LGraph destGraph, final LGraph sourceGraph, final double offsetx, final double offsety) {
    KVector graphOffset = sourceGraph.getOffset().add(offsetx, offsety);
    for (LNode node : sourceGraph.getLayerlessNodes()) {
        node.getPosition().add(graphOffset);
        for (LPort port : node.getPorts()) {
            for (LEdge edge : port.getOutgoingEdges()) {
                edge.getBendPoints().offset(graphOffset);
                KVectorChain junctionPoints = edge.getProperty(LayeredOptions.JUNCTION_POINTS);
                if (junctionPoints != null) {
                    junctionPoints.offset(graphOffset);
                }
                for (LLabel label : edge.getLabels()) {
                    label.getPosition().add(graphOffset);
                }
            }
        }
        destGraph.getLayerlessNodes().add(node);
        node.setGraph(destGraph);
    }
}
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 15 with LLabel

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

the class LongEdgeSplitter method moveHeadLabels.

/**
 * Moves all head labels from a given split edge to the new edge created to split it.
 *
 * @param oldEdge
 *            the old edge whose head labels are to be moved.
 * @param newEdge
 *            the new edge whose head labels are to be moved.
 */
private static void moveHeadLabels(final LEdge oldEdge, final LEdge newEdge) {
    ListIterator<LLabel> labelIterator = oldEdge.getLabels().listIterator();
    while (labelIterator.hasNext()) {
        LLabel label = labelIterator.next();
        EdgeLabelPlacement labelPlacement = label.getProperty(LayeredOptions.EDGE_LABELS_PLACEMENT);
        if (labelPlacement == EdgeLabelPlacement.HEAD) {
            labelIterator.remove();
            newEdge.getLabels().add(label);
            if (!label.hasProperty(InternalProperties.END_LABEL_EDGE)) {
                label.setProperty(InternalProperties.END_LABEL_EDGE, oldEdge);
            }
        }
    }
}
Also used : LLabel(org.eclipse.elk.alg.layered.graph.LLabel) EdgeLabelPlacement(org.eclipse.elk.core.options.EdgeLabelPlacement)

Aggregations

LLabel (org.eclipse.elk.alg.layered.graph.LLabel)38 LPort (org.eclipse.elk.alg.layered.graph.LPort)20 LNode (org.eclipse.elk.alg.layered.graph.LNode)19 KVector (org.eclipse.elk.core.math.KVector)19 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)14 KVectorChain (org.eclipse.elk.core.math.KVectorChain)8 PortSide (org.eclipse.elk.core.options.PortSide)5 List (java.util.List)4 ElkRectangle (org.eclipse.elk.core.math.ElkRectangle)4 ElkLabel (org.eclipse.elk.graph.ElkLabel)4 LabelCell (org.eclipse.elk.alg.common.nodespacing.cellsystem.LabelCell)3 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)3 Layer (org.eclipse.elk.alg.layered.graph.Layer)3 EdgeLabelPlacement (org.eclipse.elk.core.options.EdgeLabelPlacement)3 Lists (com.google.common.collect.Lists)2 LMargin (org.eclipse.elk.alg.layered.graph.LMargin)2 InternalProperties (org.eclipse.elk.alg.layered.options.InternalProperties)2 LayeredOptions (org.eclipse.elk.alg.layered.options.LayeredOptions)2 Direction (org.eclipse.elk.core.options.Direction)2 PortConstraints (org.eclipse.elk.core.options.PortConstraints)2