Search in sources :

Example 66 with ElkEdge

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

the class RandomGraphGenerator method connectAtomicNodesOnDifferentLevels.

private void connectAtomicNodesOnDifferentLevels(final List<List<ElkNode>> atomicNodes) {
    int numCrossHier;
    if (get(GeneratorOptions.EXACT_RELATIVE_HIER) != null) {
        Set<ElkEdge> newHashSet = Sets.newHashSet();
        for (List<ElkNode> level : atomicNodes) {
            for (ElkNode node : level) {
                newHashSet.addAll(node.getIncomingEdges());
                newHashSet.addAll(node.getOutgoingEdges());
            }
        }
        numCrossHier = (int) (newHashSet.size() * get(GeneratorOptions.EXACT_RELATIVE_HIER).val(random));
    } else {
        numCrossHier = get(GeneratorOptions.CROSS_HIER).intVal(random);
    }
    if (atomicNodes.size() < 2) {
        return;
    }
    for (int i = 0; i < numCrossHier; i++) {
        if (atomicNodes.size() > 1) {
            List<List<ElkNode>> levels = sample(atomicNodes, 2);
            connect(sample(levels.get(0), 1).get(0), sample(levels.get(1), 1).get(0));
        }
    }
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Example 67 with ElkEdge

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

the class Issue502Test method testLargeEnoughNode.

private void testLargeEnoughNode(final ElkNode node) {
    ElkRectangle requiredSize = new ElkRectangle();
    for (ElkNode child : node.getChildren()) {
        ElkRectangle childRect = new ElkRectangle(child.getX(), child.getY(), child.getWidth(), child.getHeight());
        requiredSize.union(childRect);
    }
    for (ElkEdge edge : node.getContainedEdges()) {
        for (ElkEdgeSection section : edge.getSections()) {
            for (ElkBendPoint bendPoint : section.getBendPoints()) {
                requiredSize.width = Math.max(requiredSize.width, bendPoint.getX());
                requiredSize.height = Math.max(requiredSize.height, bendPoint.getY());
            }
        }
    }
    assertTrue("Node not large enough for content. Size required: (" + requiredSize.width + ", " + requiredSize.height + "). " + "Actual size: (" + node.getWidth() + ", " + node.getHeight() + ")", node.getWidth() >= requiredSize.width && node.getHeight() >= requiredSize.height);
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) ElkBendPoint(org.eclipse.elk.graph.ElkBendPoint) ElkRectangle(org.eclipse.elk.core.math.ElkRectangle) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Example 68 with ElkEdge

use of org.eclipse.elk.graph.ElkEdge in project osate2 by osate.

the class DiagramElementLayoutUtil method applyConnectionLayout.

private static void applyConnectionLayout(final LayoutMapping mapping, final DiagramModification m) {
    // Modify Connections
    for (Entry<ElkGraphElement, Object> e : mapping.getGraphMap().entrySet()) {
        final ElkGraphElement elkElement = e.getKey();
        final Object mappedValue = e.getValue();
        if (!(elkElement instanceof ElkEdge)) {
            continue;
        }
        final ElkEdge edge = (ElkEdge) elkElement;
        // Ignore edges which do not have exactly one section. This is usually the case where it is a long hierarchical connection that has 0 sections
        if (edge.getSections().size() != 1) {
            continue;
        }
        final ElkEdgeSection edgeSection = edge.getSections().get(0);
        if (!(mappedValue instanceof DiagramElement)) {
            continue;
        }
        final DiagramElement de = (DiagramElement) mappedValue;
        if (!(de.getGraphic() instanceof AgeConnection)) {
            continue;
        }
        final AgeConnection connection = (AgeConnection) de.getGraphic();
        // Flow indicators have a position representing where the indicator ends.
        if (connection.isFlowIndicator && edge.getTargets().size() == 1) {
            final ElkPort flowIndicatorEndPort = (ElkPort) edge.getTargets().get(0);
            final ElkShape flowIndicatorEndPortShape = (ElkShape) flowIndicatorEndPort.eContainer();
            m.setPosition(de, new Point(flowIndicatorEndPortShape.getX(), flowIndicatorEndPortShape.getY()));
        }
        // Don't update connections if it wasn't updated. This prevents updating bendpoints to invalid values if an edge is not layed out.
        if (edgeSection.eIsSet(ElkGraphPackage.eINSTANCE.getElkEdgeSection_StartX()) && edgeSection.eIsSet(ElkGraphPackage.eINSTANCE.getElkEdgeSection_EndX())) {
            final List<Point> bendpointsInParentCoordinateSystem = edgeSection.getBendPoints().stream().map(bp -> new Point(bp.getX(), bp.getY())).collect(Collectors.toCollection(LinkedList::new));
            // 
            // Set bendpoints
            // 
            // Add the start and end points to the bendpoints list if the the start/end element is not a port.
            // For ports the start and end points are unnecessary and will actually be located inside the port graphic.
            final boolean srcIsPort = edge.getSources().size() == 1 ? edge.getSources().get(0) instanceof ElkPort : false;
            final boolean dstIsPort = edge.getTargets().size() == 1 ? edge.getTargets().get(0) instanceof ElkPort : false;
            if (!srcIsPort) {
                bendpointsInParentCoordinateSystem.add(0, new Point(edgeSection.getStartX(), edgeSection.getStartY()));
            }
            if (!dstIsPort) {
                bendpointsInParentCoordinateSystem.add(new Point(edgeSection.getEndX(), edgeSection.getEndY()));
            }
            // Adjust newly added bendpoints so that the connection arrows will face the appropriate direction
            if (!srcIsPort && bendpointsInParentCoordinateSystem.size() >= 2) {
                bendpointsInParentCoordinateSystem.set(0, getAdjacentPoint(bendpointsInParentCoordinateSystem.get(0), bendpointsInParentCoordinateSystem.get(1), START_AND_END_BENDPOINT_DISTANCE));
            }
            if (!dstIsPort && bendpointsInParentCoordinateSystem.size() >= 2) {
                bendpointsInParentCoordinateSystem.set(bendpointsInParentCoordinateSystem.size() - 1, getAdjacentPoint(bendpointsInParentCoordinateSystem.get(bendpointsInParentCoordinateSystem.size() - 1), bendpointsInParentCoordinateSystem.get(bendpointsInParentCoordinateSystem.size() - 2), START_AND_END_BENDPOINT_DISTANCE));
            }
            // Get the absolute coordinate in the diagram of the edge's ELK container.
            final Point elkContainerPosition;
            if (edge.getContainingNode() == mapping.getLayoutGraph()) {
                // Node available. Use the first and only child of the top level ELK node.
                if (mapping.getLayoutGraph().getChildren().size() == 1) {
                    final ElkNode topLayoutElkNode = mapping.getLayoutGraph().getChildren().get(0);
                    final Point topLayoutElkNodePosition = getAbsolutePosition((DiagramNode) mapping.getGraphMap().get(topLayoutElkNode));
                    elkContainerPosition = new Point(topLayoutElkNodePosition.x - topLayoutElkNode.getX(), topLayoutElkNodePosition.y - topLayoutElkNode.getY());
                } else {
                    elkContainerPosition = new Point(0, 0);
                }
            } else {
                elkContainerPosition = getAbsolutePosition((DiagramNode) mapping.getGraphMap().get(edge.getContainingNode()));
            }
            final List<Point> bendpointsInAbsoluteCoordinateSystem = bendpointsInParentCoordinateSystem.stream().map(p -> new Point(p.x + elkContainerPosition.x, p.y + elkContainerPosition.y)).collect(Collectors.toList());
            m.setBendpoints(de, bendpointsInAbsoluteCoordinateSystem);
            // For the midpoint calculation, the start and end points are needed. Add them if they have not already been added.
            if (srcIsPort) {
                bendpointsInParentCoordinateSystem.add(0, new Point(edgeSection.getStartX(), edgeSection.getStartY()));
            }
            if (dstIsPort) {
                bendpointsInParentCoordinateSystem.add(new Point(edgeSection.getEndX(), edgeSection.getEndY()));
            }
            // Set Label Positions
            setLabelPositionsForEdge(mapping, m, edge, findMidpoint(bendpointsInParentCoordinateSystem));
        }
    }
}
Also used : CoreOptions(org.eclipse.elk.core.options.CoreOptions) ArrayListMultimap(com.google.common.collect.ArrayListMultimap) PortSide(org.eclipse.elk.core.options.PortSide) LayoutMapping(org.eclipse.elk.core.service.LayoutMapping) ElkNode(org.eclipse.elk.graph.ElkNode) ElkPort(org.eclipse.elk.graph.ElkPort) IGraphElementVisitor(org.eclipse.elk.core.util.IGraphElementVisitor) RecursiveGraphLayoutEngine(org.eclipse.elk.core.RecursiveGraphLayoutEngine) DockArea(org.osate.ge.internal.diagram.runtime.DockArea) IStatus(org.eclipse.core.runtime.IStatus) BusinessObjectContext(org.osate.ge.BusinessObjectContext) Graphic(org.osate.ge.graphics.Graphic) DiagramNodePredicates(org.osate.ge.internal.diagram.runtime.DiagramNodePredicates) StatusManager(org.eclipse.ui.statushandlers.StatusManager) IEditorPart(org.eclipse.ui.IEditorPart) EnumSet(java.util.EnumSet) Collection(java.util.Collection) Set(java.util.Set) Status(org.eclipse.core.runtime.Status) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint) Point(org.osate.ge.graphics.Point) Collectors(java.util.stream.Collectors) DiagramElementUtil(org.osate.ge.internal.util.DiagramElementUtil) DockingPosition(org.osate.ge.DockingPosition) Objects(java.util.Objects) List(java.util.List) Stream(java.util.stream.Stream) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) NodeLabelPlacement(org.eclipse.elk.core.options.NodeLabelPlacement) GraphicalEditorException(org.osate.ge.internal.GraphicalEditorException) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) Entry(java.util.Map.Entry) Optional(java.util.Optional) ElkEdge(org.eclipse.elk.graph.ElkEdge) AgeConnection(org.osate.ge.graphics.internal.AgeConnection) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) Dimension(org.osate.ge.graphics.Dimension) ElkGraphPackage(org.eclipse.elk.graph.ElkGraphPackage) ModeGraphic(org.osate.ge.graphics.internal.ModeGraphic) DiagramModification(org.osate.ge.internal.diagram.runtime.DiagramModification) HashSet(java.util.HashSet) ElkUtil(org.eclipse.elk.core.util.ElkUtil) Style(org.osate.ge.graphics.Style) InternalDiagramEditor(org.osate.ge.internal.ui.editor.InternalDiagramEditor) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) AgeShape(org.osate.ge.graphics.internal.AgeShape) LinkedList(java.util.LinkedList) Activator(org.osate.ge.internal.Activator) DiagramElementPredicates(org.osate.ge.internal.diagram.runtime.DiagramElementPredicates) ElkLabel(org.eclipse.elk.graph.ElkLabel) KVector(org.eclipse.elk.core.math.KVector) Label(org.osate.ge.graphics.internal.Label) BasicProgressMonitor(org.eclipse.elk.core.util.BasicProgressMonitor) ElkShape(org.eclipse.elk.graph.ElkShape) Adapters(org.eclipse.core.runtime.Adapters) AgeDiagram(org.osate.ge.internal.diagram.runtime.AgeDiagram) AgeDiagramUtil(org.osate.ge.internal.diagram.runtime.AgeDiagramUtil) Comparator(java.util.Comparator) StyleProvider(org.osate.ge.internal.diagram.runtime.styling.StyleProvider) Collections(java.util.Collections) StyleCalculator(org.osate.ge.internal.diagram.runtime.styling.StyleCalculator) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) ElkNode(org.eclipse.elk.graph.ElkNode) ElkPort(org.eclipse.elk.graph.ElkPort) Point(org.osate.ge.graphics.Point) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) AgeConnection(org.osate.ge.graphics.internal.AgeConnection) ElkShape(org.eclipse.elk.graph.ElkShape) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Example 69 with ElkEdge

use of org.eclipse.elk.graph.ElkEdge in project osate2 by osate.

the class ElkGraphBuilder method createElkGraphElementsForConnections.

/**
 * Creates ELK edges for connection diagram nodes which are descendants of the specified node.
 * Even though the results of the ELK edge routing are not used, it is still important because it affects the placements of shapes.
 */
private void createElkGraphElementsForConnections(final DiagramNode dn, final LayoutMapping mapping) {
    for (final DiagramElement de : dn.getChildren()) {
        if (de.getGraphic() instanceof AgeConnection) {
            final AgeConnection connection = (AgeConnection) de.getGraphic();
            // Flow indicators are represented by a node in the container which has a port and an edge connecting that port to the starting element
            final ElkConnectableShape edgeStart = getConnectableShape(de.getStartElement(), mapping);
            ElkConnectableShape edgeEnd = null;
            if (connection.isFlowIndicator) {
                // Find the first undocked ancestor for the flow indicator
                final DiagramElement undockedContainer = DiagramElementUtil.getUndockedDiagramElement(de.getParent());
                if (undockedContainer == null) {
                    // Ignore the flow indicator if unable to find a containing element which isn't docked.
                    continue;
                }
                // Find the ELK shape for the ancestor
                final ElkConnectableShape endContainer = getConnectableShape(undockedContainer, mapping);
                if (!(endContainer instanceof ElkNode)) {
                    // Ignore the flow indicator if the container isn't a node.
                    continue;
                }
                // Create the node for the end of the flow indicator
                final ElkNode endNode = ElkGraphUtil.createNode((ElkNode) endContainer);
                endContainer.setDimensions(0, 0);
                endNode.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, EnumSet.noneOf(SizeConstraint.class));
                endNode.setProperty(CoreOptions.NODE_SIZE_OPTIONS, EnumSet.noneOf(SizeOptions.class));
                // Create port
                final ElkPort endPort = ElkGraphUtil.createPort(endNode);
                endPort.setProperty(CoreOptions.PORT_SIDE, PortSide.WEST);
                endPort.setX(0);
                endPort.setY(0);
                endPort.setWidth(0);
                endPort.setHeight(0);
                edgeEnd = endPort;
            } else {
                edgeEnd = getConnectableShape(de.getEndElement(), mapping);
            }
            if (edgeStart != null && edgeEnd != null) {
                final ElkConnectableShape start = edgeStart;
                final ElkConnectableShape end = edgeEnd;
                boolean insideSelfLoopsYo = true;
                // An example of this sort of edge is a steady state state transition in the EMV2
                if (start == end) {
                    insideSelfLoopsYo = false;
                }
                final ElkEdge newEdge = ElkGraphUtil.createSimpleEdge(start, end);
                // Allow edges with the same start and end shape because they layout as intended.
                if (start == end && start instanceof ElkPort) {
                    continue;
                }
                // Ensure the edge has at least one section. Fixes NPE that can occur when laying out connections
                // with the same source and destination port.
                ElkGraphUtil.createEdgeSection(newEdge);
                newEdge.setProperty(CoreOptions.INSIDE_SELF_LOOPS_YO, insideSelfLoopsYo);
                mapping.getGraphMap().put(newEdge, de);
                createElkLabels(de, newEdge, mapping);
                // along with other edges
                if (connection.isFlowIndicator && newEdge.getLabels().isEmpty()) {
                    final ElkLabel spacingLabel = createElkLabel(newEdge, "<Spacing>", new Dimension(10, 10));
                    if (!layoutConnectionLabels) {
                        spacingLabel.setProperty(CoreOptions.NO_LAYOUT, true);
                    }
                }
            }
        }
        createElkGraphElementsForConnections(de, mapping);
    }
}
Also used : DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) AgeConnection(org.osate.ge.graphics.internal.AgeConnection) ElkNode(org.eclipse.elk.graph.ElkNode) SizeOptions(org.eclipse.elk.core.options.SizeOptions) ElkLabel(org.eclipse.elk.graph.ElkLabel) ElkPort(org.eclipse.elk.graph.ElkPort) Dimension(org.osate.ge.graphics.Dimension) ElkConnectableShape(org.eclipse.elk.graph.ElkConnectableShape) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Example 70 with ElkEdge

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

the class LayoutedDiagramProviderTests method getConvertedDiagram.

private ELKConvertedDiagram getConvertedDiagram(Diagram originalDiagram) {
    Map<String, ElkGraphElement> id2ElkGraphElements = new HashMap<>();
    ElkNode elkDiagram = ElkGraphFactory.eINSTANCE.createElkNode();
    elkDiagram.setIdentifier(originalDiagram.getId().toString());
    Node node = originalDiagram.getNodes().get(0);
    ElkNode elkNode = ElkGraphFactory.eINSTANCE.createElkNode();
    elkNode.setIdentifier(node.getId().toString());
    elkNode.setDimensions(NODE_WIDTH, NODE_HEIGHT);
    elkNode.setX(NODE_X);
    elkNode.setY(NODE_Y);
    elkNode.setParent(elkDiagram);
    ElkLabel elkLabel = ElkGraphFactory.eINSTANCE.createElkLabel();
    elkLabel.setIdentifier(node.getLabel().getId().toString());
    elkLabel.setDimensions(LABEL_WIDTH, LABEL_HEIGHT);
    elkLabel.setX(LABEL_X);
    elkLabel.setY(LABEL_Y);
    elkLabel.setParent(elkNode);
    id2ElkGraphElements.put(elkLabel.getIdentifier(), elkLabel);
    id2ElkGraphElements.put(elkNode.getIdentifier(), elkNode);
    String edgeId = originalDiagram.getEdges().get(0).getId();
    ElkEdge elkEdge = ElkGraphFactory.eINSTANCE.createElkEdge();
    elkEdge.setIdentifier(edgeId.toString());
    elkEdge.getSources().add(elkNode);
    elkEdge.getTargets().add(elkNode);
    elkEdge.setContainingNode(elkDiagram);
    ElkEdgeSection section = ElkGraphFactory.eINSTANCE.createElkEdgeSection();
    section.setStartX(NODE_X);
    section.setStartY(NODE_Y);
    ElkBendPoint bendPoint = ElkGraphFactory.eINSTANCE.createElkBendPoint();
    bendPoint.setX(EDGE_BENDPOINT_X);
    bendPoint.setY(EDGE_BENDPOINT_Y);
    section.getBendPoints().add(bendPoint);
    section.setEndX(NODE_X);
    section.setEndY(NODE_Y);
    elkEdge.getSections().add(section);
    id2ElkGraphElements.put(elkEdge.getIdentifier(), elkEdge);
    return new ELKConvertedDiagram(elkDiagram, id2ElkGraphElements);
}
Also used : ELKConvertedDiagram(org.eclipse.sirius.components.diagrams.layout.ELKConvertedDiagram) ElkNode(org.eclipse.elk.graph.ElkNode) HashMap(java.util.HashMap) ElkLabel(org.eclipse.elk.graph.ElkLabel) Node(org.eclipse.sirius.components.diagrams.Node) ElkNode(org.eclipse.elk.graph.ElkNode) ElkBendPoint(org.eclipse.elk.graph.ElkBendPoint) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) ElkEdgeSection(org.eclipse.elk.graph.ElkEdgeSection) ElkEdge(org.eclipse.elk.graph.ElkEdge)

Aggregations

ElkEdge (org.eclipse.elk.graph.ElkEdge)73 ElkNode (org.eclipse.elk.graph.ElkNode)59 ElkPort (org.eclipse.elk.graph.ElkPort)27 KVector (org.eclipse.elk.core.math.KVector)23 ElkEdgeSection (org.eclipse.elk.graph.ElkEdgeSection)21 ElkLabel (org.eclipse.elk.graph.ElkLabel)20 ElkConnectableShape (org.eclipse.elk.graph.ElkConnectableShape)10 LinkedList (java.util.LinkedList)9 ElkBendPoint (org.eclipse.elk.graph.ElkBendPoint)9 ElkGraphElement (org.eclipse.elk.graph.ElkGraphElement)9 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)8 Test (org.junit.Test)8 ArrayList (java.util.ArrayList)7 List (java.util.List)6 ElkPadding (org.eclipse.elk.core.math.ElkPadding)6 KVectorChain (org.eclipse.elk.core.math.KVectorChain)5 HashSet (java.util.HashSet)4 Lists (com.google.common.collect.Lists)3 Collection (java.util.Collection)3 Set (java.util.Set)3