Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This tells KIML that the defined layout algorithm supports the border spacing option. And even more, it overrides the default value declared by the layout option and sets it to 20.

The meta data gathered from the extension point are made available through LayoutMetaDataService. For direct programmatic access, some of that information is duplicated with constants in the class LayoutOptions. The layout option declared above, for example, is available as LayoutOptions.NODE_LABEL_PLACEMENT.

The Layout Option Manager

By now, we have an idea of what layout options do and why they are important in the first place. However, we haven't looked at how layout options end up on KGraph elements yet. This is where the LayoutOptionManager comes in. If you are not interested in the internal details, but want to configure automatic layout for your diagram viewer or editor, you may skip this section and proceed to programmatically setting layout options.

...

The question remains how the layout options sources work. Each source is represented by a class that implements the ILayoutConfig interface, called a layout configurator. KIML currently provides the following layout configurators, each representing a particular source of layout options, listed here in order of increasing priority:

...

The source file annotations can be translated to KIML layout options with a semantic layout configurator, which is registered to each domain model class where annotations can occur.

customConfig

This extension element can be used to register arbitrary implementations of ILayoutConfig. However, this is required only for some experimental configurators used in research. Tool developers normally do not need to use this kind of extension element.

Using Volatile Configurators

The class VolatileLayoutConfig is meant for programmatic layout configuration. It stores layout option values in a hash map. Values are either set globally, that means they are applied to all graph elements, or with a specific context. Global values are easy to configure:

Code Block
themeEclipse
languagejava
DiagramLayoutEngine.INSTANCE.layout(workbenchPart, diagramPart,
        new VolatileLayoutConfig()
            .setValue(LayoutOptions.ALGORITHM, "de.cau.cs.kieler.klay.layered")
            .setValue(LayoutOptions.SPACING, 30.0f)
            .setValue(LayoutOptions.ANIMATE, true));

If multiple configurators are passed to the DiagramLayoutEngine, the layout is computed multiple times: once for each configurator. This behavior can be used to apply different layout algorithms one after another, e.g. first a node placer algorithm and then an edge router algorithm, as in this example:

Code Block
themeEclipse
languagejava
DiagramLayoutEngine.INSTANCE.layout(workbenchPart, diagramPart,
        new VolatileLayoutConfig()
            .setValue(LayoutOptions.ALGORITHM, "de.cau.cs.kieler.klay.force"),
        new VolatileLayoutConfig()
            .setValue(LayoutOptions.ALGORITHM, "de.cau.cs.kieler.kiml.libavoid"));

If you want to use multiple configurators in the same layout computation, use a CompoundLayoutConfig:

Code Block
themeEclipse
languagejava
DiagramLayoutEngine.INSTANCE.layout(workbenchPart, diagramPart,
        CompoundLayoutConfig.of(config1, config2, ...));

Setting layout option values with a specific context is done with this method of VolatileLayoutConfig:

Code Block
themeEclipse
languagejava
public <T, C> VolatileLayoutConfig setValue(final IProperty<? super T> option, final C contextObj,
            final IProperty<? super C> contextKey, final T value)

Don't be scared by the rather cryptic declaration. The arguments contextKey and contextObj determine in which context the option value is to be applied. For instance, using LayoutContext.DOMAIN_MODEL as context key and a specific domain model element as context object, the value is applied exactly to the graph element that is linked to that model element. If you want to refer to an element of the diagram viewer, i.e. the concrete syntax, use LayoutContext.DIAGRAM_PART as context key. The return value is the volatile layout configurator itself, allowing for a builder pattern.

Configuration During Layout Graph Construction

Volatile configurators are also useful for the implementation of diagram layout managers (IDiagramLayoutManager). These implementations are responsible for creating layout graphs following the KGraph meta model from a given diagram viewer (method buildLayoutGraph()). For some layout options it is reasonable to determine concrete values while the layout graph is built, e.g. for the minimal width and height of nodes:

Code Block
themeEclipse
languagejava
KNode childLayoutNode = KimlUtil.createInitializedNode();
KShapeLayout nodeLayout = childLayoutNode.getData(KShapeLayout.class);
Dimension minSize = nodeEditPart.getFigure().getMinimumSize();
nodeLayout.setProperty(LayoutOptions.MIN_WIDTH, (float) minSize.width);
nodeLayout.setProperty(LayoutOptions.MIN_HEIGHT, (float) minSize.height);

The problem is that the layout option manager that applies all configurators to the layout graph removes any option values that have been set directly on the graph elements, hence the configuration done in the previous example has no effect on the layout process. But do not fear, for salvation is near:

Code Block
themeEclipse
languagejava
mapping.getLayoutConfigs().add(VolatileLayoutConfig.fromProperties(mapping.getLayoutGraph(), PRIORITY));

The variable mapping refers to the LayoutMapping instance created in buildLayoutGraph(). The static method fromProperties() offered by VolatileLayoutConfig creates a configuration that contains all the layout option values that have previously been seen directly on the graph elements. By adding this configuration to the layout mapping, we make sure it is considered by the layout option manager and the options are applied to the graph elements exactly as we have specified. Happy end.

If you are uncertain about which value to use for PRIORITY, take something like 25.