Search in sources :

Example 1 with ElkEdgeSection

use of org.eclipse.elk.graph.ElkEdgeSection in project sirius-components by eclipse-sirius.

the class ELKLayoutedDiagramProvider method getLayoutedEdge.

private Edge getLayoutedEdge(Edge edge, ElkEdge elkEdge, Map<String, ElkGraphElement> id2ElkGraphElements) {
    List<Position> routingPoints = new ArrayList<>();
    ElkNode containingNode = elkEdge.getContainingNode();
    double xOffset = 0;
    double yOffset = 0;
    if (containingNode != null) {
        xOffset = containingNode.getX();
        yOffset = containingNode.getY();
        ElkNode parent = containingNode.getParent();
        while (parent instanceof ElkNode) {
            xOffset += parent.getX();
            yOffset += parent.getY();
            parent = parent.getParent();
        }
    }
    if (!elkEdge.getSections().isEmpty()) {
        ElkEdgeSection section = elkEdge.getSections().get(0);
        Position startPosition = Position.at(xOffset + section.getStartX(), yOffset + section.getStartY());
        routingPoints.add(startPosition);
        for (ElkBendPoint bendPoint : section.getBendPoints()) {
            Position position = Position.at(xOffset + bendPoint.getX(), yOffset + bendPoint.getY());
            routingPoints.add(position);
        }
        Position endPosition = Position.at(xOffset + section.getEndX(), yOffset + section.getEndY());
        routingPoints.add(endPosition);
    }
    Label beginLabel = edge.getBeginLabel();
    if (beginLabel != null) {
        beginLabel = this.getLayoutedLabel(beginLabel, id2ElkGraphElements, xOffset, yOffset);
    }
    Label centerLabel = edge.getCenterLabel();
    if (centerLabel != null) {
        centerLabel = this.getLayoutedLabel(centerLabel, id2ElkGraphElements, xOffset, yOffset);
    }
    Label endLabel = edge.getEndLabel();
    if (endLabel != null) {
        endLabel = this.getLayoutedLabel(endLabel, id2ElkGraphElements, xOffset, yOffset);
    }
    // @formatter:off
    return Edge.newEdge(edge).beginLabel(beginLabel).centerLabel(centerLabel).endLabel(endLabel).routingPoints(routingPoints).build();
// @formatter:on
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) Position(org.eclipse.sirius.components.diagrams.Position) ArrayList(java.util.ArrayList) ElkLabel(org.eclipse.elk.graph.ElkLabel) Label(org.eclipse.sirius.components.diagrams.Label) ElkBendPoint(org.eclipse.elk.graph.ElkBendPoint) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection)

Example 2 with ElkEdgeSection

use of org.eclipse.elk.graph.ElkEdgeSection in project elk by eclipse.

the class StraightLineEdgeRouter method routeEdges.

/**
 * Route edges from node center to node center. Then clip it, to not cross the node.
 */
public void routeEdges(final ElkNode node) {
    for (ElkEdge edge : ElkGraphUtil.allOutgoingEdges(node)) {
        if (!(edge.getSources().get(0) instanceof ElkPort)) {
            ElkNode target = ElkGraphUtil.connectableShapeToNode(edge.getTargets().get(0));
            if (!edge.isHierarchical()) {
                double sourceX = node.getX() + node.getWidth() / 2;
                double sourceY = node.getY() + node.getHeight() / 2;
                double targetX = target.getX() + target.getWidth() / 2;
                double targetY = target.getY() + target.getHeight() / 2;
                // Clipping
                KVector vector = new KVector();
                vector.x = targetX - sourceX;
                vector.y = targetY - sourceY;
                KVector sourceClip = new KVector(vector.x, vector.y);
                ElkMath.clipVector(sourceClip, node.getWidth(), node.getHeight());
                vector.x -= sourceClip.x;
                vector.y -= sourceClip.y;
                sourceX = targetX - vector.x;
                sourceY = targetY - vector.y;
                KVector targetClip = new KVector(vector.x, vector.y);
                ElkMath.clipVector(targetClip, target.getWidth(), target.getHeight());
                vector.x -= targetClip.x;
                vector.y -= targetClip.y;
                targetX = sourceX + vector.x;
                targetY = sourceY + vector.y;
                ElkEdgeSection section = ElkGraphUtil.firstEdgeSection(edge, true, true);
                section.setStartLocation(sourceX, sourceY);
                section.setEndLocation(targetX, targetY);
                routeEdges(target);
            }
        }
    }
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) ElkPort(org.eclipse.elk.graph.ElkPort) KVector(org.eclipse.elk.core.math.KVector) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Example 3 with ElkEdgeSection

use of org.eclipse.elk.graph.ElkEdgeSection in project elk by eclipse.

the class GraphRenderer method renderEdge.

/**
 * Paints an edge for the given dirty area.
 *
 * @param edge the edge to paint
 * @param graphics the graphics context used to paint
 * @param area dirty area that needs painting
 * @param offset offset to be added to relative coordinates
 * @param labelAlpha alpha value for labels
 */
private void renderEdge(final ElkEdge edge, final GC graphics, final Rectangle area, final KVector offset, final int labelAlpha) {
    if (configurator.getEdgeColor() == null) {
        return;
    }
    // Find our if the edge is actually eligible to be painted
    if (isEdgeFullyContainedInGraphToDraw(edge)) {
        // Get a PaintRectangle ready for the edge
        PaintRectangle rect = boundsMap.get(edge);
        if (rect == null) {
            rect = new PaintRectangle(edge, offset, scale);
            boundsMap.put(edge, rect);
        }
        if (!rect.painted && rect.intersects(area)) {
            // Gather some information
            final boolean splineEdge = edge.getProperty(CoreOptions.EDGE_ROUTING) == EdgeRouting.SPLINES;
            final boolean directedEdge = edge.getProperty(CoreOptions.EDGE_TYPE) != EdgeType.UNDIRECTED;
            graphics.setAlpha(255);
            // The background color is required to fill the arrow of directed edges
            graphics.setForeground(configurator.getEdgeColor());
            graphics.setBackground(configurator.getEdgeColor());
            for (ElkEdgeSection edgeSection : edge.getSections()) {
                KVectorChain bendPoints = ElkUtil.createVectorChain(edgeSection);
                bendPoints.scale(scale).offset(offset);
                // Draw the damn edge already...!
                Path path = new Path(graphics.getDevice());
                Iterator<KVector> pointIter = bendPoints.iterator();
                KVector startPoint = pointIter.next();
                path.moveTo((float) startPoint.x, (float) startPoint.y);
                KVector point1 = null;
                KVector point2 = null;
                while (pointIter.hasNext()) {
                    if (splineEdge) {
                        if (point1 == null) {
                            point1 = pointIter.next();
                        } else if (point2 == null) {
                            point2 = pointIter.next();
                        } else {
                            KVector endPoint = pointIter.next();
                            path.cubicTo((float) point1.x, (float) point1.y, (float) point2.x, (float) point2.y, (float) endPoint.x, (float) endPoint.y);
                            point1 = null;
                            point2 = null;
                        }
                    } else {
                        KVector nextPoint = pointIter.next();
                        path.lineTo((float) nextPoint.x, (float) nextPoint.y);
                    }
                }
                if (splineEdge && point2 != null) {
                    path.quadTo((float) point1.x, (float) point1.y, (float) point2.x, (float) point2.y);
                } else if (splineEdge && point1 != null) {
                    path.lineTo((float) point1.x, (float) point1.y);
                }
                graphics.drawPath(path);
                if (directedEdge) {
                    // Draw an arrow at the last segment of the connection
                    KVector referencePoint;
                    if (splineEdge && (bendPoints.size() - 1) % 3 != 1) {
                        int beginIndex;
                        if ((bendPoints.size() - 1) % 3 == 2) {
                            beginIndex = bendPoints.size() - 2;
                        } else {
                            beginIndex = bendPoints.size() - 3;
                        }
                        referencePoint = ElkMath.getPointOnBezierSegment(0.5, bendPoints.toArray(beginIndex));
                    } else {
                        referencePoint = bendPoints.get(bendPoints.size() - 2);
                    }
                    int[] arrowPoly = makeArrow(referencePoint, bendPoints.getLast());
                    if (arrowPoly != null) {
                        graphics.fillPolygon(arrowPoly);
                    }
                }
            }
            rect.painted = true;
        }
    }
    // paint junction points
    KVectorChain vc = edge.getProperty(CoreOptions.JUNCTION_POINTS);
    if (vc != null) {
        for (KVector v : vc) {
            KVector center = v.clone().scale(scale).add(offset).sub(2, 2);
            graphics.fillOval((int) center.x, (int) center.y, 6, 6);
        }
    }
    // paint the edge labels
    if (configurator.getEdgeLabelFont() != null) {
        graphics.setFont(configurator.getEdgeLabelFont());
        for (ElkLabel label : edge.getLabels()) {
            renderLabel(label, graphics, area, offset, labelAlpha);
        }
    }
}
Also used : Path(org.eclipse.swt.graphics.Path) ElkLabel(org.eclipse.elk.graph.ElkLabel) KVectorChain(org.eclipse.elk.core.math.KVectorChain) KVector(org.eclipse.elk.core.math.KVector) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) ElkBendPoint(org.eclipse.elk.graph.ElkBendPoint)

Example 4 with ElkEdgeSection

use of org.eclipse.elk.graph.ElkEdgeSection in project elk by eclipse.

the class GraphRenderingCanvas method calculateRequiredCanvasSizeAndBaseOffset.

/**
 * Sets size of the canvas by looking up the biggest distances between graph elements in x- and y-direction
 * and return a KVector with the required offset of the origin coordinates to fit all elements on the canvas.
 *
 * @param graph to be painted
 */
private KVector calculateRequiredCanvasSizeAndBaseOffset(final ElkNode graph) {
    if (graph != null) {
        double minX = Double.MAX_VALUE;
        double maxX = Double.MIN_VALUE;
        double minY = Double.MAX_VALUE;
        double maxY = Double.MIN_VALUE;
        // check all nodes for their coordinates
        for (ElkNode node : graph.getChildren()) {
            minX = Math.min(minX, node.getX());
            maxX = Math.max(maxX, node.getX() + node.getWidth());
            minY = Math.min(minY, node.getY());
            maxY = Math.max(maxY, node.getY() + node.getHeight());
            // check node labels
            for (ElkLabel nodeLabel : node.getLabels()) {
                minX = Math.min(minX, node.getX() + nodeLabel.getX());
                maxX = Math.max(maxX, node.getX() + nodeLabel.getX() + nodeLabel.getWidth());
                minY = Math.min(minY, node.getY() + nodeLabel.getY());
                maxY = Math.max(maxY, node.getY() + nodeLabel.getY() + nodeLabel.getHeight());
            }
        }
        for (ElkEdge edge : graph.getContainedEdges()) {
            // check all sections of the edges for their coordinates
            for (ElkEdgeSection edgeSection : edge.getSections()) {
                minX = Math.min(minX, edgeSection.getStartX());
                minY = Math.min(minY, edgeSection.getStartY());
                maxX = Math.max(maxX, edgeSection.getStartX());
                maxY = Math.max(maxY, edgeSection.getStartY());
                minX = Math.min(minX, edgeSection.getEndX());
                minY = Math.min(minY, edgeSection.getEndY());
                maxX = Math.max(maxX, edgeSection.getEndX());
                maxY = Math.max(maxY, edgeSection.getEndY());
                for (ElkBendPoint bendPoint : edgeSection.getBendPoints()) {
                    minX = Math.min(minX, bendPoint.getX());
                    minY = Math.min(minY, bendPoint.getY());
                    maxX = Math.max(maxX, bendPoint.getX());
                    maxY = Math.max(maxY, bendPoint.getY());
                }
            }
            // check edge labels
            for (ElkLabel edgeLabel : edge.getLabels()) {
                minX = Math.min(minX, edgeLabel.getX());
                maxX = Math.max(maxX, edgeLabel.getX() + edgeLabel.getWidth());
                minY = Math.min(minY, edgeLabel.getY());
                maxY = Math.max(maxY, edgeLabel.getY() + edgeLabel.getHeight());
            }
        }
        int x = ((int) (Math.max(graph.getWidth(), maxX) - Math.min(0, minX))) + 1;
        int y = ((int) (Math.max(graph.getHeight(), maxY) - Math.min(0, minY))) + 1;
        setSize(new Point(x, y));
        return new KVector((-Math.min(0, minX)), (-Math.min(0, minY)));
    }
    return new KVector();
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) ElkLabel(org.eclipse.elk.graph.ElkLabel) ElkBendPoint(org.eclipse.elk.graph.ElkBendPoint) Point(org.eclipse.swt.graphics.Point) ElkBendPoint(org.eclipse.elk.graph.ElkBendPoint) KVector(org.eclipse.elk.core.math.KVector) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) Point(org.eclipse.swt.graphics.Point) ElkBendPoint(org.eclipse.elk.graph.ElkBendPoint) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Example 5 with ElkEdgeSection

use of org.eclipse.elk.graph.ElkEdgeSection in project elk by eclipse.

the class RecursiveGraphLayoutEngine method postProcessInsideSelfLoops.

/**
 * Post-processes self loops routed inside by offsetting their coordinates by the coordinates of
 * their parent node. The post processing is necessary since the self loop coordinates are
 * relative to their parent node's upper left corner since, at that point, the parent node's
 * final coordinates are not determined yet.
 *
 * @param insideSelfLoops
 *            list of inside self loops to post-process.
 */
protected void postProcessInsideSelfLoops(final List<ElkEdge> insideSelfLoops) {
    for (final ElkEdge selfLoop : insideSelfLoops) {
        // MIGRATE Adapt to hyperedges and make error-safe
        final ElkConnectableShape node = ElkGraphUtil.connectableShapeToNode(selfLoop.getSources().get(0));
        final double xOffset = node.getX();
        final double yOffset = node.getY();
        // Offset the edge coordinates by the node's position
        // MIGRATE Adapt to hyperedges. Also, what about multiple edge sections?
        ElkEdgeSection section = selfLoop.getSections().get(0);
        section.setStartLocation(section.getStartX() + xOffset, section.getStartY() + yOffset);
        section.setEndLocation(section.getEndX() + xOffset, section.getEndY() + yOffset);
        for (final ElkBendPoint bend : section.getBendPoints()) {
            bend.set(bend.getX() + xOffset, bend.getY() + yOffset);
        }
        // Offset junction points by the node position
        selfLoop.getProperty(CoreOptions.JUNCTION_POINTS).offset(xOffset, yOffset);
    }
}
Also used : ElkBendPoint(org.eclipse.elk.graph.ElkBendPoint) ElkConnectableShape(org.eclipse.elk.graph.ElkConnectableShape) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Aggregations

ElkEdgeSection (org.eclipse.elk.graph.ElkEdgeSection)36 KVector (org.eclipse.elk.core.math.KVector)23 ElkEdge (org.eclipse.elk.graph.ElkEdge)21 ElkNode (org.eclipse.elk.graph.ElkNode)21 ElkLabel (org.eclipse.elk.graph.ElkLabel)14 KVectorChain (org.eclipse.elk.core.math.KVectorChain)13 ElkBendPoint (org.eclipse.elk.graph.ElkBendPoint)10 ElkPort (org.eclipse.elk.graph.ElkPort)10 LinkedList (java.util.LinkedList)6 ElkConnectableShape (org.eclipse.elk.graph.ElkConnectableShape)6 ElkPadding (org.eclipse.elk.core.math.ElkPadding)4 ArrayList (java.util.ArrayList)3 PointList (org.eclipse.draw2d.geometry.PointList)3 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)3 ElkGraphElement (org.eclipse.elk.graph.ElkGraphElement)3 Test (org.junit.Test)3 ListIterator (java.util.ListIterator)2 Point (org.eclipse.draw2d.geometry.Point)2 DCDirection (org.eclipse.elk.alg.disco.graph.DCDirection)2 DCElement (org.eclipse.elk.alg.disco.graph.DCElement)2