Search in sources :

Example 6 with ElkNode

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

the class ELKDiagramConverter method convertDiagram.

private ElkNode convertDiagram(Diagram diagram) {
    ElkNode elkDiagram = ElkGraphFactory.eINSTANCE.createElkNode();
    elkDiagram.setIdentifier(diagram.getId());
    elkDiagram.setProperty(PROPERTY_TYPE, DEFAULT_DIAGRAM_TYPE);
    return elkDiagram;
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode)

Example 7 with ElkNode

use of org.eclipse.elk.graph.ElkNode 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 8 with ElkNode

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

the class DiagramElementLayoutUtil method layout.

private static void layout(final DiagramModification m, final Collection<? extends DiagramNode> nodesToLayout, final StyleProvider styleProvider, final LayoutInfoProvider layoutInfoProvider, final LayoutOptions options) {
    Objects.requireNonNull(nodesToLayout, "nodesToLayout must not be null");
    try {
        // Layout the nodes
        final RecursiveGraphLayoutEngine layoutEngine = new RecursiveGraphLayoutEngine();
        for (final DiagramNode dn : nodesToLayout) {
            LayoutMapping mapping;
            ElkNode layoutGraph;
            // Perform the first layout. This layout will not include nested ports. This will allow ELK additional flexibility when determining port
            // placement.
            mapping = ElkGraphBuilder.buildLayoutGraph(dn, styleProvider, layoutInfoProvider, options, !options.layoutPortsOnDefaultSides, ElkGraphBuilder.FixedPortPositionProvider.NO_OP);
            layoutGraph = mapping.getLayoutGraph();
            layoutGraph.setProperty(CoreOptions.ALGORITHM, LAYOUT_ALGORITHM);
            applyProperties(dn, mapping);
            LayoutDebugUtil.saveElkGraphToDebugProject(layoutGraph, "pass1");
            layoutEngine.layout(layoutGraph, new BasicProgressMonitor());
            // nested ports and performing edge routing.
            if (layoutGraph.getProperty(AgeLayoutOptions.NESTED_PORTS_WERE_OMITTED)) {
                final LayoutMapping initialLayoutMapping = mapping;
                mapping = ElkGraphBuilder.buildLayoutGraph(dn, styleProvider, layoutInfoProvider, options, false, new ElkGraphBuilder.FixedPortPositionProvider() {

                    @Override
                    public PortSide getPortSide(final DiagramElement de) {
                        final ElkGraphElement ge = initialLayoutMapping.getGraphMap().inverse().get(de);
                        if (ge instanceof ElkPort) {
                            return ge.getProperty(CoreOptions.PORT_SIDE);
                        }
                        return null;
                    }

                    @Override
                    public Double getPortPosition(final DiagramElement de) {
                        final ElkGraphElement ge = initialLayoutMapping.getGraphMap().inverse().get(de);
                        if (ge instanceof ElkPort) {
                            final ElkPort port = (ElkPort) ge;
                            final PortSide ps = port.getProperty(CoreOptions.PORT_SIDE);
                            if (PortSide.SIDES_EAST_WEST.contains(ps)) {
                                return port.getY();
                            } else {
                                return port.getX();
                            }
                        }
                        return null;
                    }
                });
                layoutGraph = mapping.getLayoutGraph();
                layoutGraph.setProperty(CoreOptions.ALGORITHM, LAYOUT_ALGORITHM);
                applyProperties(dn, mapping);
                LayoutDebugUtil.saveElkGraphToDebugProject(layoutGraph, "pass2");
                layoutEngine.layout(layoutGraph, new BasicProgressMonitor());
            }
            LayoutDebugUtil.saveElkGraphToDebugProject(layoutGraph, "final");
            applyShapeLayout(mapping, m);
            applyConnectionLayout(mapping, m);
            // Layout feature self loop connections. These are omitted from the ELK based layout.
            dn.getAllDiagramNodes().filter(DiagramElementLayoutUtil::isFeatureSelfLoopConnection).map(DiagramElement.class::cast).forEachOrdered(de -> layoutFeatureSelfLoopConnection(de, m, layoutInfoProvider));
        }
    } catch (final RuntimeException ex) {
        // If a layout error occurs, display the exception but do not rethrow. This is so that the operation that attempted to do the layout will continue.
        // This is important because otherwise simple operations such a adding elements to the diagram will completely fail. Suppressing the error will
        // degrade performance but allow the user to keep working and should ensure things stay in a valid state.
        // It would be best for other parts of the code to handle exceptions properly to avoid entering into an invalid state but this is the best
        // workaround.
        final Status status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, "A layout error occured.", ex);
        StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.LOG);
    }
}
Also used : IStatus(org.eclipse.core.runtime.IStatus) Status(org.eclipse.core.runtime.Status) DiagramNode(org.osate.ge.internal.diagram.runtime.DiagramNode) ElkNode(org.eclipse.elk.graph.ElkNode) ElkPort(org.eclipse.elk.graph.ElkPort) RecursiveGraphLayoutEngine(org.eclipse.elk.core.RecursiveGraphLayoutEngine) DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) BasicProgressMonitor(org.eclipse.elk.core.util.BasicProgressMonitor) PortSide(org.eclipse.elk.core.options.PortSide) LayoutMapping(org.eclipse.elk.core.service.LayoutMapping) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement)

Example 9 with ElkNode

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

the class ElkGraphBuilder method createElkGraphElementForNonLabelAndUndockedShape.

private Optional<ElkGraphElement> createElkGraphElementForNonLabelAndUndockedShape(final DiagramElement de, final ElkNode layoutParent, final LayoutMapping mapping) {
    final ElkNode newNode = ElkGraphUtil.createNode(layoutParent);
    mapping.getGraphMap().put(newNode, de);
    if (de.hasPosition()) {
        newNode.setLocation(de.getX(), de.getY());
    }
    // Setting the size is disabled because setting it causes shapes which have a flow path(along with corresponding ports) to grow.
    // if (de.hasSize()) {
    // newNode.setDimensions(de.getWidth(), de.getHeight());
    // }
    final EnumSet<SizeConstraint> nodeSizeConstraints = EnumSet.of(SizeConstraint.PORTS, SizeConstraint.MINIMUM_SIZE, SizeConstraint.NODE_LABELS);
    newNode.setProperty(CoreOptions.NODE_SIZE_CONSTRAINTS, nodeSizeConstraints);
    newNode.setProperty(CoreOptions.INSIDE_SELF_LOOPS_ACTIVATE, true);
    newNode.setProperty(CoreOptions.NODE_SIZE_OPTIONS, EnumSet.of(SizeOptions.DEFAULT_MINIMUM_SIZE, SizeOptions.ASYMMETRICAL));
    // Create labels
    createElkLabels(de, newNode, mapping);
    // Create Children
    createElkGraphElementsForNonLabelChildShapes(de, newNode, mapping);
    return Optional.of(newNode);
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) SizeConstraint(org.eclipse.elk.core.options.SizeConstraint)

Example 10 with ElkNode

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

the class ElkGraphBuilder method buildLayoutGraph.

private LayoutMapping buildLayoutGraph(final DiagramNode rootDiagramNode) {
    // Create the graph
    final LayoutMapping mapping = new LayoutMapping(null);
    final ElkNode rootNode = ElkGraphUtil.createGraph();
    rootNode.setProperty(CoreOptions.DIRECTION, Direction.RIGHT);
    mapping.setLayoutGraph(rootNode);
    // As of 2020-04-06, INCLUDE_CHILDREN causes layout issues. In particular, labels can overlap with children
    // https://github.com/eclipse/elk/issues/316
    // https://github.com/eclipse/elk/issues/412
    rootNode.setProperty(CoreOptions.HIERARCHY_HANDLING, HierarchyHandling.SEPARATE_CHILDREN);
    if (rootDiagramNode instanceof AgeDiagram) {
        final ElkNode diagramElkNode = ElkGraphUtil.createNode(rootNode);
        mapping.getGraphMap().put(diagramElkNode, rootDiagramNode);
        createElkGraphElementsForNonLabelChildShapes(rootDiagramNode, diagramElkNode, mapping);
    } else if (rootDiagramNode instanceof DiagramElement) {
        createElkGraphElementsForElements(Collections.singleton((DiagramElement) rootDiagramNode), rootNode, mapping);
    }
    createElkGraphElementsForConnections(rootDiagramNode, mapping);
    return mapping;
}
Also used : DiagramElement(org.osate.ge.internal.diagram.runtime.DiagramElement) ElkNode(org.eclipse.elk.graph.ElkNode) AgeDiagram(org.osate.ge.internal.diagram.runtime.AgeDiagram) LayoutMapping(org.eclipse.elk.core.service.LayoutMapping)

Aggregations

ElkNode (org.eclipse.elk.graph.ElkNode)267 ElkEdge (org.eclipse.elk.graph.ElkEdge)64 ElkPort (org.eclipse.elk.graph.ElkPort)55 Test (org.junit.Test)52 KVector (org.eclipse.elk.core.math.KVector)51 ElkLabel (org.eclipse.elk.graph.ElkLabel)39 ElkPadding (org.eclipse.elk.core.math.ElkPadding)36 ArrayList (java.util.ArrayList)27 List (java.util.List)25 ElkEdgeSection (org.eclipse.elk.graph.ElkEdgeSection)24 LinkedList (java.util.LinkedList)23 BasicProgressMonitor (org.eclipse.elk.core.util.BasicProgressMonitor)22 ElkGraphElement (org.eclipse.elk.graph.ElkGraphElement)21 ElkConnectableShape (org.eclipse.elk.graph.ElkConnectableShape)17 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)15 Lists (com.google.common.collect.Lists)12 Collection (java.util.Collection)12 KVectorChain (org.eclipse.elk.core.math.KVectorChain)10 HashMap (java.util.HashMap)9 RecursiveGraphLayoutEngine (org.eclipse.elk.core.RecursiveGraphLayoutEngine)9