eclipse-sprotty / sprotty-server

Server implementation for the Sprotty diagramming framework
https://eclipse.org/sprotty
Eclipse Public License 2.0
23 stars 18 forks source link

Using the GraphViz Dot Algorithm #82

Open DamianRivas opened 3 years ago

DamianRivas commented 3 years ago

Hi, how can we direct our layout engine to use the graphviz dot algorithm? Right now our code just follows the example set by the yang project: https://github.com/opencaesar/oml/blob/master/io.opencaesar.oml.parent/io.opencaesar.oml.dsl.ide.server/src/io/opencaesar/oml/dsl/ide/diagram/OmlLayoutEngine.xtend

spoenemann commented 3 years ago
DamianRivas commented 3 years ago

Thank you @spoenemann. So it won't work without the Graphviz executable installed in the system?

Include GraphvizMetaDataProvider when loading layout meta data

Okay I found the point in which that's done and I made the following change

class OmlLanguageServerSetup extends DiagramLanguageServerSetup {
    override setupLanguages() {
//      ElkLayoutEngine.initialize(new LayeredMetaDataProvider)
        ElkLayoutEngine.initialize(new GraphvizMetaDataProvider)
        Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put('elkg', new ElkGraphResourceFactory)
    }
        ...

Set CoreOptions.ALGORITHM to one of the Graphviz layouters, e.g. org.eclipse.elk.graphviz.dot

So this is a source of confusion. There doesn't seem to be a main entrypoint for the dot algorithm we want to use like there is for the ELK algorithms: Compare ELK Layered with the dot package. Hmm but I did notice in your link it says the value type is a string...

Would we have to incorporate the GraphvizLayoutProvider somehow?

And is there a way to globally configure the algorithm used or is it necessary to select elements and configure them e.g. configurator.configureByType('graph').setProperty(CoreOptions.ALGORITHM, ?). Perhaps calling configurator.configure(...) on the root element of the diagram?

DamianRivas commented 3 years ago

When I look at the dot package here https://mvnrepository.com/artifact/org.eclipse.elk

It's described as "Support for the Graphviz Dot language" which is curiously different than the others e.g. "Layout algorithm based on the layered approach", "Layout algorithm based on the force approach", etc.

DamianRivas commented 3 years ago

I noticed the Layered algorithm has an id property so I tried setting it as a string

configurator.configureByType('node:module')
    .setProperty(CoreOptions.ALGORITHM, "org.eclipse.elk.alg.graphviz.dot")

But it lead to the following exception:

Layout algorithm 'org.eclipse.elk.alg.graphviz.dot' not found for Root Node root

Including the GraphvizMetaDataProvider but not explicitly specifying an algorithm leads to a different error. It seems that it doesn't choose any defaults as it seems to do so when using the LayeredMetaDataProvider

No layout algorithm has been specified for Root Node root
DamianRivas commented 3 years ago

Ok so although I was not able to implement your last step, I went through the source code and I came up with the following to get around the error:

override layout(SModelRoot root) {
    if (root instanceof SGraph) {
        val configurator = new SprottyLayoutConfigurator
        configurator.configureByType('graph')
//                .setProperty(CoreOptions.ALGORITHM, "org.eclipse.elk.alg.graphviz.dot")
            .setProperty(CoreOptions.DIRECTION, Direction.UP)
        configurator.configureByType('node:module')
            .setProperty(CoreOptions.DIRECTION, Direction.UP)
            .setProperty(CoreOptions.PADDING, new ElkPadding(50))
                // NEW CODE
        engine = new GraphvizLayoutProvider()
        (engine as GraphvizLayoutProvider).initialize("DOT")
                //
        layout(root, configurator)
    }
}

That got rid of the error and it actually rendered something, but it's basically garbage. Compare this:

image

with the layout we got using ELK Layered:

image

spoenemann commented 3 years ago

The configuration by string


configurator.configureByType('node:module')
    .setProperty(CoreOptions.ALGORITHM, "org.eclipse.elk.alg.graphviz.dot")

is the correct approach. I don't know what's going wrong. Invoking

ElkLayoutEngine.initialize(new GraphvizMetaDataProvider());

should be sufficient to enable the Dot algorithm. Please create an issue at eclipse/elk.

Alternatively, you could try to do

setEngine(new DotFactory().create());

in your ElkLayoutEngine subclass.