Search in sources :

Example 1 with RecursiveGraphLayoutEngine

use of org.eclipse.elk.core.RecursiveGraphLayoutEngine in project sirius-components by eclipse-sirius.

the class LayoutService method layout.

@Override
public Diagram layout(IEditingContext editingContext, Diagram diagram) {
    ELKConvertedDiagram convertedDiagram = this.elkDiagramConverter.convert(diagram);
    ElkNode elkDiagram = convertedDiagram.getElkDiagram();
    // @formatter:off
    var optionalDiagramDescription = this.representationDescriptionSearchService.findById(editingContext, diagram.getDescriptionId()).filter(DiagramDescription.class::isInstance).map(DiagramDescription.class::cast);
    // @formatter:on
    ISiriusWebLayoutConfigurator layoutConfigurator;
    if (optionalDiagramDescription.isPresent()) {
        var diagramDescription = optionalDiagramDescription.get();
        elkDiagram = this.layoutConfiguratorRegistry.applyBeforeLayout(elkDiagram, editingContext, diagram, diagramDescription);
        layoutConfigurator = this.layoutConfiguratorRegistry.getLayoutConfigurator(diagram, diagramDescription);
    } else {
        layoutConfigurator = this.layoutConfiguratorRegistry.getDefaultLayoutConfigurator();
    }
    ElkUtil.applyVisitors(elkDiagram, layoutConfigurator);
    IGraphLayoutEngine engine = new RecursiveGraphLayoutEngine();
    engine.layout(elkDiagram, new BasicProgressMonitor());
    if (optionalDiagramDescription.isPresent()) {
        var diagramDescription = optionalDiagramDescription.get();
        elkDiagram = this.layoutConfiguratorRegistry.applyAfterLayout(elkDiagram, editingContext, diagram, diagramDescription);
    }
    Map<String, ElkGraphElement> id2ElkGraphElements = convertedDiagram.getId2ElkGraphElements();
    Diagram layoutedDiagram = this.elkLayoutedDiagramProvider.getLayoutedDiagram(diagram, elkDiagram, id2ElkGraphElements);
    if (this.logger.isDebugEnabled()) {
        // @formatter:off
        String json = ElkGraphJson.forGraph(elkDiagram).omitLayout(true).omitZeroDimension(true).omitZeroPositions(true).shortLayoutOptionKeys(false).prettyPrint(true).toJson();
        // @formatter:on
        this.logger.debug(json);
    }
    return layoutedDiagram;
}
Also used : IGraphLayoutEngine(org.eclipse.elk.core.IGraphLayoutEngine) ElkNode(org.eclipse.elk.graph.ElkNode) RecursiveGraphLayoutEngine(org.eclipse.elk.core.RecursiveGraphLayoutEngine) BasicProgressMonitor(org.eclipse.elk.core.util.BasicProgressMonitor) DiagramDescription(org.eclipse.sirius.components.diagrams.description.DiagramDescription) ElkGraphElement(org.eclipse.elk.graph.ElkGraphElement) IncrementalLayoutConvertedDiagram(org.eclipse.sirius.components.diagrams.layout.incremental.IncrementalLayoutConvertedDiagram) Diagram(org.eclipse.sirius.components.diagrams.Diagram)

Example 2 with RecursiveGraphLayoutEngine

use of org.eclipse.elk.core.RecursiveGraphLayoutEngine 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 3 with RecursiveGraphLayoutEngine

use of org.eclipse.elk.core.RecursiveGraphLayoutEngine in project elk by eclipse.

the class LoadGraphAction method layout.

/**
 * Perform layout, if requested, and return an {@link ExecutionInfo} that contains information about the layout run.
 * That object is not added to the {@link ExecutionInfoModel} by this method.
 */
static ExecutionInfo layout(final String fileName, final boolean performLayout, final ElkNode graph) {
    IPreferenceStore prefStore = ElkServicePlugin.getInstance().getPreferenceStore();
    IElkProgressMonitor monitor = new BasicProgressMonitor().withMaxHierarchyLevels(0).withLogging(prefStore.getBoolean(DiagramLayoutEngine.PREF_DEBUG_LOGGING)).withLogPersistence(prefStore.getBoolean(DiagramLayoutEngine.PREF_DEBUG_STORE)).withExecutionTimeMeasurement(prefStore.getBoolean(DiagramLayoutEngine.PREF_DEBUG_EXEC_TIME));
    monitor.begin(fileName, 1);
    // Perform layout using a graph layout engine, if enabled
    if (performLayout) {
        IGraphLayoutEngine layoutEngine = new RecursiveGraphLayoutEngine();
        layoutEngine.layout(graph, monitor.subTask(1));
    }
    monitor.done();
    // We're not going through the DiagramLayoutEngine, but directly through the RecursiveGraphLayoutEngine, which
    // means that not layout events will be fired. We'll have to update our model manually.
    monitor.logGraph(graph, "Result");
    return ExecutionInfo.fromProgressMonitorAndFile(monitor, fileName, performLayout);
}
Also used : IGraphLayoutEngine(org.eclipse.elk.core.IGraphLayoutEngine) IElkProgressMonitor(org.eclipse.elk.core.util.IElkProgressMonitor) IPreferenceStore(org.eclipse.jface.preference.IPreferenceStore) BasicProgressMonitor(org.eclipse.elk.core.util.BasicProgressMonitor) RecursiveGraphLayoutEngine(org.eclipse.elk.core.RecursiveGraphLayoutEngine)

Example 4 with RecursiveGraphLayoutEngine

use of org.eclipse.elk.core.RecursiveGraphLayoutEngine in project elk by eclipse.

the class ScanlineOverlapRemovalTest method scanlineTest.

/**
 * Test whether the {@link ScanlineOverlapCheck} supports the overlap removal to find all
 * overlaps in a special case.
 */
@Test
public void scanlineTest() {
    // build test graphs
    ElkNode graph1 = ElkGraphUtil.createGraph();
    ElkNode n0 = ElkGraphUtil.createNode(graph1);
    ElkNode n1 = ElkGraphUtil.createNode(graph1);
    ElkNode n2 = ElkGraphUtil.createNode(graph1);
    ElkNode n3 = ElkGraphUtil.createNode(graph1);
    n0.setDimensions(160, 20);
    n1.setDimensions(160, 20);
    n2.setDimensions(20, 20);
    n3.setDimensions(20, 20);
    n0.setLocation(0, 30);
    n1.setLocation(150, 40);
    n2.setLocation(150, 0);
    n3.setLocation(150, 70);
    graph1.setProperty(CoreOptions.ALGORITHM, SporeOverlapRemovalOptions.ALGORITHM_ID);
    Copier copier = new Copier();
    ElkNode graph2 = (ElkNode) copier.copy(graph1);
    graph2.setProperty(SporeOverlapRemovalOptions.OVERLAP_REMOVAL_RUN_SCANLINE, false);
    // execute overlap removal with and without ScanlineOverlapCheck
    LayoutMetaDataService lService = LayoutMetaDataService.getInstance();
    lService.registerLayoutMetaDataProviders(new SporeMetaDataProvider());
    RecursiveGraphLayoutEngine lEngine = new RecursiveGraphLayoutEngine();
    lEngine.layout(graph1, new BasicProgressMonitor());
    lEngine.layout(graph2, new BasicProgressMonitor());
    // test
    assertFalse(hasOverlaps(graph1));
    assertTrue(hasOverlaps(graph2));
}
Also used : ElkNode(org.eclipse.elk.graph.ElkNode) SporeMetaDataProvider(org.eclipse.elk.alg.spore.options.SporeMetaDataProvider) Copier(org.eclipse.emf.ecore.util.EcoreUtil.Copier) RecursiveGraphLayoutEngine(org.eclipse.elk.core.RecursiveGraphLayoutEngine) BasicProgressMonitor(org.eclipse.elk.core.util.BasicProgressMonitor) LayoutMetaDataService(org.eclipse.elk.core.data.LayoutMetaDataService) Test(org.junit.Test)

Example 5 with RecursiveGraphLayoutEngine

use of org.eclipse.elk.core.RecursiveGraphLayoutEngine in project elk by eclipse.

the class RecursiveGraphLayoutEngineTest method testUnknownAlgorithmId.

@Test(expected = UnsupportedConfigurationException.class)
public void testUnknownAlgorithmId() {
    Graph graph = new Graph();
    graph.root.setProperty(CoreOptions.ALGORITHM, "foo.Bar");
    RecursiveGraphLayoutEngine engine = new RecursiveGraphLayoutEngine();
    engine.layout(graph.root, new BasicProgressMonitor());
}
Also used : RecursiveGraphLayoutEngine(org.eclipse.elk.core.RecursiveGraphLayoutEngine) BasicProgressMonitor(org.eclipse.elk.core.util.BasicProgressMonitor) Test(org.junit.Test)

Aggregations

RecursiveGraphLayoutEngine (org.eclipse.elk.core.RecursiveGraphLayoutEngine)13 BasicProgressMonitor (org.eclipse.elk.core.util.BasicProgressMonitor)10 Test (org.junit.Test)9 ElkNode (org.eclipse.elk.graph.ElkNode)7 NullElkProgressMonitor (org.eclipse.elk.core.util.NullElkProgressMonitor)3 IGraphLayoutEngine (org.eclipse.elk.core.IGraphLayoutEngine)2 LayoutMetaDataService (org.eclipse.elk.core.data.LayoutMetaDataService)2 IElkProgressMonitor (org.eclipse.elk.core.util.IElkProgressMonitor)2 ElkGraphElement (org.eclipse.elk.graph.ElkGraphElement)2 ElkPort (org.eclipse.elk.graph.ElkPort)2 IStatus (org.eclipse.core.runtime.IStatus)1 Status (org.eclipse.core.runtime.Status)1 LayeredOptions (org.eclipse.elk.alg.layered.options.LayeredOptions)1 SporeMetaDataProvider (org.eclipse.elk.alg.spore.options.SporeMetaDataProvider)1 TestAlgorithm (org.eclipse.elk.alg.test.framework.algorithm.TestAlgorithm)1 LayoutConfigurator (org.eclipse.elk.core.LayoutConfigurator)1 UnsupportedConfigurationException (org.eclipse.elk.core.UnsupportedConfigurationException)1 LayoutAlgorithmData (org.eclipse.elk.core.data.LayoutAlgorithmData)1 LayoutAlgorithmResolver (org.eclipse.elk.core.data.LayoutAlgorithmResolver)1 PortSide (org.eclipse.elk.core.options.PortSide)1