Welcome to this tutorial! We will work our way through installing a proper Eclipse setup and developing a first very basic layout algorithm. The layout algorithm will integrate with ELK (Eclipse Layout Kernel), our very own framework that connects graphical editors with layout algorithms. Once you're finished, you should be able to write layout algorithms for ELK. And you should have a running Eclipse-based application that should look something like this:
There's a few things to do before we dive into the tutorial itself. For example, to do Eclipse programming, you will have to get your hands on an Eclipse installation first. Read through the following sections to get ready for the tutorial tasks.
Now that the preliminaries are out of the way, it's time to develop your first layout algorithm! It will, however, be a very simple one. This tutorial focuses on creating Eclipse plug-ins and on learning how to develop with ELK.
We need to create a new plug-in to implement the layout algorithm in. Switch back to the Java or Plug-in Development perspective and follow these steps:
de.cau.cs.kieler.simplelayout
as the project name. Click Next.When writing our layout algorithm, we are going to need to be able to access code defined in several other plug-ins. To do that, we need to add dependencies to those plug-ins:
META-INF/MANIFEST.MF
. The plug-in manifest editor will open. Open its Dependencies tab.org.eclipse.elk.core
org.eclipse.elk.graph
Layout algorithms interface with ELK by means of a layout provider class that has to be created and registered with KIML.
de.cau.cs.kieler.simplelayout
, enter SimpleLayoutProvider
as the class name, and select org.eclipse.elk.core.AbstractLayoutProvider
as the superclass. (This will only be available through the Browse dialog if you have saved the plug-in manifest editor; if you haven't, Eclipse won't know about the new dependencies yet.)Implement the layout provider class:
Add the following constants:
/** default value for spacing between nodes. */ private static final float DEFAULT_SPACING = 15.0f; |
Use the following code as the skeleton of the layout(...)
method:
progressMonitor.begin("Simple layouter", 1); KShapeLayout parentLayout = layoutGraph.getData(KShapeLayout.class); float objectSpacing = parentLayout.getProperty(CoreOptions.SPACING_NODE); if (objectSpacing < 0) { objectSpacing = DEFAULT_SPACING; } float borderSpacing = parentLayout.getProperty(CoreOptions.SPACING_BORDER); if (borderSpacing < 0) { borderSpacing = DEFAULT_SPACING; } // TODO: Insert actual layout code. progressMonitor.done(); |
The following tips might come in handy...
|
Before you can test your layout code, you will have to register your new layout provider with ELK.
de.cau.cs.kieler.simplelayout
package and select New > File.The file is used to specify meta information for your layout algorithm. For this, copy the following code snippet into your editor:
package de.cau.cs.kieler.simplelayout bundle { label "Simple Layout Algoritms" metadataClass SimpleMetaDataProvider } algorithm simple(SimpleLayoutProvider) { label "Simple Test Layouter" metadataClass SimpleOptions supports org.eclipse.elk.spacing.border supports org.eclipse.elk.spacing.node } |
META-INF/MANIFEST.MF
file again and switch to the Extensions tab.org.eclipse.elk.core.layoutProviders
.SimpleMetaDataProvider
). Note that SimpleMetaDataProvider
is automatically generated from the .elkm file you created. Its name is specified by the metadataClass
keyword in the bundle
section. What is also created is the SimpleOptions
class, which contains everything you need to access layout options from within your layout algorithm.We will now have to add a new run configuration that will start an Eclipse instance with your layout code loaded into the application, ready to be used.
Layout Test
.-debug
and -consoleLog
.de.cau.cs.kieler.kgraph.text.ui
de.cau.cs.kieler.klighd.xtext
org.eclipse.ui.ide.application
org.eclipse.platform
Test the layouter in your new Eclipse instance:
Test
.
Once you're satisfied with your node placement code, it's time to take care of edge routing.
Add a new method that will implement the edge routing using the following skeleton code:
/** * Routes the edges connecting the nodes in the given graph. * * @param parentNode the graph whose edges to route. * @param yStart y coordinate of the start of the edge routing area. * @param objectSpacing the object spacing. * @return height used for edge routing. */ private float routeEdges(final KNode parentNode, final float yStart, final float objectSpacing) { // TODO: Implement edge routing return 0; } |
routeEdges(...)
in your doLayout(...)
method and implement the latter.Here's a few tips for implementing the edge routing:
|
Once you're done implementing the edge routing code, test it by running your debug configuration again, as before.