Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Eclipse Layout Kernel » How Customized ELK to fit Sirius application?
How Customized ELK to fit Sirius application? [message #1785293] Thu, 12 April 2018 07:50 Go to next message
Nicholas Kong is currently offline Nicholas KongFriend
Messages: 59
Registered: July 2016
Location: China
Member
To whom it may concern,

I want to use the ELK in Sirius application ( I am the fresh man in this field).

I installed ELK to my Eclipse, it works well using the property to do.

But some times, I want to customized some BorderNode position (ElkPort), based on the semantic model information IN/OUT. It is hard to do.

I find a presentation 'introducing the Eclipse Layout Kernel' by Christoph Daniel Schulze, which includes the same example. As following description:

index.php/fa/32587/0/


But this example code just is partial code. And then I follow the 'Advanced Configuration' tutorial, find I can prepare the parameter before DiagramLayoutEngine. However, it maybe can not specify the layout option to corresponded semantic model element. (Because the mapping(LayoutMapping) can not prepared before the DiagramLayoutEngine).

Compare these, this information makes me confused.

1) What's the correct way to customized the layout, like using the semantic model information to impact the ELK? (like Daniel's presentation)
2) Is there any example/sample for ELK tool developer?

Thanks for your reply.

[Updated on: Thu, 12 April 2018 07:54]

Report message to a moderator

Re: How Customized ELK to fit Sirius application? [message #1785299 is a reply to message #1785293] Thu, 12 April 2018 08:38 Go to previous messageGo to next message
Miro Spönemann is currently offline Miro SpönemannFriend
Messages: 78
Registered: March 2015
Location: Kiel, Germany
Member

There are many ways to configure ELK layout. If you would like to reuse the code snipped that you posted, you could try the following:


  • Implement an ILayoutSetup (see e.g. GmfLayoutSetup) and register it with the org.eclipse.elk.core.service.layoutConnectors extension point.
  • In the Guice Module returned by your setup, bind DiagramLayoutEngine to a new subclass (e.g. CustomDiagramLayoutEngine).
  • In CustomDiagramLayoutEngine, override addDiagramConfig(Parameters, LayoutMapping) to add your configuration code.


@Override
protected void addDiagramConfig(Parameters params, LayoutMapping layoutMapping) {
    LayoutConfigurator layoutConfigurator = params.addLayoutRun();
    // Put your configuration code here
    ...
    super.addDiagramConfig(params, layoutMapping);
}
Re: How Customized ELK to fit Sirius application? [message #1785301 is a reply to message #1785299] Thu, 12 April 2018 08:51 Go to previous messageGo to next message
Miro Spönemann is currently offline Miro SpönemannFriend
Messages: 78
Registered: March 2015
Location: Kiel, Germany
Member

Caution: My proposed solution does not work well if you call DiagramLayoutEngine.invokeLayout(IWorkbenchPart, Object, Parameters) somewhere and configure the layout there. The effect would be that the layout would be computed twice, which is probably not what you want.

Alternative approaches are to use the aforementioned static invokeLayout method (but then you don't have access to the LayoutMapping) or to create a subclass of GmfDiagramLayoutConnector and set the configuration properties directly on the elements of the created layout graph.
Re: How Customized ELK to fit Sirius application? [message #1785306 is a reply to message #1785301] Thu, 12 April 2018 09:54 Go to previous messageGo to next message
Nicholas Kong is currently offline Nicholas KongFriend
Messages: 59
Registered: July 2016
Location: China
Member
Dear Miro Spönemann,

Thanks for you reply quickly.

I will try to create a subclass of GmfDiagramLayoutConnector and set the configuration properties directly. In my application.

Actually, I have tried the following, the layout have be computed twice.
LayoutMapping mapping = DiagramLayoutEngine.invokeLayout(...);

....

DiagramLayoutEngine.invokeLayout(...);

But I think using the Christoph Daniel Schulze's example, it looks very easy for user to configure the Layout Option. And https://www.eclipse.org/elk/documentation/tooldevelopers/usingeclipselayout/advancedconfiguration.html
also provide this kind of 'Advanced Configuration' way.

LayoutConfigurator configurator = new LayoutConfigurator();

// Configure layout options for a concrete graph object
configurator.configure(myVerySpecialNode)
    .setProperty(CoreOptions.INTERACTIVE, true)
    .setProperty(CoreOptions.PORT_CONSTRAINTS, PortConstraints.FIXED);
...


Is there any example project for this kind of 'Configuration'? I would like to know more about it.

Thanks.


Re: How Customized ELK to fit Sirius application? [message #1785312 is a reply to message #1785306] Thu, 12 April 2018 10:44 Go to previous messageGo to next message
Miro Spönemann is currently offline Miro SpönemannFriend
Messages: 78
Registered: March 2015
Location: Kiel, Germany
Member

Nicholas Kong wrote on Thu, 12 April 2018 11:54

Is there any example project for this kind of 'Configuration'? I would like to know more about it.


Use ElkUtil.applyVisitors(graph, configurator) to apply such a configurator to a graph.
Re: How Customized ELK to fit Sirius application? [message #1785314 is a reply to message #1785312] Thu, 12 April 2018 10:56 Go to previous messageGo to next message
Nicholas Kong is currently offline Nicholas KongFriend
Messages: 59
Registered: July 2016
Location: China
Member
Miro Spönemann.

Can I use this ElkUtil.applyVisitors(graph, configurator) before the DiagramLayoutEngine.invokeLayout() ?

It looks different with 'Advanced Configuration'.

LayoutConfigurator configurator = new LayoutConfigurator();

// Configure layout options for a concrete graph object
configurator.configure(myVerySpecialNode)
    .setProperty(CoreOptions.INTERACTIVE, true)
    .setProperty(CoreOptions.PORT_CONSTRAINTS, PortConstraints.FIXED);
....

DiagramLayoutEngine.Parameters params = new DiagramLayoutEngine.Parameters();
params.addLayoutRun(configurator);
DiagramLayoutEngine.invokeLayout(workbenchPart, diagramPart, params);
Re: How Customized ELK to fit Sirius application? [message #1785317 is a reply to message #1785314] Thu, 12 April 2018 11:01 Go to previous messageGo to next message
Miro Spönemann is currently offline Miro SpönemannFriend
Messages: 78
Registered: March 2015
Location: Kiel, Germany
Member

Nicholas Kong wrote on Thu, 12 April 2018 12:56

Can I use this ElkUtil.applyVisitors(graph, configurator) before the DiagramLayoutEngine.invokeLayout() ?


No. DiagramLayoutEngine.invokeLayout() calls GmfLayoutConnector.buildLayoutGraph() in order to obtain a graph instance, so you cannot apply the configurator before the graph has been created.

You can use ElkUtil.applyVisitors(graph, configurator) in a subclass of GmfLayoutConnector.

If you add a configurator to the DiagramLayoutEngine.Parameters, you don't need to apply it yourself because ELK will take care of that.
Re: How Customized ELK to fit Sirius application? [message #1785318 is a reply to message #1785317] Thu, 12 April 2018 11:12 Go to previous messageGo to next message
Nicholas Kong is currently offline Nicholas KongFriend
Messages: 59
Registered: July 2016
Location: China
Member
Thank you. Understanding is becoming clearer.

One more question:

Also 'Advanced Configuration' part. As the guide description:
....
// Configure layout options for a concrete graph object
configurator.configure(myVerySpecialNode)
....

About the comment describes the concrete graph object, what kinds of graph object I can configure? only ELK elements (ElkNode, ElkPort)?
Can I configure GMF node or Sirius node here?
Re: How Customized ELK to fit Sirius application? [message #1785319 is a reply to message #1785318] Thu, 12 April 2018 11:19 Go to previous messageGo to next message
Miro Spönemann is currently offline Miro SpönemannFriend
Messages: 78
Registered: March 2015
Location: Kiel, Germany
Member

Here graph objects are ElkGraphElements such as ElkNode, ElkPort etc.

If you want to configure on the GMF / Sirius node (EditPart) level, do it in a subclass of GmfLayoutConnector.
Re: How Customized ELK to fit Sirius application? [message #1785320 is a reply to message #1785319] Thu, 12 April 2018 11:44 Go to previous messageGo to next message
Nicholas Kong is currently offline Nicholas KongFriend
Messages: 59
Registered: July 2016
Location: China
Member
Gotcha. Miro Spönemann, Thank you very much.
Have a good night. ( ;

Re: How Customized ELK to fit Sirius application? [message #1786733 is a reply to message #1785319] Thu, 10 May 2018 07:49 Go to previous messageGo to next message
Nicholas Kong is currently offline Nicholas KongFriend
Messages: 59
Registered: July 2016
Location: China
Member
Hi Miro SpönemannFriend,
I want to use ELK to let some specified Nodes always on the left side, no matter them have edge or not.
How can I handle this scenario?

I try to use the 'LayeredOptions.LAYERING_LAYER_CONSTRAINT', but it does not met our opinion.

index.php/fa/32799/0/
  • Attachment: Capture.PNG
    (Size: 14.24KB, Downloaded 877 times)
Re: How Customized ELK to fit Sirius application? [message #1787122 is a reply to message #1785319] Sat, 19 May 2018 10:00 Go to previous messageGo to next message
lee lucky is currently offline lee luckyFriend
Messages: 26
Registered: October 2017
Junior Member
Dear Miro Spönemann:
I configured the ELK layout for Sirius diagram as you and Nicholas Kong discussed.

LayoutConfigurator configurator = new LayoutConfigurator();
configurator.configure(ElkNode.class).setProperty(CoreOptions.ALGORITHM, "org.eclipse.elk.alg.layered")
.setProperty(CoreOptions.PORT_CONSTRAINTS, PortConstraints.FIXED_SIDE)
.setProperty(CoreOptions.PORT_LABELS_PLACEMENT, PortLabelPlacement.INSIDE)
.setProperty(CoreOptions.NODE_SIZE_OPTIONS,
.setProperty(CoreOptions.HIERARCHY_HANDLING, HierarchyHandling.INCLUDE_CHILDREN);

DiagramLayoutEngine.Parameters params = new DiagramLayoutEngine.Parameters();
params.addLayoutRun(configurator);
.................

if(***){
port.setProperty(PortSide.WEST);
}else if(***){
port.setProperty(PortSide.EAST);
}else if(***){
port.setProperty(PortSide.NORTH);
}if(***){
port.setProperty(PortSide.SOUTH);
}
..........


When I operate ELk layout, some of my diagrams occur an exception.

java.lang.ClassCastException: org.eclipse.elk.alg.layered.graph.LEdge cannot be cast to org.eclipse.elk.alg.layered.graph.LPort
at org.eclipse.elk.alg.layered.intermediate.greedyswitch.SwitchDecider.doesSwitchReduceCrossings(SwitchDecider.java:146)
at org.eclipse.elk.alg.layered.intermediate.greedyswitch.GreedySwitchHeuristic.switchIfImproves(GreedySwitchHeuristic.java:116)
at org.eclipse.elk.alg.layered.intermediate.greedyswitch.GreedySwitchHeuristic.sweepDownwardInLayer(GreedySwitchHeuristic.java:108)
at org.eclipse.elk.alg.layered.intermediate.greedyswitch.GreedySwitchHeuristic.continueSwitchingUntilNoImprovementInLayer(GreedySwitchHeuristic.java:96)
at org.eclipse.elk.alg.layered.intermediate.greedyswitch.GreedySwitchHeuristic.minimizeCrossings(GreedySwitchHeuristic.java:65)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.sweepReducingCrossings(LayerSweepCrossingMinimizer.java:239)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.sweepInHierarchicalNode(LayerSweepCrossingMinimizer.java:274)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.sweepInHierarchicalNodes(LayerSweepCrossingMinimizer.java:253)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.sweepReducingCrossings(LayerSweepCrossingMinimizer.java:237)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.minimizeCrossingsNoCounter(LayerSweepCrossingMinimizer.java:155)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.lambda$1(LayerSweepCrossingMinimizer.java:122)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.minimizeCrossings(LayerSweepCrossingMinimizer.java:131)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMjava.lang.ClassCastException: org.eclipse.elk.alg.layered.graph.LEdge cannot be cast to org.eclipse.elk.alg.layered.graph.LPort
at org.eclipse.elk.alg.layered.intermediate.greedyswitch.SwitchDecider.doesSwitchReduceCrossings(SwitchDecider.java:146)
at org.eclipse.elk.alg.layered.intermediate.greedyswitch.GreedySwitchHeuristic.switchIfImproves(GreedySwitchHeuristic.java:116)
at org.eclipse.elk.alg.layered.intermediate.greedyswitch.GreedySwitchHeuristic.sweepDownwardInLayer(GreedySwitchHeuristic.java:108)
at org.eclipse.elk.alg.layered.intermediate.greedyswitch.GreedySwitchHeuristic.continueSwitchingUntilNoImprovementInLayer(GreedySwitchHeuristic.java:96)
at org.eclipse.elk.alg.layered.intermediate.greedyswitch.GreedySwitchHeuristic.minimizeCrossings(GreedySwitchHeuristic.java:65)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.sweepReducingCrossings(LayerSweepCrossingMinimizer.java:239)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.sweepInHierarchicalNode(LayerSweepCrossingMinimizer.java:274)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.sweepInHierarchicalNodes(LayerSweepCrossingMinimizer.java:253)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.sweepReducingCrossings(LayerSweepCrossingMinimizer.java:237)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.minimizeCrossingsNoCounter(LayerSweepCrossingMinimizer.java:155)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.lambda$1(LayerSweepCrossingMinimizer.java:122)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.minimizeCrossings(LayerSweepCrossingMinimizer.java:131)
at org.eclipse.elk.alg.layered.p3order.LayerSweepCrossingMinimizer.process(LayerSweepCrossingMinimizer.java:110)
at org.eclipse.elk.alg.layered.KlayLayered.hierarchicalLayout(KlayLayered.java:233)
at org.eclipse.elk.alg.layered.KlayLayered.doCompoundLayout(KlayLayered.java:179)
at org.eclipse.elk.alg.layered.LayeredLayoutProvider.layout(LayeredLayoutProvider.java:58)
at org.eclipse.elk.core.RecursiveGraphLayoutEngine.layoutRecursively(RecursiveGraphLayoutEngine.java:181)
at org.eclipse.elk.core.RecursiveGraphLayoutEngine.layout(RecursiveGraphLayoutEngine.java:60)
at org.eclipse.elk.core.service.DiagramLayoutEngine.layout(DiagramLayoutEngine.java:725)
at org.eclipse.elk.core.service.DiagramLayoutEngine.layout(DiagramLayoutEngine.java:655)
at org.eclipse.elk.core.service.DiagramLayoutEngine$1.execute(DiagramLayoutEngine.java:414)
at org.eclipse.elk.core.service.util.MonitoredOperation.runOperation(MonitoredOperation.java:374)
at org.eclipse.elk.core.service.util.MonitoredOperation.access$2(MonitoredOperation.java:359)
at org.eclipse.elk.core.service.util.MonitoredOperation$4.run(MonitoredOperation.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)inimizer.process(LayerSweepCrossingMinimizer.java:110)
at org.eclipse.elk.alg.layered.KlayLayered.hierarchicalLayout(KlayLayered.java:233)
at org.eclipse.elk.alg.layered.KlayLayered.doCompoundLayout(KlayLayered.java:179)
at org.eclipse.elk.alg.layered.LayeredLayoutProvider.layout(LayeredLayoutProvider.java:58)
at org.eclipse.elk.core.RecursiveGraphLayoutEngine.layoutRecursively(RecursiveGraphLayoutEngine.java:181)
at org.eclipse.elk.core.RecursiveGraphLayoutEngine.layout(RecursiveGraphLayoutEngine.java:60)
at org.eclipse.elk.core.service.DiagramLayoutEngine.layout(DiagramLayoutEngine.java:725)
at org.eclipse.elk.core.service.DiagramLayoutEngine.layout(DiagramLayoutEngine.java:655)
at org.eclipse.elk.core.service.DiagramLayoutEngine$1.execute(DiagramLayoutEngine.java:414)
at org.eclipse.elk.core.service.util.MonitoredOperation.runOperation(MonitoredOperation.java:374)
at org.eclipse.elk.core.service.util.MonitoredOperation.access$2(MonitoredOperation.java:359)
at org.eclipse.elk.core.service.util.MonitoredOperation$4.run(MonitoredOperation.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)


If I comment "setProperty(CoreOptions.HIERARCHY_HANDLING, HierarchyHandling.INCLUDE_CHILDREN)", the exception will not show up.
It seems that there is something wrong with customizing port side with the property "HierarchyHandling.INCLUDE_CHILDREN". Can you give me some suggestions or guide about how to correct my customized layout ?
Thanks in advance and hope for your reply.


Re: How Customized ELK to fit Sirius application? [message #1787206 is a reply to message #1787122] Tue, 22 May 2018 06:56 Go to previous messageGo to next message
Miro Spönemann is currently offline Miro SpönemannFriend
Messages: 78
Registered: March 2015
Location: Kiel, Germany
Member

An exception like that is a bug. Please check whether it has already been reported at https://github.com/eclipse/elk/issues and create an issue if it's not there yet.
Re: How Customized ELK to fit Sirius application? [message #1787215 is a reply to message #1785293] Tue, 22 May 2018 08:14 Go to previous messageGo to next message
Ulf Rueegg is currently offline Ulf RueeggFriend
Messages: 26
Registered: February 2010
Junior Member
Deactivating greedy switch should help.
Nevertheless, it would helpful if you could share the the graph (in ELK graph format) such that we can debug the issue. There's a method 'exportLayoutGraph(...)' in the DiagramLayoutEngine to do so.
Re: How Customized ELK to fit Sirius application? [message #1794366 is a reply to message #1785314] Wed, 29 August 2018 15:33 Go to previous message
João Pedro is currently offline João PedroFriend
Messages: 52
Registered: December 2014
Member
Nicholas Kong wrote on Thu, 12 April 2018 11:56
Miro Spönemann.

Can I use this ElkUtil.applyVisitors(graph, configurator) before the DiagramLayoutEngine.invokeLayout() ?

It looks different with 'Advanced Configuration'.

LayoutConfigurator configurator = new LayoutConfigurator();

// Configure layout options for a concrete graph object
configurator.configure(myVerySpecialNode)
    .setProperty(CoreOptions.INTERACTIVE, true)
    .setProperty(CoreOptions.PORT_CONSTRAINTS, PortConstraints.FIXED);
....

DiagramLayoutEngine.Parameters params = new DiagramLayoutEngine.Parameters();
params.addLayoutRun(configurator);
DiagramLayoutEngine.invokeLayout(workbenchPart, diagramPart, params);



Dear Nicholas. Can you share your code or explain where the workbenchPart comes from?

If I do "PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActivePart()" to get my WorkbenchPart
it gives an error "No layout connector is available for the given selection blablabla.", basically because I have multiple Dialog windows (I guess...).

Thank you for your help.
Previous Topic:Compound node layout
Next Topic:Grouping of Nodes using KLay Layered Layout
Goto Forum:
  


Current Time: Thu Oct 10 08:05:40 GMT 2024

Powered by FUDForum. Page generated in 3.56142 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top