From e486c42c2135c97441f51cc497e5cf94d1b3938d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Domr=C3=B6s?= Date: Wed, 10 Apr 2024 14:34:02 +0200 Subject: [PATCH] Commit all generated layout options and providers. (#1022) Meta compiler seems to die, we have to act. --- .gitignore | 2 - .../compaction/options/PolyominoOptions.java | 129 + .../disco/options/DisCoMetaDataProvider.java | 103 + .../elk/alg/disco/options/DisCoOptions.java | 188 ++ .../force/options/ForceMetaDataProvider.java | 202 ++ .../elk/alg/force/options/ForceOptions.java | 435 +++ .../force/options/StressMetaDataProvider.java | 159 + .../elk/alg/force/options/StressOptions.java | 215 ++ .../alg/graphviz/layouter/CircoOptions.java | 230 ++ .../elk/alg/graphviz/layouter/DotOptions.java | 272 ++ .../elk/alg/graphviz/layouter/FdpOptions.java | 260 ++ .../layouter/GraphvizMetaDataProvider.java | 305 ++ .../alg/graphviz/layouter/NeatoOptions.java | 307 ++ .../alg/graphviz/layouter/TwopiOptions.java | 213 ++ .../options/LayeredMetaDataProvider.java | 2615 +++++++++++++++++ .../alg/layered/options/LayeredOptions.java | 1770 +++++++++++ .../options/LibavoidMetaDataProvider.java | 542 ++++ .../alg/libavoid/options/LibavoidOptions.java | 373 +++ .../options/MrTreeMetaDataProvider.java | 217 ++ .../elk/alg/mrtree/options/MrTreeOptions.java | 456 +++ .../options/RadialMetaDataProvider.java | 366 +++ .../elk/alg/radial/options/RadialOptions.java | 283 ++ .../options/RectPackingMetaDataProvider.java | 367 +++ .../options/RectPackingOptions.java | 382 +++ .../spore/options/SporeCompactionOptions.java | 194 ++ .../spore/options/SporeMetaDataProvider.java | 282 ++ .../options/SporeOverlapRemovalOptions.java | 150 + .../TopdownpackingMetaDataProvider.java | 77 + .../options/TopdownpackingOptions.java | 164 ++ .../elk/conn/gmf/layouter/Draw2DOptions.java | 125 + .../gmf/layouter/GmfMetaDataProvider.java | 22 + .../core/labels/LabelManagementOptions.java | 45 + .../elk/core/options/BoxLayouterOptions.java | 213 ++ .../eclipse/elk/core/options/CoreOptions.java | 2497 ++++++++++++++++ .../core/options/FixedLayouterOptions.java | 130 + .../core/options/RandomLayouterOptions.java | 125 + 36 files changed, 14413 insertions(+), 2 deletions(-) create mode 100644 plugins/org.eclipse.elk.alg.common/src-gen/org/eclipse/elk/alg/common/compaction/options/PolyominoOptions.java create mode 100644 plugins/org.eclipse.elk.alg.disco/src-gen/org/eclipse/elk/alg/disco/options/DisCoMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.alg.disco/src-gen/org/eclipse/elk/alg/disco/options/DisCoOptions.java create mode 100644 plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/ForceMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/ForceOptions.java create mode 100644 plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/StressMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/StressOptions.java create mode 100644 plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/CircoOptions.java create mode 100644 plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/DotOptions.java create mode 100644 plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/FdpOptions.java create mode 100644 plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/GraphvizMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/NeatoOptions.java create mode 100644 plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/TwopiOptions.java create mode 100644 plugins/org.eclipse.elk.alg.layered/src-gen/org/eclipse/elk/alg/layered/options/LayeredMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.alg.layered/src-gen/org/eclipse/elk/alg/layered/options/LayeredOptions.java create mode 100644 plugins/org.eclipse.elk.alg.libavoid/src-gen/org/eclipse/elk/alg/libavoid/options/LibavoidMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.alg.libavoid/src-gen/org/eclipse/elk/alg/libavoid/options/LibavoidOptions.java create mode 100644 plugins/org.eclipse.elk.alg.mrtree/src-gen/org/eclipse/elk/alg/mrtree/options/MrTreeMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.alg.mrtree/src-gen/org/eclipse/elk/alg/mrtree/options/MrTreeOptions.java create mode 100644 plugins/org.eclipse.elk.alg.radial/src-gen/org/eclipse/elk/alg/radial/options/RadialMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.alg.radial/src-gen/org/eclipse/elk/alg/radial/options/RadialOptions.java create mode 100644 plugins/org.eclipse.elk.alg.rectpacking/src-gen/org/eclipse/elk/alg/rectpacking/options/RectPackingMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.alg.rectpacking/src-gen/org/eclipse/elk/alg/rectpacking/options/RectPackingOptions.java create mode 100644 plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeCompactionOptions.java create mode 100644 plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeOverlapRemovalOptions.java create mode 100644 plugins/org.eclipse.elk.alg.topdownpacking/src-gen/org/eclipse/elk/alg/topdownpacking/options/TopdownpackingMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.alg.topdownpacking/src-gen/org/eclipse/elk/alg/topdownpacking/options/TopdownpackingOptions.java create mode 100644 plugins/org.eclipse.elk.conn.gmf/src-gen/org/eclipse/elk/conn/gmf/layouter/Draw2DOptions.java create mode 100644 plugins/org.eclipse.elk.conn.gmf/src-gen/org/eclipse/elk/conn/gmf/layouter/GmfMetaDataProvider.java create mode 100644 plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/labels/LabelManagementOptions.java create mode 100644 plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/BoxLayouterOptions.java create mode 100644 plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/CoreOptions.java create mode 100644 plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/FixedLayouterOptions.java create mode 100644 plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/RandomLayouterOptions.java diff --git a/.gitignore b/.gitignore index 9381709b4..a08bc1401 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,6 @@ xtend-gen/ *.pdf *_trace *.sublime-workspace -/**/src-gen/**/*Options.java -/**/src-gen/**/*MetaDataProvider.java docs/content/reference/algorithms/ docs/content/reference/options/ docs/content/reference/groups/ diff --git a/plugins/org.eclipse.elk.alg.common/src-gen/org/eclipse/elk/alg/common/compaction/options/PolyominoOptions.java b/plugins/org.eclipse.elk.alg.common/src-gen/org/eclipse/elk/alg/common/compaction/options/PolyominoOptions.java new file mode 100644 index 000000000..908fede92 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.common/src-gen/org/eclipse/elk/alg/common/compaction/options/PolyominoOptions.java @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2017 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.common.compaction.options; + +import java.util.EnumSet; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class PolyominoOptions implements ILayoutMetaDataProvider { + /** + * Default value for {@link #POLYOMINO_TRAVERSAL_STRATEGY}. + */ + private static final TraversalStrategy POLYOMINO_TRAVERSAL_STRATEGY_DEFAULT = TraversalStrategy.QUADRANTS_LINE_BY_LINE; + + /** + * Traversal strategy for trying different candidate positions for polyominoes. + */ + public static final IProperty POLYOMINO_TRAVERSAL_STRATEGY = new Property( + "org.eclipse.elk.polyomino.traversalStrategy", + POLYOMINO_TRAVERSAL_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #POLYOMINO_LOW_LEVEL_SORT}. + */ + private static final LowLevelSortingCriterion POLYOMINO_LOW_LEVEL_SORT_DEFAULT = LowLevelSortingCriterion.BY_SIZE_AND_SHAPE; + + /** + * Possible secondary sorting criteria for the processing order of polyominoes. + * They are used when polyominoes are equal according to the primary + * sorting criterion HighLevelSortingCriterion. + */ + public static final IProperty POLYOMINO_LOW_LEVEL_SORT = new Property( + "org.eclipse.elk.polyomino.lowLevelSort", + POLYOMINO_LOW_LEVEL_SORT_DEFAULT, + null, + null); + + /** + * Default value for {@link #POLYOMINO_HIGH_LEVEL_SORT}. + */ + private static final HighLevelSortingCriterion POLYOMINO_HIGH_LEVEL_SORT_DEFAULT = HighLevelSortingCriterion.NUM_OF_EXTERNAL_SIDES_THAN_NUM_OF_EXTENSIONS_LAST; + + /** + * Possible primary sorting criteria for the processing order of polyominoes. + */ + public static final IProperty POLYOMINO_HIGH_LEVEL_SORT = new Property( + "org.eclipse.elk.polyomino.highLevelSort", + POLYOMINO_HIGH_LEVEL_SORT_DEFAULT, + null, + null); + + /** + * Default value for {@link #POLYOMINO_FILL}. + */ + private static final boolean POLYOMINO_FILL_DEFAULT = true; + + /** + * Use the Profile Fill algorithm to fill polyominoes to prevent small polyominoes + * from being placed inside of big polyominoes with large holes. Might increase packing area. + */ + public static final IProperty POLYOMINO_FILL = new Property( + "org.eclipse.elk.polyomino.fill", + POLYOMINO_FILL_DEFAULT, + null, + null); + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.polyomino.traversalStrategy") + .group("polyomino") + .name("Polyomino Traversal Strategy") + .description("Traversal strategy for trying different candidate positions for polyominoes.") + .defaultValue(POLYOMINO_TRAVERSAL_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(TraversalStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.polyomino.lowLevelSort") + .group("polyomino") + .name("Polyomino Secondary Sorting Criterion") + .description("Possible secondary sorting criteria for the processing order of polyominoes. They are used when polyominoes are equal according to the primary sorting criterion HighLevelSortingCriterion.") + .defaultValue(POLYOMINO_LOW_LEVEL_SORT_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(LowLevelSortingCriterion.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.polyomino.highLevelSort") + .group("polyomino") + .name("Polyomino Primary Sorting Criterion") + .description("Possible primary sorting criteria for the processing order of polyominoes.") + .defaultValue(POLYOMINO_HIGH_LEVEL_SORT_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(HighLevelSortingCriterion.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.polyomino.fill") + .group("polyomino") + .name("Fill Polyominoes") + .description("Use the Profile Fill algorithm to fill polyominoes to prevent small polyominoes from being placed inside of big polyominoes with large holes. Might increase packing area.") + .defaultValue(POLYOMINO_FILL_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.disco/src-gen/org/eclipse/elk/alg/disco/options/DisCoMetaDataProvider.java b/plugins/org.eclipse.elk.alg.disco/src-gen/org/eclipse/elk/alg/disco/options/DisCoMetaDataProvider.java new file mode 100644 index 000000000..b526e6468 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.disco/src-gen/org/eclipse/elk/alg/disco/options/DisCoMetaDataProvider.java @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2017 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.disco.options; + +import java.util.EnumSet; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class DisCoMetaDataProvider implements ILayoutMetaDataProvider { + /** + * Default value for {@link #COMPONENT_COMPACTION_STRATEGY}. + */ + private static final CompactionStrategy COMPONENT_COMPACTION_STRATEGY_DEFAULT = CompactionStrategy.POLYOMINO; + + /** + * Strategy for packing different connected components in order to save space + * and enhance readability of a graph. + */ + public static final IProperty COMPONENT_COMPACTION_STRATEGY = new Property( + "org.eclipse.elk.disco.componentCompaction.strategy", + COMPONENT_COMPACTION_STRATEGY_DEFAULT, + null, + null); + + /** + * A layout algorithm that is to be applied to each connected component + * before the components themselves are compacted. If unspecified, + * the positions of the components' nodes are not altered. + */ + public static final IProperty COMPONENT_COMPACTION_COMPONENT_LAYOUT_ALGORITHM = new Property( + "org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm"); + + /** + * Access to the DCGraph is intended for the debug view, + */ + public static final IProperty DEBUG_DISCO_GRAPH = new Property( + "org.eclipse.elk.disco.debug.discoGraph"); + + /** + * Access to the polyominoes is intended for the debug view, + */ + public static final IProperty DEBUG_DISCO_POLYS = new Property( + "org.eclipse.elk.disco.debug.discoPolys"); + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.disco.componentCompaction.strategy") + .group("componentCompaction") + .name("Connected Components Compaction Strategy") + .description("Strategy for packing different connected components in order to save space and enhance readability of a graph.") + .defaultValue(COMPONENT_COMPACTION_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(CompactionStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm") + .group("componentCompaction") + .name("Connected Components Layout Algorithm") + .description("A layout algorithm that is to be applied to each connected component before the components themselves are compacted. If unspecified, the positions of the components\' nodes are not altered.") + .type(LayoutOptionData.Type.STRING) + .optionClass(String.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.disco.debug.discoGraph") + .group("debug") + .name("DCGraph") + .description("Access to the DCGraph is intended for the debug view,") + .type(LayoutOptionData.Type.OBJECT) + .optionClass(Object.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.disco.debug.discoPolys") + .group("debug") + .name("List of Polyominoes") + .description("Access to the polyominoes is intended for the debug view,") + .type(LayoutOptionData.Type.OBJECT) + .optionClass(Object.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + new org.eclipse.elk.alg.disco.options.DisCoOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.alg.disco/src-gen/org/eclipse/elk/alg/disco/options/DisCoOptions.java b/plugins/org.eclipse.elk.alg.disco/src-gen/org/eclipse/elk/alg/disco/options/DisCoOptions.java new file mode 100644 index 000000000..dcf8e45f8 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.disco/src-gen/org/eclipse/elk/alg/disco/options/DisCoOptions.java @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2017 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.disco.options; + +import org.eclipse.elk.alg.common.compaction.options.HighLevelSortingCriterion; +import org.eclipse.elk.alg.common.compaction.options.LowLevelSortingCriterion; +import org.eclipse.elk.alg.common.compaction.options.PolyominoOptions; +import org.eclipse.elk.alg.common.compaction.options.TraversalStrategy; +import org.eclipse.elk.alg.disco.DisCoLayoutProvider; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.graph.properties.IProperty; + +@SuppressWarnings("all") +public class DisCoOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK DisCo algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.disco"; + + /** + * Spacing to be preserved between pairs of connected components. + * This option is only relevant if 'separateConnectedComponents' is activated. + */ + public static final IProperty SPACING_COMPONENT_COMPONENT = CoreOptions.SPACING_COMPONENT_COMPONENT; + + /** + * The thickness of an edge. This is a hint on the line width used to draw an edge, possibly + * requiring more space to be reserved for it. + */ + public static final IProperty EDGE_THICKNESS = CoreOptions.EDGE_THICKNESS; + + /** + * The desired aspect ratio of the drawing, that is the quotient of width by height. + */ + public static final IProperty ASPECT_RATIO = CoreOptions.ASPECT_RATIO; + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = CoreOptions.PADDING; + + /** + * Possible secondary sorting criteria for the processing order of polyominoes. + * They are used when polyominoes are equal according to the primary + * sorting criterion HighLevelSortingCriterion. + */ + public static final IProperty POLYOMINO_LOW_LEVEL_SORT = PolyominoOptions.POLYOMINO_LOW_LEVEL_SORT; + + /** + * Possible primary sorting criteria for the processing order of polyominoes. + */ + public static final IProperty POLYOMINO_HIGH_LEVEL_SORT = PolyominoOptions.POLYOMINO_HIGH_LEVEL_SORT; + + /** + * Traversal strategy for trying different candidate positions for polyominoes. + */ + public static final IProperty POLYOMINO_TRAVERSAL_STRATEGY = PolyominoOptions.POLYOMINO_TRAVERSAL_STRATEGY; + + /** + * Use the Profile Fill algorithm to fill polyominoes to prevent small polyominoes + * from being placed inside of big polyominoes with large holes. Might increase packing area. + */ + public static final IProperty POLYOMINO_FILL = PolyominoOptions.POLYOMINO_FILL; + + /** + * Strategy for packing different connected components in order to save space + * and enhance readability of a graph. + */ + public static final IProperty COMPONENT_COMPACTION_STRATEGY = DisCoMetaDataProvider.COMPONENT_COMPACTION_STRATEGY; + + /** + * A layout algorithm that is to be applied to each connected component + * before the components themselves are compacted. If unspecified, + * the positions of the components' nodes are not altered. + */ + public static final IProperty COMPONENT_COMPACTION_COMPONENT_LAYOUT_ALGORITHM = DisCoMetaDataProvider.COMPONENT_COMPACTION_COMPONENT_LAYOUT_ALGORITHM; + + /** + * Access to the DCGraph is intended for the debug view, + */ + public static final IProperty DEBUG_DISCO_GRAPH = DisCoMetaDataProvider.DEBUG_DISCO_GRAPH; + + /** + * Access to the polyominoes is intended for the debug view, + */ + public static final IProperty DEBUG_DISCO_POLYS = DisCoMetaDataProvider.DEBUG_DISCO_POLYS; + + /** + * Layouter-specific algorithm factory. + */ + public static class DiscoFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new DisCoLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.disco") + .name("ELK DisCo") + .description("Layouter for arranging unconnected subgraphs. The subgraphs themselves are, by default, not laid out.") + .providerFactory(new DiscoFactory()) + .melkBundleName(null) + .definingBundleId("org.eclipse.elk.alg.disco") + .imagePath("images/disco_layout.png") + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.spacing.componentComponent", + SPACING_COMPONENT_COMPONENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.edge.thickness", + EDGE_THICKNESS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.aspectRatio", + ASPECT_RATIO.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.padding", + PADDING.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.polyomino.lowLevelSort", + POLYOMINO_LOW_LEVEL_SORT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.polyomino.highLevelSort", + POLYOMINO_HIGH_LEVEL_SORT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.polyomino.traversalStrategy", + POLYOMINO_TRAVERSAL_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.polyomino.fill", + POLYOMINO_FILL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.disco.componentCompaction.strategy", + COMPONENT_COMPACTION_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm", + COMPONENT_COMPACTION_COMPONENT_LAYOUT_ALGORITHM.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.disco.debug.discoGraph", + DEBUG_DISCO_GRAPH.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.disco", + "org.eclipse.elk.disco.debug.discoPolys", + DEBUG_DISCO_POLYS.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/ForceMetaDataProvider.java b/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/ForceMetaDataProvider.java new file mode 100644 index 000000000..a79f216b3 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/ForceMetaDataProvider.java @@ -0,0 +1,202 @@ +/** + * Copyright (c) 2015, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.force.options; + +import java.util.EnumSet; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.core.util.ExclusiveBounds; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +/** + * Declarations for the ELK Force layout algorithm. + */ +@SuppressWarnings("all") +public class ForceMetaDataProvider implements ILayoutMetaDataProvider { + /** + * Default value for {@link #MODEL}. + */ + private static final ForceModelStrategy MODEL_DEFAULT = ForceModelStrategy.FRUCHTERMAN_REINGOLD; + + /** + * Determines the model for force calculation. + */ + public static final IProperty MODEL = new Property( + "org.eclipse.elk.force.model", + MODEL_DEFAULT, + null, + null); + + /** + * Default value for {@link #ITERATIONS}. + */ + private static final int ITERATIONS_DEFAULT = 300; + + /** + * Lower bound value for {@link #ITERATIONS}. + */ + private static final Comparable ITERATIONS_LOWER_BOUND = Integer.valueOf(1); + + /** + * The number of iterations on the force model. + */ + public static final IProperty ITERATIONS = new Property( + "org.eclipse.elk.force.iterations", + ITERATIONS_DEFAULT, + ITERATIONS_LOWER_BOUND, + null); + + /** + * Default value for {@link #REPULSIVE_POWER}. + */ + private static final int REPULSIVE_POWER_DEFAULT = 0; + + /** + * Lower bound value for {@link #REPULSIVE_POWER}. + */ + private static final Comparable REPULSIVE_POWER_LOWER_BOUND = Integer.valueOf(0); + + /** + * Determines how many bend points are added to the edge; such bend points are regarded as + * repelling particles in the force model + */ + public static final IProperty REPULSIVE_POWER = new Property( + "org.eclipse.elk.force.repulsivePower", + REPULSIVE_POWER_DEFAULT, + REPULSIVE_POWER_LOWER_BOUND, + null); + + /** + * Default value for {@link #TEMPERATURE}. + */ + private static final double TEMPERATURE_DEFAULT = 0.001; + + /** + * Lower bound value for {@link #TEMPERATURE}. + */ + private static final Comparable TEMPERATURE_LOWER_BOUND = ExclusiveBounds.greaterThan(0); + + /** + * The temperature is used as a scaling factor for particle displacements. + */ + public static final IProperty TEMPERATURE = new Property( + "org.eclipse.elk.force.temperature", + TEMPERATURE_DEFAULT, + TEMPERATURE_LOWER_BOUND, + null); + + /** + * Default value for {@link #REPULSION}. + */ + private static final double REPULSION_DEFAULT = 5.0; + + /** + * Lower bound value for {@link #REPULSION}. + */ + private static final Comparable REPULSION_LOWER_BOUND = ExclusiveBounds.greaterThan(0); + + /** + * Factor for repulsive forces in Eades' model. + */ + public static final IProperty REPULSION = new Property( + "org.eclipse.elk.force.repulsion", + REPULSION_DEFAULT, + REPULSION_LOWER_BOUND, + null); + + /** + * Required value for dependency between {@link #TEMPERATURE} and {@link #MODEL}. + */ + private static final ForceModelStrategy TEMPERATURE_DEP_MODEL_0 = ForceModelStrategy.FRUCHTERMAN_REINGOLD; + + /** + * Required value for dependency between {@link #REPULSION} and {@link #MODEL}. + */ + private static final ForceModelStrategy REPULSION_DEP_MODEL_0 = ForceModelStrategy.EADES; + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.force.model") + .group("") + .name("Force Model") + .description("Determines the model for force calculation.") + .defaultValue(MODEL_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(ForceModelStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.force.iterations") + .group("") + .name("Iterations") + .description("The number of iterations on the force model.") + .defaultValue(ITERATIONS_DEFAULT) + .lowerBound(ITERATIONS_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.force.repulsivePower") + .group("") + .name("Repulsive Power") + .description("Determines how many bend points are added to the edge; such bend points are regarded as repelling particles in the force model") + .defaultValue(REPULSIVE_POWER_DEFAULT) + .lowerBound(REPULSIVE_POWER_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.force.temperature") + .group("") + .name("FR Temperature") + .description("The temperature is used as a scaling factor for particle displacements.") + .defaultValue(TEMPERATURE_DEFAULT) + .lowerBound(TEMPERATURE_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.addDependency( + "org.eclipse.elk.force.temperature", + "org.eclipse.elk.force.model", + TEMPERATURE_DEP_MODEL_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.force.repulsion") + .group("") + .name("Eades Repulsion") + .description("Factor for repulsive forces in Eades\' model.") + .defaultValue(REPULSION_DEFAULT) + .lowerBound(REPULSION_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.addDependency( + "org.eclipse.elk.force.repulsion", + "org.eclipse.elk.force.model", + REPULSION_DEP_MODEL_0 + ); + new org.eclipse.elk.alg.force.options.ForceOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/ForceOptions.java b/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/ForceOptions.java new file mode 100644 index 000000000..77b480d0f --- /dev/null +++ b/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/ForceOptions.java @@ -0,0 +1,435 @@ +/** + * Copyright (c) 2015, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.force.options; + +import java.util.EnumSet; +import org.eclipse.elk.alg.force.ForceLayoutProvider; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.NodeLabelPlacement; +import org.eclipse.elk.core.options.PortConstraints; +import org.eclipse.elk.core.options.PortLabelPlacement; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.core.options.SizeOptions; +import org.eclipse.elk.core.options.TopdownNodeTypes; +import org.eclipse.elk.graph.properties.GraphFeature; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class ForceOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK Force algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.force"; + + /** + * Default value for {@link #PRIORITY} with algorithm "ELK Force". + */ + private static final int PRIORITY_DEFAULT = 1; + + /** + * Defines the priority of an object; its meaning depends on the specific layout algorithm + * and the context where it is used. + *

Algorithm Specific Details

+ * Priorities set on nodes determine the order in which connected components are placed: + * components with a higher sum of node priorities will end up + * before components with a lower sum. + * Priorities set on edges usually directly influence the attractive force of a connection, + * with higher priorities corresponding to greater attractive forces. + */ + public static final IProperty PRIORITY = new Property( + CoreOptions.PRIORITY, + PRIORITY_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "ELK Force". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 80; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * Default value for {@link #SPACING_EDGE_LABEL} with algorithm "ELK Force". + */ + private static final double SPACING_EDGE_LABEL_DEFAULT = 5; + + /** + * The minimal distance to be preserved between a label and the edge it is associated with. + * Note that the placement of a label is influenced by the 'edgelabels.placement' option. + */ + public static final IProperty SPACING_EDGE_LABEL = new Property( + CoreOptions.SPACING_EDGE_LABEL, + SPACING_EDGE_LABEL_DEFAULT); + + /** + * Default value for {@link #ASPECT_RATIO} with algorithm "ELK Force". + */ + private static final double ASPECT_RATIO_DEFAULT = 1.6f; + + /** + * The desired aspect ratio of the drawing, that is the quotient of width by height. + */ + public static final IProperty ASPECT_RATIO = new Property( + CoreOptions.ASPECT_RATIO, + ASPECT_RATIO_DEFAULT); + + /** + * Default value for {@link #RANDOM_SEED} with algorithm "ELK Force". + */ + private static final int RANDOM_SEED_DEFAULT = 1; + + /** + * Seed used for pseudo-random number generators to control the layout algorithm. If the + * value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time). + */ + public static final IProperty RANDOM_SEED = new Property( + CoreOptions.RANDOM_SEED, + RANDOM_SEED_DEFAULT); + + /** + * Default value for {@link #SEPARATE_CONNECTED_COMPONENTS} with algorithm "ELK Force". + */ + private static final boolean SEPARATE_CONNECTED_COMPONENTS_DEFAULT = true; + + /** + * Whether each connected component should be processed separately. + */ + public static final IProperty SEPARATE_CONNECTED_COMPONENTS = new Property( + CoreOptions.SEPARATE_CONNECTED_COMPONENTS, + SEPARATE_CONNECTED_COMPONENTS_DEFAULT); + + /** + * Default value for {@link #PADDING} with algorithm "ELK Force". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(50); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Whether the algorithm should be run in interactive mode for the content of a parent node. + * What this means exactly depends on how the specific algorithm interprets this option. + * Usually in the interactive mode algorithms try to modify the current layout as little as + * possible. + */ + public static final IProperty INTERACTIVE = CoreOptions.INTERACTIVE; + + /** + * Defines constraints of the position of the ports of a node. + */ + public static final IProperty PORT_CONSTRAINTS = CoreOptions.PORT_CONSTRAINTS; + + /** + * Default value for {@link #EDGE_LABELS_INLINE} with algorithm "ELK Force". + */ + private static final boolean EDGE_LABELS_INLINE_DEFAULT = false; + + /** + * If true, an edge label is placed directly on its edge. May only apply to center edge labels. + * This kind of label placement is only advisable if the label's rendering is such that it is not + * crossed by its edge and thus stays legible. + */ + public static final IProperty EDGE_LABELS_INLINE = new Property( + CoreOptions.EDGE_LABELS_INLINE, + EDGE_LABELS_INLINE_DEFAULT); + + /** + * Node micro layout comprises the computation of node dimensions (if requested), the placement of ports + * and their labels, and the placement of node labels. + * The functionality is implemented independent of any specific layout algorithm and shouldn't have any + * negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, + * this option allows to deactivate the micro layout. + */ + public static final IProperty OMIT_NODE_MICRO_LAYOUT = CoreOptions.OMIT_NODE_MICRO_LAYOUT; + + /** + * By default, the fixed layout provider will enlarge a graph until it is large enough to contain + * its children. If this option is set, it won't do so. + */ + public static final IProperty NODE_SIZE_FIXED_GRAPH_SIZE = CoreOptions.NODE_SIZE_FIXED_GRAPH_SIZE; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * Hints for where node labels are to be placed; if empty, the node label's position is not + * modified. + */ + public static final IProperty> NODE_LABELS_PLACEMENT = CoreOptions.NODE_LABELS_PLACEMENT; + + /** + * Decides on a placement method for port labels; if empty, the node label's position is not + * modified. + */ + public static final IProperty> PORT_LABELS_PLACEMENT = CoreOptions.PORT_LABELS_PLACEMENT; + + /** + * Determines the model for force calculation. + */ + public static final IProperty MODEL = ForceMetaDataProvider.MODEL; + + /** + * The temperature is used as a scaling factor for particle displacements. + */ + public static final IProperty TEMPERATURE = ForceMetaDataProvider.TEMPERATURE; + + /** + * The number of iterations on the force model. + */ + public static final IProperty ITERATIONS = ForceMetaDataProvider.ITERATIONS; + + /** + * Factor for repulsive forces in Eades' model. + */ + public static final IProperty REPULSION = ForceMetaDataProvider.REPULSION; + + /** + * Determines how many bend points are added to the edge; such bend points are regarded as + * repelling particles in the force model + */ + public static final IProperty REPULSIVE_POWER = ForceMetaDataProvider.REPULSIVE_POWER; + + /** + * Turns topdown layout on and off. If this option is enabled, hierarchical layout will be computed first for + * the root node and then for its children recursively. Layouts are then scaled down to fit the area provided by + * their parents. Graphs must follow a certain structure for topdown layout to work properly. + * {@link TopdownNodeTypes.PARALLEL_NODE} nodes must have children of type + * {@link TopdownNodeTypes.HIERARCHICAL_NODE} and must define {@link topdown.hierarchicalNodeWidth} and + * {@link topdown.hierarchicalNodeAspectRatio} for their children. Furthermore they need to be laid out using an + * algorithm that is a {@link TopdownLayoutProvider}. Hierarchical nodes can also be parents of other hierarchical + * nodes and can optionally use a {@link TopdownSizeApproximator} to dynamically set sizes during topdown layout. + * In this case {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} should be set + * on the node itself rather than the parent. The values are then used by the size approximator as base values. + * Hierarchical nodes require the layout option {@link nodeSize.fixedGraphSize} to be true to prevent the algorithm + * used there from resizing the hierarchical node. This option is not supported if 'Hierarchy Handling' is set to + * 'INCLUDE_CHILDREN' + */ + public static final IProperty TOPDOWN_LAYOUT = CoreOptions.TOPDOWN_LAYOUT; + + /** + * The scaling factor to be applied to the nodes laid out within the node in recursive topdown + * layout. The difference to 'Scale Factor' is that the node itself is not scaled. This value has to be set on + * hierarchical nodes. + */ + public static final IProperty TOPDOWN_SCALE_FACTOR = CoreOptions.TOPDOWN_SCALE_FACTOR; + + /** + * The fixed size of a hierarchical node when using topdown layout. If this value is set on a parallel + * node it applies to its children, when set on a hierarchical node it applies to the node itself. + */ + public static final IProperty TOPDOWN_HIERARCHICAL_NODE_WIDTH = CoreOptions.TOPDOWN_HIERARCHICAL_NODE_WIDTH; + + /** + * The fixed aspect ratio of a hierarchical node when using topdown layout. Default is 1/sqrt(2). If this + * value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to + * the node itself. + */ + public static final IProperty TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO = CoreOptions.TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO; + + /** + * Default value for {@link #TOPDOWN_NODE_TYPE} with algorithm "ELK Force". + */ + private static final TopdownNodeTypes TOPDOWN_NODE_TYPE_DEFAULT = TopdownNodeTypes.HIERARCHICAL_NODE; + + /** + * The different node types used for topdown layout. If the node type is set + * to {@link TopdownNodeTypes.PARALLEL_NODE} the algorithm must be set to a {@link TopdownLayoutProvider} such + * as {@link TopdownPacking}. The {@link nodeSize.fixedGraphSize} option is technically only required for + * hierarchical nodes. + */ + public static final IProperty TOPDOWN_NODE_TYPE = new Property( + CoreOptions.TOPDOWN_NODE_TYPE, + TOPDOWN_NODE_TYPE_DEFAULT); + + /** + * Layouter-specific algorithm factory. + */ + public static class ForceFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new ForceLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.force") + .name("ELK Force") + .description("Force-based algorithm provided by the Eclipse Layout Kernel. Implements methods that follow physical analogies by simulating forces that move the nodes into a balanced distribution. Currently the original Eades model and the Fruchterman - Reingold model are supported.") + .providerFactory(new ForceFactory()) + .category("org.eclipse.elk.force") + .melkBundleName(null) + .definingBundleId("org.eclipse.elk.alg.force") + .imagePath("images/force_layout.png") + .supportedFeatures(EnumSet.of(GraphFeature.MULTI_EDGES, GraphFeature.EDGE_LABELS)) + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.priority", + PRIORITY_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.spacing.edgeLabel", + SPACING_EDGE_LABEL_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.aspectRatio", + ASPECT_RATIO_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.randomSeed", + RANDOM_SEED_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.separateConnectedComponents", + SEPARATE_CONNECTED_COMPONENTS_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.interactive", + INTERACTIVE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.portConstraints", + PORT_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.edgeLabels.inline", + EDGE_LABELS_INLINE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.omitNodeMicroLayout", + OMIT_NODE_MICRO_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.nodeSize.fixedGraphSize", + NODE_SIZE_FIXED_GRAPH_SIZE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.nodeLabels.placement", + NODE_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.portLabels.placement", + PORT_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.force.model", + MODEL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.force.temperature", + TEMPERATURE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.force.iterations", + ITERATIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.force.repulsion", + REPULSION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.force.repulsivePower", + REPULSIVE_POWER.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.topdownLayout", + TOPDOWN_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.topdown.scaleFactor", + TOPDOWN_SCALE_FACTOR.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.topdown.hierarchicalNodeWidth", + TOPDOWN_HIERARCHICAL_NODE_WIDTH.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.topdown.hierarchicalNodeAspectRatio", + TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.force", + "org.eclipse.elk.topdown.nodeType", + TOPDOWN_NODE_TYPE_DEFAULT + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/StressMetaDataProvider.java b/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/StressMetaDataProvider.java new file mode 100644 index 000000000..a7f3fec4e --- /dev/null +++ b/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/StressMetaDataProvider.java @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2016, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.force.options; + +import java.util.EnumSet; +import org.eclipse.elk.alg.force.stress.StressMajorization; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +/** + * Declarations for the ELK Stress layout algorithm. + */ +@SuppressWarnings("all") +public class StressMetaDataProvider implements ILayoutMetaDataProvider { + /** + * Default value for {@link #FIXED}. + */ + private static final boolean FIXED_DEFAULT = false; + + /** + * Prevent that the node is moved by the layout algorithm. + */ + public static final IProperty FIXED = new Property( + "org.eclipse.elk.stress.fixed", + FIXED_DEFAULT, + null, + null); + + /** + * Default value for {@link #DESIRED_EDGE_LENGTH}. + */ + private static final double DESIRED_EDGE_LENGTH_DEFAULT = 100.0; + + /** + * Either specified for parent nodes or for individual edges, + * where the latter takes higher precedence. + */ + public static final IProperty DESIRED_EDGE_LENGTH = new Property( + "org.eclipse.elk.stress.desiredEdgeLength", + DESIRED_EDGE_LENGTH_DEFAULT, + null, + null); + + /** + * Default value for {@link #DIMENSION}. + */ + private static final StressMajorization.Dimension DIMENSION_DEFAULT = StressMajorization.Dimension.XY; + + /** + * Dimensions that are permitted to be altered during layout. + */ + public static final IProperty DIMENSION = new Property( + "org.eclipse.elk.stress.dimension", + DIMENSION_DEFAULT, + null, + null); + + /** + * Default value for {@link #EPSILON}. + */ + private static final double EPSILON_DEFAULT = 10e-4; + + /** + * Termination criterion for the iterative process. + */ + public static final IProperty EPSILON = new Property( + "org.eclipse.elk.stress.epsilon", + EPSILON_DEFAULT, + null, + null); + + /** + * Default value for {@link #ITERATION_LIMIT}. + */ + private static final int ITERATION_LIMIT_DEFAULT = Integer.MAX_VALUE; + + /** + * Maximum number of performed iterations. Takes higher + * precedence than 'epsilon'. + */ + public static final IProperty ITERATION_LIMIT = new Property( + "org.eclipse.elk.stress.iterationLimit", + ITERATION_LIMIT_DEFAULT, + null, + null); + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.stress.fixed") + .group("") + .name("Fixed Position") + .description("Prevent that the node is moved by the layout algorithm.") + .defaultValue(FIXED_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.stress.desiredEdgeLength") + .group("") + .name("Desired Edge Length") + .description("Either specified for parent nodes or for individual edges, where the latter takes higher precedence.") + .defaultValue(DESIRED_EDGE_LENGTH_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS, LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.stress.dimension") + .group("") + .name("Layout Dimension") + .description("Dimensions that are permitted to be altered during layout.") + .defaultValue(DIMENSION_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(StressMajorization.Dimension.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.stress.epsilon") + .group("") + .name("Stress Epsilon") + .description("Termination criterion for the iterative process.") + .defaultValue(EPSILON_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.stress.iterationLimit") + .group("") + .name("Iteration Limit") + .description("Maximum number of performed iterations. Takes higher precedence than \'epsilon\'.") + .defaultValue(ITERATION_LIMIT_DEFAULT) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + new org.eclipse.elk.alg.force.options.StressOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/StressOptions.java b/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/StressOptions.java new file mode 100644 index 000000000..a3c654cf7 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.force/src-gen/org/eclipse/elk/alg/force/options/StressOptions.java @@ -0,0 +1,215 @@ +/** + * Copyright (c) 2016, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.force.options; + +import java.util.EnumSet; +import org.eclipse.elk.alg.force.stress.StressLayoutProvider; +import org.eclipse.elk.alg.force.stress.StressMajorization; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.KVector; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.NodeLabelPlacement; +import org.eclipse.elk.core.options.PortLabelPlacement; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.core.options.SizeOptions; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class StressOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK Stress algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.stress"; + + /** + * Whether the algorithm should be run in interactive mode for the content of a parent node. + * What this means exactly depends on how the specific algorithm interprets this option. + * Usually in the interactive mode algorithms try to modify the current layout as little as + * possible. + */ + public static final IProperty INTERACTIVE = CoreOptions.INTERACTIVE; + + /** + * Default value for {@link #EDGE_LABELS_INLINE} with algorithm "ELK Stress". + */ + private static final boolean EDGE_LABELS_INLINE_DEFAULT = true; + + /** + * If true, an edge label is placed directly on its edge. May only apply to center edge labels. + * This kind of label placement is only advisable if the label's rendering is such that it is not + * crossed by its edge and thus stays legible. + */ + public static final IProperty EDGE_LABELS_INLINE = new Property( + CoreOptions.EDGE_LABELS_INLINE, + EDGE_LABELS_INLINE_DEFAULT); + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * The minimal size to which a node can be reduced. + */ + public static final IProperty NODE_SIZE_MINIMUM = CoreOptions.NODE_SIZE_MINIMUM; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * Hints for where node labels are to be placed; if empty, the node label's position is not + * modified. + */ + public static final IProperty> NODE_LABELS_PLACEMENT = CoreOptions.NODE_LABELS_PLACEMENT; + + /** + * Node micro layout comprises the computation of node dimensions (if requested), the placement of ports + * and their labels, and the placement of node labels. + * The functionality is implemented independent of any specific layout algorithm and shouldn't have any + * negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, + * this option allows to deactivate the micro layout. + */ + public static final IProperty OMIT_NODE_MICRO_LAYOUT = CoreOptions.OMIT_NODE_MICRO_LAYOUT; + + /** + * Decides on a placement method for port labels; if empty, the node label's position is not + * modified. + */ + public static final IProperty> PORT_LABELS_PLACEMENT = CoreOptions.PORT_LABELS_PLACEMENT; + + /** + * Prevent that the node is moved by the layout algorithm. + */ + public static final IProperty FIXED = StressMetaDataProvider.FIXED; + + /** + * Dimensions that are permitted to be altered during layout. + */ + public static final IProperty DIMENSION = StressMetaDataProvider.DIMENSION; + + /** + * Termination criterion for the iterative process. + */ + public static final IProperty EPSILON = StressMetaDataProvider.EPSILON; + + /** + * Maximum number of performed iterations. Takes higher + * precedence than 'epsilon'. + */ + public static final IProperty ITERATION_LIMIT = StressMetaDataProvider.ITERATION_LIMIT; + + /** + * Either specified for parent nodes or for individual edges, + * where the latter takes higher precedence. + */ + public static final IProperty DESIRED_EDGE_LENGTH = StressMetaDataProvider.DESIRED_EDGE_LENGTH; + + /** + * Layouter-specific algorithm factory. + */ + public static class StressFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new StressLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.stress") + .name("ELK Stress") + .description("Minimizes the stress within a layout using stress majorization. Stress exists if the euclidean distance between a pair of nodes doesn\'t match their graph theoretic distance, that is, the shortest path between the two nodes. The method allows to specify individual edge lengths.") + .providerFactory(new StressFactory()) + .category("org.eclipse.elk.force") + .melkBundleName(null) + .definingBundleId("org.eclipse.elk.alg.force") + .imagePath("images/stress_layout.png") + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.interactive", + INTERACTIVE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.edgeLabels.inline", + EDGE_LABELS_INLINE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.nodeSize.minimum", + NODE_SIZE_MINIMUM.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.nodeLabels.placement", + NODE_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.omitNodeMicroLayout", + OMIT_NODE_MICRO_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.portLabels.placement", + PORT_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.stress.fixed", + FIXED.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.stress.dimension", + DIMENSION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.stress.epsilon", + EPSILON.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.stress.iterationLimit", + ITERATION_LIMIT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.stress", + "org.eclipse.elk.stress.desiredEdgeLength", + DESIRED_EDGE_LENGTH.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/CircoOptions.java b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/CircoOptions.java new file mode 100644 index 000000000..2ef64fe4d --- /dev/null +++ b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/CircoOptions.java @@ -0,0 +1,230 @@ +/** + * Copyright (c) 2015 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.graphviz.layouter; + +import java.util.EnumSet; +import org.eclipse.elk.alg.graphviz.dot.transform.OverlapMode; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.EdgeRouting; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.core.options.SizeOptions; +import org.eclipse.elk.graph.properties.GraphFeature; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class CircoOptions implements ILayoutMetaDataProvider { + /** + * The id of the Graphviz Circo algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.graphviz.circo"; + + /** + * Default value for {@link #PADDING} with algorithm "Graphviz Circo". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(10); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "Graphviz Circo". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 40; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * The minimal distance to be preserved between a label and the edge it is associated with. + * Note that the placement of a label is influenced by the 'edgelabels.placement' option. + */ + public static final IProperty SPACING_EDGE_LABEL = CoreOptions.SPACING_EDGE_LABEL; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * Default value for {@link #EDGE_ROUTING} with algorithm "Graphviz Circo". + */ + private static final EdgeRouting EDGE_ROUTING_DEFAULT = EdgeRouting.SPLINES; + + /** + * What kind of edge routing style should be applied for the content of a parent node. + * Algorithms may also set this option to single edges in order to mark them as splines. + * The bend point list of edges with this option set to SPLINES must be interpreted as control + * points for a piecewise cubic spline. + */ + public static final IProperty EDGE_ROUTING = new Property( + CoreOptions.EDGE_ROUTING, + EDGE_ROUTING_DEFAULT); + + /** + * Whether additional debug information shall be generated. + */ + public static final IProperty DEBUG_MODE = CoreOptions.DEBUG_MODE; + + /** + * Default value for {@link #SEPARATE_CONNECTED_COMPONENTS} with algorithm "Graphviz Circo". + */ + private static final boolean SEPARATE_CONNECTED_COMPONENTS_DEFAULT = false; + + /** + * Whether each connected component should be processed separately. + */ + public static final IProperty SEPARATE_CONNECTED_COMPONENTS = new Property( + CoreOptions.SEPARATE_CONNECTED_COMPONENTS, + SEPARATE_CONNECTED_COMPONENTS_DEFAULT); + + /** + * Merges multiedges into a single edge and causes partially parallel edges to share part of + * their paths. + */ + public static final IProperty CONCENTRATE = GraphvizMetaDataProvider.CONCENTRATE; + + /** + * Distance of head / tail positioned edge labels to the source or target node. + */ + public static final IProperty LABEL_DISTANCE = GraphvizMetaDataProvider.LABEL_DISTANCE; + + /** + * Angle between head / tail positioned edge labels and the corresponding edge. + */ + public static final IProperty LABEL_ANGLE = GraphvizMetaDataProvider.LABEL_ANGLE; + + /** + * Determines if and how node overlaps should be removed. + */ + public static final IProperty OVERLAP_MODE = GraphvizMetaDataProvider.OVERLAP_MODE; + + /** + * Whether ports should be moved to the point where edges cross the node's bounds. + */ + public static final IProperty ADAPT_PORT_POSITIONS = GraphvizMetaDataProvider.ADAPT_PORT_POSITIONS; + + /** + * Layouter-specific algorithm factory. + */ + public static class CircoFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new GraphvizLayoutProvider(); + provider.initialize("CIRCO"); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.graphviz.circo") + .name("Graphviz Circo") + .description("Circular layout, after Six and Tollis \'99, Kaufmann and Wiese \'02. The algorithm finds biconnected components and arranges each component in a circle, trying to minimize the number of crossings inside the circle. This is suitable for certain diagrams of multiple cyclic structures such as certain telecommunications networks.") + .providerFactory(new CircoFactory()) + .category("org.eclipse.elk.circle") + .melkBundleName("Graphviz") + .definingBundleId("org.eclipse.elk.alg.graphviz.layouter") + .imagePath("images/circo_layout.png") + .supportedFeatures(EnumSet.of(GraphFeature.SELF_LOOPS, GraphFeature.MULTI_EDGES, GraphFeature.EDGE_LABELS)) + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.spacing.edgeLabel", + SPACING_EDGE_LABEL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.edgeRouting", + EDGE_ROUTING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.debugMode", + DEBUG_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.separateConnectedComponents", + SEPARATE_CONNECTED_COMPONENTS_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.graphviz.concentrate", + CONCENTRATE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.graphviz.labelDistance", + LABEL_DISTANCE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.graphviz.labelAngle", + LABEL_ANGLE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.graphviz.overlapMode", + OVERLAP_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.circo", + "org.eclipse.elk.graphviz.adaptPortPositions", + ADAPT_PORT_POSITIONS.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/DotOptions.java b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/DotOptions.java new file mode 100644 index 000000000..507c980af --- /dev/null +++ b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/DotOptions.java @@ -0,0 +1,272 @@ +/** + * Copyright (c) 2015 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.graphviz.layouter; + +import java.util.EnumSet; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.Direction; +import org.eclipse.elk.core.options.EdgeRouting; +import org.eclipse.elk.core.options.HierarchyHandling; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.core.options.SizeOptions; +import org.eclipse.elk.graph.properties.GraphFeature; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class DotOptions implements ILayoutMetaDataProvider { + /** + * The id of the Graphviz Dot algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.graphviz.dot"; + + /** + * Default value for {@link #PADDING} with algorithm "Graphviz Dot". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(10); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #DIRECTION} with algorithm "Graphviz Dot". + */ + private static final Direction DIRECTION_DEFAULT = Direction.DOWN; + + /** + * Overall direction of edges: horizontal (right / left) or + * vertical (down / up). + */ + public static final IProperty DIRECTION = new Property( + CoreOptions.DIRECTION, + DIRECTION_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "Graphviz Dot". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 20; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * The minimal distance to be preserved between a label and the edge it is associated with. + * Note that the placement of a label is influenced by the 'edgelabels.placement' option. + */ + public static final IProperty SPACING_EDGE_LABEL = CoreOptions.SPACING_EDGE_LABEL; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * Default value for {@link #EDGE_ROUTING} with algorithm "Graphviz Dot". + */ + private static final EdgeRouting EDGE_ROUTING_DEFAULT = EdgeRouting.SPLINES; + + /** + * What kind of edge routing style should be applied for the content of a parent node. + * Algorithms may also set this option to single edges in order to mark them as splines. + * The bend point list of edges with this option set to SPLINES must be interpreted as control + * points for a piecewise cubic spline. + */ + public static final IProperty EDGE_ROUTING = new Property( + CoreOptions.EDGE_ROUTING, + EDGE_ROUTING_DEFAULT); + + /** + * Whether additional debug information shall be generated. + */ + public static final IProperty DEBUG_MODE = CoreOptions.DEBUG_MODE; + + /** + * Determines whether separate layout runs are triggered for different compound nodes in a + * hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay + * out that node and all of its descendants in a single layout run, until a descendant is + * encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, + * `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that + * setting. Including multiple levels of hierarchy in a single layout run may allow + * cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` + * (or not set at all), the default behavior is `SEPARATE_CHILDREN`. + *

Algorithm Specific Details

+ * If activated, the whole hierarchical graph is passed to dot as a whole. + * Note however that dot performs a 'compound' layout where it somewhat flattens + * the hierarchy and performs a layout on the flattened graph. + * As a consequence, padding information of hierarchical child nodes is discarded. + */ + public static final IProperty HIERARCHY_HANDLING = CoreOptions.HIERARCHY_HANDLING; + + /** + * Default value for {@link #ITERATIONS_FACTOR} with algorithm "Graphviz Dot". + */ + private static final double ITERATIONS_FACTOR_DEFAULT = 1; + + /** + * Multiplicative scale factor for the maximal number of iterations used during crossing + * minimization, node ranking, and node positioning. + */ + public static final IProperty ITERATIONS_FACTOR = new Property( + GraphvizMetaDataProvider.ITERATIONS_FACTOR, + ITERATIONS_FACTOR_DEFAULT); + + /** + * Merges multiedges into a single edge and causes partially parallel edges to share part of + * their paths. + */ + public static final IProperty CONCENTRATE = GraphvizMetaDataProvider.CONCENTRATE; + + /** + * Distance of head / tail positioned edge labels to the source or target node. + */ + public static final IProperty LABEL_DISTANCE = GraphvizMetaDataProvider.LABEL_DISTANCE; + + /** + * Angle between head / tail positioned edge labels and the corresponding edge. + */ + public static final IProperty LABEL_ANGLE = GraphvizMetaDataProvider.LABEL_ANGLE; + + /** + * Factor for the spacing of different layers (ranks). + */ + public static final IProperty LAYER_SPACING_FACTOR = GraphvizMetaDataProvider.LAYER_SPACING_FACTOR; + + /** + * Whether ports should be moved to the point where edges cross the node's bounds. + */ + public static final IProperty ADAPT_PORT_POSITIONS = GraphvizMetaDataProvider.ADAPT_PORT_POSITIONS; + + /** + * Layouter-specific algorithm factory. + */ + public static class DotFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new GraphvizLayoutProvider(); + provider.initialize("DOT"); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.graphviz.dot") + .name("Graphviz Dot") + .description("Layered drawings of directed graphs. The algorithm aims edges in the same direction (top to bottom, or left to right) and then attempts to avoid edge crossings and reduce edge length. Edges are routed as spline curves and are thus drawn very smoothly. This algorithm is very suitable for state machine and activity diagrams, where the direction of edges has an important role.") + .providerFactory(new DotFactory()) + .category("org.eclipse.elk.layered") + .melkBundleName("Graphviz") + .definingBundleId("org.eclipse.elk.alg.graphviz.layouter") + .imagePath("images/dot_layout.png") + .supportedFeatures(EnumSet.of(GraphFeature.SELF_LOOPS, GraphFeature.MULTI_EDGES, GraphFeature.EDGE_LABELS, GraphFeature.COMPOUND, GraphFeature.CLUSTERS)) + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.direction", + DIRECTION_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.spacing.edgeLabel", + SPACING_EDGE_LABEL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.edgeRouting", + EDGE_ROUTING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.debugMode", + DEBUG_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.hierarchyHandling", + HIERARCHY_HANDLING.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.graphviz.iterationsFactor", + ITERATIONS_FACTOR_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.graphviz.concentrate", + CONCENTRATE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.graphviz.labelDistance", + LABEL_DISTANCE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.graphviz.labelAngle", + LABEL_ANGLE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.graphviz.layerSpacingFactor", + LAYER_SPACING_FACTOR.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.dot", + "org.eclipse.elk.graphviz.adaptPortPositions", + ADAPT_PORT_POSITIONS.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/FdpOptions.java b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/FdpOptions.java new file mode 100644 index 000000000..62784b485 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/FdpOptions.java @@ -0,0 +1,260 @@ +/** + * Copyright (c) 2015 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.graphviz.layouter; + +import java.util.EnumSet; +import org.eclipse.elk.alg.graphviz.dot.transform.OverlapMode; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.EdgeRouting; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.core.options.SizeOptions; +import org.eclipse.elk.graph.properties.GraphFeature; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class FdpOptions implements ILayoutMetaDataProvider { + /** + * The id of the Graphviz FDP algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.graphviz.fdp"; + + /** + * Default value for {@link #PADDING} with algorithm "Graphviz FDP". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(10); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "Graphviz FDP". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 40; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * The minimal distance to be preserved between a label and the edge it is associated with. + * Note that the placement of a label is influenced by the 'edgelabels.placement' option. + */ + public static final IProperty SPACING_EDGE_LABEL = CoreOptions.SPACING_EDGE_LABEL; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * Whether the algorithm should be run in interactive mode for the content of a parent node. + * What this means exactly depends on how the specific algorithm interprets this option. + * Usually in the interactive mode algorithms try to modify the current layout as little as + * possible. + */ + public static final IProperty INTERACTIVE = CoreOptions.INTERACTIVE; + + /** + * Default value for {@link #EDGE_ROUTING} with algorithm "Graphviz FDP". + */ + private static final EdgeRouting EDGE_ROUTING_DEFAULT = EdgeRouting.SPLINES; + + /** + * What kind of edge routing style should be applied for the content of a parent node. + * Algorithms may also set this option to single edges in order to mark them as splines. + * The bend point list of edges with this option set to SPLINES must be interpreted as control + * points for a piecewise cubic spline. + */ + public static final IProperty EDGE_ROUTING = new Property( + CoreOptions.EDGE_ROUTING, + EDGE_ROUTING_DEFAULT); + + /** + * Whether additional debug information shall be generated. + */ + public static final IProperty DEBUG_MODE = CoreOptions.DEBUG_MODE; + + /** + * Default value for {@link #SEPARATE_CONNECTED_COMPONENTS} with algorithm "Graphviz FDP". + */ + private static final boolean SEPARATE_CONNECTED_COMPONENTS_DEFAULT = false; + + /** + * Whether each connected component should be processed separately. + */ + public static final IProperty SEPARATE_CONNECTED_COMPONENTS = new Property( + CoreOptions.SEPARATE_CONNECTED_COMPONENTS, + SEPARATE_CONNECTED_COMPONENTS_DEFAULT); + + /** + * Merges multiedges into a single edge and causes partially parallel edges to share part of + * their paths. + */ + public static final IProperty CONCENTRATE = GraphvizMetaDataProvider.CONCENTRATE; + + /** + * Distance of head / tail positioned edge labels to the source or target node. + */ + public static final IProperty LABEL_DISTANCE = GraphvizMetaDataProvider.LABEL_DISTANCE; + + /** + * Angle between head / tail positioned edge labels and the corresponding edge. + */ + public static final IProperty LABEL_ANGLE = GraphvizMetaDataProvider.LABEL_ANGLE; + + /** + * Default value for {@link #MAXITER} with algorithm "Graphviz FDP". + */ + private static final int MAXITER_DEFAULT = 600; + + /** + * The maximum number of iterations. + */ + public static final IProperty MAXITER = new Property( + GraphvizMetaDataProvider.MAXITER, + MAXITER_DEFAULT); + + /** + * Determines if and how node overlaps should be removed. + */ + public static final IProperty OVERLAP_MODE = GraphvizMetaDataProvider.OVERLAP_MODE; + + /** + * Whether ports should be moved to the point where edges cross the node's bounds. + */ + public static final IProperty ADAPT_PORT_POSITIONS = GraphvizMetaDataProvider.ADAPT_PORT_POSITIONS; + + /** + * Layouter-specific algorithm factory. + */ + public static class FdpFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new GraphvizLayoutProvider(); + provider.initialize("FDP"); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.graphviz.fdp") + .name("Graphviz FDP") + .description("Spring model layouts similar to those of Neato, but does this by reducing forces rather than working with energy. Fdp implements the Fruchterman-Reingold heuristic including a multigrid solver that handles larger graphs and clustered undirected graphs.") + .providerFactory(new FdpFactory()) + .category("org.eclipse.elk.force") + .melkBundleName("Graphviz") + .definingBundleId("org.eclipse.elk.alg.graphviz.layouter") + .imagePath("images/fdp_layout.png") + .supportedFeatures(EnumSet.of(GraphFeature.SELF_LOOPS, GraphFeature.MULTI_EDGES, GraphFeature.EDGE_LABELS, GraphFeature.CLUSTERS)) + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.spacing.edgeLabel", + SPACING_EDGE_LABEL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.interactive", + INTERACTIVE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.edgeRouting", + EDGE_ROUTING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.debugMode", + DEBUG_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.separateConnectedComponents", + SEPARATE_CONNECTED_COMPONENTS_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.graphviz.concentrate", + CONCENTRATE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.graphviz.labelDistance", + LABEL_DISTANCE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.graphviz.labelAngle", + LABEL_ANGLE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.graphviz.maxiter", + MAXITER_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.graphviz.overlapMode", + OVERLAP_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.fdp", + "org.eclipse.elk.graphviz.adaptPortPositions", + ADAPT_PORT_POSITIONS.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/GraphvizMetaDataProvider.java b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/GraphvizMetaDataProvider.java new file mode 100644 index 000000000..c827c6c29 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/GraphvizMetaDataProvider.java @@ -0,0 +1,305 @@ +/** + * Copyright (c) 2015 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.graphviz.layouter; + +import java.util.EnumSet; +import org.eclipse.elk.alg.graphviz.dot.transform.NeatoModel; +import org.eclipse.elk.alg.graphviz.dot.transform.OverlapMode; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.core.util.ExclusiveBounds; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class GraphvizMetaDataProvider implements ILayoutMetaDataProvider { + /** + * Default value for {@link #ADAPT_PORT_POSITIONS}. + */ + private static final boolean ADAPT_PORT_POSITIONS_DEFAULT = true; + + /** + * Whether ports should be moved to the point where edges cross the node's bounds. + */ + public static final IProperty ADAPT_PORT_POSITIONS = new Property( + "org.eclipse.elk.graphviz.adaptPortPositions", + ADAPT_PORT_POSITIONS_DEFAULT, + null, + null); + + /** + * Default value for {@link #CONCENTRATE}. + */ + private static final boolean CONCENTRATE_DEFAULT = false; + + /** + * Merges multiedges into a single edge and causes partially parallel edges to share part of + * their paths. + */ + public static final IProperty CONCENTRATE = new Property( + "org.eclipse.elk.graphviz.concentrate", + CONCENTRATE_DEFAULT, + null, + null); + + /** + * Lower bound value for {@link #EPSILON}. + */ + private static final Comparable EPSILON_LOWER_BOUND = ExclusiveBounds.greaterThan(0); + + /** + * Terminating condition. If the length squared of all energy gradients are less than + * epsilon, the algorithm stops. + */ + public static final IProperty EPSILON = new Property( + "org.eclipse.elk.graphviz.epsilon", + null, + EPSILON_LOWER_BOUND, + null); + + /** + * Lower bound value for {@link #ITERATIONS_FACTOR}. + */ + private static final Comparable ITERATIONS_FACTOR_LOWER_BOUND = ExclusiveBounds.greaterThan(0); + + /** + * Multiplicative scale factor for the maximal number of iterations used during crossing + * minimization, node ranking, and node positioning. + */ + public static final IProperty ITERATIONS_FACTOR = new Property( + "org.eclipse.elk.graphviz.iterationsFactor", + null, + ITERATIONS_FACTOR_LOWER_BOUND, + null); + + /** + * Default value for {@link #LABEL_ANGLE}. + */ + private static final double LABEL_ANGLE_DEFAULT = (-25); + + /** + * Angle between head / tail positioned edge labels and the corresponding edge. + */ + public static final IProperty LABEL_ANGLE = new Property( + "org.eclipse.elk.graphviz.labelAngle", + LABEL_ANGLE_DEFAULT, + null, + null); + + /** + * Default value for {@link #LABEL_DISTANCE}. + */ + private static final double LABEL_DISTANCE_DEFAULT = 1; + + /** + * Lower bound value for {@link #LABEL_DISTANCE}. + */ + private static final Comparable LABEL_DISTANCE_LOWER_BOUND = Double.valueOf(0.0); + + /** + * Distance of head / tail positioned edge labels to the source or target node. + */ + public static final IProperty LABEL_DISTANCE = new Property( + "org.eclipse.elk.graphviz.labelDistance", + LABEL_DISTANCE_DEFAULT, + LABEL_DISTANCE_LOWER_BOUND, + null); + + /** + * Default value for {@link #LAYER_SPACING_FACTOR}. + */ + private static final double LAYER_SPACING_FACTOR_DEFAULT = 1; + + /** + * Lower bound value for {@link #LAYER_SPACING_FACTOR}. + */ + private static final Comparable LAYER_SPACING_FACTOR_LOWER_BOUND = ExclusiveBounds.greaterThan(0); + + /** + * Factor for the spacing of different layers (ranks). + */ + public static final IProperty LAYER_SPACING_FACTOR = new Property( + "org.eclipse.elk.graphviz.layerSpacingFactor", + LAYER_SPACING_FACTOR_DEFAULT, + LAYER_SPACING_FACTOR_LOWER_BOUND, + null); + + /** + * Lower bound value for {@link #MAXITER}. + */ + private static final Comparable MAXITER_LOWER_BOUND = Integer.valueOf(1); + + /** + * The maximum number of iterations. + */ + public static final IProperty MAXITER = new Property( + "org.eclipse.elk.graphviz.maxiter", + null, + MAXITER_LOWER_BOUND, + null); + + /** + * Default value for {@link #NEATO_MODEL}. + */ + private static final NeatoModel NEATO_MODEL_DEFAULT = NeatoModel.SHORTPATH; + + /** + * Specifies how the distance matrix is computed for the input graph. + */ + public static final IProperty NEATO_MODEL = new Property( + "org.eclipse.elk.graphviz.neatoModel", + NEATO_MODEL_DEFAULT, + null, + null); + + /** + * Default value for {@link #OVERLAP_MODE}. + */ + private static final OverlapMode OVERLAP_MODE_DEFAULT = OverlapMode.PRISM; + + /** + * Determines if and how node overlaps should be removed. + */ + public static final IProperty OVERLAP_MODE = new Property( + "org.eclipse.elk.graphviz.overlapMode", + OVERLAP_MODE_DEFAULT, + null, + null); + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.graphviz.adaptPortPositions") + .group("") + .name("Adapt Port Positions") + .description("Whether ports should be moved to the point where edges cross the node\'s bounds.") + .defaultValue(ADAPT_PORT_POSITIONS_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.graphviz.concentrate") + .group("") + .name("Concentrate Edges") + .description("Merges multiedges into a single edge and causes partially parallel edges to share part of their paths.") + .defaultValue(CONCENTRATE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.graphviz.epsilon") + .group("") + .name("Epsilon") + .description("Terminating condition. If the length squared of all energy gradients are less than epsilon, the algorithm stops.") + .lowerBound(EPSILON_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.graphviz.iterationsFactor") + .group("") + .name("Iterations Factor") + .description("Multiplicative scale factor for the maximal number of iterations used during crossing minimization, node ranking, and node positioning.") + .lowerBound(ITERATIONS_FACTOR_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.graphviz.labelAngle") + .group("") + .name("Label Angle") + .description("Angle between head / tail positioned edge labels and the corresponding edge.") + .defaultValue(LABEL_ANGLE_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.graphviz.labelDistance") + .group("") + .name("Label Distance") + .description("Distance of head / tail positioned edge labels to the source or target node.") + .defaultValue(LABEL_DISTANCE_DEFAULT) + .lowerBound(LABEL_DISTANCE_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.graphviz.layerSpacingFactor") + .group("") + .name("Layer Spacing Factor") + .description("Factor for the spacing of different layers (ranks).") + .defaultValue(LAYER_SPACING_FACTOR_DEFAULT) + .lowerBound(LAYER_SPACING_FACTOR_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.graphviz.maxiter") + .group("") + .name("Max. Iterations") + .description("The maximum number of iterations.") + .lowerBound(MAXITER_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.graphviz.neatoModel") + .group("") + .name("Distance Model") + .description("Specifies how the distance matrix is computed for the input graph.") + .defaultValue(NEATO_MODEL_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(NeatoModel.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.graphviz.overlapMode") + .group("") + .name("Overlap Removal") + .description("Determines if and how node overlaps should be removed.") + .defaultValue(OVERLAP_MODE_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(OverlapMode.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + new org.eclipse.elk.alg.graphviz.layouter.DotOptions().apply(registry); + new org.eclipse.elk.alg.graphviz.layouter.NeatoOptions().apply(registry); + new org.eclipse.elk.alg.graphviz.layouter.FdpOptions().apply(registry); + new org.eclipse.elk.alg.graphviz.layouter.TwopiOptions().apply(registry); + new org.eclipse.elk.alg.graphviz.layouter.CircoOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/NeatoOptions.java b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/NeatoOptions.java new file mode 100644 index 000000000..5bbbc7af9 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/NeatoOptions.java @@ -0,0 +1,307 @@ +/** + * Copyright (c) 2015 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.graphviz.layouter; + +import java.util.EnumSet; +import org.eclipse.elk.alg.graphviz.dot.transform.NeatoModel; +import org.eclipse.elk.alg.graphviz.dot.transform.OverlapMode; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.EdgeRouting; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.core.options.SizeOptions; +import org.eclipse.elk.graph.properties.GraphFeature; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class NeatoOptions implements ILayoutMetaDataProvider { + /** + * The id of the Graphviz Neato algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.graphviz.neato"; + + /** + * Default value for {@link #PADDING} with algorithm "Graphviz Neato". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(10); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "Graphviz Neato". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 40; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * The minimal distance to be preserved between a label and the edge it is associated with. + * Note that the placement of a label is influenced by the 'edgelabels.placement' option. + */ + public static final IProperty SPACING_EDGE_LABEL = CoreOptions.SPACING_EDGE_LABEL; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * Default value for {@link #RANDOM_SEED} with algorithm "Graphviz Neato". + */ + private static final int RANDOM_SEED_DEFAULT = 1; + + /** + * Seed used for pseudo-random number generators to control the layout algorithm. If the + * value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time). + */ + public static final IProperty RANDOM_SEED = new Property( + CoreOptions.RANDOM_SEED, + RANDOM_SEED_DEFAULT); + + /** + * Whether the algorithm should be run in interactive mode for the content of a parent node. + * What this means exactly depends on how the specific algorithm interprets this option. + * Usually in the interactive mode algorithms try to modify the current layout as little as + * possible. + */ + public static final IProperty INTERACTIVE = CoreOptions.INTERACTIVE; + + /** + * Default value for {@link #EDGE_ROUTING} with algorithm "Graphviz Neato". + */ + private static final EdgeRouting EDGE_ROUTING_DEFAULT = EdgeRouting.SPLINES; + + /** + * What kind of edge routing style should be applied for the content of a parent node. + * Algorithms may also set this option to single edges in order to mark them as splines. + * The bend point list of edges with this option set to SPLINES must be interpreted as control + * points for a piecewise cubic spline. + */ + public static final IProperty EDGE_ROUTING = new Property( + CoreOptions.EDGE_ROUTING, + EDGE_ROUTING_DEFAULT); + + /** + * Whether additional debug information shall be generated. + */ + public static final IProperty DEBUG_MODE = CoreOptions.DEBUG_MODE; + + /** + * Default value for {@link #SEPARATE_CONNECTED_COMPONENTS} with algorithm "Graphviz Neato". + */ + private static final boolean SEPARATE_CONNECTED_COMPONENTS_DEFAULT = false; + + /** + * Whether each connected component should be processed separately. + */ + public static final IProperty SEPARATE_CONNECTED_COMPONENTS = new Property( + CoreOptions.SEPARATE_CONNECTED_COMPONENTS, + SEPARATE_CONNECTED_COMPONENTS_DEFAULT); + + /** + * Merges multiedges into a single edge and causes partially parallel edges to share part of + * their paths. + */ + public static final IProperty CONCENTRATE = GraphvizMetaDataProvider.CONCENTRATE; + + /** + * Default value for {@link #EPSILON} with algorithm "Graphviz Neato". + */ + private static final double EPSILON_DEFAULT = 0.0001f; + + /** + * Terminating condition. If the length squared of all energy gradients are less than + * epsilon, the algorithm stops. + */ + public static final IProperty EPSILON = new Property( + GraphvizMetaDataProvider.EPSILON, + EPSILON_DEFAULT); + + /** + * Distance of head / tail positioned edge labels to the source or target node. + */ + public static final IProperty LABEL_DISTANCE = GraphvizMetaDataProvider.LABEL_DISTANCE; + + /** + * Angle between head / tail positioned edge labels and the corresponding edge. + */ + public static final IProperty LABEL_ANGLE = GraphvizMetaDataProvider.LABEL_ANGLE; + + /** + * Default value for {@link #MAXITER} with algorithm "Graphviz Neato". + */ + private static final int MAXITER_DEFAULT = 200; + + /** + * The maximum number of iterations. + */ + public static final IProperty MAXITER = new Property( + GraphvizMetaDataProvider.MAXITER, + MAXITER_DEFAULT); + + /** + * Specifies how the distance matrix is computed for the input graph. + */ + public static final IProperty NEATO_MODEL = GraphvizMetaDataProvider.NEATO_MODEL; + + /** + * Determines if and how node overlaps should be removed. + */ + public static final IProperty OVERLAP_MODE = GraphvizMetaDataProvider.OVERLAP_MODE; + + /** + * Whether ports should be moved to the point where edges cross the node's bounds. + */ + public static final IProperty ADAPT_PORT_POSITIONS = GraphvizMetaDataProvider.ADAPT_PORT_POSITIONS; + + /** + * Layouter-specific algorithm factory. + */ + public static class NeatoFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new GraphvizLayoutProvider(); + provider.initialize("NEATO"); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.graphviz.neato") + .name("Graphviz Neato") + .description("Spring model layouts. Neato attempts to minimize a global energy function, which is equivalent to statistical multi-dimensional scaling. The solution is achieved using stress majorization, though the older Kamada-Kawai algorithm, using steepest descent, is also available.") + .providerFactory(new NeatoFactory()) + .category("org.eclipse.elk.force") + .melkBundleName("Graphviz") + .definingBundleId("org.eclipse.elk.alg.graphviz.layouter") + .imagePath("images/neato_layout.png") + .supportedFeatures(EnumSet.of(GraphFeature.SELF_LOOPS, GraphFeature.MULTI_EDGES, GraphFeature.EDGE_LABELS)) + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.spacing.edgeLabel", + SPACING_EDGE_LABEL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.randomSeed", + RANDOM_SEED_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.interactive", + INTERACTIVE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.edgeRouting", + EDGE_ROUTING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.debugMode", + DEBUG_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.separateConnectedComponents", + SEPARATE_CONNECTED_COMPONENTS_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.graphviz.concentrate", + CONCENTRATE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.graphviz.epsilon", + EPSILON_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.graphviz.labelDistance", + LABEL_DISTANCE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.graphviz.labelAngle", + LABEL_ANGLE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.graphviz.maxiter", + MAXITER_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.graphviz.neatoModel", + NEATO_MODEL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.graphviz.overlapMode", + OVERLAP_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.neato", + "org.eclipse.elk.graphviz.adaptPortPositions", + ADAPT_PORT_POSITIONS.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/TwopiOptions.java b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/TwopiOptions.java new file mode 100644 index 000000000..6d018d004 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.graphviz.layouter/src-gen/org/eclipse/elk/alg/graphviz/layouter/TwopiOptions.java @@ -0,0 +1,213 @@ +/** + * Copyright (c) 2015 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.graphviz.layouter; + +import java.util.EnumSet; +import org.eclipse.elk.alg.graphviz.dot.transform.OverlapMode; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.EdgeRouting; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.core.options.SizeOptions; +import org.eclipse.elk.graph.properties.GraphFeature; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class TwopiOptions implements ILayoutMetaDataProvider { + /** + * The id of the Graphviz Twopi algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.graphviz.twopi"; + + /** + * Default value for {@link #PADDING} with algorithm "Graphviz Twopi". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(10); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "Graphviz Twopi". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 60; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * The minimal distance to be preserved between a label and the edge it is associated with. + * Note that the placement of a label is influenced by the 'edgelabels.placement' option. + */ + public static final IProperty SPACING_EDGE_LABEL = CoreOptions.SPACING_EDGE_LABEL; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * Default value for {@link #EDGE_ROUTING} with algorithm "Graphviz Twopi". + */ + private static final EdgeRouting EDGE_ROUTING_DEFAULT = EdgeRouting.SPLINES; + + /** + * What kind of edge routing style should be applied for the content of a parent node. + * Algorithms may also set this option to single edges in order to mark them as splines. + * The bend point list of edges with this option set to SPLINES must be interpreted as control + * points for a piecewise cubic spline. + */ + public static final IProperty EDGE_ROUTING = new Property( + CoreOptions.EDGE_ROUTING, + EDGE_ROUTING_DEFAULT); + + /** + * Whether additional debug information shall be generated. + */ + public static final IProperty DEBUG_MODE = CoreOptions.DEBUG_MODE; + + /** + * Merges multiedges into a single edge and causes partially parallel edges to share part of + * their paths. + */ + public static final IProperty CONCENTRATE = GraphvizMetaDataProvider.CONCENTRATE; + + /** + * Distance of head / tail positioned edge labels to the source or target node. + */ + public static final IProperty LABEL_DISTANCE = GraphvizMetaDataProvider.LABEL_DISTANCE; + + /** + * Angle between head / tail positioned edge labels and the corresponding edge. + */ + public static final IProperty LABEL_ANGLE = GraphvizMetaDataProvider.LABEL_ANGLE; + + /** + * Determines if and how node overlaps should be removed. + */ + public static final IProperty OVERLAP_MODE = GraphvizMetaDataProvider.OVERLAP_MODE; + + /** + * Whether ports should be moved to the point where edges cross the node's bounds. + */ + public static final IProperty ADAPT_PORT_POSITIONS = GraphvizMetaDataProvider.ADAPT_PORT_POSITIONS; + + /** + * Layouter-specific algorithm factory. + */ + public static class TwopiFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new GraphvizLayoutProvider(); + provider.initialize("TWOPI"); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.graphviz.twopi") + .name("Graphviz Twopi") + .description("Radial layouts, after Wills \'97. The nodes are placed on concentric circles depending on their distance from a given root node. The algorithm is designed to handle not only small graphs, but also very large ones.") + .providerFactory(new TwopiFactory()) + .category("org.eclipse.elk.radial") + .melkBundleName("Graphviz") + .definingBundleId("org.eclipse.elk.alg.graphviz.layouter") + .imagePath("images/twopi_layout.png") + .supportedFeatures(EnumSet.of(GraphFeature.SELF_LOOPS, GraphFeature.MULTI_EDGES, GraphFeature.EDGE_LABELS)) + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.spacing.edgeLabel", + SPACING_EDGE_LABEL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.edgeRouting", + EDGE_ROUTING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.debugMode", + DEBUG_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.graphviz.concentrate", + CONCENTRATE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.graphviz.labelDistance", + LABEL_DISTANCE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.graphviz.labelAngle", + LABEL_ANGLE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.graphviz.overlapMode", + OVERLAP_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.graphviz.twopi", + "org.eclipse.elk.graphviz.adaptPortPositions", + ADAPT_PORT_POSITIONS.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.layered/src-gen/org/eclipse/elk/alg/layered/options/LayeredMetaDataProvider.java b/plugins/org.eclipse.elk.alg.layered/src-gen/org/eclipse/elk/alg/layered/options/LayeredMetaDataProvider.java new file mode 100644 index 000000000..69bbbf7a4 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.layered/src-gen/org/eclipse/elk/alg/layered/options/LayeredMetaDataProvider.java @@ -0,0 +1,2615 @@ +/** + * Copyright (c) 2015, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.layered.options; + +import java.util.EnumSet; +import java.util.List; +import org.eclipse.elk.alg.layered.components.ComponentOrderingStrategy; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.core.options.EdgeRouting; +import org.eclipse.elk.core.options.HierarchyHandling; +import org.eclipse.elk.core.util.ExclusiveBounds; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +/** + * Declarations for the ELK Layered layout algorithm. + */ +@SuppressWarnings("all") +public class LayeredMetaDataProvider implements ILayoutMetaDataProvider { + /** + * Default value for {@link #DIRECTION_CONGRUENCY}. + */ + private static final DirectionCongruency DIRECTION_CONGRUENCY_DEFAULT = DirectionCongruency.READING_DIRECTION; + + /** + * Specifies how drawings of the same graph with different layout directions compare to each other: + * either a natural reading direction is preserved or the drawings are rotated versions of each other. + */ + public static final IProperty DIRECTION_CONGRUENCY = new Property( + "org.eclipse.elk.layered.directionCongruency", + DIRECTION_CONGRUENCY_DEFAULT, + null, + null); + + /** + * Default value for {@link #FEEDBACK_EDGES}. + */ + private static final boolean FEEDBACK_EDGES_DEFAULT = false; + + /** + * Whether feedback edges should be highlighted by routing around the nodes. + */ + public static final IProperty FEEDBACK_EDGES = new Property( + "org.eclipse.elk.layered.feedbackEdges", + FEEDBACK_EDGES_DEFAULT, + null, + null); + + /** + * Default value for {@link #INTERACTIVE_REFERENCE_POINT}. + */ + private static final InteractiveReferencePoint INTERACTIVE_REFERENCE_POINT_DEFAULT = InteractiveReferencePoint.CENTER; + + /** + * Determines which point of a node is considered by interactive layout phases. + */ + public static final IProperty INTERACTIVE_REFERENCE_POINT = new Property( + "org.eclipse.elk.layered.interactiveReferencePoint", + INTERACTIVE_REFERENCE_POINT_DEFAULT, + null, + null); + + /** + * Default value for {@link #MERGE_EDGES}. + */ + private static final boolean MERGE_EDGES_DEFAULT = false; + + /** + * Edges that have no ports are merged so they touch the connected nodes at the same points. + * When this option is disabled, one port is created for each edge directly connected to a + * node. When it is enabled, all such incoming edges share an input port, and all outgoing + * edges share an output port. + */ + public static final IProperty MERGE_EDGES = new Property( + "org.eclipse.elk.layered.mergeEdges", + MERGE_EDGES_DEFAULT, + null, + null); + + /** + * Default value for {@link #MERGE_HIERARCHY_EDGES}. + */ + private static final boolean MERGE_HIERARCHY_EDGES_DEFAULT = true; + + /** + * If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports + * as possible. They are broken by the algorithm, with hierarchical ports inserted as + * required. Usually, one such port is created for each edge at each hierarchy crossing point. + * With this option set to true, we try to create as few hierarchical ports as possible in + * the process. In particular, all edges that form a hyperedge can share a port. + */ + public static final IProperty MERGE_HIERARCHY_EDGES = new Property( + "org.eclipse.elk.layered.mergeHierarchyEdges", + MERGE_HIERARCHY_EDGES_DEFAULT, + null, + null); + + /** + * Default value for {@link #ALLOW_NON_FLOW_PORTS_TO_SWITCH_SIDES}. + */ + private static final boolean ALLOW_NON_FLOW_PORTS_TO_SWITCH_SIDES_DEFAULT = false; + + /** + * Specifies whether non-flow ports may switch sides if their node's port constraints are either FIXED_SIDE + * or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. + * For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. + * Further note that the underlying criterium whether to switch sides or not solely relies on the + * minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed. + */ + public static final IProperty ALLOW_NON_FLOW_PORTS_TO_SWITCH_SIDES = new Property( + "org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides", + ALLOW_NON_FLOW_PORTS_TO_SWITCH_SIDES_DEFAULT, + null, + null); + + /** + * Default value for {@link #PORT_SORTING_STRATEGY}. + */ + private static final PortSortingStrategy PORT_SORTING_STRATEGY_DEFAULT = PortSortingStrategy.INPUT_ORDER; + + /** + * Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node's ports are + * distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes. + */ + public static final IProperty PORT_SORTING_STRATEGY = new Property( + "org.eclipse.elk.layered.portSortingStrategy", + PORT_SORTING_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #THOROUGHNESS}. + */ + private static final int THOROUGHNESS_DEFAULT = 7; + + /** + * Lower bound value for {@link #THOROUGHNESS}. + */ + private static final Comparable THOROUGHNESS_LOWER_BOUND = Integer.valueOf(1); + + /** + * How much effort should be spent to produce a nice layout. + */ + public static final IProperty THOROUGHNESS = new Property( + "org.eclipse.elk.layered.thoroughness", + THOROUGHNESS_DEFAULT, + THOROUGHNESS_LOWER_BOUND, + null); + + /** + * Default value for {@link #UNNECESSARY_BENDPOINTS}. + */ + private static final boolean UNNECESSARY_BENDPOINTS_DEFAULT = false; + + /** + * Adds bend points even if an edge does not change direction. If true, each long edge dummy + * will contribute a bend point to its edges and hierarchy-crossing edges will always get a + * bend point where they cross hierarchy boundaries. By default, bend points are only added + * where an edge changes direction. + */ + public static final IProperty UNNECESSARY_BENDPOINTS = new Property( + "org.eclipse.elk.layered.unnecessaryBendpoints", + UNNECESSARY_BENDPOINTS_DEFAULT, + null, + null); + + /** + * Default value for {@link #GENERATE_POSITION_AND_LAYER_IDS}. + */ + private static final boolean GENERATE_POSITION_AND_LAYER_IDS_DEFAULT = false; + + /** + * If enabled position id and layer id are generated, which are usually only used internally + * when setting the interactiveLayout option. This option should be specified on the root node. + */ + public static final IProperty GENERATE_POSITION_AND_LAYER_IDS = new Property( + "org.eclipse.elk.layered.generatePositionAndLayerIds", + GENERATE_POSITION_AND_LAYER_IDS_DEFAULT, + null, + null); + + /** + * Default value for {@link #CYCLE_BREAKING_STRATEGY}. + */ + private static final CycleBreakingStrategy CYCLE_BREAKING_STRATEGY_DEFAULT = CycleBreakingStrategy.GREEDY; + + /** + * Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines + * which edges to reverse to break the cycles. Reversed edges will end up pointing to the + * opposite direction of regular edges (that is, reversed edges will point left if edges + * usually point right). + */ + public static final IProperty CYCLE_BREAKING_STRATEGY = new Property( + "org.eclipse.elk.layered.cycleBreaking.strategy", + CYCLE_BREAKING_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #LAYERING_STRATEGY}. + */ + private static final LayeringStrategy LAYERING_STRATEGY_DEFAULT = LayeringStrategy.NETWORK_SIMPLEX; + + /** + * Strategy for node layering. + */ + public static final IProperty LAYERING_STRATEGY = new Property( + "org.eclipse.elk.layered.layering.strategy", + LAYERING_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #LAYERING_LAYER_CONSTRAINT}. + */ + private static final LayerConstraint LAYERING_LAYER_CONSTRAINT_DEFAULT = LayerConstraint.NONE; + + /** + * Determines a constraint on the placement of the node regarding the layering. + */ + public static final IProperty LAYERING_LAYER_CONSTRAINT = new Property( + "org.eclipse.elk.layered.layering.layerConstraint", + LAYERING_LAYER_CONSTRAINT_DEFAULT, + null, + null); + + /** + * Default value for {@link #LAYERING_LAYER_CHOICE_CONSTRAINT}. + */ + private static final Integer LAYERING_LAYER_CHOICE_CONSTRAINT_DEFAULT = null; + + /** + * Lower bound value for {@link #LAYERING_LAYER_CHOICE_CONSTRAINT}. + */ + private static final Comparable LAYERING_LAYER_CHOICE_CONSTRAINT_LOWER_BOUND = Integer.valueOf((-1)); + + /** + * Allows to set a constraint regarding the layer placement of a node. + * Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. + * If set to i, it expresses that the node should be placed in i-th layer. + * Should i>=n be true then the node is placed in the last layer of the drawing. + * + * Note that this option is not part of any of ELK Layered's default configurations + * but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, + * which must be applied manually or used via the `DiagramLayoutEngine. + */ + public static final IProperty LAYERING_LAYER_CHOICE_CONSTRAINT = new Property( + "org.eclipse.elk.layered.layering.layerChoiceConstraint", + LAYERING_LAYER_CHOICE_CONSTRAINT_DEFAULT, + LAYERING_LAYER_CHOICE_CONSTRAINT_LOWER_BOUND, + null); + + /** + * Default value for {@link #LAYERING_LAYER_ID}. + */ + private static final int LAYERING_LAYER_ID_DEFAULT = (-1); + + /** + * Lower bound value for {@link #LAYERING_LAYER_ID}. + */ + private static final Comparable LAYERING_LAYER_ID_LOWER_BOUND = Integer.valueOf((-1)); + + /** + * Layer identifier that was calculated by ELK Layered for a node. + * This is only generated if interactiveLayot or generatePositionAndLayerIds is set. + */ + public static final IProperty LAYERING_LAYER_ID = new Property( + "org.eclipse.elk.layered.layering.layerId", + LAYERING_LAYER_ID_DEFAULT, + LAYERING_LAYER_ID_LOWER_BOUND, + null); + + /** + * Default value for {@link #LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH}. + */ + private static final int LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH_DEFAULT = 4; + + /** + * Lower bound value for {@link #LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH}. + */ + private static final Comparable LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH_LOWER_BOUND = Integer.valueOf((-1)); + + /** + * Defines a loose upper bound on the width of the MinWidth layerer. + * If set to '-1' multiple values are tested and the best result is selected. + */ + public static final IProperty LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH = new Property( + "org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth", + LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH_DEFAULT, + LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH_LOWER_BOUND, + null); + + /** + * Default value for {@link #LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR}. + */ + private static final int LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR_DEFAULT = 2; + + /** + * Lower bound value for {@link #LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR}. + */ + private static final Comparable LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR_LOWER_BOUND = Integer.valueOf((-1)); + + /** + * Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which + * haven't been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth + * algorithm. Compensates for too high estimations. + * If set to '-1' multiple values are tested and the best result is selected. + */ + public static final IProperty LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR = new Property( + "org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor", + LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR_DEFAULT, + LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR_LOWER_BOUND, + null); + + /** + * Default value for {@link #LAYERING_NODE_PROMOTION_STRATEGY}. + */ + private static final NodePromotionStrategy LAYERING_NODE_PROMOTION_STRATEGY_DEFAULT = NodePromotionStrategy.NONE; + + /** + * Reduces number of dummy nodes after layering phase (if possible). + */ + public static final IProperty LAYERING_NODE_PROMOTION_STRATEGY = new Property( + "org.eclipse.elk.layered.layering.nodePromotion.strategy", + LAYERING_NODE_PROMOTION_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #LAYERING_NODE_PROMOTION_MAX_ITERATIONS}. + */ + private static final int LAYERING_NODE_PROMOTION_MAX_ITERATIONS_DEFAULT = 0; + + /** + * Lower bound value for {@link #LAYERING_NODE_PROMOTION_MAX_ITERATIONS}. + */ + private static final Comparable LAYERING_NODE_PROMOTION_MAX_ITERATIONS_LOWER_BOUND = Integer.valueOf(0); + + /** + * Limits the number of iterations for node promotion. + */ + public static final IProperty LAYERING_NODE_PROMOTION_MAX_ITERATIONS = new Property( + "org.eclipse.elk.layered.layering.nodePromotion.maxIterations", + LAYERING_NODE_PROMOTION_MAX_ITERATIONS_DEFAULT, + LAYERING_NODE_PROMOTION_MAX_ITERATIONS_LOWER_BOUND, + null); + + /** + * Default value for {@link #LAYERING_COFFMAN_GRAHAM_LAYER_BOUND}. + */ + private static final int LAYERING_COFFMAN_GRAHAM_LAYER_BOUND_DEFAULT = Integer.MAX_VALUE; + + /** + * The maximum number of nodes allowed per layer. + */ + public static final IProperty LAYERING_COFFMAN_GRAHAM_LAYER_BOUND = new Property( + "org.eclipse.elk.layered.layering.coffmanGraham.layerBound", + LAYERING_COFFMAN_GRAHAM_LAYER_BOUND_DEFAULT, + null, + null); + + /** + * Default value for {@link #CROSSING_MINIMIZATION_STRATEGY}. + */ + private static final CrossingMinimizationStrategy CROSSING_MINIMIZATION_STRATEGY_DEFAULT = CrossingMinimizationStrategy.LAYER_SWEEP; + + /** + * Strategy for crossing minimization. + */ + public static final IProperty CROSSING_MINIMIZATION_STRATEGY = new Property( + "org.eclipse.elk.layered.crossingMinimization.strategy", + CROSSING_MINIMIZATION_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #CROSSING_MINIMIZATION_FORCE_NODE_MODEL_ORDER}. + */ + private static final boolean CROSSING_MINIMIZATION_FORCE_NODE_MODEL_ORDER_DEFAULT = false; + + /** + * The node order given by the model does not change to produce a better layout. E.g. if node A + * is before node B in the model this is not changed during crossing minimization. This assumes that the + * node model order is already respected before crossing minimization. This can be achieved by setting + * considerModelOrder.strategy to NODES_AND_EDGES. + */ + public static final IProperty CROSSING_MINIMIZATION_FORCE_NODE_MODEL_ORDER = new Property( + "org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder", + CROSSING_MINIMIZATION_FORCE_NODE_MODEL_ORDER_DEFAULT, + null, + null); + + /** + * Default value for {@link #CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS}. + */ + private static final double CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS_DEFAULT = 0.1; + + /** + * How likely it is to use cross-hierarchy (1) vs bottom-up (-1). + */ + public static final IProperty CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS = new Property( + "org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness", + CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS_DEFAULT, + null, + null); + + /** + * Default value for {@link #CROSSING_MINIMIZATION_SEMI_INTERACTIVE}. + */ + private static final boolean CROSSING_MINIMIZATION_SEMI_INTERACTIVE_DEFAULT = false; + + /** + * Preserves the order of nodes within a layer but still minimizes crossings between edges connecting + * long edge dummies. Derives the desired order from positions specified by the 'org.eclipse.elk.position' + * layout option. Requires a crossing minimization strategy that is able to process 'in-layer' constraints. + */ + public static final IProperty CROSSING_MINIMIZATION_SEMI_INTERACTIVE = new Property( + "org.eclipse.elk.layered.crossingMinimization.semiInteractive", + CROSSING_MINIMIZATION_SEMI_INTERACTIVE_DEFAULT, + null, + null); + + /** + * Default value for {@link #CROSSING_MINIMIZATION_IN_LAYER_PRED_OF}. + */ + private static final String CROSSING_MINIMIZATION_IN_LAYER_PRED_OF_DEFAULT = null; + + /** + * Allows to set a constraint which specifies of which node + * the current node is the predecessor. + * If set to 's' then the node is the predecessor of 's' and is in the same layer + */ + public static final IProperty CROSSING_MINIMIZATION_IN_LAYER_PRED_OF = new Property( + "org.eclipse.elk.layered.crossingMinimization.inLayerPredOf", + CROSSING_MINIMIZATION_IN_LAYER_PRED_OF_DEFAULT, + null, + null); + + /** + * Default value for {@link #CROSSING_MINIMIZATION_IN_LAYER_SUCC_OF}. + */ + private static final String CROSSING_MINIMIZATION_IN_LAYER_SUCC_OF_DEFAULT = null; + + /** + * Allows to set a constraint which specifies of which node + * the current node is the successor. + * If set to 's' then the node is the successor of 's' and is in the same layer + */ + public static final IProperty CROSSING_MINIMIZATION_IN_LAYER_SUCC_OF = new Property( + "org.eclipse.elk.layered.crossingMinimization.inLayerSuccOf", + CROSSING_MINIMIZATION_IN_LAYER_SUCC_OF_DEFAULT, + null, + null); + + /** + * Default value for {@link #CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT}. + */ + private static final Integer CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT_DEFAULT = null; + + /** + * Lower bound value for {@link #CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT}. + */ + private static final Comparable CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT_LOWER_BOUND = Integer.valueOf((-1)); + + /** + * Allows to set a constraint regarding the position placement of a node in a layer. + * Assumed the layer in which the node placed includes n other nodes and i < n. + * If set to i, it expresses that the node should be placed at the i-th position. + * Should i>=n be true then the node is placed at the last position in the layer. + * + * Note that this option is not part of any of ELK Layered's default configurations + * but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, + * which must be applied manually or used via the `DiagramLayoutEngine. + */ + public static final IProperty CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT = new Property( + "org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint", + CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT_DEFAULT, + CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT_LOWER_BOUND, + null); + + /** + * Default value for {@link #CROSSING_MINIMIZATION_POSITION_ID}. + */ + private static final int CROSSING_MINIMIZATION_POSITION_ID_DEFAULT = (-1); + + /** + * Lower bound value for {@link #CROSSING_MINIMIZATION_POSITION_ID}. + */ + private static final Comparable CROSSING_MINIMIZATION_POSITION_ID_LOWER_BOUND = Integer.valueOf((-1)); + + /** + * Position within a layer that was determined by ELK Layered for a node. + * This is only generated if interactiveLayot or generatePositionAndLayerIds is set. + */ + public static final IProperty CROSSING_MINIMIZATION_POSITION_ID = new Property( + "org.eclipse.elk.layered.crossingMinimization.positionId", + CROSSING_MINIMIZATION_POSITION_ID_DEFAULT, + CROSSING_MINIMIZATION_POSITION_ID_LOWER_BOUND, + null); + + /** + * Default value for {@link #CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD}. + */ + private static final int CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD_DEFAULT = 40; + + /** + * Lower bound value for {@link #CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD}. + */ + private static final Comparable CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD_LOWER_BOUND = Integer.valueOf(0); + + /** + * By default it is decided automatically if the greedy switch is activated or not. + * The decision is based on whether the size of the input graph (without dummy nodes) + * is smaller than the value of this option. A '0' enforces the activation. + */ + public static final IProperty CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD = new Property( + "org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold", + CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD_DEFAULT, + CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD_LOWER_BOUND, + null); + + /** + * Default value for {@link #CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE}. + */ + private static final GreedySwitchType CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE_DEFAULT = GreedySwitchType.TWO_SIDED; + + /** + * Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed + * after the regular crossing minimization as a post-processor. + * Note that if 'hierarchyHandling' is set to 'INCLUDE_CHILDREN', the 'greedySwitchHierarchical.type' + * option must be used. + */ + public static final IProperty CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE = new Property( + "org.eclipse.elk.layered.crossingMinimization.greedySwitch.type", + CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE_DEFAULT, + null, + null); + + /** + * Default value for {@link #CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE}. + */ + private static final GreedySwitchType CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE_DEFAULT = GreedySwitchType.OFF; + + /** + * Activates the greedy switch heuristic in case hierarchical layout is used. + * The differences to the non-hierarchical case (see 'greedySwitch.type') are: + * 1) greedy switch is inactive by default, + * 3) only the option value set on the node at which hierarchical layout starts is relevant, and + * 2) if it's activated by the user, it properly addresses hierarchy-crossing edges. + */ + public static final IProperty CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE = new Property( + "org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type", + CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE_DEFAULT, + null, + null); + + /** + * Default value for {@link #NODE_PLACEMENT_STRATEGY}. + */ + private static final NodePlacementStrategy NODE_PLACEMENT_STRATEGY_DEFAULT = NodePlacementStrategy.BRANDES_KOEPF; + + /** + * Strategy for node placement. + */ + public static final IProperty NODE_PLACEMENT_STRATEGY = new Property( + "org.eclipse.elk.layered.nodePlacement.strategy", + NODE_PLACEMENT_STRATEGY_DEFAULT, + null, + null); + + /** + * Favor straight edges over a balanced node placement. + * The default behavior is determined automatically based on the used 'edgeRouting'. + * For an orthogonal style it is set to true, for all other styles to false. + */ + public static final IProperty NODE_PLACEMENT_FAVOR_STRAIGHT_EDGES = new Property( + "org.eclipse.elk.layered.nodePlacement.favorStraightEdges"); + + /** + * Default value for {@link #NODE_PLACEMENT_BK_EDGE_STRAIGHTENING}. + */ + private static final EdgeStraighteningStrategy NODE_PLACEMENT_BK_EDGE_STRAIGHTENING_DEFAULT = EdgeStraighteningStrategy.IMPROVE_STRAIGHTNESS; + + /** + * Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges + * at the expense of diagram size. + * There is a subtle difference to the 'favorStraightEdges' option, which decides whether + * a balanced placement of the nodes is desired, or not. In bk terms this means combining the four + * alignments into a single balanced one, or not. This option on the other hand tries to straighten + * additional edges during the creation of each of the four alignments. + */ + public static final IProperty NODE_PLACEMENT_BK_EDGE_STRAIGHTENING = new Property( + "org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening", + NODE_PLACEMENT_BK_EDGE_STRAIGHTENING_DEFAULT, + null, + null); + + /** + * Default value for {@link #NODE_PLACEMENT_BK_FIXED_ALIGNMENT}. + */ + private static final FixedAlignment NODE_PLACEMENT_BK_FIXED_ALIGNMENT_DEFAULT = FixedAlignment.NONE; + + /** + * Tells the BK node placer to use a certain alignment (out of its four) instead of the + * one producing the smallest height, or the combination of all four. + */ + public static final IProperty NODE_PLACEMENT_BK_FIXED_ALIGNMENT = new Property( + "org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment", + NODE_PLACEMENT_BK_FIXED_ALIGNMENT_DEFAULT, + null, + null); + + /** + * Default value for {@link #NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING}. + */ + private static final double NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING_DEFAULT = 0.3; + + /** + * Lower bound value for {@link #NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING}. + */ + private static final Comparable NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING_LOWER_BOUND = ExclusiveBounds.greaterThan(0); + + /** + * Dampens the movement of nodes to keep the diagram from getting too large. + */ + public static final IProperty NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING = new Property( + "org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening", + NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING_DEFAULT, + NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING_LOWER_BOUND, + null); + + /** + * Aims at shorter and straighter edges. Two configurations are possible: + * (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), + * (b) additionally allow to enlarge a node wherever it helps. + * If this option is not configured for a node, the 'nodeFlexibility.default' value is used, + * which is specified for the node's parent. + */ + public static final IProperty NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY = new Property( + "org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility"); + + /** + * Default value for {@link #NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEFAULT}. + */ + private static final NodeFlexibility NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEFAULT_DEFAULT = NodeFlexibility.NONE; + + /** + * Default value of the 'nodeFlexibility' option for the children of a hierarchical node. + */ + public static final IProperty NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEFAULT = new Property( + "org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default", + NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEFAULT_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_ROUTING_SELF_LOOP_DISTRIBUTION}. + */ + private static final SelfLoopDistributionStrategy EDGE_ROUTING_SELF_LOOP_DISTRIBUTION_DEFAULT = SelfLoopDistributionStrategy.NORTH; + + /** + * Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE. + */ + public static final IProperty EDGE_ROUTING_SELF_LOOP_DISTRIBUTION = new Property( + "org.eclipse.elk.layered.edgeRouting.selfLoopDistribution", + EDGE_ROUTING_SELF_LOOP_DISTRIBUTION_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_ROUTING_SELF_LOOP_ORDERING}. + */ + private static final SelfLoopOrderingStrategy EDGE_ROUTING_SELF_LOOP_ORDERING_DEFAULT = SelfLoopOrderingStrategy.STACKED; + + /** + * Alter the ordering of the loops they can either be stacked or sequenced. + * It only takes effect for PortConstraints.FREE. + */ + public static final IProperty EDGE_ROUTING_SELF_LOOP_ORDERING = new Property( + "org.eclipse.elk.layered.edgeRouting.selfLoopOrdering", + EDGE_ROUTING_SELF_LOOP_ORDERING_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_ROUTING_SPLINES_MODE}. + */ + private static final SplineRoutingMode EDGE_ROUTING_SPLINES_MODE_DEFAULT = SplineRoutingMode.SLOPPY; + + /** + * Specifies the way control points are assembled for each individual edge. + * CONSERVATIVE ensures that edges are properly routed around the nodes + * but feels rather orthogonal at times. + * SLOPPY uses fewer control points to obtain curvier edge routes but may result in + * edges overlapping nodes. + */ + public static final IProperty EDGE_ROUTING_SPLINES_MODE = new Property( + "org.eclipse.elk.layered.edgeRouting.splines.mode", + EDGE_ROUTING_SPLINES_MODE_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR}. + */ + private static final double EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR_DEFAULT = 0.2; + + /** + * Spacing factor for routing area between layers when using sloppy spline routing. + */ + public static final IProperty EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR = new Property( + "org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor", + EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_ROUTING_POLYLINE_SLOPED_EDGE_ZONE_WIDTH}. + */ + private static final double EDGE_ROUTING_POLYLINE_SLOPED_EDGE_ZONE_WIDTH_DEFAULT = 2.0; + + /** + * Width of the strip to the left and to the right of each layer where the polyline edge router + * is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward + * bend points for nodes that extent almost to the edge of their layer. + */ + public static final IProperty EDGE_ROUTING_POLYLINE_SLOPED_EDGE_ZONE_WIDTH = new Property( + "org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth", + EDGE_ROUTING_POLYLINE_SLOPED_EDGE_ZONE_WIDTH_DEFAULT, + null, + null); + + /** + * Lower bound value for {@link #SPACING_BASE_VALUE}. + */ + private static final Comparable SPACING_BASE_VALUE_LOWER_BOUND = Double.valueOf(0.0); + + /** + * An optional base value for all other layout options of the 'spacing' group. It can be used to conveniently + * alter the overall 'spaciousness' of the drawing. Whenever an explicit value is set for the other layout + * options, this base value will have no effect. The base value is not inherited, i.e. it must be set for + * each hierarchical node. + */ + public static final IProperty SPACING_BASE_VALUE = new Property( + "org.eclipse.elk.layered.spacing.baseValue", + null, + SPACING_BASE_VALUE_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_EDGE_NODE_BETWEEN_LAYERS}. + */ + private static final double SPACING_EDGE_NODE_BETWEEN_LAYERS_DEFAULT = 10; + + /** + * Lower bound value for {@link #SPACING_EDGE_NODE_BETWEEN_LAYERS}. + */ + private static final Comparable SPACING_EDGE_NODE_BETWEEN_LAYERS_LOWER_BOUND = Double.valueOf(0.0); + + /** + * The spacing to be preserved between nodes and edges that are routed next to the node's layer. + * For the spacing between nodes and edges that cross the node's layer 'spacing.edgeNode' is used. + */ + public static final IProperty SPACING_EDGE_NODE_BETWEEN_LAYERS = new Property( + "org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers", + SPACING_EDGE_NODE_BETWEEN_LAYERS_DEFAULT, + SPACING_EDGE_NODE_BETWEEN_LAYERS_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_EDGE_EDGE_BETWEEN_LAYERS}. + */ + private static final double SPACING_EDGE_EDGE_BETWEEN_LAYERS_DEFAULT = 10; + + /** + * Lower bound value for {@link #SPACING_EDGE_EDGE_BETWEEN_LAYERS}. + */ + private static final Comparable SPACING_EDGE_EDGE_BETWEEN_LAYERS_LOWER_BOUND = Double.valueOf(0.0); + + /** + * Spacing to be preserved between pairs of edges that are routed between the same pair of layers. + * Note that 'spacing.edgeEdge' is used for the spacing between pairs of edges crossing the same layer. + */ + public static final IProperty SPACING_EDGE_EDGE_BETWEEN_LAYERS = new Property( + "org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers", + SPACING_EDGE_EDGE_BETWEEN_LAYERS_DEFAULT, + SPACING_EDGE_EDGE_BETWEEN_LAYERS_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_NODE_NODE_BETWEEN_LAYERS}. + */ + private static final double SPACING_NODE_NODE_BETWEEN_LAYERS_DEFAULT = 20; + + /** + * Lower bound value for {@link #SPACING_NODE_NODE_BETWEEN_LAYERS}. + */ + private static final Comparable SPACING_NODE_NODE_BETWEEN_LAYERS_LOWER_BOUND = Double.valueOf(0.0); + + /** + * The spacing to be preserved between any pair of nodes of two adjacent layers. + * Note that 'spacing.nodeNode' is used for the spacing between nodes within the layer itself. + */ + public static final IProperty SPACING_NODE_NODE_BETWEEN_LAYERS = new Property( + "org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers", + SPACING_NODE_NODE_BETWEEN_LAYERS_DEFAULT, + SPACING_NODE_NODE_BETWEEN_LAYERS_LOWER_BOUND, + null); + + /** + * Default value for {@link #PRIORITY_DIRECTION}. + */ + private static final int PRIORITY_DIRECTION_DEFAULT = 0; + + /** + * Lower bound value for {@link #PRIORITY_DIRECTION}. + */ + private static final Comparable PRIORITY_DIRECTION_LOWER_BOUND = Integer.valueOf(0); + + /** + * Defines how important it is to have a certain edge point into the direction of the overall layout. + * This option is evaluated during the cycle breaking phase. + */ + public static final IProperty PRIORITY_DIRECTION = new Property( + "org.eclipse.elk.layered.priority.direction", + PRIORITY_DIRECTION_DEFAULT, + PRIORITY_DIRECTION_LOWER_BOUND, + null); + + /** + * Default value for {@link #PRIORITY_SHORTNESS}. + */ + private static final int PRIORITY_SHORTNESS_DEFAULT = 0; + + /** + * Lower bound value for {@link #PRIORITY_SHORTNESS}. + */ + private static final Comparable PRIORITY_SHORTNESS_LOWER_BOUND = Integer.valueOf(0); + + /** + * Defines how important it is to keep an edge as short as possible. + * This option is evaluated during the layering phase. + */ + public static final IProperty PRIORITY_SHORTNESS = new Property( + "org.eclipse.elk.layered.priority.shortness", + PRIORITY_SHORTNESS_DEFAULT, + PRIORITY_SHORTNESS_LOWER_BOUND, + null); + + /** + * Default value for {@link #PRIORITY_STRAIGHTNESS}. + */ + private static final int PRIORITY_STRAIGHTNESS_DEFAULT = 0; + + /** + * Lower bound value for {@link #PRIORITY_STRAIGHTNESS}. + */ + private static final Comparable PRIORITY_STRAIGHTNESS_LOWER_BOUND = Integer.valueOf(0); + + /** + * Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. + * This option is evaluated during node placement. + */ + public static final IProperty PRIORITY_STRAIGHTNESS = new Property( + "org.eclipse.elk.layered.priority.straightness", + PRIORITY_STRAIGHTNESS_DEFAULT, + PRIORITY_STRAIGHTNESS_LOWER_BOUND, + null); + + /** + * Default value for {@link #COMPACTION_CONNECTED_COMPONENTS}. + */ + private static final boolean COMPACTION_CONNECTED_COMPONENTS_DEFAULT = false; + + /** + * Tries to further compact components (disconnected sub-graphs). + */ + public static final IProperty COMPACTION_CONNECTED_COMPONENTS = new Property( + "org.eclipse.elk.layered.compaction.connectedComponents", + COMPACTION_CONNECTED_COMPONENTS_DEFAULT, + null, + null); + + /** + * Default value for {@link #COMPACTION_POST_COMPACTION_STRATEGY}. + */ + private static final GraphCompactionStrategy COMPACTION_POST_COMPACTION_STRATEGY_DEFAULT = GraphCompactionStrategy.NONE; + + /** + * Specifies whether and how post-process compaction is applied. + */ + public static final IProperty COMPACTION_POST_COMPACTION_STRATEGY = new Property( + "org.eclipse.elk.layered.compaction.postCompaction.strategy", + COMPACTION_POST_COMPACTION_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #COMPACTION_POST_COMPACTION_CONSTRAINTS}. + */ + private static final ConstraintCalculationStrategy COMPACTION_POST_COMPACTION_CONSTRAINTS_DEFAULT = ConstraintCalculationStrategy.SCANLINE; + + /** + * Specifies whether and how post-process compaction is applied. + */ + public static final IProperty COMPACTION_POST_COMPACTION_CONSTRAINTS = new Property( + "org.eclipse.elk.layered.compaction.postCompaction.constraints", + COMPACTION_POST_COMPACTION_CONSTRAINTS_DEFAULT, + null, + null); + + /** + * Default value for {@link #HIGH_DEGREE_NODES_TREATMENT}. + */ + private static final boolean HIGH_DEGREE_NODES_TREATMENT_DEFAULT = false; + + /** + * Makes room around high degree nodes to place leafs and trees. + */ + public static final IProperty HIGH_DEGREE_NODES_TREATMENT = new Property( + "org.eclipse.elk.layered.highDegreeNodes.treatment", + HIGH_DEGREE_NODES_TREATMENT_DEFAULT, + null, + null); + + /** + * Default value for {@link #HIGH_DEGREE_NODES_THRESHOLD}. + */ + private static final int HIGH_DEGREE_NODES_THRESHOLD_DEFAULT = 16; + + /** + * Lower bound value for {@link #HIGH_DEGREE_NODES_THRESHOLD}. + */ + private static final Comparable HIGH_DEGREE_NODES_THRESHOLD_LOWER_BOUND = Integer.valueOf(0); + + /** + * Whether a node is considered to have a high degree. + */ + public static final IProperty HIGH_DEGREE_NODES_THRESHOLD = new Property( + "org.eclipse.elk.layered.highDegreeNodes.threshold", + HIGH_DEGREE_NODES_THRESHOLD_DEFAULT, + HIGH_DEGREE_NODES_THRESHOLD_LOWER_BOUND, + null); + + /** + * Default value for {@link #HIGH_DEGREE_NODES_TREE_HEIGHT}. + */ + private static final int HIGH_DEGREE_NODES_TREE_HEIGHT_DEFAULT = 5; + + /** + * Lower bound value for {@link #HIGH_DEGREE_NODES_TREE_HEIGHT}. + */ + private static final Comparable HIGH_DEGREE_NODES_TREE_HEIGHT_LOWER_BOUND = Integer.valueOf(0); + + /** + * Maximum height of a subtree connected to a high degree node to be moved to separate layers. + */ + public static final IProperty HIGH_DEGREE_NODES_TREE_HEIGHT = new Property( + "org.eclipse.elk.layered.highDegreeNodes.treeHeight", + HIGH_DEGREE_NODES_TREE_HEIGHT_DEFAULT, + HIGH_DEGREE_NODES_TREE_HEIGHT_LOWER_BOUND, + null); + + /** + * Default value for {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_STRATEGY_DEFAULT = WrappingStrategy.OFF; + + /** + * For certain graphs and certain prescribed drawing areas it may be desirable to + * split the laid out graph into chunks that are placed side by side. + * The edges that connect different chunks are 'wrapped' around from the end of + * one chunk to the start of the other chunk. + * The points between the chunks are referred to as 'cuts'. + */ + public static final IProperty WRAPPING_STRATEGY = new Property( + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #WRAPPING_ADDITIONAL_EDGE_SPACING}. + */ + private static final double WRAPPING_ADDITIONAL_EDGE_SPACING_DEFAULT = 10; + + /** + * To visually separate edges that are wrapped from regularly routed edges an additional spacing value + * can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing. + */ + public static final IProperty WRAPPING_ADDITIONAL_EDGE_SPACING = new Property( + "org.eclipse.elk.layered.wrapping.additionalEdgeSpacing", + WRAPPING_ADDITIONAL_EDGE_SPACING_DEFAULT, + null, + null); + + /** + * Default value for {@link #WRAPPING_CORRECTION_FACTOR}. + */ + private static final double WRAPPING_CORRECTION_FACTOR_DEFAULT = 1.0; + + /** + * At times and for certain types of graphs the executed wrapping may produce results that + * are consistently biased in the same fashion: either wrapping to often or to rarely. + * This factor can be used to correct the bias. Internally, it is simply multiplied with + * the 'aspect ratio' layout option. + */ + public static final IProperty WRAPPING_CORRECTION_FACTOR = new Property( + "org.eclipse.elk.layered.wrapping.correctionFactor", + WRAPPING_CORRECTION_FACTOR_DEFAULT, + null, + null); + + /** + * Default value for {@link #WRAPPING_CUTTING_STRATEGY}. + */ + private static final CuttingStrategy WRAPPING_CUTTING_STRATEGY_DEFAULT = CuttingStrategy.MSD; + + /** + * The strategy by which the layer indexes are determined at which the layering crumbles into chunks. + */ + public static final IProperty WRAPPING_CUTTING_STRATEGY = new Property( + "org.eclipse.elk.layered.wrapping.cutting.strategy", + WRAPPING_CUTTING_STRATEGY_DEFAULT, + null, + null); + + /** + * Allows the user to specify her own cuts for a certain graph. + */ + public static final IProperty> WRAPPING_CUTTING_CUTS = new Property>( + "org.eclipse.elk.layered.wrapping.cutting.cuts"); + + /** + * Default value for {@link #WRAPPING_CUTTING_MSD_FREEDOM}. + */ + private static final Integer WRAPPING_CUTTING_MSD_FREEDOM_DEFAULT = Integer.valueOf(1); + + /** + * Lower bound value for {@link #WRAPPING_CUTTING_MSD_FREEDOM}. + */ + private static final Comparable WRAPPING_CUTTING_MSD_FREEDOM_LOWER_BOUND = Integer.valueOf(0); + + /** + * The MSD cutting strategy starts with an initial guess on the number of chunks the graph + * should be split into. The freedom specifies how much the strategy may deviate from this guess. + * E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts. + */ + public static final IProperty WRAPPING_CUTTING_MSD_FREEDOM = new Property( + "org.eclipse.elk.layered.wrapping.cutting.msd.freedom", + WRAPPING_CUTTING_MSD_FREEDOM_DEFAULT, + WRAPPING_CUTTING_MSD_FREEDOM_LOWER_BOUND, + null); + + /** + * Default value for {@link #WRAPPING_VALIDIFY_STRATEGY}. + */ + private static final ValidifyStrategy WRAPPING_VALIDIFY_STRATEGY_DEFAULT = ValidifyStrategy.GREEDY; + + /** + * When wrapping graphs, one can specify indices that are not allowed as split points. + * The validification strategy makes sure every computed split point is allowed. + */ + public static final IProperty WRAPPING_VALIDIFY_STRATEGY = new Property( + "org.eclipse.elk.layered.wrapping.validify.strategy", + WRAPPING_VALIDIFY_STRATEGY_DEFAULT, + null, + null); + + public static final IProperty> WRAPPING_VALIDIFY_FORBIDDEN_INDICES = new Property>( + "org.eclipse.elk.layered.wrapping.validify.forbiddenIndices"); + + /** + * Default value for {@link #WRAPPING_MULTI_EDGE_IMPROVE_CUTS}. + */ + private static final boolean WRAPPING_MULTI_EDGE_IMPROVE_CUTS_DEFAULT = true; + + /** + * For general graphs it is important that not too many edges wrap backwards. + * Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought. + */ + public static final IProperty WRAPPING_MULTI_EDGE_IMPROVE_CUTS = new Property( + "org.eclipse.elk.layered.wrapping.multiEdge.improveCuts", + WRAPPING_MULTI_EDGE_IMPROVE_CUTS_DEFAULT, + null, + null); + + /** + * Default value for {@link #WRAPPING_MULTI_EDGE_DISTANCE_PENALTY}. + */ + private static final double WRAPPING_MULTI_EDGE_DISTANCE_PENALTY_DEFAULT = 2.0; + + public static final IProperty WRAPPING_MULTI_EDGE_DISTANCE_PENALTY = new Property( + "org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty", + WRAPPING_MULTI_EDGE_DISTANCE_PENALTY_DEFAULT, + null, + null); + + /** + * Default value for {@link #WRAPPING_MULTI_EDGE_IMPROVE_WRAPPED_EDGES}. + */ + private static final boolean WRAPPING_MULTI_EDGE_IMPROVE_WRAPPED_EDGES_DEFAULT = true; + + /** + * The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from + * one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges. + */ + public static final IProperty WRAPPING_MULTI_EDGE_IMPROVE_WRAPPED_EDGES = new Property( + "org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges", + WRAPPING_MULTI_EDGE_IMPROVE_WRAPPED_EDGES_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_LABELS_SIDE_SELECTION}. + */ + private static final EdgeLabelSideSelection EDGE_LABELS_SIDE_SELECTION_DEFAULT = EdgeLabelSideSelection.SMART_DOWN; + + /** + * Method to decide on edge label sides. + */ + public static final IProperty EDGE_LABELS_SIDE_SELECTION = new Property( + "org.eclipse.elk.layered.edgeLabels.sideSelection", + EDGE_LABELS_SIDE_SELECTION_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_LABELS_CENTER_LABEL_PLACEMENT_STRATEGY}. + */ + private static final CenterEdgeLabelPlacementStrategy EDGE_LABELS_CENTER_LABEL_PLACEMENT_STRATEGY_DEFAULT = CenterEdgeLabelPlacementStrategy.MEDIAN_LAYER; + + /** + * Determines in which layer center labels of long edges should be placed. + */ + public static final IProperty EDGE_LABELS_CENTER_LABEL_PLACEMENT_STRATEGY = new Property( + "org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy", + EDGE_LABELS_CENTER_LABEL_PLACEMENT_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #CONSIDER_MODEL_ORDER_STRATEGY}. + */ + private static final OrderingStrategy CONSIDER_MODEL_ORDER_STRATEGY_DEFAULT = OrderingStrategy.NONE; + + /** + * Preserves the order of nodes and edges in the model file if this does not lead to additional edge + * crossings. Depending on the strategy this is not always possible since the node and edge order might be + * conflicting. + */ + public static final IProperty CONSIDER_MODEL_ORDER_STRATEGY = new Property( + "org.eclipse.elk.layered.considerModelOrder.strategy", + CONSIDER_MODEL_ORDER_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #CONSIDER_MODEL_ORDER_PORT_MODEL_ORDER}. + */ + private static final boolean CONSIDER_MODEL_ORDER_PORT_MODEL_ORDER_DEFAULT = false; + + /** + * If disabled the port order of output ports is derived from the edge order and input ports are ordered by + * their incoming connections. If enabled all ports are ordered by the port model order. + */ + public static final IProperty CONSIDER_MODEL_ORDER_PORT_MODEL_ORDER = new Property( + "org.eclipse.elk.layered.considerModelOrder.portModelOrder", + CONSIDER_MODEL_ORDER_PORT_MODEL_ORDER_DEFAULT, + null, + null); + + /** + * Default value for {@link #CONSIDER_MODEL_ORDER_NO_MODEL_ORDER}. + */ + private static final boolean CONSIDER_MODEL_ORDER_NO_MODEL_ORDER_DEFAULT = false; + + /** + * Set on a node to not set a model order for this node even though it is a real node. + */ + public static final IProperty CONSIDER_MODEL_ORDER_NO_MODEL_ORDER = new Property( + "org.eclipse.elk.layered.considerModelOrder.noModelOrder", + CONSIDER_MODEL_ORDER_NO_MODEL_ORDER_DEFAULT, + null, + null); + + /** + * Default value for {@link #CONSIDER_MODEL_ORDER_COMPONENTS}. + */ + private static final ComponentOrderingStrategy CONSIDER_MODEL_ORDER_COMPONENTS_DEFAULT = ComponentOrderingStrategy.NONE; + + /** + * If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. + * INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. + * FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub + * optimal drawings in terms of used area since the ordering should be respected. + */ + public static final IProperty CONSIDER_MODEL_ORDER_COMPONENTS = new Property( + "org.eclipse.elk.layered.considerModelOrder.components", + CONSIDER_MODEL_ORDER_COMPONENTS_DEFAULT, + null, + null); + + /** + * Default value for {@link #CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY}. + */ + private static final LongEdgeOrderingStrategy CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY_DEFAULT = LongEdgeOrderingStrategy.DUMMY_NODE_OVER; + + /** + * Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a + * previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a + * vertical layout. + */ + public static final IProperty CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY = new Property( + "org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy", + CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #CONSIDER_MODEL_ORDER_CROSSING_COUNTER_NODE_INFLUENCE}. + */ + private static final double CONSIDER_MODEL_ORDER_CROSSING_COUNTER_NODE_INFLUENCE_DEFAULT = 0; + + /** + * Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the + * crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. + * This allows some edge crossings in favor of preserving the model order. It is advised to set this value to + * a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no + * influence (0). + */ + public static final IProperty CONSIDER_MODEL_ORDER_CROSSING_COUNTER_NODE_INFLUENCE = new Property( + "org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence", + CONSIDER_MODEL_ORDER_CROSSING_COUNTER_NODE_INFLUENCE_DEFAULT, + null, + null); + + /** + * Default value for {@link #CONSIDER_MODEL_ORDER_CROSSING_COUNTER_PORT_INFLUENCE}. + */ + private static final double CONSIDER_MODEL_ORDER_CROSSING_COUNTER_PORT_INFLUENCE_DEFAULT = 0; + + /** + * Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the + * crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. + * This allows some edge crossings in favor of preserving the model order. It is advised to set this value to + * a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no + * influence (0). + */ + public static final IProperty CONSIDER_MODEL_ORDER_CROSSING_COUNTER_PORT_INFLUENCE = new Property( + "org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence", + CONSIDER_MODEL_ORDER_CROSSING_COUNTER_PORT_INFLUENCE_DEFAULT, + null, + null); + + /** + * Required value for dependency between {@link #INTERACTIVE_REFERENCE_POINT} and {@link #CYCLE_BREAKING_STRATEGY}. + */ + private static final CycleBreakingStrategy INTERACTIVE_REFERENCE_POINT_DEP_CYCLE_BREAKING_STRATEGY_0 = CycleBreakingStrategy.INTERACTIVE; + + /** + * Required value for dependency between {@link #INTERACTIVE_REFERENCE_POINT} and {@link #CROSSING_MINIMIZATION_STRATEGY}. + */ + private static final CrossingMinimizationStrategy INTERACTIVE_REFERENCE_POINT_DEP_CROSSING_MINIMIZATION_STRATEGY_1 = CrossingMinimizationStrategy.INTERACTIVE; + + /** + * Required value for dependency between {@link #LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH} and {@link #LAYERING_STRATEGY}. + */ + private static final LayeringStrategy LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH_DEP_LAYERING_STRATEGY_0 = LayeringStrategy.MIN_WIDTH; + + /** + * Required value for dependency between {@link #LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR} and {@link #LAYERING_STRATEGY}. + */ + private static final LayeringStrategy LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR_DEP_LAYERING_STRATEGY_0 = LayeringStrategy.MIN_WIDTH; + + /** + * Required value for dependency between {@link #LAYERING_COFFMAN_GRAHAM_LAYER_BOUND} and {@link #LAYERING_STRATEGY}. + */ + private static final LayeringStrategy LAYERING_COFFMAN_GRAHAM_LAYER_BOUND_DEP_LAYERING_STRATEGY_0 = LayeringStrategy.COFFMAN_GRAHAM; + + /** + * Required value for dependency between {@link #CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS} and {@link #HIERARCHY_HANDLING}. + */ + private static final HierarchyHandling CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS_DEP_HIERARCHY_HANDLING_0 = HierarchyHandling.INCLUDE_CHILDREN; + + /** + * Required value for dependency between {@link #CROSSING_MINIMIZATION_SEMI_INTERACTIVE} and {@link #CROSSING_MINIMIZATION_STRATEGY}. + */ + private static final CrossingMinimizationStrategy CROSSING_MINIMIZATION_SEMI_INTERACTIVE_DEP_CROSSING_MINIMIZATION_STRATEGY_0 = CrossingMinimizationStrategy.LAYER_SWEEP; + + /** + * Required value for dependency between {@link #CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE} and {@link #CROSSING_MINIMIZATION_STRATEGY}. + */ + private static final CrossingMinimizationStrategy CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE_DEP_CROSSING_MINIMIZATION_STRATEGY_0 = CrossingMinimizationStrategy.LAYER_SWEEP; + + /** + * Required value for dependency between {@link #CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE} and {@link #CROSSING_MINIMIZATION_STRATEGY}. + */ + private static final CrossingMinimizationStrategy CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE_DEP_CROSSING_MINIMIZATION_STRATEGY_0 = CrossingMinimizationStrategy.LAYER_SWEEP; + + /** + * Required value for dependency between {@link #CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE} and {@link #HIERARCHY_HANDLING}. + */ + private static final HierarchyHandling CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE_DEP_HIERARCHY_HANDLING_1 = HierarchyHandling.INCLUDE_CHILDREN; + + /** + * Required value for dependency between {@link #NODE_PLACEMENT_FAVOR_STRAIGHT_EDGES} and {@link #NODE_PLACEMENT_STRATEGY}. + */ + private static final NodePlacementStrategy NODE_PLACEMENT_FAVOR_STRAIGHT_EDGES_DEP_NODE_PLACEMENT_STRATEGY_0 = NodePlacementStrategy.NETWORK_SIMPLEX; + + /** + * Required value for dependency between {@link #NODE_PLACEMENT_FAVOR_STRAIGHT_EDGES} and {@link #NODE_PLACEMENT_STRATEGY}. + */ + private static final NodePlacementStrategy NODE_PLACEMENT_FAVOR_STRAIGHT_EDGES_DEP_NODE_PLACEMENT_STRATEGY_1 = NodePlacementStrategy.BRANDES_KOEPF; + + /** + * Required value for dependency between {@link #NODE_PLACEMENT_BK_EDGE_STRAIGHTENING} and {@link #NODE_PLACEMENT_STRATEGY}. + */ + private static final NodePlacementStrategy NODE_PLACEMENT_BK_EDGE_STRAIGHTENING_DEP_NODE_PLACEMENT_STRATEGY_0 = NodePlacementStrategy.BRANDES_KOEPF; + + /** + * Required value for dependency between {@link #NODE_PLACEMENT_BK_FIXED_ALIGNMENT} and {@link #NODE_PLACEMENT_STRATEGY}. + */ + private static final NodePlacementStrategy NODE_PLACEMENT_BK_FIXED_ALIGNMENT_DEP_NODE_PLACEMENT_STRATEGY_0 = NodePlacementStrategy.BRANDES_KOEPF; + + /** + * Required value for dependency between {@link #NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING} and {@link #NODE_PLACEMENT_STRATEGY}. + */ + private static final NodePlacementStrategy NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING_DEP_NODE_PLACEMENT_STRATEGY_0 = NodePlacementStrategy.LINEAR_SEGMENTS; + + /** + * Required value for dependency between {@link #NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY} and {@link #NODE_PLACEMENT_STRATEGY}. + */ + private static final NodePlacementStrategy NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEP_NODE_PLACEMENT_STRATEGY_0 = NodePlacementStrategy.NETWORK_SIMPLEX; + + /** + * Required value for dependency between {@link #NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEFAULT} and {@link #NODE_PLACEMENT_STRATEGY}. + */ + private static final NodePlacementStrategy NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEFAULT_DEP_NODE_PLACEMENT_STRATEGY_0 = NodePlacementStrategy.NETWORK_SIMPLEX; + + /** + * Required value for dependency between {@link #EDGE_ROUTING_SPLINES_MODE} and {@link #EDGE_ROUTING}. + */ + private static final EdgeRouting EDGE_ROUTING_SPLINES_MODE_DEP_EDGE_ROUTING_0 = EdgeRouting.SPLINES; + + /** + * Required value for dependency between {@link #EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR} and {@link #EDGE_ROUTING}. + */ + private static final EdgeRouting EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR_DEP_EDGE_ROUTING_0 = EdgeRouting.SPLINES; + + /** + * Required value for dependency between {@link #EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR} and {@link #EDGE_ROUTING_SPLINES_MODE}. + */ + private static final SplineRoutingMode EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR_DEP_EDGE_ROUTING_SPLINES_MODE_1 = SplineRoutingMode.SLOPPY; + + /** + * Required value for dependency between {@link #EDGE_ROUTING_POLYLINE_SLOPED_EDGE_ZONE_WIDTH} and {@link #EDGE_ROUTING}. + */ + private static final EdgeRouting EDGE_ROUTING_POLYLINE_SLOPED_EDGE_ZONE_WIDTH_DEP_EDGE_ROUTING_0 = EdgeRouting.POLYLINE; + + /** + * Required value for dependency between {@link #COMPACTION_CONNECTED_COMPONENTS} and {@link #SEPARATE_CONNECTED_COMPONENTS}. + */ + private static final boolean COMPACTION_CONNECTED_COMPONENTS_DEP_SEPARATE_CONNECTED_COMPONENTS_0 = true; + + /** + * Required value for dependency between {@link #HIGH_DEGREE_NODES_THRESHOLD} and {@link #HIGH_DEGREE_NODES_TREATMENT}. + */ + private static final boolean HIGH_DEGREE_NODES_THRESHOLD_DEP_HIGH_DEGREE_NODES_TREATMENT_0 = true; + + /** + * Required value for dependency between {@link #HIGH_DEGREE_NODES_TREE_HEIGHT} and {@link #HIGH_DEGREE_NODES_TREATMENT}. + */ + private static final boolean HIGH_DEGREE_NODES_TREE_HEIGHT_DEP_HIGH_DEGREE_NODES_TREATMENT_0 = true; + + /** + * Required value for dependency between {@link #WRAPPING_ADDITIONAL_EDGE_SPACING} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_ADDITIONAL_EDGE_SPACING_DEP_WRAPPING_STRATEGY_0 = WrappingStrategy.SINGLE_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_ADDITIONAL_EDGE_SPACING} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_ADDITIONAL_EDGE_SPACING_DEP_WRAPPING_STRATEGY_1 = WrappingStrategy.MULTI_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_CORRECTION_FACTOR} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_CORRECTION_FACTOR_DEP_WRAPPING_STRATEGY_0 = WrappingStrategy.SINGLE_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_CORRECTION_FACTOR} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_CORRECTION_FACTOR_DEP_WRAPPING_STRATEGY_1 = WrappingStrategy.MULTI_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_CUTTING_STRATEGY} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_CUTTING_STRATEGY_DEP_WRAPPING_STRATEGY_0 = WrappingStrategy.SINGLE_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_CUTTING_STRATEGY} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_CUTTING_STRATEGY_DEP_WRAPPING_STRATEGY_1 = WrappingStrategy.MULTI_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_CUTTING_CUTS} and {@link #WRAPPING_CUTTING_STRATEGY}. + */ + private static final CuttingStrategy WRAPPING_CUTTING_CUTS_DEP_WRAPPING_CUTTING_STRATEGY_0 = CuttingStrategy.MANUAL; + + /** + * Required value for dependency between {@link #WRAPPING_CUTTING_MSD_FREEDOM} and {@link #WRAPPING_CUTTING_STRATEGY}. + */ + private static final CuttingStrategy WRAPPING_CUTTING_MSD_FREEDOM_DEP_WRAPPING_CUTTING_STRATEGY_0 = CuttingStrategy.MSD; + + /** + * Required value for dependency between {@link #WRAPPING_VALIDIFY_STRATEGY} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_VALIDIFY_STRATEGY_DEP_WRAPPING_STRATEGY_0 = WrappingStrategy.SINGLE_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_VALIDIFY_STRATEGY} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_VALIDIFY_STRATEGY_DEP_WRAPPING_STRATEGY_1 = WrappingStrategy.MULTI_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_VALIDIFY_FORBIDDEN_INDICES} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_VALIDIFY_FORBIDDEN_INDICES_DEP_WRAPPING_STRATEGY_0 = WrappingStrategy.SINGLE_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_VALIDIFY_FORBIDDEN_INDICES} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_VALIDIFY_FORBIDDEN_INDICES_DEP_WRAPPING_STRATEGY_1 = WrappingStrategy.MULTI_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_MULTI_EDGE_IMPROVE_CUTS} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_MULTI_EDGE_IMPROVE_CUTS_DEP_WRAPPING_STRATEGY_0 = WrappingStrategy.MULTI_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_MULTI_EDGE_DISTANCE_PENALTY} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_MULTI_EDGE_DISTANCE_PENALTY_DEP_WRAPPING_STRATEGY_0 = WrappingStrategy.MULTI_EDGE; + + /** + * Required value for dependency between {@link #WRAPPING_MULTI_EDGE_DISTANCE_PENALTY} and {@link #WRAPPING_MULTI_EDGE_IMPROVE_CUTS}. + */ + private static final boolean WRAPPING_MULTI_EDGE_DISTANCE_PENALTY_DEP_WRAPPING_MULTI_EDGE_IMPROVE_CUTS_1 = true; + + /** + * Required value for dependency between {@link #WRAPPING_MULTI_EDGE_IMPROVE_WRAPPED_EDGES} and {@link #WRAPPING_STRATEGY}. + */ + private static final WrappingStrategy WRAPPING_MULTI_EDGE_IMPROVE_WRAPPED_EDGES_DEP_WRAPPING_STRATEGY_0 = WrappingStrategy.MULTI_EDGE; + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.directionCongruency") + .group("") + .name("Direction Congruency") + .description("Specifies how drawings of the same graph with different layout directions compare to each other: either a natural reading direction is preserved or the drawings are rotated versions of each other.") + .defaultValue(DIRECTION_CONGRUENCY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(DirectionCongruency.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.feedbackEdges") + .group("") + .name("Feedback Edges") + .description("Whether feedback edges should be highlighted by routing around the nodes.") + .defaultValue(FEEDBACK_EDGES_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.interactiveReferencePoint") + .group("") + .name("Interactive Reference Point") + .description("Determines which point of a node is considered by interactive layout phases.") + .defaultValue(INTERACTIVE_REFERENCE_POINT_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(InteractiveReferencePoint.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.interactiveReferencePoint", + "org.eclipse.elk.layered.cycleBreaking.strategy", + INTERACTIVE_REFERENCE_POINT_DEP_CYCLE_BREAKING_STRATEGY_0 + ); + registry.addDependency( + "org.eclipse.elk.layered.interactiveReferencePoint", + "org.eclipse.elk.layered.crossingMinimization.strategy", + INTERACTIVE_REFERENCE_POINT_DEP_CROSSING_MINIMIZATION_STRATEGY_1 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.mergeEdges") + .group("") + .name("Merge Edges") + .description("Edges that have no ports are merged so they touch the connected nodes at the same points. When this option is disabled, one port is created for each edge directly connected to a node. When it is enabled, all such incoming edges share an input port, and all outgoing edges share an output port.") + .defaultValue(MERGE_EDGES_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.mergeHierarchyEdges") + .group("") + .name("Merge Hierarchy-Crossing Edges") + .description("If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports as possible. They are broken by the algorithm, with hierarchical ports inserted as required. Usually, one such port is created for each edge at each hierarchy crossing point. With this option set to true, we try to create as few hierarchical ports as possible in the process. In particular, all edges that form a hyperedge can share a port.") + .defaultValue(MERGE_HIERARCHY_EDGES_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides") + .group("") + .name("Allow Non-Flow Ports To Switch Sides") + .description("Specifies whether non-flow ports may switch sides if their node\'s port constraints are either FIXED_SIDE or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. Further note that the underlying criterium whether to switch sides or not solely relies on the minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed.") + .defaultValue(ALLOW_NON_FLOW_PORTS_TO_SWITCH_SIDES_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PORTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .legacyIds("org.eclipse.elk.layered.northOrSouthPort") + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.portSortingStrategy") + .group("") + .name("Port Sorting Strategy") + .description("Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node\'s ports are distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes.") + .defaultValue(PORT_SORTING_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(PortSortingStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.thoroughness") + .group("") + .name("Thoroughness") + .description("How much effort should be spent to produce a nice layout.") + .defaultValue(THOROUGHNESS_DEFAULT) + .lowerBound(THOROUGHNESS_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.unnecessaryBendpoints") + .group("") + .name("Add Unnecessary Bendpoints") + .description("Adds bend points even if an edge does not change direction. If true, each long edge dummy will contribute a bend point to its edges and hierarchy-crossing edges will always get a bend point where they cross hierarchy boundaries. By default, bend points are only added where an edge changes direction.") + .defaultValue(UNNECESSARY_BENDPOINTS_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.generatePositionAndLayerIds") + .group("") + .name("Generate Position and Layer IDs") + .description("If enabled position id and layer id are generated, which are usually only used internally when setting the interactiveLayout option. This option should be specified on the root node.") + .defaultValue(GENERATE_POSITION_AND_LAYER_IDS_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.cycleBreaking.strategy") + .group("cycleBreaking") + .name("Cycle Breaking Strategy") + .description("Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines which edges to reverse to break the cycles. Reversed edges will end up pointing to the opposite direction of regular edges (that is, reversed edges will point left if edges usually point right).") + .defaultValue(CYCLE_BREAKING_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(CycleBreakingStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.layering.strategy") + .group("layering") + .name("Node Layering Strategy") + .description("Strategy for node layering.") + .defaultValue(LAYERING_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(LayeringStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.layering.layerConstraint") + .group("layering") + .name("Layer Constraint") + .description("Determines a constraint on the placement of the node regarding the layering.") + .defaultValue(LAYERING_LAYER_CONSTRAINT_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(LayerConstraint.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.layering.layerChoiceConstraint") + .group("layering") + .name("Layer Choice Constraint") + .description("Allows to set a constraint regarding the layer placement of a node. Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. If set to i, it expresses that the node should be placed in i-th layer. Should i>=n be true then the node is placed in the last layer of the drawing. Note that this option is not part of any of ELK Layered\'s default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine.") + .defaultValue(LAYERING_LAYER_CHOICE_CONSTRAINT_DEFAULT) + .lowerBound(LAYERING_LAYER_CHOICE_CONSTRAINT_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.layering.layerId") + .group("layering") + .name("Layer ID") + .description("Layer identifier that was calculated by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set.") + .defaultValue(LAYERING_LAYER_ID_DEFAULT) + .lowerBound(LAYERING_LAYER_ID_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth") + .group("layering.minWidth") + .name("Upper Bound On Width [MinWidth Layerer]") + .description("Defines a loose upper bound on the width of the MinWidth layerer. If set to \'-1\' multiple values are tested and the best result is selected.") + .defaultValue(LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH_DEFAULT) + .lowerBound(LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth", + "org.eclipse.elk.layered.layering.strategy", + LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH_DEP_LAYERING_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor") + .group("layering.minWidth") + .name("Upper Layer Estimation Scaling Factor [MinWidth Layerer]") + .description("Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which haven\'t been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth algorithm. Compensates for too high estimations. If set to \'-1\' multiple values are tested and the best result is selected.") + .defaultValue(LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR_DEFAULT) + .lowerBound(LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor", + "org.eclipse.elk.layered.layering.strategy", + LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR_DEP_LAYERING_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.layering.nodePromotion.strategy") + .group("layering.nodePromotion") + .name("Node Promotion Strategy") + .description("Reduces number of dummy nodes after layering phase (if possible).") + .defaultValue(LAYERING_NODE_PROMOTION_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(NodePromotionStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.layering.nodePromotion.maxIterations") + .group("layering.nodePromotion") + .name("Max Node Promotion Iterations") + .description("Limits the number of iterations for node promotion.") + .defaultValue(LAYERING_NODE_PROMOTION_MAX_ITERATIONS_DEFAULT) + .lowerBound(LAYERING_NODE_PROMOTION_MAX_ITERATIONS_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.layering.nodePromotion.maxIterations", + "org.eclipse.elk.layered.layering.nodePromotion.strategy", + null + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.layering.coffmanGraham.layerBound") + .group("layering.coffmanGraham") + .name("Layer Bound") + .description("The maximum number of nodes allowed per layer.") + .defaultValue(LAYERING_COFFMAN_GRAHAM_LAYER_BOUND_DEFAULT) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.layering.coffmanGraham.layerBound", + "org.eclipse.elk.layered.layering.strategy", + LAYERING_COFFMAN_GRAHAM_LAYER_BOUND_DEP_LAYERING_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.crossingMinimization.strategy") + .group("crossingMinimization") + .name("Crossing Minimization Strategy") + .description("Strategy for crossing minimization.") + .defaultValue(CROSSING_MINIMIZATION_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(CrossingMinimizationStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder") + .group("crossingMinimization") + .name("Force Node Model Order") + .description("The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES.") + .defaultValue(CROSSING_MINIMIZATION_FORCE_NODE_MODEL_ORDER_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness") + .group("crossingMinimization") + .name("Hierarchical Sweepiness") + .description("How likely it is to use cross-hierarchy (1) vs bottom-up (-1).") + .defaultValue(CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness", + "org.eclipse.elk.hierarchyHandling", + CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS_DEP_HIERARCHY_HANDLING_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.crossingMinimization.semiInteractive") + .group("crossingMinimization") + .name("Semi-Interactive Crossing Minimization") + .description("Preserves the order of nodes within a layer but still minimizes crossings between edges connecting long edge dummies. Derives the desired order from positions specified by the \'org.eclipse.elk.position\' layout option. Requires a crossing minimization strategy that is able to process \'in-layer\' constraints.") + .defaultValue(CROSSING_MINIMIZATION_SEMI_INTERACTIVE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.crossingMinimization.semiInteractive", + "org.eclipse.elk.layered.crossingMinimization.strategy", + CROSSING_MINIMIZATION_SEMI_INTERACTIVE_DEP_CROSSING_MINIMIZATION_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.crossingMinimization.inLayerPredOf") + .group("crossingMinimization") + .name("In Layer Predecessor of") + .description("Allows to set a constraint which specifies of which node the current node is the predecessor. If set to \'s\' then the node is the predecessor of \'s\' and is in the same layer") + .defaultValue(CROSSING_MINIMIZATION_IN_LAYER_PRED_OF_DEFAULT) + .type(LayoutOptionData.Type.STRING) + .optionClass(String.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.crossingMinimization.inLayerSuccOf") + .group("crossingMinimization") + .name("In Layer Successor of") + .description("Allows to set a constraint which specifies of which node the current node is the successor. If set to \'s\' then the node is the successor of \'s\' and is in the same layer") + .defaultValue(CROSSING_MINIMIZATION_IN_LAYER_SUCC_OF_DEFAULT) + .type(LayoutOptionData.Type.STRING) + .optionClass(String.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint") + .group("crossingMinimization") + .name("Position Choice Constraint") + .description("Allows to set a constraint regarding the position placement of a node in a layer. Assumed the layer in which the node placed includes n other nodes and i < n. If set to i, it expresses that the node should be placed at the i-th position. Should i>=n be true then the node is placed at the last position in the layer. Note that this option is not part of any of ELK Layered\'s default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine.") + .defaultValue(CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT_DEFAULT) + .lowerBound(CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.crossingMinimization.positionId") + .group("crossingMinimization") + .name("Position ID") + .description("Position within a layer that was determined by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set.") + .defaultValue(CROSSING_MINIMIZATION_POSITION_ID_DEFAULT) + .lowerBound(CROSSING_MINIMIZATION_POSITION_ID_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold") + .group("crossingMinimization.greedySwitch") + .name("Greedy Switch Activation Threshold") + .description("By default it is decided automatically if the greedy switch is activated or not. The decision is based on whether the size of the input graph (without dummy nodes) is smaller than the value of this option. A \'0\' enforces the activation.") + .defaultValue(CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD_DEFAULT) + .lowerBound(CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.crossingMinimization.greedySwitch.type") + .group("crossingMinimization.greedySwitch") + .name("Greedy Switch Crossing Minimization") + .description("Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed after the regular crossing minimization as a post-processor. Note that if \'hierarchyHandling\' is set to \'INCLUDE_CHILDREN\', the \'greedySwitchHierarchical.type\' option must be used.") + .defaultValue(CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(GreedySwitchType.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.crossingMinimization.greedySwitch.type", + "org.eclipse.elk.layered.crossingMinimization.strategy", + CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE_DEP_CROSSING_MINIMIZATION_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type") + .group("crossingMinimization.greedySwitchHierarchical") + .name("Greedy Switch Crossing Minimization (hierarchical)") + .description("Activates the greedy switch heuristic in case hierarchical layout is used. The differences to the non-hierarchical case (see \'greedySwitch.type\') are: 1) greedy switch is inactive by default, 3) only the option value set on the node at which hierarchical layout starts is relevant, and 2) if it\'s activated by the user, it properly addresses hierarchy-crossing edges.") + .defaultValue(CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(GreedySwitchType.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type", + "org.eclipse.elk.layered.crossingMinimization.strategy", + CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE_DEP_CROSSING_MINIMIZATION_STRATEGY_0 + ); + registry.addDependency( + "org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type", + "org.eclipse.elk.hierarchyHandling", + CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE_DEP_HIERARCHY_HANDLING_1 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.nodePlacement.strategy") + .group("nodePlacement") + .name("Node Placement Strategy") + .description("Strategy for node placement.") + .defaultValue(NODE_PLACEMENT_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(NodePlacementStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.nodePlacement.favorStraightEdges") + .group("nodePlacement") + .name("Favor Straight Edges Over Balancing") + .description("Favor straight edges over a balanced node placement. The default behavior is determined automatically based on the used \'edgeRouting\'. For an orthogonal style it is set to true, for all other styles to false.") + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.nodePlacement.favorStraightEdges", + "org.eclipse.elk.layered.nodePlacement.strategy", + NODE_PLACEMENT_FAVOR_STRAIGHT_EDGES_DEP_NODE_PLACEMENT_STRATEGY_0 + ); + registry.addDependency( + "org.eclipse.elk.layered.nodePlacement.favorStraightEdges", + "org.eclipse.elk.layered.nodePlacement.strategy", + NODE_PLACEMENT_FAVOR_STRAIGHT_EDGES_DEP_NODE_PLACEMENT_STRATEGY_1 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening") + .group("nodePlacement.bk") + .name("BK Edge Straightening") + .description("Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges at the expense of diagram size. There is a subtle difference to the \'favorStraightEdges\' option, which decides whether a balanced placement of the nodes is desired, or not. In bk terms this means combining the four alignments into a single balanced one, or not. This option on the other hand tries to straighten additional edges during the creation of each of the four alignments.") + .defaultValue(NODE_PLACEMENT_BK_EDGE_STRAIGHTENING_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(EdgeStraighteningStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening", + "org.eclipse.elk.layered.nodePlacement.strategy", + NODE_PLACEMENT_BK_EDGE_STRAIGHTENING_DEP_NODE_PLACEMENT_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment") + .group("nodePlacement.bk") + .name("BK Fixed Alignment") + .description("Tells the BK node placer to use a certain alignment (out of its four) instead of the one producing the smallest height, or the combination of all four.") + .defaultValue(NODE_PLACEMENT_BK_FIXED_ALIGNMENT_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(FixedAlignment.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment", + "org.eclipse.elk.layered.nodePlacement.strategy", + NODE_PLACEMENT_BK_FIXED_ALIGNMENT_DEP_NODE_PLACEMENT_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening") + .group("nodePlacement.linearSegments") + .name("Linear Segments Deflection Dampening") + .description("Dampens the movement of nodes to keep the diagram from getting too large.") + .defaultValue(NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING_DEFAULT) + .lowerBound(NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening", + "org.eclipse.elk.layered.nodePlacement.strategy", + NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING_DEP_NODE_PLACEMENT_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility") + .group("nodePlacement.networkSimplex") + .name("Node Flexibility") + .description("Aims at shorter and straighter edges. Two configurations are possible: (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), (b) additionally allow to enlarge a node wherever it helps. If this option is not configured for a node, the \'nodeFlexibility.default\' value is used, which is specified for the node\'s parent.") + .type(LayoutOptionData.Type.ENUM) + .optionClass(NodeFlexibility.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility", + "org.eclipse.elk.layered.nodePlacement.strategy", + NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEP_NODE_PLACEMENT_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default") + .group("nodePlacement.networkSimplex.nodeFlexibility") + .name("Node Flexibility Default") + .description("Default value of the \'nodeFlexibility\' option for the children of a hierarchical node.") + .defaultValue(NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEFAULT_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(NodeFlexibility.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default", + "org.eclipse.elk.layered.nodePlacement.strategy", + NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEFAULT_DEP_NODE_PLACEMENT_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.edgeRouting.selfLoopDistribution") + .group("edgeRouting") + .name("Self-Loop Distribution") + .description("Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE.") + .defaultValue(EDGE_ROUTING_SELF_LOOP_DISTRIBUTION_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(SelfLoopDistributionStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.edgeRouting.selfLoopOrdering") + .group("edgeRouting") + .name("Self-Loop Ordering") + .description("Alter the ordering of the loops they can either be stacked or sequenced. It only takes effect for PortConstraints.FREE.") + .defaultValue(EDGE_ROUTING_SELF_LOOP_ORDERING_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(SelfLoopOrderingStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.edgeRouting.splines.mode") + .group("edgeRouting.splines") + .name("Spline Routing Mode") + .description("Specifies the way control points are assembled for each individual edge. CONSERVATIVE ensures that edges are properly routed around the nodes but feels rather orthogonal at times. SLOPPY uses fewer control points to obtain curvier edge routes but may result in edges overlapping nodes.") + .defaultValue(EDGE_ROUTING_SPLINES_MODE_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(SplineRoutingMode.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.edgeRouting.splines.mode", + "org.eclipse.elk.edgeRouting", + EDGE_ROUTING_SPLINES_MODE_DEP_EDGE_ROUTING_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor") + .group("edgeRouting.splines.sloppy") + .name("Sloppy Spline Layer Spacing Factor") + .description("Spacing factor for routing area between layers when using sloppy spline routing.") + .defaultValue(EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor", + "org.eclipse.elk.edgeRouting", + EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR_DEP_EDGE_ROUTING_0 + ); + registry.addDependency( + "org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor", + "org.eclipse.elk.layered.edgeRouting.splines.mode", + EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR_DEP_EDGE_ROUTING_SPLINES_MODE_1 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth") + .group("edgeRouting.polyline") + .name("Sloped Edge Zone Width") + .description("Width of the strip to the left and to the right of each layer where the polyline edge router is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward bend points for nodes that extent almost to the edge of their layer.") + .defaultValue(EDGE_ROUTING_POLYLINE_SLOPED_EDGE_ZONE_WIDTH_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth", + "org.eclipse.elk.edgeRouting", + EDGE_ROUTING_POLYLINE_SLOPED_EDGE_ZONE_WIDTH_DEP_EDGE_ROUTING_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.spacing.baseValue") + .group("spacing") + .name("Spacing Base Value") + .description("An optional base value for all other layout options of the \'spacing\' group. It can be used to conveniently alter the overall \'spaciousness\' of the drawing. Whenever an explicit value is set for the other layout options, this base value will have no effect. The base value is not inherited, i.e. it must be set for each hierarchical node.") + .lowerBound(SPACING_BASE_VALUE_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers") + .group("spacing") + .name("Edge Node Between Layers Spacing") + .description("The spacing to be preserved between nodes and edges that are routed next to the node\'s layer. For the spacing between nodes and edges that cross the node\'s layer \'spacing.edgeNode\' is used.") + .defaultValue(SPACING_EDGE_NODE_BETWEEN_LAYERS_DEFAULT) + .lowerBound(SPACING_EDGE_NODE_BETWEEN_LAYERS_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers") + .group("spacing") + .name("Edge Edge Between Layer Spacing") + .description("Spacing to be preserved between pairs of edges that are routed between the same pair of layers. Note that \'spacing.edgeEdge\' is used for the spacing between pairs of edges crossing the same layer.") + .defaultValue(SPACING_EDGE_EDGE_BETWEEN_LAYERS_DEFAULT) + .lowerBound(SPACING_EDGE_EDGE_BETWEEN_LAYERS_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers") + .group("spacing") + .name("Node Node Between Layers Spacing") + .description("The spacing to be preserved between any pair of nodes of two adjacent layers. Note that \'spacing.nodeNode\' is used for the spacing between nodes within the layer itself.") + .defaultValue(SPACING_NODE_NODE_BETWEEN_LAYERS_DEFAULT) + .lowerBound(SPACING_NODE_NODE_BETWEEN_LAYERS_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.priority.direction") + .group("priority") + .name("Direction Priority") + .description("Defines how important it is to have a certain edge point into the direction of the overall layout. This option is evaluated during the cycle breaking phase.") + .defaultValue(PRIORITY_DIRECTION_DEFAULT) + .lowerBound(PRIORITY_DIRECTION_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.priority.shortness") + .group("priority") + .name("Shortness Priority") + .description("Defines how important it is to keep an edge as short as possible. This option is evaluated during the layering phase.") + .defaultValue(PRIORITY_SHORTNESS_DEFAULT) + .lowerBound(PRIORITY_SHORTNESS_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.priority.straightness") + .group("priority") + .name("Straightness Priority") + .description("Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. This option is evaluated during node placement.") + .defaultValue(PRIORITY_STRAIGHTNESS_DEFAULT) + .lowerBound(PRIORITY_STRAIGHTNESS_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.compaction.connectedComponents") + .group("compaction") + .name("Connected Components Compaction") + .description("Tries to further compact components (disconnected sub-graphs).") + .defaultValue(COMPACTION_CONNECTED_COMPONENTS_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.compaction.connectedComponents", + "org.eclipse.elk.separateConnectedComponents", + COMPACTION_CONNECTED_COMPONENTS_DEP_SEPARATE_CONNECTED_COMPONENTS_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.compaction.postCompaction.strategy") + .group("compaction.postCompaction") + .name("Post Compaction Strategy") + .description("Specifies whether and how post-process compaction is applied.") + .defaultValue(COMPACTION_POST_COMPACTION_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(GraphCompactionStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.compaction.postCompaction.constraints") + .group("compaction.postCompaction") + .name("Post Compaction Constraint Calculation") + .description("Specifies whether and how post-process compaction is applied.") + .defaultValue(COMPACTION_POST_COMPACTION_CONSTRAINTS_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(ConstraintCalculationStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.highDegreeNodes.treatment") + .group("highDegreeNodes") + .name("High Degree Node Treatment") + .description("Makes room around high degree nodes to place leafs and trees.") + .defaultValue(HIGH_DEGREE_NODES_TREATMENT_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.highDegreeNodes.threshold") + .group("highDegreeNodes") + .name("High Degree Node Threshold") + .description("Whether a node is considered to have a high degree.") + .defaultValue(HIGH_DEGREE_NODES_THRESHOLD_DEFAULT) + .lowerBound(HIGH_DEGREE_NODES_THRESHOLD_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.highDegreeNodes.threshold", + "org.eclipse.elk.layered.highDegreeNodes.treatment", + HIGH_DEGREE_NODES_THRESHOLD_DEP_HIGH_DEGREE_NODES_TREATMENT_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.highDegreeNodes.treeHeight") + .group("highDegreeNodes") + .name("High Degree Node Maximum Tree Height") + .description("Maximum height of a subtree connected to a high degree node to be moved to separate layers.") + .defaultValue(HIGH_DEGREE_NODES_TREE_HEIGHT_DEFAULT) + .lowerBound(HIGH_DEGREE_NODES_TREE_HEIGHT_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.highDegreeNodes.treeHeight", + "org.eclipse.elk.layered.highDegreeNodes.treatment", + HIGH_DEGREE_NODES_TREE_HEIGHT_DEP_HIGH_DEGREE_NODES_TREATMENT_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.wrapping.strategy") + .group("wrapping") + .name("Graph Wrapping Strategy") + .description("For certain graphs and certain prescribed drawing areas it may be desirable to split the laid out graph into chunks that are placed side by side. The edges that connect different chunks are \'wrapped\' around from the end of one chunk to the start of the other chunk. The points between the chunks are referred to as \'cuts\'.") + .defaultValue(WRAPPING_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(WrappingStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.wrapping.additionalEdgeSpacing") + .group("wrapping") + .name("Additional Wrapped Edges Spacing") + .description("To visually separate edges that are wrapped from regularly routed edges an additional spacing value can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing.") + .defaultValue(WRAPPING_ADDITIONAL_EDGE_SPACING_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.additionalEdgeSpacing", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_ADDITIONAL_EDGE_SPACING_DEP_WRAPPING_STRATEGY_0 + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.additionalEdgeSpacing", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_ADDITIONAL_EDGE_SPACING_DEP_WRAPPING_STRATEGY_1 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.wrapping.correctionFactor") + .group("wrapping") + .name("Correction Factor for Wrapping") + .description("At times and for certain types of graphs the executed wrapping may produce results that are consistently biased in the same fashion: either wrapping to often or to rarely. This factor can be used to correct the bias. Internally, it is simply multiplied with the \'aspect ratio\' layout option.") + .defaultValue(WRAPPING_CORRECTION_FACTOR_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.correctionFactor", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_CORRECTION_FACTOR_DEP_WRAPPING_STRATEGY_0 + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.correctionFactor", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_CORRECTION_FACTOR_DEP_WRAPPING_STRATEGY_1 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.wrapping.cutting.strategy") + .group("wrapping.cutting") + .name("Cutting Strategy") + .description("The strategy by which the layer indexes are determined at which the layering crumbles into chunks.") + .defaultValue(WRAPPING_CUTTING_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(CuttingStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.cutting.strategy", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_CUTTING_STRATEGY_DEP_WRAPPING_STRATEGY_0 + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.cutting.strategy", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_CUTTING_STRATEGY_DEP_WRAPPING_STRATEGY_1 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.wrapping.cutting.cuts") + .group("wrapping.cutting") + .name("Manually Specified Cuts") + .description("Allows the user to specify her own cuts for a certain graph.") + .type(LayoutOptionData.Type.OBJECT) + .optionClass(List.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.cutting.cuts", + "org.eclipse.elk.layered.wrapping.cutting.strategy", + WRAPPING_CUTTING_CUTS_DEP_WRAPPING_CUTTING_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.wrapping.cutting.msd.freedom") + .group("wrapping.cutting.msd") + .name("MSD Freedom") + .description("The MSD cutting strategy starts with an initial guess on the number of chunks the graph should be split into. The freedom specifies how much the strategy may deviate from this guess. E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts.") + .defaultValue(WRAPPING_CUTTING_MSD_FREEDOM_DEFAULT) + .lowerBound(WRAPPING_CUTTING_MSD_FREEDOM_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.cutting.msd.freedom", + "org.eclipse.elk.layered.wrapping.cutting.strategy", + WRAPPING_CUTTING_MSD_FREEDOM_DEP_WRAPPING_CUTTING_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.wrapping.validify.strategy") + .group("wrapping.validify") + .name("Validification Strategy") + .description("When wrapping graphs, one can specify indices that are not allowed as split points. The validification strategy makes sure every computed split point is allowed.") + .defaultValue(WRAPPING_VALIDIFY_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(ValidifyStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.validify.strategy", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_VALIDIFY_STRATEGY_DEP_WRAPPING_STRATEGY_0 + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.validify.strategy", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_VALIDIFY_STRATEGY_DEP_WRAPPING_STRATEGY_1 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.wrapping.validify.forbiddenIndices") + .group("wrapping.validify") + .name("Valid Indices for Wrapping") + .description(null) + .type(LayoutOptionData.Type.OBJECT) + .optionClass(List.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.validify.forbiddenIndices", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_VALIDIFY_FORBIDDEN_INDICES_DEP_WRAPPING_STRATEGY_0 + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.validify.forbiddenIndices", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_VALIDIFY_FORBIDDEN_INDICES_DEP_WRAPPING_STRATEGY_1 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.wrapping.multiEdge.improveCuts") + .group("wrapping.multiEdge") + .name("Improve Cuts") + .description("For general graphs it is important that not too many edges wrap backwards. Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought.") + .defaultValue(WRAPPING_MULTI_EDGE_IMPROVE_CUTS_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.multiEdge.improveCuts", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_MULTI_EDGE_IMPROVE_CUTS_DEP_WRAPPING_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty") + .group("wrapping.multiEdge") + .name("Distance Penalty When Improving Cuts") + .description(null) + .defaultValue(WRAPPING_MULTI_EDGE_DISTANCE_PENALTY_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_MULTI_EDGE_DISTANCE_PENALTY_DEP_WRAPPING_STRATEGY_0 + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty", + "org.eclipse.elk.layered.wrapping.multiEdge.improveCuts", + WRAPPING_MULTI_EDGE_DISTANCE_PENALTY_DEP_WRAPPING_MULTI_EDGE_IMPROVE_CUTS_1 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges") + .group("wrapping.multiEdge") + .name("Improve Wrapped Edges") + .description("The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges.") + .defaultValue(WRAPPING_MULTI_EDGE_IMPROVE_WRAPPED_EDGES_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_MULTI_EDGE_IMPROVE_WRAPPED_EDGES_DEP_WRAPPING_STRATEGY_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.edgeLabels.sideSelection") + .group("edgeLabels") + .name("Edge Label Side Selection") + .description("Method to decide on edge label sides.") + .defaultValue(EDGE_LABELS_SIDE_SELECTION_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(EdgeLabelSideSelection.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy") + .group("edgeLabels") + .name("Edge Center Label Placement Strategy") + .description("Determines in which layer center labels of long edges should be placed.") + .defaultValue(EDGE_LABELS_CENTER_LABEL_PLACEMENT_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(CenterEdgeLabelPlacementStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS, LayoutOptionData.Target.LABELS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.considerModelOrder.strategy") + .group("considerModelOrder") + .name("Consider Model Order") + .description("Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting.") + .defaultValue(CONSIDER_MODEL_ORDER_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(OrderingStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.considerModelOrder.portModelOrder") + .group("considerModelOrder") + .name("Consider Port Order") + .description("If disabled the port order of output ports is derived from the edge order and input ports are ordered by their incoming connections. If enabled all ports are ordered by the port model order.") + .defaultValue(CONSIDER_MODEL_ORDER_PORT_MODEL_ORDER_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.considerModelOrder.noModelOrder") + .group("considerModelOrder") + .name("No Model Order") + .description("Set on a node to not set a model order for this node even though it is a real node.") + .defaultValue(CONSIDER_MODEL_ORDER_NO_MODEL_ORDER_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.considerModelOrder.components") + .group("considerModelOrder") + .name("Consider Model Order for Components") + .description("If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub optimal drawings in terms of used area since the ordering should be respected.") + .defaultValue(CONSIDER_MODEL_ORDER_COMPONENTS_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(ComponentOrderingStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.considerModelOrder.components", + "org.eclipse.elk.separateConnectedComponents", + null + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy") + .group("considerModelOrder") + .name("Long Edge Ordering Strategy") + .description("Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a vertical layout.") + .defaultValue(CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(LongEdgeOrderingStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence") + .group("considerModelOrder") + .name("Crossing Counter Node Order Influence") + .description("Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no influence (0).") + .defaultValue(CONSIDER_MODEL_ORDER_CROSSING_COUNTER_NODE_INFLUENCE_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence", + "org.eclipse.elk.layered.considerModelOrder.strategy", + null + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence") + .group("considerModelOrder") + .name("Crossing Counter Port Order Influence") + .description("Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no influence (0).") + .defaultValue(CONSIDER_MODEL_ORDER_CROSSING_COUNTER_PORT_INFLUENCE_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.addDependency( + "org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence", + "org.eclipse.elk.layered.considerModelOrder.strategy", + null + ); + new org.eclipse.elk.alg.layered.options.LayeredOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.alg.layered/src-gen/org/eclipse/elk/alg/layered/options/LayeredOptions.java b/plugins/org.eclipse.elk.alg.layered/src-gen/org/eclipse/elk/alg/layered/options/LayeredOptions.java new file mode 100644 index 000000000..d03ec4517 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.layered/src-gen/org/eclipse/elk/alg/layered/options/LayeredOptions.java @@ -0,0 +1,1770 @@ +/** + * Copyright (c) 2015, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.layered.options; + +import java.util.EnumSet; +import java.util.List; +import org.eclipse.elk.alg.layered.LayeredLayoutProvider; +import org.eclipse.elk.alg.layered.components.ComponentOrderingStrategy; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkMargin; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.math.KVector; +import org.eclipse.elk.core.math.KVectorChain; +import org.eclipse.elk.core.options.Alignment; +import org.eclipse.elk.core.options.ContentAlignment; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.Direction; +import org.eclipse.elk.core.options.EdgeLabelPlacement; +import org.eclipse.elk.core.options.EdgeRouting; +import org.eclipse.elk.core.options.HierarchyHandling; +import org.eclipse.elk.core.options.NodeLabelPlacement; +import org.eclipse.elk.core.options.PortAlignment; +import org.eclipse.elk.core.options.PortConstraints; +import org.eclipse.elk.core.options.PortLabelPlacement; +import org.eclipse.elk.core.options.PortSide; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.core.options.SizeOptions; +import org.eclipse.elk.core.options.TopdownNodeTypes; +import org.eclipse.elk.core.util.IndividualSpacings; +import org.eclipse.elk.graph.properties.GraphFeature; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class LayeredOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK Layered algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.layered"; + + /** + * Spacing to be preserved between a comment box and other comment boxes connected to the same node. + * The space left between comment boxes of different nodes is controlled by the node-node spacing. + */ + public static final IProperty SPACING_COMMENT_COMMENT = CoreOptions.SPACING_COMMENT_COMMENT; + + /** + * Spacing to be preserved between a node and its connected comment boxes. The space left between a node + * and the comments of another node is controlled by the node-node spacing. + */ + public static final IProperty SPACING_COMMENT_NODE = CoreOptions.SPACING_COMMENT_NODE; + + /** + * Spacing to be preserved between pairs of connected components. + * This option is only relevant if 'separateConnectedComponents' is activated. + */ + public static final IProperty SPACING_COMPONENT_COMPONENT = CoreOptions.SPACING_COMPONENT_COMPONENT; + + /** + * Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied + * for the segments of orthogonally drawn edges, it is harder for general polylines or splines. + */ + public static final IProperty SPACING_EDGE_EDGE = CoreOptions.SPACING_EDGE_EDGE; + + /** + * The minimal distance to be preserved between a label and the edge it is associated with. + * Note that the placement of a label is influenced by the 'edgelabels.placement' option. + */ + public static final IProperty SPACING_EDGE_LABEL = CoreOptions.SPACING_EDGE_LABEL; + + /** + * Spacing to be preserved between nodes and edges. + */ + public static final IProperty SPACING_EDGE_NODE = CoreOptions.SPACING_EDGE_NODE; + + /** + * Determines the amount of space to be left between two labels + * of the same graph element. + */ + public static final IProperty SPACING_LABEL_LABEL = CoreOptions.SPACING_LABEL_LABEL; + + /** + * Horizontal spacing to be preserved between labels and the ports they are associated with. + * Note that the placement of a label is influenced by the 'portlabels.placement' option. + */ + public static final IProperty SPACING_LABEL_PORT_HORIZONTAL = CoreOptions.SPACING_LABEL_PORT_HORIZONTAL; + + /** + * Vertical spacing to be preserved between labels and the ports they are associated with. + * Note that the placement of a label is influenced by the 'portlabels.placement' option. + */ + public static final IProperty SPACING_LABEL_PORT_VERTICAL = CoreOptions.SPACING_LABEL_PORT_VERTICAL; + + /** + * Spacing to be preserved between labels and the border of node they are associated with. + * Note that the placement of a label is influenced by the 'nodelabels.placement' option. + */ + public static final IProperty SPACING_LABEL_NODE = CoreOptions.SPACING_LABEL_NODE; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = CoreOptions.SPACING_NODE_NODE; + + /** + * Spacing to be preserved between a node and its self loops. + */ + public static final IProperty SPACING_NODE_SELF_LOOP = CoreOptions.SPACING_NODE_SELF_LOOP; + + /** + * Spacing between pairs of ports of the same node. + */ + public static final IProperty SPACING_PORT_PORT = CoreOptions.SPACING_PORT_PORT; + + /** + * Allows to specify individual spacing values for graph elements that shall be different from + * the value specified for the element's parent. + *

Algorithm Specific Details

+ * Most parts of the algorithm do not support this yet. + */ + public static final IProperty SPACING_INDIVIDUAL = CoreOptions.SPACING_INDIVIDUAL; + + /** + * An optional base value for all other layout options of the 'spacing' group. It can be used to conveniently + * alter the overall 'spaciousness' of the drawing. Whenever an explicit value is set for the other layout + * options, this base value will have no effect. The base value is not inherited, i.e. it must be set for + * each hierarchical node. + */ + public static final IProperty SPACING_BASE_VALUE = LayeredMetaDataProvider.SPACING_BASE_VALUE; + + /** + * Spacing to be preserved between pairs of edges that are routed between the same pair of layers. + * Note that 'spacing.edgeEdge' is used for the spacing between pairs of edges crossing the same layer. + */ + public static final IProperty SPACING_EDGE_EDGE_BETWEEN_LAYERS = LayeredMetaDataProvider.SPACING_EDGE_EDGE_BETWEEN_LAYERS; + + /** + * The spacing to be preserved between nodes and edges that are routed next to the node's layer. + * For the spacing between nodes and edges that cross the node's layer 'spacing.edgeNode' is used. + */ + public static final IProperty SPACING_EDGE_NODE_BETWEEN_LAYERS = LayeredMetaDataProvider.SPACING_EDGE_NODE_BETWEEN_LAYERS; + + /** + * The spacing to be preserved between any pair of nodes of two adjacent layers. + * Note that 'spacing.nodeNode' is used for the spacing between nodes within the layer itself. + */ + public static final IProperty SPACING_NODE_NODE_BETWEEN_LAYERS = LayeredMetaDataProvider.SPACING_NODE_NODE_BETWEEN_LAYERS; + + /** + * Default value for {@link #PRIORITY} with algorithm "ELK Layered". + */ + private static final int PRIORITY_DEFAULT = 0; + + /** + * Defines the priority of an object; its meaning depends on the specific layout algorithm + * and the context where it is used. + *

Algorithm Specific Details

+ * Used by the 'simple row graph placer' to decide which connected components to place first. + * A component's priority is the sum of the node priorities, + * and components with higher priorities will be placed + * before components with lower priorities. + */ + public static final IProperty PRIORITY = new Property( + CoreOptions.PRIORITY, + PRIORITY_DEFAULT); + + /** + * Defines how important it is to have a certain edge point into the direction of the overall layout. + * This option is evaluated during the cycle breaking phase. + */ + public static final IProperty PRIORITY_DIRECTION = LayeredMetaDataProvider.PRIORITY_DIRECTION; + + /** + * Defines how important it is to keep an edge as short as possible. + * This option is evaluated during the layering phase. + *

Algorithm Specific Details

+ * Currently only supported by the network simplex layerer. + */ + public static final IProperty PRIORITY_SHORTNESS = LayeredMetaDataProvider.PRIORITY_SHORTNESS; + + /** + * Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. + * This option is evaluated during node placement. + */ + public static final IProperty PRIORITY_STRAIGHTNESS = LayeredMetaDataProvider.PRIORITY_STRAIGHTNESS; + + /** + * For certain graphs and certain prescribed drawing areas it may be desirable to + * split the laid out graph into chunks that are placed side by side. + * The edges that connect different chunks are 'wrapped' around from the end of + * one chunk to the start of the other chunk. + * The points between the chunks are referred to as 'cuts'. + */ + public static final IProperty WRAPPING_STRATEGY = LayeredMetaDataProvider.WRAPPING_STRATEGY; + + /** + * To visually separate edges that are wrapped from regularly routed edges an additional spacing value + * can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing. + */ + public static final IProperty WRAPPING_ADDITIONAL_EDGE_SPACING = LayeredMetaDataProvider.WRAPPING_ADDITIONAL_EDGE_SPACING; + + /** + * At times and for certain types of graphs the executed wrapping may produce results that + * are consistently biased in the same fashion: either wrapping to often or to rarely. + * This factor can be used to correct the bias. Internally, it is simply multiplied with + * the 'aspect ratio' layout option. + */ + public static final IProperty WRAPPING_CORRECTION_FACTOR = LayeredMetaDataProvider.WRAPPING_CORRECTION_FACTOR; + + /** + * The strategy by which the layer indexes are determined at which the layering crumbles into chunks. + */ + public static final IProperty WRAPPING_CUTTING_STRATEGY = LayeredMetaDataProvider.WRAPPING_CUTTING_STRATEGY; + + /** + * Allows the user to specify her own cuts for a certain graph. + */ + public static final IProperty> WRAPPING_CUTTING_CUTS = LayeredMetaDataProvider.WRAPPING_CUTTING_CUTS; + + /** + * The MSD cutting strategy starts with an initial guess on the number of chunks the graph + * should be split into. The freedom specifies how much the strategy may deviate from this guess. + * E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts. + */ + public static final IProperty WRAPPING_CUTTING_MSD_FREEDOM = LayeredMetaDataProvider.WRAPPING_CUTTING_MSD_FREEDOM; + + /** + * When wrapping graphs, one can specify indices that are not allowed as split points. + * The validification strategy makes sure every computed split point is allowed. + */ + public static final IProperty WRAPPING_VALIDIFY_STRATEGY = LayeredMetaDataProvider.WRAPPING_VALIDIFY_STRATEGY; + + /** + * null + */ + public static final IProperty> WRAPPING_VALIDIFY_FORBIDDEN_INDICES = LayeredMetaDataProvider.WRAPPING_VALIDIFY_FORBIDDEN_INDICES; + + /** + * For general graphs it is important that not too many edges wrap backwards. + * Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought. + */ + public static final IProperty WRAPPING_MULTI_EDGE_IMPROVE_CUTS = LayeredMetaDataProvider.WRAPPING_MULTI_EDGE_IMPROVE_CUTS; + + /** + * null + */ + public static final IProperty WRAPPING_MULTI_EDGE_DISTANCE_PENALTY = LayeredMetaDataProvider.WRAPPING_MULTI_EDGE_DISTANCE_PENALTY; + + /** + * The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from + * one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges. + */ + public static final IProperty WRAPPING_MULTI_EDGE_IMPROVE_WRAPPED_EDGES = LayeredMetaDataProvider.WRAPPING_MULTI_EDGE_IMPROVE_WRAPPED_EDGES; + + /** + * Aims at shorter and straighter edges. Two configurations are possible: + * (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), + * (b) additionally allow to enlarge a node wherever it helps. + * If this option is not configured for a node, the 'nodeFlexibility.default' value is used, + * which is specified for the node's parent. + */ + public static final IProperty NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY = LayeredMetaDataProvider.NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY; + + /** + * Default value of the 'nodeFlexibility' option for the children of a hierarchical node. + */ + public static final IProperty NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEFAULT = LayeredMetaDataProvider.NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEFAULT; + + /** + * Specifies the way control points are assembled for each individual edge. + * CONSERVATIVE ensures that edges are properly routed around the nodes + * but feels rather orthogonal at times. + * SLOPPY uses fewer control points to obtain curvier edge routes but may result in + * edges overlapping nodes. + */ + public static final IProperty EDGE_ROUTING_SPLINES_MODE = LayeredMetaDataProvider.EDGE_ROUTING_SPLINES_MODE; + + /** + * Spacing factor for routing area between layers when using sloppy spline routing. + */ + public static final IProperty EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR = LayeredMetaDataProvider.EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR; + + /** + * Turns topdown layout on and off. If this option is enabled, hierarchical layout will be computed first for + * the root node and then for its children recursively. Layouts are then scaled down to fit the area provided by + * their parents. Graphs must follow a certain structure for topdown layout to work properly. + * {@link TopdownNodeTypes.PARALLEL_NODE} nodes must have children of type + * {@link TopdownNodeTypes.HIERARCHICAL_NODE} and must define {@link topdown.hierarchicalNodeWidth} and + * {@link topdown.hierarchicalNodeAspectRatio} for their children. Furthermore they need to be laid out using an + * algorithm that is a {@link TopdownLayoutProvider}. Hierarchical nodes can also be parents of other hierarchical + * nodes and can optionally use a {@link TopdownSizeApproximator} to dynamically set sizes during topdown layout. + * In this case {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} should be set + * on the node itself rather than the parent. The values are then used by the size approximator as base values. + * Hierarchical nodes require the layout option {@link nodeSize.fixedGraphSize} to be true to prevent the algorithm + * used there from resizing the hierarchical node. This option is not supported if 'Hierarchy Handling' is set to + * 'INCLUDE_CHILDREN' + */ + public static final IProperty TOPDOWN_LAYOUT = CoreOptions.TOPDOWN_LAYOUT; + + /** + * The scaling factor to be applied to the nodes laid out within the node in recursive topdown + * layout. The difference to 'Scale Factor' is that the node itself is not scaled. This value has to be set on + * hierarchical nodes. + */ + public static final IProperty TOPDOWN_SCALE_FACTOR = CoreOptions.TOPDOWN_SCALE_FACTOR; + + /** + * The fixed size of a hierarchical node when using topdown layout. If this value is set on a parallel + * node it applies to its children, when set on a hierarchical node it applies to the node itself. + */ + public static final IProperty TOPDOWN_HIERARCHICAL_NODE_WIDTH = CoreOptions.TOPDOWN_HIERARCHICAL_NODE_WIDTH; + + /** + * The fixed aspect ratio of a hierarchical node when using topdown layout. Default is 1/sqrt(2). If this + * value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to + * the node itself. + */ + public static final IProperty TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO = CoreOptions.TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO; + + /** + * Default value for {@link #TOPDOWN_NODE_TYPE} with algorithm "ELK Layered". + */ + private static final TopdownNodeTypes TOPDOWN_NODE_TYPE_DEFAULT = TopdownNodeTypes.HIERARCHICAL_NODE; + + /** + * The different node types used for topdown layout. If the node type is set + * to {@link TopdownNodeTypes.PARALLEL_NODE} the algorithm must be set to a {@link TopdownLayoutProvider} such + * as {@link TopdownPacking}. The {@link nodeSize.fixedGraphSize} option is technically only required for + * hierarchical nodes. + */ + public static final IProperty TOPDOWN_NODE_TYPE = new Property( + CoreOptions.TOPDOWN_NODE_TYPE, + TOPDOWN_NODE_TYPE_DEFAULT); + + /** + * Default value for {@link #PADDING} with algorithm "ELK Layered". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(12); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #EDGE_ROUTING} with algorithm "ELK Layered". + */ + private static final EdgeRouting EDGE_ROUTING_DEFAULT = EdgeRouting.ORTHOGONAL; + + /** + * What kind of edge routing style should be applied for the content of a parent node. + * Algorithms may also set this option to single edges in order to mark them as splines. + * The bend point list of edges with this option set to SPLINES must be interpreted as control + * points for a piecewise cubic spline. + */ + public static final IProperty EDGE_ROUTING = new Property( + CoreOptions.EDGE_ROUTING, + EDGE_ROUTING_DEFAULT); + + /** + * Default value for {@link #PORT_BORDER_OFFSET} with algorithm "ELK Layered". + */ + private static final double PORT_BORDER_OFFSET_DEFAULT = 0; + + /** + * The offset of ports on the node border. With a positive offset the port is moved outside + * of the node, while with a negative offset the port is moved towards the inside. An offset + * of 0 means that the port is placed directly on the node border, i.e. + * if the port side is north, the port's south border touches the nodes's north border; + * if the port side is east, the port's west border touches the nodes's east border; + * if the port side is south, the port's north border touches the node's south border; + * if the port side is west, the port's east border touches the node's west border. + */ + public static final IProperty PORT_BORDER_OFFSET = new Property( + CoreOptions.PORT_BORDER_OFFSET, + PORT_BORDER_OFFSET_DEFAULT); + + /** + * Default value for {@link #RANDOM_SEED} with algorithm "ELK Layered". + */ + private static final int RANDOM_SEED_DEFAULT = 1; + + /** + * Seed used for pseudo-random number generators to control the layout algorithm. If the + * value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time). + */ + public static final IProperty RANDOM_SEED = new Property( + CoreOptions.RANDOM_SEED, + RANDOM_SEED_DEFAULT); + + /** + * Default value for {@link #ASPECT_RATIO} with algorithm "ELK Layered". + */ + private static final double ASPECT_RATIO_DEFAULT = 1.6f; + + /** + * The desired aspect ratio of the drawing, that is the quotient of width by height. + */ + public static final IProperty ASPECT_RATIO = new Property( + CoreOptions.ASPECT_RATIO, + ASPECT_RATIO_DEFAULT); + + /** + * No layout is done for the associated element. This is used to mark parts of a diagram to + * avoid their inclusion in the layout graph, or to mark parts of the layout graph to + * prevent layout engines from processing them. If you wish to exclude the contents of a + * compound node from automatic layout, while the node itself is still considered on its own + * layer, use the 'Fixed Layout' algorithm for that node. + */ + public static final IProperty NO_LAYOUT = CoreOptions.NO_LAYOUT; + + /** + * Defines constraints of the position of the ports of a node. + */ + public static final IProperty PORT_CONSTRAINTS = CoreOptions.PORT_CONSTRAINTS; + + /** + * The side of a node on which a port is situated. This option must be set if 'Port + * Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given + * for the ports. + */ + public static final IProperty PORT_SIDE = CoreOptions.PORT_SIDE; + + /** + * Whether additional debug information shall be generated. + */ + public static final IProperty DEBUG_MODE = CoreOptions.DEBUG_MODE; + + /** + * Alignment of the selected node relative to other nodes; + * the exact meaning depends on the used algorithm. + */ + public static final IProperty ALIGNMENT = CoreOptions.ALIGNMENT; + + /** + * Determines whether separate layout runs are triggered for different compound nodes in a + * hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay + * out that node and all of its descendants in a single layout run, until a descendant is + * encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, + * `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that + * setting. Including multiple levels of hierarchy in a single layout run may allow + * cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` + * (or not set at all), the default behavior is `SEPARATE_CHILDREN`. + */ + public static final IProperty HIERARCHY_HANDLING = CoreOptions.HIERARCHY_HANDLING; + + /** + * Default value for {@link #SEPARATE_CONNECTED_COMPONENTS} with algorithm "ELK Layered". + */ + private static final boolean SEPARATE_CONNECTED_COMPONENTS_DEFAULT = true; + + /** + * Whether each connected component should be processed separately. + */ + public static final IProperty SEPARATE_CONNECTED_COMPONENTS = new Property( + CoreOptions.SEPARATE_CONNECTED_COMPONENTS, + SEPARATE_CONNECTED_COMPONENTS_DEFAULT); + + /** + * Whether this node allows to route self loops inside of it instead of around it. If set to true, + * this will make the node a compound node if it isn't already, and will require the layout algorithm + * to support compound nodes with hierarchical ports. + */ + public static final IProperty INSIDE_SELF_LOOPS_ACTIVATE = CoreOptions.INSIDE_SELF_LOOPS_ACTIVATE; + + /** + * Whether a self loop should be routed inside a node instead of around that node. + */ + public static final IProperty INSIDE_SELF_LOOPS_YO = CoreOptions.INSIDE_SELF_LOOPS_YO; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * By default, the fixed layout provider will enlarge a graph until it is large enough to contain + * its children. If this option is set, it won't do so. + */ + public static final IProperty NODE_SIZE_FIXED_GRAPH_SIZE = CoreOptions.NODE_SIZE_FIXED_GRAPH_SIZE; + + /** + * Default value for {@link #DIRECTION} with algorithm "ELK Layered". + */ + private static final Direction DIRECTION_DEFAULT = Direction.UNDEFINED; + + /** + * Overall direction of edges: horizontal (right / left) or + * vertical (down / up). + */ + public static final IProperty DIRECTION = new Property( + CoreOptions.DIRECTION, + DIRECTION_DEFAULT); + + /** + * Hints for where node labels are to be placed; if empty, the node label's position is not + * modified. + */ + public static final IProperty> NODE_LABELS_PLACEMENT = CoreOptions.NODE_LABELS_PLACEMENT; + + /** + * Define padding for node labels that are placed inside of a node. + */ + public static final IProperty NODE_LABELS_PADDING = CoreOptions.NODE_LABELS_PADDING; + + /** + * Decides on a placement method for port labels; if empty, the node label's position is not + * modified. + */ + public static final IProperty> PORT_LABELS_PLACEMENT = CoreOptions.PORT_LABELS_PLACEMENT; + + /** + * Use 'portLabels.placement': NEXT_TO_PORT_OF_POSSIBLE. + */ + @Deprecated + public static final IProperty PORT_LABELS_NEXT_TO_PORT_IF_POSSIBLE = CoreOptions.PORT_LABELS_NEXT_TO_PORT_IF_POSSIBLE; + + /** + * If this option is true (default), the labels of a port will be treated as a group when + * it comes to centering them next to their port. If this option is false, only the first label will + * be centered next to the port, with the others being placed below. This only applies to labels of + * eastern and western ports and will have no effect if labels are not placed next to their port. + */ + public static final IProperty PORT_LABELS_TREAT_AS_GROUP = CoreOptions.PORT_LABELS_TREAT_AS_GROUP; + + /** + * Default value for {@link #PORT_ALIGNMENT_DEFAULT} with algorithm "ELK Layered". + */ + private static final PortAlignment PORT_ALIGNMENT_DEFAULT_DEFAULT = PortAlignment.JUSTIFIED; + + /** + * Defines the default port distribution for a node. May be overridden for each side individually. + */ + public static final IProperty PORT_ALIGNMENT_DEFAULT = new Property( + CoreOptions.PORT_ALIGNMENT_DEFAULT, + PORT_ALIGNMENT_DEFAULT_DEFAULT); + + /** + * Defines how ports on the northern side are placed, overriding the node's general port alignment. + */ + public static final IProperty PORT_ALIGNMENT_NORTH = CoreOptions.PORT_ALIGNMENT_NORTH; + + /** + * Defines how ports on the southern side are placed, overriding the node's general port alignment. + */ + public static final IProperty PORT_ALIGNMENT_SOUTH = CoreOptions.PORT_ALIGNMENT_SOUTH; + + /** + * Defines how ports on the western side are placed, overriding the node's general port alignment. + */ + public static final IProperty PORT_ALIGNMENT_WEST = CoreOptions.PORT_ALIGNMENT_WEST; + + /** + * Defines how ports on the eastern side are placed, overriding the node's general port alignment. + */ + public static final IProperty PORT_ALIGNMENT_EAST = CoreOptions.PORT_ALIGNMENT_EAST; + + /** + * Adds bend points even if an edge does not change direction. If true, each long edge dummy + * will contribute a bend point to its edges and hierarchy-crossing edges will always get a + * bend point where they cross hierarchy boundaries. By default, bend points are only added + * where an edge changes direction. + */ + public static final IProperty UNNECESSARY_BENDPOINTS = LayeredMetaDataProvider.UNNECESSARY_BENDPOINTS; + + /** + * Strategy for node layering. + */ + public static final IProperty LAYERING_STRATEGY = LayeredMetaDataProvider.LAYERING_STRATEGY; + + /** + * Reduces number of dummy nodes after layering phase (if possible). + */ + public static final IProperty LAYERING_NODE_PROMOTION_STRATEGY = LayeredMetaDataProvider.LAYERING_NODE_PROMOTION_STRATEGY; + + /** + * How much effort should be spent to produce a nice layout. + */ + public static final IProperty THOROUGHNESS = LayeredMetaDataProvider.THOROUGHNESS; + + /** + * Determines a constraint on the placement of the node regarding the layering. + */ + public static final IProperty LAYERING_LAYER_CONSTRAINT = LayeredMetaDataProvider.LAYERING_LAYER_CONSTRAINT; + + /** + * Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines + * which edges to reverse to break the cycles. Reversed edges will end up pointing to the + * opposite direction of regular edges (that is, reversed edges will point left if edges + * usually point right). + */ + public static final IProperty CYCLE_BREAKING_STRATEGY = LayeredMetaDataProvider.CYCLE_BREAKING_STRATEGY; + + /** + * Strategy for crossing minimization. + */ + public static final IProperty CROSSING_MINIMIZATION_STRATEGY = LayeredMetaDataProvider.CROSSING_MINIMIZATION_STRATEGY; + + /** + * The node order given by the model does not change to produce a better layout. E.g. if node A + * is before node B in the model this is not changed during crossing minimization. This assumes that the + * node model order is already respected before crossing minimization. This can be achieved by setting + * considerModelOrder.strategy to NODES_AND_EDGES. + */ + public static final IProperty CROSSING_MINIMIZATION_FORCE_NODE_MODEL_ORDER = LayeredMetaDataProvider.CROSSING_MINIMIZATION_FORCE_NODE_MODEL_ORDER; + + /** + * By default it is decided automatically if the greedy switch is activated or not. + * The decision is based on whether the size of the input graph (without dummy nodes) + * is smaller than the value of this option. A '0' enforces the activation. + */ + public static final IProperty CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD = LayeredMetaDataProvider.CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD; + + /** + * Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed + * after the regular crossing minimization as a post-processor. + * Note that if 'hierarchyHandling' is set to 'INCLUDE_CHILDREN', the 'greedySwitchHierarchical.type' + * option must be used. + */ + public static final IProperty CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE = LayeredMetaDataProvider.CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE; + + /** + * Activates the greedy switch heuristic in case hierarchical layout is used. + * The differences to the non-hierarchical case (see 'greedySwitch.type') are: + * 1) greedy switch is inactive by default, + * 3) only the option value set on the node at which hierarchical layout starts is relevant, and + * 2) if it's activated by the user, it properly addresses hierarchy-crossing edges. + */ + public static final IProperty CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE = LayeredMetaDataProvider.CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE; + + /** + * Preserves the order of nodes within a layer but still minimizes crossings between edges connecting + * long edge dummies. Derives the desired order from positions specified by the 'org.eclipse.elk.position' + * layout option. Requires a crossing minimization strategy that is able to process 'in-layer' constraints. + */ + public static final IProperty CROSSING_MINIMIZATION_SEMI_INTERACTIVE = LayeredMetaDataProvider.CROSSING_MINIMIZATION_SEMI_INTERACTIVE; + + /** + * Edges that have no ports are merged so they touch the connected nodes at the same points. + * When this option is disabled, one port is created for each edge directly connected to a + * node. When it is enabled, all such incoming edges share an input port, and all outgoing + * edges share an output port. + */ + public static final IProperty MERGE_EDGES = LayeredMetaDataProvider.MERGE_EDGES; + + /** + * If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports + * as possible. They are broken by the algorithm, with hierarchical ports inserted as + * required. Usually, one such port is created for each edge at each hierarchy crossing point. + * With this option set to true, we try to create as few hierarchical ports as possible in + * the process. In particular, all edges that form a hyperedge can share a port. + */ + public static final IProperty MERGE_HIERARCHY_EDGES = LayeredMetaDataProvider.MERGE_HIERARCHY_EDGES; + + /** + * Determines which point of a node is considered by interactive layout phases. + */ + public static final IProperty INTERACTIVE_REFERENCE_POINT = LayeredMetaDataProvider.INTERACTIVE_REFERENCE_POINT; + + /** + * Strategy for node placement. + */ + public static final IProperty NODE_PLACEMENT_STRATEGY = LayeredMetaDataProvider.NODE_PLACEMENT_STRATEGY; + + /** + * Tells the BK node placer to use a certain alignment (out of its four) instead of the + * one producing the smallest height, or the combination of all four. + */ + public static final IProperty NODE_PLACEMENT_BK_FIXED_ALIGNMENT = LayeredMetaDataProvider.NODE_PLACEMENT_BK_FIXED_ALIGNMENT; + + /** + * Whether feedback edges should be highlighted by routing around the nodes. + */ + public static final IProperty FEEDBACK_EDGES = LayeredMetaDataProvider.FEEDBACK_EDGES; + + /** + * Dampens the movement of nodes to keep the diagram from getting too large. + */ + public static final IProperty NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING = LayeredMetaDataProvider.NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING; + + /** + * Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE. + */ + public static final IProperty EDGE_ROUTING_SELF_LOOP_DISTRIBUTION = LayeredMetaDataProvider.EDGE_ROUTING_SELF_LOOP_DISTRIBUTION; + + /** + * Alter the ordering of the loops they can either be stacked or sequenced. + * It only takes effect for PortConstraints.FREE. + */ + public static final IProperty EDGE_ROUTING_SELF_LOOP_ORDERING = LayeredMetaDataProvider.EDGE_ROUTING_SELF_LOOP_ORDERING; + + /** + * Specifies how the content of a node are aligned. Each node can individually control the alignment of its + * contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that + * option. + */ + public static final IProperty> CONTENT_ALIGNMENT = CoreOptions.CONTENT_ALIGNMENT; + + /** + * Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges + * at the expense of diagram size. + * There is a subtle difference to the 'favorStraightEdges' option, which decides whether + * a balanced placement of the nodes is desired, or not. In bk terms this means combining the four + * alignments into a single balanced one, or not. This option on the other hand tries to straighten + * additional edges during the creation of each of the four alignments. + */ + public static final IProperty NODE_PLACEMENT_BK_EDGE_STRAIGHTENING = LayeredMetaDataProvider.NODE_PLACEMENT_BK_EDGE_STRAIGHTENING; + + /** + * Specifies whether and how post-process compaction is applied. + */ + public static final IProperty COMPACTION_POST_COMPACTION_STRATEGY = LayeredMetaDataProvider.COMPACTION_POST_COMPACTION_STRATEGY; + + /** + * Specifies whether and how post-process compaction is applied. + */ + public static final IProperty COMPACTION_POST_COMPACTION_CONSTRAINTS = LayeredMetaDataProvider.COMPACTION_POST_COMPACTION_CONSTRAINTS; + + /** + * Tries to further compact components (disconnected sub-graphs). + */ + public static final IProperty COMPACTION_CONNECTED_COMPONENTS = LayeredMetaDataProvider.COMPACTION_CONNECTED_COMPONENTS; + + /** + * Makes room around high degree nodes to place leafs and trees. + */ + public static final IProperty HIGH_DEGREE_NODES_TREATMENT = LayeredMetaDataProvider.HIGH_DEGREE_NODES_TREATMENT; + + /** + * Whether a node is considered to have a high degree. + */ + public static final IProperty HIGH_DEGREE_NODES_THRESHOLD = LayeredMetaDataProvider.HIGH_DEGREE_NODES_THRESHOLD; + + /** + * Maximum height of a subtree connected to a high degree node to be moved to separate layers. + */ + public static final IProperty HIGH_DEGREE_NODES_TREE_HEIGHT = LayeredMetaDataProvider.HIGH_DEGREE_NODES_TREE_HEIGHT; + + /** + * The minimal size to which a node can be reduced. + */ + public static final IProperty NODE_SIZE_MINIMUM = CoreOptions.NODE_SIZE_MINIMUM; + + /** + * This option is not used as option, but as output of the layout algorithms. It is + * attached to edges and determines the points where junction symbols should be drawn in + * order to represent hyperedges with orthogonal routing. Whether such points are computed + * depends on the chosen layout algorithm and edge routing style. The points are put into + * the vector chain with no specific order. + */ + public static final IProperty JUNCTION_POINTS = CoreOptions.JUNCTION_POINTS; + + /** + * The thickness of an edge. This is a hint on the line width used to draw an edge, possibly + * requiring more space to be reserved for it. + */ + public static final IProperty EDGE_THICKNESS = CoreOptions.EDGE_THICKNESS; + + /** + * Gives a hint on where to put edge labels. + */ + public static final IProperty EDGE_LABELS_PLACEMENT = CoreOptions.EDGE_LABELS_PLACEMENT; + + /** + * If true, an edge label is placed directly on its edge. May only apply to center edge labels. + * This kind of label placement is only advisable if the label's rendering is such that it is not + * crossed by its edge and thus stays legible. + */ + public static final IProperty EDGE_LABELS_INLINE = CoreOptions.EDGE_LABELS_INLINE; + + /** + * How likely it is to use cross-hierarchy (1) vs bottom-up (-1). + */ + public static final IProperty CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS = LayeredMetaDataProvider.CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS; + + /** + * The index of a port in the fixed order around a node. The order is assumed as clockwise, + * starting with the leftmost port on the top side. This option must be set if 'Port + * Constraints' is set to FIXED_ORDER and no specific positions are given for the ports. + * Additionally, the option 'Port Side' must be defined in this case. + */ + public static final IProperty PORT_INDEX = CoreOptions.PORT_INDEX; + + /** + * Whether the node should be regarded as a comment box instead of a regular node. In that + * case its placement should be similar to how labels are handled. Any edges incident to a + * comment box specify to which graph elements the comment is related. + */ + public static final IProperty COMMENT_BOX = CoreOptions.COMMENT_BOX; + + /** + * Whether the node should be handled as a hypernode. + */ + public static final IProperty HYPERNODE = CoreOptions.HYPERNODE; + + /** + * The offset to the port position where connections shall be attached. + */ + public static final IProperty PORT_ANCHOR = CoreOptions.PORT_ANCHOR; + + /** + * Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. + * a pair of nodes with different partition indices is then placed such that the node with lower index is + * placed to the left of the other node (with left-to-right layout direction). Depending on the layout + * algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least + * if edges that cross partitions are not part of a partition-crossing cycle. + */ + public static final IProperty PARTITIONING_ACTIVATE = CoreOptions.PARTITIONING_ACTIVATE; + + /** + * Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower + * partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout + * direction). + */ + public static final IProperty PARTITIONING_PARTITION = CoreOptions.PARTITIONING_PARTITION; + + /** + * Defines a loose upper bound on the width of the MinWidth layerer. + * If set to '-1' multiple values are tested and the best result is selected. + */ + public static final IProperty LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH = LayeredMetaDataProvider.LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH; + + /** + * Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which + * haven't been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth + * algorithm. Compensates for too high estimations. + * If set to '-1' multiple values are tested and the best result is selected. + */ + public static final IProperty LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR = LayeredMetaDataProvider.LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR; + + /** + * The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to + * specify a pre-defined position. + */ + public static final IProperty POSITION = CoreOptions.POSITION; + + /** + * Specifies whether non-flow ports may switch sides if their node's port constraints are either FIXED_SIDE + * or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. + * For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. + * Further note that the underlying criterium whether to switch sides or not solely relies on the + * minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed. + */ + public static final IProperty ALLOW_NON_FLOW_PORTS_TO_SWITCH_SIDES = LayeredMetaDataProvider.ALLOW_NON_FLOW_PORTS_TO_SWITCH_SIDES; + + /** + * Limits the number of iterations for node promotion. + */ + public static final IProperty LAYERING_NODE_PROMOTION_MAX_ITERATIONS = LayeredMetaDataProvider.LAYERING_NODE_PROMOTION_MAX_ITERATIONS; + + /** + * Method to decide on edge label sides. + */ + public static final IProperty EDGE_LABELS_SIDE_SELECTION = LayeredMetaDataProvider.EDGE_LABELS_SIDE_SELECTION; + + /** + * Determines in which layer center labels of long edges should be placed. + */ + public static final IProperty EDGE_LABELS_CENTER_LABEL_PLACEMENT_STRATEGY = LayeredMetaDataProvider.EDGE_LABELS_CENTER_LABEL_PLACEMENT_STRATEGY; + + /** + * Margins define additional space around the actual bounds of a graph element. For instance, + * ports or labels being placed on the outside of a node's border might introduce such a + * margin. The margin is used to guarantee non-overlap of other graph elements with those + * ports or labels. + */ + public static final IProperty MARGINS = CoreOptions.MARGINS; + + /** + * The maximum number of nodes allowed per layer. + */ + public static final IProperty LAYERING_COFFMAN_GRAHAM_LAYER_BOUND = LayeredMetaDataProvider.LAYERING_COFFMAN_GRAHAM_LAYER_BOUND; + + /** + * Favor straight edges over a balanced node placement. + * The default behavior is determined automatically based on the used 'edgeRouting'. + * For an orthogonal style it is set to true, for all other styles to false. + */ + public static final IProperty NODE_PLACEMENT_FAVOR_STRAIGHT_EDGES = LayeredMetaDataProvider.NODE_PLACEMENT_FAVOR_STRAIGHT_EDGES; + + /** + * Additional space around the sets of ports on each node side. For each side of a node, + * this option can reserve additional space before and after the ports on each side. For + * example, a top spacing of 20 makes sure that the first port on the western and eastern + * side is 20 units away from the northern border. + */ + public static final IProperty SPACING_PORTS_SURROUNDING = CoreOptions.SPACING_PORTS_SURROUNDING; + + /** + * Specifies how drawings of the same graph with different layout directions compare to each other: + * either a natural reading direction is preserved or the drawings are rotated versions of each other. + */ + public static final IProperty DIRECTION_CONGRUENCY = LayeredMetaDataProvider.DIRECTION_CONGRUENCY; + + /** + * Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node's ports are + * distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes. + */ + public static final IProperty PORT_SORTING_STRATEGY = LayeredMetaDataProvider.PORT_SORTING_STRATEGY; + + /** + * Width of the strip to the left and to the right of each layer where the polyline edge router + * is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward + * bend points for nodes that extent almost to the edge of their layer. + */ + public static final IProperty EDGE_ROUTING_POLYLINE_SLOPED_EDGE_ZONE_WIDTH = LayeredMetaDataProvider.EDGE_ROUTING_POLYLINE_SLOPED_EDGE_ZONE_WIDTH; + + /** + * Allows to set a constraint which specifies of which node + * the current node is the predecessor. + * If set to 's' then the node is the predecessor of 's' and is in the same layer + */ + public static final IProperty CROSSING_MINIMIZATION_IN_LAYER_PRED_OF = LayeredMetaDataProvider.CROSSING_MINIMIZATION_IN_LAYER_PRED_OF; + + /** + * Allows to set a constraint which specifies of which node + * the current node is the successor. + * If set to 's' then the node is the successor of 's' and is in the same layer + */ + public static final IProperty CROSSING_MINIMIZATION_IN_LAYER_SUCC_OF = LayeredMetaDataProvider.CROSSING_MINIMIZATION_IN_LAYER_SUCC_OF; + + /** + * Allows to set a constraint regarding the layer placement of a node. + * Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. + * If set to i, it expresses that the node should be placed in i-th layer. + * Should i>=n be true then the node is placed in the last layer of the drawing. + * + * Note that this option is not part of any of ELK Layered's default configurations + * but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, + * which must be applied manually or used via the `DiagramLayoutEngine. + */ + public static final IProperty LAYERING_LAYER_CHOICE_CONSTRAINT = LayeredMetaDataProvider.LAYERING_LAYER_CHOICE_CONSTRAINT; + + /** + * Allows to set a constraint regarding the position placement of a node in a layer. + * Assumed the layer in which the node placed includes n other nodes and i < n. + * If set to i, it expresses that the node should be placed at the i-th position. + * Should i>=n be true then the node is placed at the last position in the layer. + * + * Note that this option is not part of any of ELK Layered's default configurations + * but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, + * which must be applied manually or used via the `DiagramLayoutEngine. + */ + public static final IProperty CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT = LayeredMetaDataProvider.CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT; + + /** + * Whether the graph should be changeable interactively and by setting constraints + */ + public static final IProperty INTERACTIVE_LAYOUT = CoreOptions.INTERACTIVE_LAYOUT; + + /** + * Layer identifier that was calculated by ELK Layered for a node. + * This is only generated if interactiveLayot or generatePositionAndLayerIds is set. + */ + public static final IProperty LAYERING_LAYER_ID = LayeredMetaDataProvider.LAYERING_LAYER_ID; + + /** + * Position within a layer that was determined by ELK Layered for a node. + * This is only generated if interactiveLayot or generatePositionAndLayerIds is set. + */ + public static final IProperty CROSSING_MINIMIZATION_POSITION_ID = LayeredMetaDataProvider.CROSSING_MINIMIZATION_POSITION_ID; + + /** + * Preserves the order of nodes and edges in the model file if this does not lead to additional edge + * crossings. Depending on the strategy this is not always possible since the node and edge order might be + * conflicting. + */ + public static final IProperty CONSIDER_MODEL_ORDER_STRATEGY = LayeredMetaDataProvider.CONSIDER_MODEL_ORDER_STRATEGY; + + /** + * Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a + * previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a + * vertical layout. + */ + public static final IProperty CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY = LayeredMetaDataProvider.CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY; + + /** + * Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the + * crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. + * This allows some edge crossings in favor of preserving the model order. It is advised to set this value to + * a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no + * influence (0). + */ + public static final IProperty CONSIDER_MODEL_ORDER_CROSSING_COUNTER_NODE_INFLUENCE = LayeredMetaDataProvider.CONSIDER_MODEL_ORDER_CROSSING_COUNTER_NODE_INFLUENCE; + + /** + * Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the + * crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. + * This allows some edge crossings in favor of preserving the model order. It is advised to set this value to + * a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no + * influence (0). + */ + public static final IProperty CONSIDER_MODEL_ORDER_CROSSING_COUNTER_PORT_INFLUENCE = LayeredMetaDataProvider.CONSIDER_MODEL_ORDER_CROSSING_COUNTER_PORT_INFLUENCE; + + /** + * Set on a node to not set a model order for this node even though it is a real node. + */ + public static final IProperty CONSIDER_MODEL_ORDER_NO_MODEL_ORDER = LayeredMetaDataProvider.CONSIDER_MODEL_ORDER_NO_MODEL_ORDER; + + /** + * If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. + * INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. + * FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub + * optimal drawings in terms of used area since the ordering should be respected. + */ + public static final IProperty CONSIDER_MODEL_ORDER_COMPONENTS = LayeredMetaDataProvider.CONSIDER_MODEL_ORDER_COMPONENTS; + + /** + * If disabled the port order of output ports is derived from the edge order and input ports are ordered by + * their incoming connections. If enabled all ports are ordered by the port model order. + */ + public static final IProperty CONSIDER_MODEL_ORDER_PORT_MODEL_ORDER = LayeredMetaDataProvider.CONSIDER_MODEL_ORDER_PORT_MODEL_ORDER; + + /** + * If enabled position id and layer id are generated, which are usually only used internally + * when setting the interactiveLayout option. This option should be specified on the root node. + */ + public static final IProperty GENERATE_POSITION_AND_LAYER_IDS = LayeredMetaDataProvider.GENERATE_POSITION_AND_LAYER_IDS; + + /** + * Layouter-specific algorithm factory. + */ + public static class LayeredFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new LayeredLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.layered") + .name("ELK Layered") + .description("Layer-based algorithm provided by the Eclipse Layout Kernel. Arranges as many edges as possible into one direction by placing nodes into subsequent layers. This implementation supports different routing styles (straight, orthogonal, splines); if orthogonal routing is selected, arbitrary port constraints are respected, thus enabling the layout of block diagrams such as actor-oriented models or circuit schematics. Furthermore, full layout of compound graphs with cross-hierarchy edges is supported when the respective option is activated on the top level.") + .providerFactory(new LayeredFactory()) + .category("org.eclipse.elk.layered") + .melkBundleName(null) + .definingBundleId("org.eclipse.elk.alg.layered") + .imagePath("images/layered_layout.png") + .supportedFeatures(EnumSet.of(GraphFeature.SELF_LOOPS, GraphFeature.INSIDE_SELF_LOOPS, GraphFeature.MULTI_EDGES, GraphFeature.EDGE_LABELS, GraphFeature.PORTS, GraphFeature.COMPOUND, GraphFeature.CLUSTERS)) + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.commentComment", + SPACING_COMMENT_COMMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.commentNode", + SPACING_COMMENT_NODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.componentComponent", + SPACING_COMPONENT_COMPONENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.edgeEdge", + SPACING_EDGE_EDGE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.edgeLabel", + SPACING_EDGE_LABEL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.edgeNode", + SPACING_EDGE_NODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.labelLabel", + SPACING_LABEL_LABEL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.labelPortHorizontal", + SPACING_LABEL_PORT_HORIZONTAL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.labelPortVertical", + SPACING_LABEL_PORT_VERTICAL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.labelNode", + SPACING_LABEL_NODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.nodeSelfLoop", + SPACING_NODE_SELF_LOOP.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.portPort", + SPACING_PORT_PORT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.individual", + SPACING_INDIVIDUAL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.spacing.baseValue", + SPACING_BASE_VALUE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers", + SPACING_EDGE_EDGE_BETWEEN_LAYERS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers", + SPACING_EDGE_NODE_BETWEEN_LAYERS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers", + SPACING_NODE_NODE_BETWEEN_LAYERS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.priority", + PRIORITY_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.priority.direction", + PRIORITY_DIRECTION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.priority.shortness", + PRIORITY_SHORTNESS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.priority.straightness", + PRIORITY_STRAIGHTNESS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.wrapping.strategy", + WRAPPING_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.wrapping.additionalEdgeSpacing", + WRAPPING_ADDITIONAL_EDGE_SPACING.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.wrapping.correctionFactor", + WRAPPING_CORRECTION_FACTOR.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.wrapping.cutting.strategy", + WRAPPING_CUTTING_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.wrapping.cutting.cuts", + WRAPPING_CUTTING_CUTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.wrapping.cutting.msd.freedom", + WRAPPING_CUTTING_MSD_FREEDOM.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.wrapping.validify.strategy", + WRAPPING_VALIDIFY_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.wrapping.validify.forbiddenIndices", + WRAPPING_VALIDIFY_FORBIDDEN_INDICES.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.wrapping.multiEdge.improveCuts", + WRAPPING_MULTI_EDGE_IMPROVE_CUTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty", + WRAPPING_MULTI_EDGE_DISTANCE_PENALTY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges", + WRAPPING_MULTI_EDGE_IMPROVE_WRAPPED_EDGES.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility", + NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default", + NODE_PLACEMENT_NETWORK_SIMPLEX_NODE_FLEXIBILITY_DEFAULT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.edgeRouting.splines.mode", + EDGE_ROUTING_SPLINES_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor", + EDGE_ROUTING_SPLINES_SLOPPY_LAYER_SPACING_FACTOR.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.topdownLayout", + TOPDOWN_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.topdown.scaleFactor", + TOPDOWN_SCALE_FACTOR.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.topdown.hierarchicalNodeWidth", + TOPDOWN_HIERARCHICAL_NODE_WIDTH.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.topdown.hierarchicalNodeAspectRatio", + TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.topdown.nodeType", + TOPDOWN_NODE_TYPE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.edgeRouting", + EDGE_ROUTING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.port.borderOffset", + PORT_BORDER_OFFSET_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.randomSeed", + RANDOM_SEED_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.aspectRatio", + ASPECT_RATIO_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.noLayout", + NO_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.portConstraints", + PORT_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.port.side", + PORT_SIDE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.debugMode", + DEBUG_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.alignment", + ALIGNMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.hierarchyHandling", + HIERARCHY_HANDLING.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.separateConnectedComponents", + SEPARATE_CONNECTED_COMPONENTS_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.insideSelfLoops.activate", + INSIDE_SELF_LOOPS_ACTIVATE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.insideSelfLoops.yo", + INSIDE_SELF_LOOPS_YO.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.nodeSize.fixedGraphSize", + NODE_SIZE_FIXED_GRAPH_SIZE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.direction", + DIRECTION_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.nodeLabels.placement", + NODE_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.nodeLabels.padding", + NODE_LABELS_PADDING.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.portLabels.placement", + PORT_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.portLabels.nextToPortIfPossible", + PORT_LABELS_NEXT_TO_PORT_IF_POSSIBLE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.portLabels.treatAsGroup", + PORT_LABELS_TREAT_AS_GROUP.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.portAlignment.default", + PORT_ALIGNMENT_DEFAULT_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.portAlignment.north", + PORT_ALIGNMENT_NORTH.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.portAlignment.south", + PORT_ALIGNMENT_SOUTH.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.portAlignment.west", + PORT_ALIGNMENT_WEST.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.portAlignment.east", + PORT_ALIGNMENT_EAST.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.unnecessaryBendpoints", + UNNECESSARY_BENDPOINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.layering.strategy", + LAYERING_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.layering.nodePromotion.strategy", + LAYERING_NODE_PROMOTION_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.thoroughness", + THOROUGHNESS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.layering.layerConstraint", + LAYERING_LAYER_CONSTRAINT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.cycleBreaking.strategy", + CYCLE_BREAKING_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.crossingMinimization.strategy", + CROSSING_MINIMIZATION_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder", + CROSSING_MINIMIZATION_FORCE_NODE_MODEL_ORDER.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold", + CROSSING_MINIMIZATION_GREEDY_SWITCH_ACTIVATION_THRESHOLD.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.crossingMinimization.greedySwitch.type", + CROSSING_MINIMIZATION_GREEDY_SWITCH_TYPE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type", + CROSSING_MINIMIZATION_GREEDY_SWITCH_HIERARCHICAL_TYPE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.crossingMinimization.semiInteractive", + CROSSING_MINIMIZATION_SEMI_INTERACTIVE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.mergeEdges", + MERGE_EDGES.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.mergeHierarchyEdges", + MERGE_HIERARCHY_EDGES.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.interactiveReferencePoint", + INTERACTIVE_REFERENCE_POINT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.nodePlacement.strategy", + NODE_PLACEMENT_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment", + NODE_PLACEMENT_BK_FIXED_ALIGNMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.feedbackEdges", + FEEDBACK_EDGES.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening", + NODE_PLACEMENT_LINEAR_SEGMENTS_DEFLECTION_DAMPENING.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.edgeRouting.selfLoopDistribution", + EDGE_ROUTING_SELF_LOOP_DISTRIBUTION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.edgeRouting.selfLoopOrdering", + EDGE_ROUTING_SELF_LOOP_ORDERING.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.contentAlignment", + CONTENT_ALIGNMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening", + NODE_PLACEMENT_BK_EDGE_STRAIGHTENING.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.compaction.postCompaction.strategy", + COMPACTION_POST_COMPACTION_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.compaction.postCompaction.constraints", + COMPACTION_POST_COMPACTION_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.compaction.connectedComponents", + COMPACTION_CONNECTED_COMPONENTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.highDegreeNodes.treatment", + HIGH_DEGREE_NODES_TREATMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.highDegreeNodes.threshold", + HIGH_DEGREE_NODES_THRESHOLD.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.highDegreeNodes.treeHeight", + HIGH_DEGREE_NODES_TREE_HEIGHT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.nodeSize.minimum", + NODE_SIZE_MINIMUM.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.junctionPoints", + JUNCTION_POINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.edge.thickness", + EDGE_THICKNESS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.edgeLabels.placement", + EDGE_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.edgeLabels.inline", + EDGE_LABELS_INLINE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness", + CROSSING_MINIMIZATION_HIERARCHICAL_SWEEPINESS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.port.index", + PORT_INDEX.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.commentBox", + COMMENT_BOX.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.hypernode", + HYPERNODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.port.anchor", + PORT_ANCHOR.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.partitioning.activate", + PARTITIONING_ACTIVATE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.partitioning.partition", + PARTITIONING_PARTITION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth", + LAYERING_MIN_WIDTH_UPPER_BOUND_ON_WIDTH.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor", + LAYERING_MIN_WIDTH_UPPER_LAYER_ESTIMATION_SCALING_FACTOR.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.position", + POSITION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides", + ALLOW_NON_FLOW_PORTS_TO_SWITCH_SIDES.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.layering.nodePromotion.maxIterations", + LAYERING_NODE_PROMOTION_MAX_ITERATIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.edgeLabels.sideSelection", + EDGE_LABELS_SIDE_SELECTION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy", + EDGE_LABELS_CENTER_LABEL_PLACEMENT_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.margins", + MARGINS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.layering.coffmanGraham.layerBound", + LAYERING_COFFMAN_GRAHAM_LAYER_BOUND.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.nodePlacement.favorStraightEdges", + NODE_PLACEMENT_FAVOR_STRAIGHT_EDGES.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.spacing.portsSurrounding", + SPACING_PORTS_SURROUNDING.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.directionCongruency", + DIRECTION_CONGRUENCY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.portSortingStrategy", + PORT_SORTING_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth", + EDGE_ROUTING_POLYLINE_SLOPED_EDGE_ZONE_WIDTH.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.crossingMinimization.inLayerPredOf", + CROSSING_MINIMIZATION_IN_LAYER_PRED_OF.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.crossingMinimization.inLayerSuccOf", + CROSSING_MINIMIZATION_IN_LAYER_SUCC_OF.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.layering.layerChoiceConstraint", + LAYERING_LAYER_CHOICE_CONSTRAINT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint", + CROSSING_MINIMIZATION_POSITION_CHOICE_CONSTRAINT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.interactiveLayout", + INTERACTIVE_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.layering.layerId", + LAYERING_LAYER_ID.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.crossingMinimization.positionId", + CROSSING_MINIMIZATION_POSITION_ID.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.considerModelOrder.strategy", + CONSIDER_MODEL_ORDER_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy", + CONSIDER_MODEL_ORDER_LONG_EDGE_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence", + CONSIDER_MODEL_ORDER_CROSSING_COUNTER_NODE_INFLUENCE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence", + CONSIDER_MODEL_ORDER_CROSSING_COUNTER_PORT_INFLUENCE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.considerModelOrder.noModelOrder", + CONSIDER_MODEL_ORDER_NO_MODEL_ORDER.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.considerModelOrder.components", + CONSIDER_MODEL_ORDER_COMPONENTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.considerModelOrder.portModelOrder", + CONSIDER_MODEL_ORDER_PORT_MODEL_ORDER.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.layered", + "org.eclipse.elk.layered.generatePositionAndLayerIds", + GENERATE_POSITION_AND_LAYER_IDS.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.libavoid/src-gen/org/eclipse/elk/alg/libavoid/options/LibavoidMetaDataProvider.java b/plugins/org.eclipse.elk.alg.libavoid/src-gen/org/eclipse/elk/alg/libavoid/options/LibavoidMetaDataProvider.java new file mode 100644 index 000000000..f14bc5b07 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.libavoid/src-gen/org/eclipse/elk/alg/libavoid/options/LibavoidMetaDataProvider.java @@ -0,0 +1,542 @@ +/** + * Copyright (c) 2016, 2023 Kiel University, Primetals Technologies Austria GmbH and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.libavoid.options; + +import java.util.EnumSet; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutCategoryData; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class LibavoidMetaDataProvider implements ILayoutMetaDataProvider { + /** + * Default value for {@link #SEGMENT_PENALTY}. + */ + private static final double SEGMENT_PENALTY_DEFAULT = 10; + + /** + * This penalty is applied for each segment in the connector path beyond the first. + * This should always normally be set when doing orthogonal routing to prevent + * step-like connector paths. + */ + public static final IProperty SEGMENT_PENALTY = new Property( + "org.eclipse.elk.alg.libavoid.segmentPenalty", + SEGMENT_PENALTY_DEFAULT, + null, + null); + + /** + * Default value for {@link #ANGLE_PENALTY}. + */ + private static final double ANGLE_PENALTY_DEFAULT = 0; + + /** + * This penalty is applied in its full amount to tight acute bends in the connector path. + * A smaller portion of the penalty is applied for slight bends, i.e., where the bend is close + * to 180 degrees. This is useful for polyline routing where there is some evidence that tighter + * corners are worse for readability, but that slight bends might not be so bad, + * especially when smoothed by curves. + */ + public static final IProperty ANGLE_PENALTY = new Property( + "org.eclipse.elk.alg.libavoid.anglePenalty", + ANGLE_PENALTY_DEFAULT, + null, + null); + + /** + * Default value for {@link #CROSSING_PENALTY}. + */ + private static final double CROSSING_PENALTY_DEFAULT = 0; + + /** + * This penalty is applied whenever a connector path crosses another connector path. + * It takes shared paths into consideration and the penalty is only applied + * if there is an actual crossing. + */ + public static final IProperty CROSSING_PENALTY = new Property( + "org.eclipse.elk.alg.libavoid.crossingPenalty", + CROSSING_PENALTY_DEFAULT, + null, + null); + + /** + * Default value for {@link #CLUSTER_CROSSING_PENALTY}. + */ + private static final double CLUSTER_CROSSING_PENALTY_DEFAULT = 0; + + /** + * This penalty is applied whenever a connector path crosses a cluster boundary. + */ + public static final IProperty CLUSTER_CROSSING_PENALTY = new Property( + "org.eclipse.elk.alg.libavoid.clusterCrossingPenalty", + CLUSTER_CROSSING_PENALTY_DEFAULT, + null, + null); + + /** + * Default value for {@link #FIXED_SHARED_PATH_PENALTY}. + */ + private static final double FIXED_SHARED_PATH_PENALTY_DEFAULT = 0; + + /** + * This penalty is applied whenever a connector path shares some segments with an immovable + * portion of an existing connector route (such as the first or last segment of a connector). + */ + public static final IProperty FIXED_SHARED_PATH_PENALTY = new Property( + "org.eclipse.elk.alg.libavoid.fixedSharedPathPenalty", + FIXED_SHARED_PATH_PENALTY_DEFAULT, + null, + null); + + /** + * Default value for {@link #PORT_DIRECTION_PENALTY}. + */ + private static final double PORT_DIRECTION_PENALTY_DEFAULT = 0; + + /** + * This penalty is applied to port selection choice when the other end of the connector + * being routed does not appear in any of the 90 degree visibility cones centered on the + * visibility directions for the port. + */ + public static final IProperty PORT_DIRECTION_PENALTY = new Property( + "org.eclipse.elk.alg.libavoid.portDirectionPenalty", + PORT_DIRECTION_PENALTY_DEFAULT, + null, + null); + + /** + * Default value for {@link #SHAPE_BUFFER_DISTANCE}. + */ + private static final double SHAPE_BUFFER_DISTANCE_DEFAULT = 4; + + /** + * This parameter defines the spacing distance that will be added to the sides of each + * shape when determining obstacle sizes for routing. This controls how closely connectors + * pass shapes, and can be used to prevent connectors overlapping with shape boundaries. + */ + public static final IProperty SHAPE_BUFFER_DISTANCE = new Property( + "org.eclipse.elk.alg.libavoid.shapeBufferDistance", + SHAPE_BUFFER_DISTANCE_DEFAULT, + null, + null); + + /** + * Default value for {@link #IDEAL_NUDGING_DISTANCE}. + */ + private static final double IDEAL_NUDGING_DISTANCE_DEFAULT = 4; + + /** + * This parameter defines the spacing distance that will be used for nudging apart + * overlapping corners and line segments of connectors. + */ + public static final IProperty IDEAL_NUDGING_DISTANCE = new Property( + "org.eclipse.elk.alg.libavoid.idealNudgingDistance", + IDEAL_NUDGING_DISTANCE_DEFAULT, + null, + null); + + /** + * Default value for {@link #REVERSE_DIRECTION_PENALTY}. + */ + private static final double REVERSE_DIRECTION_PENALTY_DEFAULT = 0; + + /** + * This penalty is applied whenever a connector path travels in the direction opposite + * of the destination from the source endpoint. By default this penalty is set to zero. + * This shouldn't be needed in most cases but can be useful if you use penalties such as + * crossingPenalty which cause connectors to loop around obstacles. + */ + public static final IProperty REVERSE_DIRECTION_PENALTY = new Property( + "org.eclipse.elk.alg.libavoid.reverseDirectionPenalty", + REVERSE_DIRECTION_PENALTY_DEFAULT, + null, + null); + + /** + * Default value for {@link #NUDGE_ORTHOGONAL_SEGMENTS_CONNECTED_TO_SHAPES}. + */ + private static final boolean NUDGE_ORTHOGONAL_SEGMENTS_CONNECTED_TO_SHAPES_DEFAULT = false; + + /** + * This option causes the final segments of connectors, which are attached to shapes, + * to be nudged apart. Usually these segments are fixed, since they are considered to be + * attached to ports. + */ + public static final IProperty NUDGE_ORTHOGONAL_SEGMENTS_CONNECTED_TO_SHAPES = new Property( + "org.eclipse.elk.alg.libavoid.nudgeOrthogonalSegmentsConnectedToShapes", + NUDGE_ORTHOGONAL_SEGMENTS_CONNECTED_TO_SHAPES_DEFAULT, + null, + null); + + /** + * Default value for {@link #IMPROVE_HYPEREDGE_ROUTES_MOVING_JUNCTIONS}. + */ + private static final boolean IMPROVE_HYPEREDGE_ROUTES_MOVING_JUNCTIONS_DEFAULT = true; + + /** + * This option causes hyperedge routes to be locally improved fixing obviously bad paths. + * As part of this process libavoid will effectively move junctions, setting new ideal positions + * for each junction. + */ + public static final IProperty IMPROVE_HYPEREDGE_ROUTES_MOVING_JUNCTIONS = new Property( + "org.eclipse.elk.alg.libavoid.improveHyperedgeRoutesMovingJunctions", + IMPROVE_HYPEREDGE_ROUTES_MOVING_JUNCTIONS_DEFAULT, + null, + null); + + /** + * Default value for {@link #PENALISE_ORTHOGONAL_SHARED_PATHS_AT_CONN_ENDS}. + */ + private static final boolean PENALISE_ORTHOGONAL_SHARED_PATHS_AT_CONN_ENDS_DEFAULT = false; + + /** + * This option penalises and attempts to reroute orthogonal shared connector paths terminating + * at a common junction or shape connection pin. When multiple connector paths enter or leave + * the same side of a junction (or shape pin), the router will attempt to reroute these to + * different sides of the junction or different shape pins. This option depends on the + * fixedSharedPathPenalty penalty having been set. + */ + public static final IProperty PENALISE_ORTHOGONAL_SHARED_PATHS_AT_CONN_ENDS = new Property( + "org.eclipse.elk.alg.libavoid.penaliseOrthogonalSharedPathsAtConnEnds", + PENALISE_ORTHOGONAL_SHARED_PATHS_AT_CONN_ENDS_DEFAULT, + null, + null); + + /** + * Default value for {@link #NUDGE_ORTHOGONAL_TOUCHING_COLINEAR_SEGMENTS}. + */ + private static final boolean NUDGE_ORTHOGONAL_TOUCHING_COLINEAR_SEGMENTS_DEFAULT = false; + + /** + * This option can be used to control whether colinear line segments that touch just at + * their ends will be nudged apart. The overlap will usually be resolved in the other dimension, + * so this is not usually required. + */ + public static final IProperty NUDGE_ORTHOGONAL_TOUCHING_COLINEAR_SEGMENTS = new Property( + "org.eclipse.elk.alg.libavoid.nudgeOrthogonalTouchingColinearSegments", + NUDGE_ORTHOGONAL_TOUCHING_COLINEAR_SEGMENTS_DEFAULT, + null, + null); + + /** + * Default value for {@link #PERFORM_UNIFYING_NUDGING_PREPROCESSING_STEP}. + */ + private static final boolean PERFORM_UNIFYING_NUDGING_PREPROCESSING_STEP_DEFAULT = true; + + /** + * This option can be used to control whether the router performs a preprocessing step before + * orthogonal nudging where is tries to unify segments and centre them in free space. + * This generally results in better quality ordering and nudging. + */ + public static final IProperty PERFORM_UNIFYING_NUDGING_PREPROCESSING_STEP = new Property( + "org.eclipse.elk.alg.libavoid.performUnifyingNudgingPreprocessingStep", + PERFORM_UNIFYING_NUDGING_PREPROCESSING_STEP_DEFAULT, + null, + null); + + /** + * Default value for {@link #IMPROVE_HYPEREDGE_ROUTES_MOVING_ADDING_AND_DELETING_JUNCTIONS}. + */ + private static final boolean IMPROVE_HYPEREDGE_ROUTES_MOVING_ADDING_AND_DELETING_JUNCTIONS_DEFAULT = false; + + /** + * This option causes hyperedge routes to be locally improved fixing obviously bad paths. + * It can cause junctions and connectors to be added or removed from hyperedges. As part of + * this process libavoid will effectively move junctions by setting new ideal positions for + * each remaining or added junction. If set, this option overrides the + * improveHyperedgeRoutesMovingJunctions option. + */ + public static final IProperty IMPROVE_HYPEREDGE_ROUTES_MOVING_ADDING_AND_DELETING_JUNCTIONS = new Property( + "org.eclipse.elk.alg.libavoid.improveHyperedgeRoutesMovingAddingAndDeletingJunctions", + IMPROVE_HYPEREDGE_ROUTES_MOVING_ADDING_AND_DELETING_JUNCTIONS_DEFAULT, + null, + null); + + /** + * Default value for {@link #NUDGE_SHARED_PATHS_WITH_COMMON_END_POINT}. + */ + private static final boolean NUDGE_SHARED_PATHS_WITH_COMMON_END_POINT_DEFAULT = true; + + /** + * This option determines whether intermediate segments of connectors that are attached to + * common endpoints will be nudged apart. Usually these segments get nudged apart, but you + * may want to turn this off if you would prefer that entire shared paths terminating at a + * common end point should overlap. + */ + public static final IProperty NUDGE_SHARED_PATHS_WITH_COMMON_END_POINT = new Property( + "org.eclipse.elk.alg.libavoid.nudgeSharedPathsWithCommonEndPoint", + NUDGE_SHARED_PATHS_WITH_COMMON_END_POINT_DEFAULT, + null, + null); + + /** + * Default value for {@link #ENABLE_HYPEREDGES_FROM_COMMON_SOURCE}. + */ + private static final boolean ENABLE_HYPEREDGES_FROM_COMMON_SOURCE_DEFAULT = false; + + /** + * This option enables a post-processing step that creates hyperedges for all edges with the same source. + * Be aware that this step will significantly decrease performance. + */ + public static final IProperty ENABLE_HYPEREDGES_FROM_COMMON_SOURCE = new Property( + "org.eclipse.elk.alg.libavoid.enableHyperedgesFromCommonSource", + ENABLE_HYPEREDGES_FROM_COMMON_SOURCE_DEFAULT, + null, + null); + + /** + * Default value for {@link #IS_CLUSTER}. + */ + private static final boolean IS_CLUSTER_DEFAULT = false; + + /** + * This option marks a node as a cluster, resulting in its children being handled as + * relative to the graph itself while the marked node is only added as a cluster. + * Note that clusters are experimental and can therefore have a negative impact on performance. + * The cluster node cannot have: + * - clusters as children + * - outgoing or incoming connections (directly to the node) + * - ports + * Edges into or out of the cluster must be added across the cluster's borders, without the use of hierarchical ports. + */ + public static final IProperty IS_CLUSTER = new Property( + "org.eclipse.elk.alg.libavoid.isCluster", + IS_CLUSTER_DEFAULT, + null, + null); + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.segmentPenalty") + .group("") + .name("Segment Penalty") + .description("This penalty is applied for each segment in the connector path beyond the first. This should always normally be set when doing orthogonal routing to prevent step-like connector paths.") + .defaultValue(SEGMENT_PENALTY_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.anglePenalty") + .group("") + .name("Angle Penalty") + .description("This penalty is applied in its full amount to tight acute bends in the connector path. A smaller portion of the penalty is applied for slight bends, i.e., where the bend is close to 180 degrees. This is useful for polyline routing where there is some evidence that tighter corners are worse for readability, but that slight bends might not be so bad, especially when smoothed by curves.") + .defaultValue(ANGLE_PENALTY_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.crossingPenalty") + .group("") + .name("Crossing Penalty") + .description("This penalty is applied whenever a connector path crosses another connector path. It takes shared paths into consideration and the penalty is only applied if there is an actual crossing.") + .defaultValue(CROSSING_PENALTY_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.clusterCrossingPenalty") + .group("") + .name("Cluster Crossing Penalty") + .description("This penalty is applied whenever a connector path crosses a cluster boundary.") + .defaultValue(CLUSTER_CROSSING_PENALTY_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.fixedSharedPathPenalty") + .group("") + .name("Fixed Shared Path Penalty") + .description("This penalty is applied whenever a connector path shares some segments with an immovable portion of an existing connector route (such as the first or last segment of a connector).") + .defaultValue(FIXED_SHARED_PATH_PENALTY_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.portDirectionPenalty") + .group("") + .name("Port Direction Penalty") + .description("This penalty is applied to port selection choice when the other end of the connector being routed does not appear in any of the 90 degree visibility cones centered on the visibility directions for the port.") + .defaultValue(PORT_DIRECTION_PENALTY_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.shapeBufferDistance") + .group("") + .name("Shape Buffer Distance") + .description("This parameter defines the spacing distance that will be added to the sides of each shape when determining obstacle sizes for routing. This controls how closely connectors pass shapes, and can be used to prevent connectors overlapping with shape boundaries.") + .defaultValue(SHAPE_BUFFER_DISTANCE_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.idealNudgingDistance") + .group("") + .name("Ideal Nudging Distance") + .description("This parameter defines the spacing distance that will be used for nudging apart overlapping corners and line segments of connectors.") + .defaultValue(IDEAL_NUDGING_DISTANCE_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.reverseDirectionPenalty") + .group("") + .name("Reverse Direction Penalty") + .description("This penalty is applied whenever a connector path travels in the direction opposite of the destination from the source endpoint. By default this penalty is set to zero. This shouldn\'t be needed in most cases but can be useful if you use penalties such as crossingPenalty which cause connectors to loop around obstacles.") + .defaultValue(REVERSE_DIRECTION_PENALTY_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.nudgeOrthogonalSegmentsConnectedToShapes") + .group("") + .name("Nudge Orthogonal Segments") + .description("This option causes the final segments of connectors, which are attached to shapes, to be nudged apart. Usually these segments are fixed, since they are considered to be attached to ports.") + .defaultValue(NUDGE_ORTHOGONAL_SEGMENTS_CONNECTED_TO_SHAPES_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.improveHyperedgeRoutesMovingJunctions") + .group("") + .name("Improve Hyperedge Routes") + .description("This option causes hyperedge routes to be locally improved fixing obviously bad paths. As part of this process libavoid will effectively move junctions, setting new ideal positions for each junction.") + .defaultValue(IMPROVE_HYPEREDGE_ROUTES_MOVING_JUNCTIONS_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.penaliseOrthogonalSharedPathsAtConnEnds") + .group("") + .name("Penalise Orthogonal Shared Paths") + .description("This option penalises and attempts to reroute orthogonal shared connector paths terminating at a common junction or shape connection pin. When multiple connector paths enter or leave the same side of a junction (or shape pin), the router will attempt to reroute these to different sides of the junction or different shape pins. This option depends on the fixedSharedPathPenalty penalty having been set.") + .defaultValue(PENALISE_ORTHOGONAL_SHARED_PATHS_AT_CONN_ENDS_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.nudgeOrthogonalTouchingColinearSegments") + .group("") + .name("Nudge Orthogonal Touching Colinear Segments") + .description("This option can be used to control whether colinear line segments that touch just at their ends will be nudged apart. The overlap will usually be resolved in the other dimension, so this is not usually required.") + .defaultValue(NUDGE_ORTHOGONAL_TOUCHING_COLINEAR_SEGMENTS_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.performUnifyingNudgingPreprocessingStep") + .group("") + .name("Perform Unifying Nudging Preprocessing") + .description("This option can be used to control whether the router performs a preprocessing step before orthogonal nudging where is tries to unify segments and centre them in free space. This generally results in better quality ordering and nudging.") + .defaultValue(PERFORM_UNIFYING_NUDGING_PREPROCESSING_STEP_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.improveHyperedgeRoutesMovingAddingAndDeletingJunctions") + .group("") + .name("Improve Hyperedge Routes Add/Delete") + .description("This option causes hyperedge routes to be locally improved fixing obviously bad paths. It can cause junctions and connectors to be added or removed from hyperedges. As part of this process libavoid will effectively move junctions by setting new ideal positions for each remaining or added junction. If set, this option overrides the improveHyperedgeRoutesMovingJunctions option.") + .defaultValue(IMPROVE_HYPEREDGE_ROUTES_MOVING_ADDING_AND_DELETING_JUNCTIONS_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.nudgeSharedPathsWithCommonEndPoint") + .group("") + .name("Nudge Shared Paths With Common Endpoint") + .description("This option determines whether intermediate segments of connectors that are attached to common endpoints will be nudged apart. Usually these segments get nudged apart, but you may want to turn this off if you would prefer that entire shared paths terminating at a common end point should overlap.") + .defaultValue(NUDGE_SHARED_PATHS_WITH_COMMON_END_POINT_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.enableHyperedgesFromCommonSource") + .group("") + .name("Enable Hyperedges From Common Source") + .description("This option enables a post-processing step that creates hyperedges for all edges with the same source. Be aware that this step will significantly decrease performance.") + .defaultValue(ENABLE_HYPEREDGES_FROM_COMMON_SOURCE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alg.libavoid.isCluster") + .group("") + .name("Marks a node as a cluster") + .description("This option marks a node as a cluster, resulting in its children being handled as relative to the graph itself while the marked node is only added as a cluster. Note that clusters are experimental and can therefore have a negative impact on performance. The cluster node cannot have: - clusters as children - outgoing or incoming connections (directly to the node) - ports Edges into or out of the cluster must be added across the cluster\'s borders, without the use of hierarchical ports.") + .defaultValue(IS_CLUSTER_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutCategoryData.Builder() + .id("org.eclipse.elk.alg.libavoid.edge") + .name("Edge Routing") + .description("Only route the edges without touching the node's positions.") + .create() + ); + new org.eclipse.elk.alg.libavoid.options.LibavoidOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.alg.libavoid/src-gen/org/eclipse/elk/alg/libavoid/options/LibavoidOptions.java b/plugins/org.eclipse.elk.alg.libavoid/src-gen/org/eclipse/elk/alg/libavoid/options/LibavoidOptions.java new file mode 100644 index 000000000..7b6484b24 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.libavoid/src-gen/org/eclipse/elk/alg/libavoid/options/LibavoidOptions.java @@ -0,0 +1,373 @@ +/** + * Copyright (c) 2016, 2023 Kiel University, Primetals Technologies Austria GmbH and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.libavoid.options; + +import org.eclipse.elk.alg.libavoid.LibavoidLayoutProvider; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.Direction; +import org.eclipse.elk.core.options.EdgeRouting; +import org.eclipse.elk.core.options.PortConstraints; +import org.eclipse.elk.core.options.PortSide; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class LibavoidOptions implements ILayoutMetaDataProvider { + /** + * The id of the Libavoid algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.alg.libavoid"; + + /** + * Default value for {@link #DEBUG_MODE} with algorithm "Libavoid". + */ + private static final boolean DEBUG_MODE_DEFAULT = false; + + /** + * Whether additional debug information shall be generated. + */ + public static final IProperty DEBUG_MODE = new Property( + CoreOptions.DEBUG_MODE, + DEBUG_MODE_DEFAULT); + + /** + * The side of a node on which a port is situated. This option must be set if 'Port + * Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given + * for the ports. + */ + public static final IProperty PORT_SIDE = CoreOptions.PORT_SIDE; + + /** + * Overall direction of edges: horizontal (right / left) or + * vertical (down / up). + */ + public static final IProperty DIRECTION = CoreOptions.DIRECTION; + + /** + * Default value for {@link #EDGE_ROUTING} with algorithm "Libavoid". + */ + private static final EdgeRouting EDGE_ROUTING_DEFAULT = EdgeRouting.ORTHOGONAL; + + /** + * What kind of edge routing style should be applied for the content of a parent node. + * Algorithms may also set this option to single edges in order to mark them as splines. + * The bend point list of edges with this option set to SPLINES must be interpreted as control + * points for a piecewise cubic spline. + */ + public static final IProperty EDGE_ROUTING = new Property( + CoreOptions.EDGE_ROUTING, + EDGE_ROUTING_DEFAULT); + + /** + * Default value for {@link #PORT_CONSTRAINTS} with algorithm "Libavoid". + */ + private static final PortConstraints PORT_CONSTRAINTS_DEFAULT = PortConstraints.FREE; + + /** + * Defines constraints of the position of the ports of a node. + */ + public static final IProperty PORT_CONSTRAINTS = new Property( + CoreOptions.PORT_CONSTRAINTS, + PORT_CONSTRAINTS_DEFAULT); + + /** + * Node micro layout comprises the computation of node dimensions (if requested), the placement of ports + * and their labels, and the placement of node labels. + * The functionality is implemented independent of any specific layout algorithm and shouldn't have any + * negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, + * this option allows to deactivate the micro layout. + */ + public static final IProperty OMIT_NODE_MICRO_LAYOUT = CoreOptions.OMIT_NODE_MICRO_LAYOUT; + + /** + * This penalty is applied for each segment in the connector path beyond the first. + * This should always normally be set when doing orthogonal routing to prevent + * step-like connector paths. + */ + public static final IProperty SEGMENT_PENALTY = LibavoidMetaDataProvider.SEGMENT_PENALTY; + + /** + * This penalty is applied in its full amount to tight acute bends in the connector path. + * A smaller portion of the penalty is applied for slight bends, i.e., where the bend is close + * to 180 degrees. This is useful for polyline routing where there is some evidence that tighter + * corners are worse for readability, but that slight bends might not be so bad, + * especially when smoothed by curves. + */ + public static final IProperty ANGLE_PENALTY = LibavoidMetaDataProvider.ANGLE_PENALTY; + + /** + * This penalty is applied whenever a connector path crosses another connector path. + * It takes shared paths into consideration and the penalty is only applied + * if there is an actual crossing. + */ + public static final IProperty CROSSING_PENALTY = LibavoidMetaDataProvider.CROSSING_PENALTY; + + /** + * This penalty is applied whenever a connector path crosses a cluster boundary. + */ + public static final IProperty CLUSTER_CROSSING_PENALTY = LibavoidMetaDataProvider.CLUSTER_CROSSING_PENALTY; + + /** + * This penalty is applied whenever a connector path shares some segments with an immovable + * portion of an existing connector route (such as the first or last segment of a connector). + */ + public static final IProperty FIXED_SHARED_PATH_PENALTY = LibavoidMetaDataProvider.FIXED_SHARED_PATH_PENALTY; + + /** + * This penalty is applied to port selection choice when the other end of the connector + * being routed does not appear in any of the 90 degree visibility cones centered on the + * visibility directions for the port. + */ + public static final IProperty PORT_DIRECTION_PENALTY = LibavoidMetaDataProvider.PORT_DIRECTION_PENALTY; + + /** + * This parameter defines the spacing distance that will be added to the sides of each + * shape when determining obstacle sizes for routing. This controls how closely connectors + * pass shapes, and can be used to prevent connectors overlapping with shape boundaries. + */ + public static final IProperty SHAPE_BUFFER_DISTANCE = LibavoidMetaDataProvider.SHAPE_BUFFER_DISTANCE; + + /** + * This parameter defines the spacing distance that will be used for nudging apart + * overlapping corners and line segments of connectors. + */ + public static final IProperty IDEAL_NUDGING_DISTANCE = LibavoidMetaDataProvider.IDEAL_NUDGING_DISTANCE; + + /** + * This penalty is applied whenever a connector path travels in the direction opposite + * of the destination from the source endpoint. By default this penalty is set to zero. + * This shouldn't be needed in most cases but can be useful if you use penalties such as + * crossingPenalty which cause connectors to loop around obstacles. + */ + public static final IProperty REVERSE_DIRECTION_PENALTY = LibavoidMetaDataProvider.REVERSE_DIRECTION_PENALTY; + + /** + * This option causes the final segments of connectors, which are attached to shapes, + * to be nudged apart. Usually these segments are fixed, since they are considered to be + * attached to ports. + */ + public static final IProperty NUDGE_ORTHOGONAL_SEGMENTS_CONNECTED_TO_SHAPES = LibavoidMetaDataProvider.NUDGE_ORTHOGONAL_SEGMENTS_CONNECTED_TO_SHAPES; + + /** + * This option causes hyperedge routes to be locally improved fixing obviously bad paths. + * As part of this process libavoid will effectively move junctions, setting new ideal positions + * for each junction. + */ + public static final IProperty IMPROVE_HYPEREDGE_ROUTES_MOVING_JUNCTIONS = LibavoidMetaDataProvider.IMPROVE_HYPEREDGE_ROUTES_MOVING_JUNCTIONS; + + /** + * This option penalises and attempts to reroute orthogonal shared connector paths terminating + * at a common junction or shape connection pin. When multiple connector paths enter or leave + * the same side of a junction (or shape pin), the router will attempt to reroute these to + * different sides of the junction or different shape pins. This option depends on the + * fixedSharedPathPenalty penalty having been set. + */ + public static final IProperty PENALISE_ORTHOGONAL_SHARED_PATHS_AT_CONN_ENDS = LibavoidMetaDataProvider.PENALISE_ORTHOGONAL_SHARED_PATHS_AT_CONN_ENDS; + + /** + * This option can be used to control whether colinear line segments that touch just at + * their ends will be nudged apart. The overlap will usually be resolved in the other dimension, + * so this is not usually required. + */ + public static final IProperty NUDGE_ORTHOGONAL_TOUCHING_COLINEAR_SEGMENTS = LibavoidMetaDataProvider.NUDGE_ORTHOGONAL_TOUCHING_COLINEAR_SEGMENTS; + + /** + * This option can be used to control whether the router performs a preprocessing step before + * orthogonal nudging where is tries to unify segments and centre them in free space. + * This generally results in better quality ordering and nudging. + */ + public static final IProperty PERFORM_UNIFYING_NUDGING_PREPROCESSING_STEP = LibavoidMetaDataProvider.PERFORM_UNIFYING_NUDGING_PREPROCESSING_STEP; + + /** + * This option causes hyperedge routes to be locally improved fixing obviously bad paths. + * It can cause junctions and connectors to be added or removed from hyperedges. As part of + * this process libavoid will effectively move junctions by setting new ideal positions for + * each remaining or added junction. If set, this option overrides the + * improveHyperedgeRoutesMovingJunctions option. + */ + public static final IProperty IMPROVE_HYPEREDGE_ROUTES_MOVING_ADDING_AND_DELETING_JUNCTIONS = LibavoidMetaDataProvider.IMPROVE_HYPEREDGE_ROUTES_MOVING_ADDING_AND_DELETING_JUNCTIONS; + + /** + * This option determines whether intermediate segments of connectors that are attached to + * common endpoints will be nudged apart. Usually these segments get nudged apart, but you + * may want to turn this off if you would prefer that entire shared paths terminating at a + * common end point should overlap. + */ + public static final IProperty NUDGE_SHARED_PATHS_WITH_COMMON_END_POINT = LibavoidMetaDataProvider.NUDGE_SHARED_PATHS_WITH_COMMON_END_POINT; + + /** + * This option enables a post-processing step that creates hyperedges for all edges with the same source. + * Be aware that this step will significantly decrease performance. + */ + public static final IProperty ENABLE_HYPEREDGES_FROM_COMMON_SOURCE = LibavoidMetaDataProvider.ENABLE_HYPEREDGES_FROM_COMMON_SOURCE; + + /** + * This option marks a node as a cluster, resulting in its children being handled as + * relative to the graph itself while the marked node is only added as a cluster. + * Note that clusters are experimental and can therefore have a negative impact on performance. + * The cluster node cannot have: + * - clusters as children + * - outgoing or incoming connections (directly to the node) + * - ports + * Edges into or out of the cluster must be added across the cluster's borders, without the use of hierarchical ports. + */ + public static final IProperty IS_CLUSTER = LibavoidMetaDataProvider.IS_CLUSTER; + + /** + * Layouter-specific algorithm factory. + */ + public static class LibavoidFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new LibavoidLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.alg.libavoid") + .name("Libavoid") + .description("libavoid is a cross-platform C++ library providing fast, object-avoiding orthogonal and polyline connector routing for use in interactive diagram editors.") + .providerFactory(new LibavoidFactory()) + .category("org.eclipse.elk.alg.libavoid.edge") + .melkBundleName("Libavoid Connector Routing") + .definingBundleId("org.eclipse.elk.alg.libavoid") + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.debugMode", + DEBUG_MODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.port.side", + PORT_SIDE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.direction", + DIRECTION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.edgeRouting", + EDGE_ROUTING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.portConstraints", + PORT_CONSTRAINTS_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.omitNodeMicroLayout", + OMIT_NODE_MICRO_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.segmentPenalty", + SEGMENT_PENALTY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.anglePenalty", + ANGLE_PENALTY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.crossingPenalty", + CROSSING_PENALTY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.clusterCrossingPenalty", + CLUSTER_CROSSING_PENALTY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.fixedSharedPathPenalty", + FIXED_SHARED_PATH_PENALTY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.portDirectionPenalty", + PORT_DIRECTION_PENALTY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.shapeBufferDistance", + SHAPE_BUFFER_DISTANCE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.idealNudgingDistance", + IDEAL_NUDGING_DISTANCE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.reverseDirectionPenalty", + REVERSE_DIRECTION_PENALTY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.nudgeOrthogonalSegmentsConnectedToShapes", + NUDGE_ORTHOGONAL_SEGMENTS_CONNECTED_TO_SHAPES.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.improveHyperedgeRoutesMovingJunctions", + IMPROVE_HYPEREDGE_ROUTES_MOVING_JUNCTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.penaliseOrthogonalSharedPathsAtConnEnds", + PENALISE_ORTHOGONAL_SHARED_PATHS_AT_CONN_ENDS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.nudgeOrthogonalTouchingColinearSegments", + NUDGE_ORTHOGONAL_TOUCHING_COLINEAR_SEGMENTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.performUnifyingNudgingPreprocessingStep", + PERFORM_UNIFYING_NUDGING_PREPROCESSING_STEP.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.improveHyperedgeRoutesMovingAddingAndDeletingJunctions", + IMPROVE_HYPEREDGE_ROUTES_MOVING_ADDING_AND_DELETING_JUNCTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.nudgeSharedPathsWithCommonEndPoint", + NUDGE_SHARED_PATHS_WITH_COMMON_END_POINT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.enableHyperedgesFromCommonSource", + ENABLE_HYPEREDGES_FROM_COMMON_SOURCE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.alg.libavoid", + "org.eclipse.elk.alg.libavoid.isCluster", + IS_CLUSTER.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.mrtree/src-gen/org/eclipse/elk/alg/mrtree/options/MrTreeMetaDataProvider.java b/plugins/org.eclipse.elk.alg.mrtree/src-gen/org/eclipse/elk/alg/mrtree/options/MrTreeMetaDataProvider.java new file mode 100644 index 000000000..883b0606a --- /dev/null +++ b/plugins/org.eclipse.elk.alg.mrtree/src-gen/org/eclipse/elk/alg/mrtree/options/MrTreeMetaDataProvider.java @@ -0,0 +1,217 @@ +/** + * Copyright (c) 2015 - 2022 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.mrtree.options; + +import java.util.EnumSet; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +/** + * Declarations for the ELK Tree layout algorithm. + */ +@SuppressWarnings("all") +public class MrTreeMetaDataProvider implements ILayoutMetaDataProvider { + /** + * Default value for {@link #COMPACTION}. + */ + private static final boolean COMPACTION_DEFAULT = false; + + /** + * Turns on Tree compaction which decreases the size of the whole tree by placing nodes of multiple + * levels in one large level + */ + public static final IProperty COMPACTION = new Property( + "org.eclipse.elk.mrtree.compaction", + COMPACTION_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_END_TEXTURE_LENGTH}. + */ + private static final double EDGE_END_TEXTURE_LENGTH_DEFAULT = 7; + + /** + * Should be set to the length of the texture at the end of an edge. + * This value can be used to improve the Edge Routing. + */ + public static final IProperty EDGE_END_TEXTURE_LENGTH = new Property( + "org.eclipse.elk.mrtree.edgeEndTextureLength", + EDGE_END_TEXTURE_LENGTH_DEFAULT, + null, + null); + + /** + * Default value for {@link #TREE_LEVEL}. + */ + private static final int TREE_LEVEL_DEFAULT = 0; + + /** + * Lower bound value for {@link #TREE_LEVEL}. + */ + private static final Comparable TREE_LEVEL_LOWER_BOUND = Integer.valueOf(0); + + /** + * The index for the tree level the node is in + */ + public static final IProperty TREE_LEVEL = new Property( + "org.eclipse.elk.mrtree.treeLevel", + TREE_LEVEL_DEFAULT, + TREE_LEVEL_LOWER_BOUND, + null); + + /** + * Default value for {@link #POSITION_CONSTRAINT}. + */ + private static final int POSITION_CONSTRAINT_DEFAULT = (-1); + + /** + * When set to a positive number this option will force the algorithm to place the node to the + * specified position within the trees layer if weighting is set to constraint + */ + public static final IProperty POSITION_CONSTRAINT = new Property( + "org.eclipse.elk.mrtree.positionConstraint", + POSITION_CONSTRAINT_DEFAULT, + null, + null); + + /** + * Default value for {@link #WEIGHTING}. + */ + private static final OrderWeighting WEIGHTING_DEFAULT = OrderWeighting.MODEL_ORDER; + + /** + * Which weighting to use when computing a node order. + */ + public static final IProperty WEIGHTING = new Property( + "org.eclipse.elk.mrtree.weighting", + WEIGHTING_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_ROUTING_MODE}. + */ + private static final EdgeRoutingMode EDGE_ROUTING_MODE_DEFAULT = EdgeRoutingMode.AVOID_OVERLAP; + + /** + * Chooses an Edge Routing algorithm. + */ + public static final IProperty EDGE_ROUTING_MODE = new Property( + "org.eclipse.elk.mrtree.edgeRoutingMode", + EDGE_ROUTING_MODE_DEFAULT, + null, + null); + + /** + * Default value for {@link #SEARCH_ORDER}. + */ + private static final TreeifyingOrder SEARCH_ORDER_DEFAULT = TreeifyingOrder.DFS; + + /** + * Which search order to use when computing a spanning tree. + */ + public static final IProperty SEARCH_ORDER = new Property( + "org.eclipse.elk.mrtree.searchOrder", + SEARCH_ORDER_DEFAULT, + null, + null); + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.mrtree.compaction") + .group("") + .name("Position Constraint") + .description("Turns on Tree compaction which decreases the size of the whole tree by placing nodes of multiple levels in one large level") + .defaultValue(COMPACTION_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.mrtree.edgeEndTextureLength") + .group("") + .name("Edge End Texture Length") + .description("Should be set to the length of the texture at the end of an edge. This value can be used to improve the Edge Routing.") + .defaultValue(EDGE_END_TEXTURE_LENGTH_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.mrtree.treeLevel") + .group("") + .name("Tree Level") + .description("The index for the tree level the node is in") + .defaultValue(TREE_LEVEL_DEFAULT) + .lowerBound(TREE_LEVEL_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.mrtree.positionConstraint") + .group("") + .name("Position Constraint") + .description("When set to a positive number this option will force the algorithm to place the node to the specified position within the trees layer if weighting is set to constraint") + .defaultValue(POSITION_CONSTRAINT_DEFAULT) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.mrtree.weighting") + .group("") + .name("Weighting of Nodes") + .description("Which weighting to use when computing a node order.") + .defaultValue(WEIGHTING_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(OrderWeighting.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.mrtree.edgeRoutingMode") + .group("") + .name("Edge Routing Mode") + .description("Chooses an Edge Routing algorithm.") + .defaultValue(EDGE_ROUTING_MODE_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(EdgeRoutingMode.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.mrtree.searchOrder") + .group("") + .name("Search Order") + .description("Which search order to use when computing a spanning tree.") + .defaultValue(SEARCH_ORDER_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(TreeifyingOrder.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + new org.eclipse.elk.alg.mrtree.options.MrTreeOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.alg.mrtree/src-gen/org/eclipse/elk/alg/mrtree/options/MrTreeOptions.java b/plugins/org.eclipse.elk.alg.mrtree/src-gen/org/eclipse/elk/alg/mrtree/options/MrTreeOptions.java new file mode 100644 index 000000000..423ac99df --- /dev/null +++ b/plugins/org.eclipse.elk.alg.mrtree/src-gen/org/eclipse/elk/alg/mrtree/options/MrTreeOptions.java @@ -0,0 +1,456 @@ +/** + * Copyright (c) 2015 - 2022 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.mrtree.options; + +import java.util.EnumSet; +import org.eclipse.elk.alg.mrtree.TreeLayoutProvider; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.math.KVector; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.Direction; +import org.eclipse.elk.core.options.NodeLabelPlacement; +import org.eclipse.elk.core.options.PortLabelPlacement; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.core.options.SizeOptions; +import org.eclipse.elk.core.options.TopdownNodeTypes; +import org.eclipse.elk.graph.properties.GraphFeature; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class MrTreeOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK Mr. Tree algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.mrtree"; + + /** + * Default value for {@link #PADDING} with algorithm "ELK Mr. Tree". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(20); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "ELK Mr. Tree". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 20; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * Default value for {@link #SPACING_EDGE_NODE} with algorithm "ELK Mr. Tree". + */ + private static final double SPACING_EDGE_NODE_DEFAULT = 3; + + /** + * Spacing to be preserved between nodes and edges. + */ + public static final IProperty SPACING_EDGE_NODE = new Property( + CoreOptions.SPACING_EDGE_NODE, + SPACING_EDGE_NODE_DEFAULT); + + /** + * Default value for {@link #ASPECT_RATIO} with algorithm "ELK Mr. Tree". + */ + private static final double ASPECT_RATIO_DEFAULT = 1.6f; + + /** + * The desired aspect ratio of the drawing, that is the quotient of width by height. + */ + public static final IProperty ASPECT_RATIO = new Property( + CoreOptions.ASPECT_RATIO, + ASPECT_RATIO_DEFAULT); + + /** + * Default value for {@link #PRIORITY} with algorithm "ELK Mr. Tree". + */ + private static final int PRIORITY_DEFAULT = 1; + + /** + * Defines the priority of an object; its meaning depends on the specific layout algorithm + * and the context where it is used. + *

Algorithm Specific Details

+ * Priorities set on nodes determine the order in which connected components are placed: + * components with a higher sum of node priorities will end up + * before components with a lower sum. + */ + public static final IProperty PRIORITY = new Property( + CoreOptions.PRIORITY, + PRIORITY_DEFAULT); + + /** + * Default value for {@link #SEPARATE_CONNECTED_COMPONENTS} with algorithm "ELK Mr. Tree". + */ + private static final boolean SEPARATE_CONNECTED_COMPONENTS_DEFAULT = true; + + /** + * Whether each connected component should be processed separately. + */ + public static final IProperty SEPARATE_CONNECTED_COMPONENTS = new Property( + CoreOptions.SEPARATE_CONNECTED_COMPONENTS, + SEPARATE_CONNECTED_COMPONENTS_DEFAULT); + + /** + * Whether additional debug information shall be generated. + */ + public static final IProperty DEBUG_MODE = CoreOptions.DEBUG_MODE; + + /** + * Default value for {@link #DIRECTION} with algorithm "ELK Mr. Tree". + */ + private static final Direction DIRECTION_DEFAULT = Direction.UNDEFINED; + + /** + * Overall direction of edges: horizontal (right / left) or + * vertical (down / up). + */ + public static final IProperty DIRECTION = new Property( + CoreOptions.DIRECTION, + DIRECTION_DEFAULT); + + /** + * Whether the algorithm should be run in interactive mode for the content of a parent node. + * What this means exactly depends on how the specific algorithm interprets this option. + * Usually in the interactive mode algorithms try to modify the current layout as little as + * possible. + */ + public static final IProperty INTERACTIVE = CoreOptions.INTERACTIVE; + + /** + * Whether the graph should be changeable interactively and by setting constraints + */ + public static final IProperty INTERACTIVE_LAYOUT = CoreOptions.INTERACTIVE_LAYOUT; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * By default, the fixed layout provider will enlarge a graph until it is large enough to contain + * its children. If this option is set, it won't do so. + */ + public static final IProperty NODE_SIZE_FIXED_GRAPH_SIZE = CoreOptions.NODE_SIZE_FIXED_GRAPH_SIZE; + + /** + * The minimal size to which a node can be reduced. + */ + public static final IProperty NODE_SIZE_MINIMUM = CoreOptions.NODE_SIZE_MINIMUM; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * Hints for where node labels are to be placed; if empty, the node label's position is not + * modified. + */ + public static final IProperty> NODE_LABELS_PLACEMENT = CoreOptions.NODE_LABELS_PLACEMENT; + + /** + * Node micro layout comprises the computation of node dimensions (if requested), the placement of ports + * and their labels, and the placement of node labels. + * The functionality is implemented independent of any specific layout algorithm and shouldn't have any + * negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, + * this option allows to deactivate the micro layout. + */ + public static final IProperty OMIT_NODE_MICRO_LAYOUT = CoreOptions.OMIT_NODE_MICRO_LAYOUT; + + /** + * Decides on a placement method for port labels; if empty, the node label's position is not + * modified. + */ + public static final IProperty> PORT_LABELS_PLACEMENT = CoreOptions.PORT_LABELS_PLACEMENT; + + /** + * Which weighting to use when computing a node order. + */ + public static final IProperty WEIGHTING = MrTreeMetaDataProvider.WEIGHTING; + + /** + * Which search order to use when computing a spanning tree. + */ + public static final IProperty SEARCH_ORDER = MrTreeMetaDataProvider.SEARCH_ORDER; + + /** + * Turns topdown layout on and off. If this option is enabled, hierarchical layout will be computed first for + * the root node and then for its children recursively. Layouts are then scaled down to fit the area provided by + * their parents. Graphs must follow a certain structure for topdown layout to work properly. + * {@link TopdownNodeTypes.PARALLEL_NODE} nodes must have children of type + * {@link TopdownNodeTypes.HIERARCHICAL_NODE} and must define {@link topdown.hierarchicalNodeWidth} and + * {@link topdown.hierarchicalNodeAspectRatio} for their children. Furthermore they need to be laid out using an + * algorithm that is a {@link TopdownLayoutProvider}. Hierarchical nodes can also be parents of other hierarchical + * nodes and can optionally use a {@link TopdownSizeApproximator} to dynamically set sizes during topdown layout. + * In this case {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} should be set + * on the node itself rather than the parent. The values are then used by the size approximator as base values. + * Hierarchical nodes require the layout option {@link nodeSize.fixedGraphSize} to be true to prevent the algorithm + * used there from resizing the hierarchical node. This option is not supported if 'Hierarchy Handling' is set to + * 'INCLUDE_CHILDREN' + */ + public static final IProperty TOPDOWN_LAYOUT = CoreOptions.TOPDOWN_LAYOUT; + + /** + * The scaling factor to be applied to the nodes laid out within the node in recursive topdown + * layout. The difference to 'Scale Factor' is that the node itself is not scaled. This value has to be set on + * hierarchical nodes. + */ + public static final IProperty TOPDOWN_SCALE_FACTOR = CoreOptions.TOPDOWN_SCALE_FACTOR; + + /** + * The fixed size of a hierarchical node when using topdown layout. If this value is set on a parallel + * node it applies to its children, when set on a hierarchical node it applies to the node itself. + */ + public static final IProperty TOPDOWN_HIERARCHICAL_NODE_WIDTH = CoreOptions.TOPDOWN_HIERARCHICAL_NODE_WIDTH; + + /** + * The fixed aspect ratio of a hierarchical node when using topdown layout. Default is 1/sqrt(2). If this + * value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to + * the node itself. + */ + public static final IProperty TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO = CoreOptions.TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO; + + /** + * Default value for {@link #TOPDOWN_NODE_TYPE} with algorithm "ELK Mr. Tree". + */ + private static final TopdownNodeTypes TOPDOWN_NODE_TYPE_DEFAULT = TopdownNodeTypes.HIERARCHICAL_NODE; + + /** + * The different node types used for topdown layout. If the node type is set + * to {@link TopdownNodeTypes.PARALLEL_NODE} the algorithm must be set to a {@link TopdownLayoutProvider} such + * as {@link TopdownPacking}. The {@link nodeSize.fixedGraphSize} option is technically only required for + * hierarchical nodes. + */ + public static final IProperty TOPDOWN_NODE_TYPE = new Property( + CoreOptions.TOPDOWN_NODE_TYPE, + TOPDOWN_NODE_TYPE_DEFAULT); + + /** + * When set to a positive number this option will force the algorithm to place the node to the + * specified position within the trees layer if weighting is set to constraint + */ + public static final IProperty POSITION_CONSTRAINT = MrTreeMetaDataProvider.POSITION_CONSTRAINT; + + /** + * Chooses an Edge Routing algorithm. + */ + public static final IProperty EDGE_ROUTING_MODE = MrTreeMetaDataProvider.EDGE_ROUTING_MODE; + + /** + * The index for the tree level the node is in + */ + public static final IProperty TREE_LEVEL = MrTreeMetaDataProvider.TREE_LEVEL; + + /** + * Turns on Tree compaction which decreases the size of the whole tree by placing nodes of multiple + * levels in one large level + */ + public static final IProperty COMPACTION = MrTreeMetaDataProvider.COMPACTION; + + /** + * Should be set to the length of the texture at the end of an edge. + * This value can be used to improve the Edge Routing. + */ + public static final IProperty EDGE_END_TEXTURE_LENGTH = MrTreeMetaDataProvider.EDGE_END_TEXTURE_LENGTH; + + /** + * Layouter-specific algorithm factory. + */ + public static class MrtreeFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new TreeLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.mrtree") + .name("ELK Mr. Tree") + .description("Tree-based algorithm provided by the Eclipse Layout Kernel. Computes a spanning tree of the input graph and arranges all nodes according to the resulting parent-children hierarchy. I pity the fool who doesn\'t use Mr. Tree Layout.") + .providerFactory(new MrtreeFactory()) + .category("org.eclipse.elk.tree") + .melkBundleName(null) + .definingBundleId("org.eclipse.elk.alg.mrtree") + .imagePath("images/mrtree_layout.png") + .supportedFeatures(EnumSet.of(GraphFeature.DISCONNECTED)) + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.spacing.edgeNode", + SPACING_EDGE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.aspectRatio", + ASPECT_RATIO_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.priority", + PRIORITY_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.separateConnectedComponents", + SEPARATE_CONNECTED_COMPONENTS_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.debugMode", + DEBUG_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.direction", + DIRECTION_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.interactive", + INTERACTIVE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.interactiveLayout", + INTERACTIVE_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.nodeSize.fixedGraphSize", + NODE_SIZE_FIXED_GRAPH_SIZE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.nodeSize.minimum", + NODE_SIZE_MINIMUM.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.nodeLabels.placement", + NODE_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.omitNodeMicroLayout", + OMIT_NODE_MICRO_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.portLabels.placement", + PORT_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.mrtree.weighting", + WEIGHTING.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.mrtree.searchOrder", + SEARCH_ORDER.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.topdownLayout", + TOPDOWN_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.topdown.scaleFactor", + TOPDOWN_SCALE_FACTOR.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.topdown.hierarchicalNodeWidth", + TOPDOWN_HIERARCHICAL_NODE_WIDTH.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.topdown.hierarchicalNodeAspectRatio", + TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.topdown.nodeType", + TOPDOWN_NODE_TYPE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.mrtree.positionConstraint", + POSITION_CONSTRAINT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.mrtree.edgeRoutingMode", + EDGE_ROUTING_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.mrtree.treeLevel", + TREE_LEVEL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.mrtree.compaction", + COMPACTION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.mrtree", + "org.eclipse.elk.mrtree.edgeEndTextureLength", + EDGE_END_TEXTURE_LENGTH.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.radial/src-gen/org/eclipse/elk/alg/radial/options/RadialMetaDataProvider.java b/plugins/org.eclipse.elk.alg.radial/src-gen/org/eclipse/elk/alg/radial/options/RadialMetaDataProvider.java new file mode 100644 index 000000000..273165e37 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.radial/src-gen/org/eclipse/elk/alg/radial/options/RadialMetaDataProvider.java @@ -0,0 +1,366 @@ +/** + * Copyright (c) 2017, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.radial.options; + +import java.util.EnumSet; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class RadialMetaDataProvider implements ILayoutMetaDataProvider { + /** + * Default value for {@link #CENTER_ON_ROOT}. + */ + private static final boolean CENTER_ON_ROOT_DEFAULT = false; + + /** + * Centers the layout on the root of the tree i.e. so that the central node is also the center node of the + * final layout. This introduces additional whitespace. + */ + public static final IProperty CENTER_ON_ROOT = new Property( + "org.eclipse.elk.radial.centerOnRoot", + CENTER_ON_ROOT_DEFAULT, + null, + null); + + /** + * Default value for {@link #ORDER_ID}. + */ + private static final int ORDER_ID_DEFAULT = 0; + + /** + * The id can be used to define an order for nodes of one radius. This can be used to sort them in the + * layer accordingly. + */ + public static final IProperty ORDER_ID = new Property( + "org.eclipse.elk.radial.orderId", + ORDER_ID_DEFAULT, + null, + null); + + /** + * Default value for {@link #RADIUS}. + */ + private static final double RADIUS_DEFAULT = 0.0; + + /** + * The radius option can be used to set the initial radius for the radial layouter. + */ + public static final IProperty RADIUS = new Property( + "org.eclipse.elk.radial.radius", + RADIUS_DEFAULT, + null, + null); + + /** + * Default value for {@link #ROTATE}. + */ + private static final boolean ROTATE_DEFAULT = false; + + /** + * The rotate option determines whether a rotation of the layout should be performed. + */ + public static final IProperty ROTATE = new Property( + "org.eclipse.elk.radial.rotate", + ROTATE_DEFAULT, + null, + null); + + /** + * Default value for {@link #COMPACTOR}. + */ + private static final CompactionStrategy COMPACTOR_DEFAULT = CompactionStrategy.NONE; + + /** + * With the compacter option it can be determined how compaction on the graph is done. + * It can be chosen between none, the radial compaction or the compaction of wedges separately. + */ + public static final IProperty COMPACTOR = new Property( + "org.eclipse.elk.radial.compactor", + COMPACTOR_DEFAULT, + null, + null); + + /** + * Default value for {@link #COMPACTION_STEP_SIZE}. + */ + private static final int COMPACTION_STEP_SIZE_DEFAULT = 1; + + /** + * Lower bound value for {@link #COMPACTION_STEP_SIZE}. + */ + private static final Comparable COMPACTION_STEP_SIZE_LOWER_BOUND = Integer.valueOf(0); + + /** + * Determine the size of steps with which the compaction is done. + * Step size 1 correlates to a compaction of 1 pixel per Iteration. + */ + public static final IProperty COMPACTION_STEP_SIZE = new Property( + "org.eclipse.elk.radial.compactionStepSize", + COMPACTION_STEP_SIZE_DEFAULT, + COMPACTION_STEP_SIZE_LOWER_BOUND, + null); + + /** + * Default value for {@link #SORTER}. + */ + private static final SortingStrategy SORTER_DEFAULT = SortingStrategy.NONE; + + /** + * Sort the nodes per radius according to the sorting algorithm. The strategies are none, by the given order id, + * or sorting them by polar coordinates. + */ + public static final IProperty SORTER = new Property( + "org.eclipse.elk.radial.sorter", + SORTER_DEFAULT, + null, + null); + + /** + * Default value for {@link #WEDGE_CRITERIA}. + */ + private static final AnnulusWedgeCriteria WEDGE_CRITERIA_DEFAULT = AnnulusWedgeCriteria.NODE_SIZE; + + /** + * Determine how the wedge for the node placement is calculated. + * It can be chosen between wedge determination by the number of leaves or by the maximum sum of diagonals. + */ + public static final IProperty WEDGE_CRITERIA = new Property( + "org.eclipse.elk.radial.wedgeCriteria", + WEDGE_CRITERIA_DEFAULT, + null, + null); + + /** + * Default value for {@link #OPTIMIZATION_CRITERIA}. + */ + private static final RadialTranslationStrategy OPTIMIZATION_CRITERIA_DEFAULT = RadialTranslationStrategy.NONE; + + /** + * Find the optimal translation of the nodes of the first radii according to this criteria. + * For example edge crossings can be minimized. + */ + public static final IProperty OPTIMIZATION_CRITERIA = new Property( + "org.eclipse.elk.radial.optimizationCriteria", + OPTIMIZATION_CRITERIA_DEFAULT, + null, + null); + + /** + * Default value for {@link #ROTATION_TARGET_ANGLE}. + */ + private static final double ROTATION_TARGET_ANGLE_DEFAULT = 0; + + /** + * The angle in radians that the layout should be rotated to after layout. + */ + public static final IProperty ROTATION_TARGET_ANGLE = new Property( + "org.eclipse.elk.radial.rotation.targetAngle", + ROTATION_TARGET_ANGLE_DEFAULT, + null, + null); + + /** + * Default value for {@link #ROTATION_COMPUTE_ADDITIONAL_WEDGE_SPACE}. + */ + private static final boolean ROTATION_COMPUTE_ADDITIONAL_WEDGE_SPACE_DEFAULT = false; + + /** + * If set to true, modifies the target angle by rotating further such that space is left + * for an edge to pass in between the nodes. This option should only be used in conjunction + * with top-down layout. + */ + public static final IProperty ROTATION_COMPUTE_ADDITIONAL_WEDGE_SPACE = new Property( + "org.eclipse.elk.radial.rotation.computeAdditionalWedgeSpace", + ROTATION_COMPUTE_ADDITIONAL_WEDGE_SPACE_DEFAULT, + null, + null); + + /** + * Default value for {@link #ROTATION_OUTGOING_EDGE_ANGLES}. + */ + private static final boolean ROTATION_OUTGOING_EDGE_ANGLES_DEFAULT = false; + + /** + * Calculate the required angle of connected nodes to leave space for an incoming edge. This + * option should only be used in conjunction with top-down layout. + */ + public static final IProperty ROTATION_OUTGOING_EDGE_ANGLES = new Property( + "org.eclipse.elk.radial.rotation.outgoingEdgeAngles", + ROTATION_OUTGOING_EDGE_ANGLES_DEFAULT, + null, + null); + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.centerOnRoot") + .group("") + .name("Center On Root") + .description("Centers the layout on the root of the tree i.e. so that the central node is also the center node of the final layout. This introduces additional whitespace.") + .defaultValue(CENTER_ON_ROOT_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.orderId") + .group("") + .name("Order ID") + .description("The id can be used to define an order for nodes of one radius. This can be used to sort them in the layer accordingly.") + .defaultValue(ORDER_ID_DEFAULT) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.radius") + .group("") + .name("Radius") + .description("The radius option can be used to set the initial radius for the radial layouter.") + .defaultValue(RADIUS_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.rotate") + .group("") + .name("Rotate") + .description("The rotate option determines whether a rotation of the layout should be performed.") + .defaultValue(ROTATE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.compactor") + .group("") + .name("Compaction") + .description("With the compacter option it can be determined how compaction on the graph is done. It can be chosen between none, the radial compaction or the compaction of wedges separately.") + .defaultValue(COMPACTOR_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(CompactionStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.compactionStepSize") + .group("") + .name("Compaction Step Size") + .description("Determine the size of steps with which the compaction is done. Step size 1 correlates to a compaction of 1 pixel per Iteration.") + .defaultValue(COMPACTION_STEP_SIZE_DEFAULT) + .lowerBound(COMPACTION_STEP_SIZE_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.addDependency( + "org.eclipse.elk.radial.compactionStepSize", + "org.eclipse.elk.radial.compactor", + null + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.sorter") + .group("") + .name("Sorter") + .description("Sort the nodes per radius according to the sorting algorithm. The strategies are none, by the given order id, or sorting them by polar coordinates.") + .defaultValue(SORTER_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(SortingStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.wedgeCriteria") + .group("") + .name("Annulus Wedge Criteria") + .description("Determine how the wedge for the node placement is calculated. It can be chosen between wedge determination by the number of leaves or by the maximum sum of diagonals.") + .defaultValue(WEDGE_CRITERIA_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(AnnulusWedgeCriteria.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.optimizationCriteria") + .group("") + .name("Translation Optimization") + .description("Find the optimal translation of the nodes of the first radii according to this criteria. For example edge crossings can be minimized.") + .defaultValue(OPTIMIZATION_CRITERIA_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(RadialTranslationStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.rotation.targetAngle") + .group("rotation") + .name("Target Angle") + .description("The angle in radians that the layout should be rotated to after layout.") + .defaultValue(ROTATION_TARGET_ANGLE_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.addDependency( + "org.eclipse.elk.radial.rotation.targetAngle", + "org.eclipse.elk.radial.rotate", + null + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.rotation.computeAdditionalWedgeSpace") + .group("rotation") + .name("Additional Wedge Space") + .description("If set to true, modifies the target angle by rotating further such that space is left for an edge to pass in between the nodes. This option should only be used in conjunction with top-down layout.") + .defaultValue(ROTATION_COMPUTE_ADDITIONAL_WEDGE_SPACE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.radial.rotation.computeAdditionalWedgeSpace", + "org.eclipse.elk.radial.rotate", + null + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.radial.rotation.outgoingEdgeAngles") + .group("rotation") + .name("Outgoing Edge Angles") + .description("Calculate the required angle of connected nodes to leave space for an incoming edge. This option should only be used in conjunction with top-down layout.") + .defaultValue(ROTATION_OUTGOING_EDGE_ANGLES_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + new org.eclipse.elk.alg.radial.options.RadialOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.alg.radial/src-gen/org/eclipse/elk/alg/radial/options/RadialOptions.java b/plugins/org.eclipse.elk.alg.radial/src-gen/org/eclipse/elk/alg/radial/options/RadialOptions.java new file mode 100644 index 000000000..79271f156 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.radial/src-gen/org/eclipse/elk/alg/radial/options/RadialOptions.java @@ -0,0 +1,283 @@ +/** + * Copyright (c) 2017, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.radial.options; + +import java.util.EnumSet; +import org.eclipse.elk.alg.radial.RadialLayoutProvider; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.KVector; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.NodeLabelPlacement; +import org.eclipse.elk.core.options.PortLabelPlacement; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.core.options.SizeOptions; +import org.eclipse.elk.graph.properties.IProperty; + +/** + * @radial.md + */ +@SuppressWarnings("all") +public class RadialOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK Radial algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.radial"; + + /** + * The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to + * specify a pre-defined position. + */ + public static final IProperty POSITION = CoreOptions.POSITION; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = CoreOptions.SPACING_NODE_NODE; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * The minimal size to which a node can be reduced. + */ + public static final IProperty NODE_SIZE_MINIMUM = CoreOptions.NODE_SIZE_MINIMUM; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * Hints for where node labels are to be placed; if empty, the node label's position is not + * modified. + */ + public static final IProperty> NODE_LABELS_PLACEMENT = CoreOptions.NODE_LABELS_PLACEMENT; + + /** + * Node micro layout comprises the computation of node dimensions (if requested), the placement of ports + * and their labels, and the placement of node labels. + * The functionality is implemented independent of any specific layout algorithm and shouldn't have any + * negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, + * this option allows to deactivate the micro layout. + */ + public static final IProperty OMIT_NODE_MICRO_LAYOUT = CoreOptions.OMIT_NODE_MICRO_LAYOUT; + + /** + * Decides on a placement method for port labels; if empty, the node label's position is not + * modified. + */ + public static final IProperty> PORT_LABELS_PLACEMENT = CoreOptions.PORT_LABELS_PLACEMENT; + + /** + * Determine the size of steps with which the compaction is done. + * Step size 1 correlates to a compaction of 1 pixel per Iteration. + */ + public static final IProperty COMPACTION_STEP_SIZE = RadialMetaDataProvider.COMPACTION_STEP_SIZE; + + /** + * With the compacter option it can be determined how compaction on the graph is done. + * It can be chosen between none, the radial compaction or the compaction of wedges separately. + */ + public static final IProperty COMPACTOR = RadialMetaDataProvider.COMPACTOR; + + /** + * The rotate option determines whether a rotation of the layout should be performed. + */ + public static final IProperty ROTATE = RadialMetaDataProvider.ROTATE; + + /** + * The angle in radians that the layout should be rotated to after layout. + */ + public static final IProperty ROTATION_TARGET_ANGLE = RadialMetaDataProvider.ROTATION_TARGET_ANGLE; + + /** + * If set to true, modifies the target angle by rotating further such that space is left + * for an edge to pass in between the nodes. This option should only be used in conjunction + * with top-down layout. + */ + public static final IProperty ROTATION_COMPUTE_ADDITIONAL_WEDGE_SPACE = RadialMetaDataProvider.ROTATION_COMPUTE_ADDITIONAL_WEDGE_SPACE; + + /** + * Calculate the required angle of connected nodes to leave space for an incoming edge. This + * option should only be used in conjunction with top-down layout. + */ + public static final IProperty ROTATION_OUTGOING_EDGE_ANGLES = RadialMetaDataProvider.ROTATION_OUTGOING_EDGE_ANGLES; + + /** + * Find the optimal translation of the nodes of the first radii according to this criteria. + * For example edge crossings can be minimized. + */ + public static final IProperty OPTIMIZATION_CRITERIA = RadialMetaDataProvider.OPTIMIZATION_CRITERIA; + + /** + * The id can be used to define an order for nodes of one radius. This can be used to sort them in the + * layer accordingly. + */ + public static final IProperty ORDER_ID = RadialMetaDataProvider.ORDER_ID; + + /** + * The radius option can be used to set the initial radius for the radial layouter. + */ + public static final IProperty RADIUS = RadialMetaDataProvider.RADIUS; + + /** + * Sort the nodes per radius according to the sorting algorithm. The strategies are none, by the given order id, + * or sorting them by polar coordinates. + */ + public static final IProperty SORTER = RadialMetaDataProvider.SORTER; + + /** + * Determine how the wedge for the node placement is calculated. + * It can be chosen between wedge determination by the number of leaves or by the maximum sum of diagonals. + */ + public static final IProperty WEDGE_CRITERIA = RadialMetaDataProvider.WEDGE_CRITERIA; + + /** + * Centers the layout on the root of the tree i.e. so that the central node is also the center node of the + * final layout. This introduces additional whitespace. + */ + public static final IProperty CENTER_ON_ROOT = RadialMetaDataProvider.CENTER_ON_ROOT; + + /** + * Layouter-specific algorithm factory. + */ + public static class RadialFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new RadialLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.radial") + .name("ELK Radial") + .description("A radial layout provider which is based on the algorithm of Peter Eades published in \"Drawing free trees.\", published by International Institute for Advanced Study of Social Information Science, Fujitsu Limited in 1991. The radial layouter takes a tree and places the nodes in radial order around the root. The nodes of the same tree level are placed on the same radius.") + .providerFactory(new RadialFactory()) + .category("org.eclipse.elk.radial") + .melkBundleName(null) + .definingBundleId("org.eclipse.elk.alg.radial") + .imagePath("images/radial_layout.png") + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.position", + POSITION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.nodeSize.minimum", + NODE_SIZE_MINIMUM.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.nodeLabels.placement", + NODE_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.omitNodeMicroLayout", + OMIT_NODE_MICRO_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.portLabels.placement", + PORT_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.compactionStepSize", + COMPACTION_STEP_SIZE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.compactor", + COMPACTOR.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.rotate", + ROTATE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.rotation.targetAngle", + ROTATION_TARGET_ANGLE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.rotation.computeAdditionalWedgeSpace", + ROTATION_COMPUTE_ADDITIONAL_WEDGE_SPACE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.rotation.outgoingEdgeAngles", + ROTATION_OUTGOING_EDGE_ANGLES.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.optimizationCriteria", + OPTIMIZATION_CRITERIA.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.orderId", + ORDER_ID.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.radius", + RADIUS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.sorter", + SORTER.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.wedgeCriteria", + WEDGE_CRITERIA.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.radial", + "org.eclipse.elk.radial.centerOnRoot", + CENTER_ON_ROOT.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.rectpacking/src-gen/org/eclipse/elk/alg/rectpacking/options/RectPackingMetaDataProvider.java b/plugins/org.eclipse.elk.alg.rectpacking/src-gen/org/eclipse/elk/alg/rectpacking/options/RectPackingMetaDataProvider.java new file mode 100644 index 000000000..8055537bc --- /dev/null +++ b/plugins/org.eclipse.elk.alg.rectpacking/src-gen/org/eclipse/elk/alg/rectpacking/options/RectPackingMetaDataProvider.java @@ -0,0 +1,367 @@ +/** + * Copyright (c) 2018, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.rectpacking.options; + +import java.util.EnumSet; +import org.eclipse.elk.alg.rectpacking.p1widthapproximation.WidthApproximationStrategy; +import org.eclipse.elk.alg.rectpacking.p2packing.PackingStrategy; +import org.eclipse.elk.alg.rectpacking.p3whitespaceelimination.WhiteSpaceEliminationStrategy; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class RectPackingMetaDataProvider implements ILayoutMetaDataProvider { + /** + * Default value for {@link #TRYBOX}. + */ + private static final boolean TRYBOX_DEFAULT = false; + + /** + * Whether one should check whether the regions are stackable to see whether box layout would do the job. + * For example, nodes with the same height are not stackable inside a row. Therefore, box layout will perform + * better and faster. + */ + public static final IProperty TRYBOX = new Property( + "org.eclipse.elk.rectpacking.trybox", + TRYBOX_DEFAULT, + null, + null); + + /** + * Default value for {@link #CURRENT_POSITION}. + */ + private static final int CURRENT_POSITION_DEFAULT = (-1); + + /** + * Lower bound value for {@link #CURRENT_POSITION}. + */ + private static final Comparable CURRENT_POSITION_LOWER_BOUND = Integer.valueOf((-1)); + + /** + * The rectangles are ordered. Normally according to their definition the the model. + * This option specifies the current position of a node. + */ + public static final IProperty CURRENT_POSITION = new Property( + "org.eclipse.elk.rectpacking.currentPosition", + CURRENT_POSITION_DEFAULT, + CURRENT_POSITION_LOWER_BOUND, + null); + + /** + * Default value for {@link #DESIRED_POSITION}. + */ + private static final int DESIRED_POSITION_DEFAULT = (-1); + + /** + * Lower bound value for {@link #DESIRED_POSITION}. + */ + private static final Comparable DESIRED_POSITION_LOWER_BOUND = Integer.valueOf((-1)); + + /** + * The rectangles are ordered. Normally according to their definition the the model. + * This option allows to specify a desired position that has preference over the original position. + */ + public static final IProperty DESIRED_POSITION = new Property( + "org.eclipse.elk.rectpacking.desiredPosition", + DESIRED_POSITION_DEFAULT, + DESIRED_POSITION_LOWER_BOUND, + null); + + /** + * Default value for {@link #IN_NEW_ROW}. + */ + private static final boolean IN_NEW_ROW_DEFAULT = false; + + /** + * If set to true this node begins in a new row. Consequently this node cannot be moved in a previous layer during + * compaction. Width approximation does does not take this into account. + */ + public static final IProperty IN_NEW_ROW = new Property( + "org.eclipse.elk.rectpacking.inNewRow", + IN_NEW_ROW_DEFAULT, + null, + null); + + /** + * Default value for {@link #WIDTH_APPROXIMATION_STRATEGY}. + */ + private static final WidthApproximationStrategy WIDTH_APPROXIMATION_STRATEGY_DEFAULT = WidthApproximationStrategy.GREEDY; + + /** + * Strategy for finding an initial width of the drawing. + */ + public static final IProperty WIDTH_APPROXIMATION_STRATEGY = new Property( + "org.eclipse.elk.rectpacking.widthApproximation.strategy", + WIDTH_APPROXIMATION_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #WIDTH_APPROXIMATION_TARGET_WIDTH}. + */ + private static final double WIDTH_APPROXIMATION_TARGET_WIDTH_DEFAULT = (-1); + + /** + * Option to place the rectangles in the given target width instead of approximating the width using the desired + * aspect ratio. + * The padding is not included in this. Meaning a drawing will have width of targetwidth + + * horizontal padding. + */ + public static final IProperty WIDTH_APPROXIMATION_TARGET_WIDTH = new Property( + "org.eclipse.elk.rectpacking.widthApproximation.targetWidth", + WIDTH_APPROXIMATION_TARGET_WIDTH_DEFAULT, + null, + null); + + /** + * Default value for {@link #WIDTH_APPROXIMATION_OPTIMIZATION_GOAL}. + */ + private static final OptimizationGoal WIDTH_APPROXIMATION_OPTIMIZATION_GOAL_DEFAULT = OptimizationGoal.MAX_SCALE_DRIVEN; + + /** + * Optimization goal for approximation of the bounding box given by the first iteration. Determines whether layout is + * sorted by the maximum scaling, aspect ratio, or area. Depending on the strategy the aspect ratio might be nearly ignored. + */ + public static final IProperty WIDTH_APPROXIMATION_OPTIMIZATION_GOAL = new Property( + "org.eclipse.elk.rectpacking.widthApproximation.optimizationGoal", + WIDTH_APPROXIMATION_OPTIMIZATION_GOAL_DEFAULT, + null, + null); + + /** + * Default value for {@link #WIDTH_APPROXIMATION_LAST_PLACE_SHIFT}. + */ + private static final boolean WIDTH_APPROXIMATION_LAST_PLACE_SHIFT_DEFAULT = true; + + /** + * When placing a rectangle behind or below the last placed rectangle in the first iteration, it is sometimes + * possible to shift the rectangle further to the left or right, resulting in less whitespace. True (default) + * enables the shift and false disables it. Disabling the shift produces a greater approximated area by the first + * iteration and a layout, when using ONLY the first iteration (default not the case), where it is sometimes + * impossible to implement a size transformation of rectangles that will fill the bounding box and eliminate + * empty spaces. + */ + public static final IProperty WIDTH_APPROXIMATION_LAST_PLACE_SHIFT = new Property( + "org.eclipse.elk.rectpacking.widthApproximation.lastPlaceShift", + WIDTH_APPROXIMATION_LAST_PLACE_SHIFT_DEFAULT, + null, + null); + + /** + * Default value for {@link #PACKING_STRATEGY}. + */ + private static final PackingStrategy PACKING_STRATEGY_DEFAULT = PackingStrategy.COMPACTION; + + /** + * Strategy for finding an initial placement on nodes. + */ + public static final IProperty PACKING_STRATEGY = new Property( + "org.eclipse.elk.rectpacking.packing.strategy", + PACKING_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #PACKING_COMPACTION_ROW_HEIGHT_REEVALUATION}. + */ + private static final boolean PACKING_COMPACTION_ROW_HEIGHT_REEVALUATION_DEFAULT = false; + + /** + * During the compaction step the height of a row is normally not changed. + * If this options is set, the blocks of other rows might be added if they exceed the row height. + * If this is the case the whole row has to be packed again to be optimal regarding the new row height. + * This option should, therefore, be used with care since it might be computation heavy. + */ + public static final IProperty PACKING_COMPACTION_ROW_HEIGHT_REEVALUATION = new Property( + "org.eclipse.elk.rectpacking.packing.compaction.rowHeightReevaluation", + PACKING_COMPACTION_ROW_HEIGHT_REEVALUATION_DEFAULT, + null, + null); + + /** + * Default value for {@link #PACKING_COMPACTION_ITERATIONS}. + */ + private static final int PACKING_COMPACTION_ITERATIONS_DEFAULT = 1; + + /** + * Lower bound value for {@link #PACKING_COMPACTION_ITERATIONS}. + */ + private static final Comparable PACKING_COMPACTION_ITERATIONS_LOWER_BOUND = Integer.valueOf(1); + + /** + * Defines the number of compaction iterations. E.g. if set to 2 the width is initially approximated, + * then the drawing is compacted and based on the resulting drawing the target width is decreased or + * increased and a second compaction step is executed and the result compared to the first one. The best + * run is used based on the scale measure. + */ + public static final IProperty PACKING_COMPACTION_ITERATIONS = new Property( + "org.eclipse.elk.rectpacking.packing.compaction.iterations", + PACKING_COMPACTION_ITERATIONS_DEFAULT, + PACKING_COMPACTION_ITERATIONS_LOWER_BOUND, + null); + + /** + * Strategy for expanding nodes such that whitespace in the parent is eliminated. + */ + public static final IProperty WHITE_SPACE_ELIMINATION_STRATEGY = new Property( + "org.eclipse.elk.rectpacking.whiteSpaceElimination.strategy"); + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.trybox") + .group("") + .name("Try box layout first") + .description("Whether one should check whether the regions are stackable to see whether box layout would do the job. For example, nodes with the same height are not stackable inside a row. Therefore, box layout will perform better and faster.") + .defaultValue(TRYBOX_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.currentPosition") + .group("") + .name("Current position of a node in the order of nodes") + .description("The rectangles are ordered. Normally according to their definition the the model. This option specifies the current position of a node.") + .defaultValue(CURRENT_POSITION_DEFAULT) + .lowerBound(CURRENT_POSITION_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.desiredPosition") + .group("") + .name("Desired index of node") + .description("The rectangles are ordered. Normally according to their definition the the model. This option allows to specify a desired position that has preference over the original position.") + .defaultValue(DESIRED_POSITION_DEFAULT) + .lowerBound(DESIRED_POSITION_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.inNewRow") + .group("") + .name("In new Row") + .description("If set to true this node begins in a new row. Consequently this node cannot be moved in a previous layer during compaction. Width approximation does does not take this into account.") + .defaultValue(IN_NEW_ROW_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.widthApproximation.strategy") + .group("widthApproximation") + .name("Width Approximation Strategy") + .description("Strategy for finding an initial width of the drawing.") + .defaultValue(WIDTH_APPROXIMATION_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(WidthApproximationStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.widthApproximation.targetWidth") + .group("widthApproximation") + .name("Target Width") + .description("Option to place the rectangles in the given target width instead of approximating the width using the desired aspect ratio. The padding is not included in this. Meaning a drawing will have width of targetwidth + horizontal padding.") + .defaultValue(WIDTH_APPROXIMATION_TARGET_WIDTH_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.widthApproximation.optimizationGoal") + .group("widthApproximation") + .name("Optimization Goal") + .description("Optimization goal for approximation of the bounding box given by the first iteration. Determines whether layout is sorted by the maximum scaling, aspect ratio, or area. Depending on the strategy the aspect ratio might be nearly ignored.") + .defaultValue(WIDTH_APPROXIMATION_OPTIMIZATION_GOAL_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(OptimizationGoal.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.widthApproximation.lastPlaceShift") + .group("widthApproximation") + .name("Shift Last Placed.") + .description("When placing a rectangle behind or below the last placed rectangle in the first iteration, it is sometimes possible to shift the rectangle further to the left or right, resulting in less whitespace. True (default) enables the shift and false disables it. Disabling the shift produces a greater approximated area by the first iteration and a layout, when using ONLY the first iteration (default not the case), where it is sometimes impossible to implement a size transformation of rectangles that will fill the bounding box and eliminate empty spaces.") + .defaultValue(WIDTH_APPROXIMATION_LAST_PLACE_SHIFT_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.packing.strategy") + .group("packing") + .name("Compaction Strategy") + .description("Strategy for finding an initial placement on nodes.") + .defaultValue(PACKING_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(PackingStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.packing.compaction.rowHeightReevaluation") + .group("packing.compaction") + .name("Row Height Reevaluation") + .description("During the compaction step the height of a row is normally not changed. If this options is set, the blocks of other rows might be added if they exceed the row height. If this is the case the whole row has to be packed again to be optimal regarding the new row height. This option should, therefore, be used with care since it might be computation heavy.") + .defaultValue(PACKING_COMPACTION_ROW_HEIGHT_REEVALUATION_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.packing.compaction.iterations") + .group("packing.compaction") + .name("Compaction iterations") + .description("Defines the number of compaction iterations. E.g. if set to 2 the width is initially approximated, then the drawing is compacted and based on the resulting drawing the target width is decreased or increased and a second compaction step is executed and the result compared to the first one. The best run is used based on the scale measure.") + .defaultValue(PACKING_COMPACTION_ITERATIONS_DEFAULT) + .lowerBound(PACKING_COMPACTION_ITERATIONS_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.rectpacking.whiteSpaceElimination.strategy") + .group("whiteSpaceElimination") + .name("White Space Approximation Strategy") + .description("Strategy for expanding nodes such that whitespace in the parent is eliminated.") + .type(LayoutOptionData.Type.ENUM) + .optionClass(WhiteSpaceEliminationStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + new org.eclipse.elk.alg.rectpacking.options.RectPackingOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.alg.rectpacking/src-gen/org/eclipse/elk/alg/rectpacking/options/RectPackingOptions.java b/plugins/org.eclipse.elk.alg.rectpacking/src-gen/org/eclipse/elk/alg/rectpacking/options/RectPackingOptions.java new file mode 100644 index 000000000..203c518c8 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.rectpacking/src-gen/org/eclipse/elk/alg/rectpacking/options/RectPackingOptions.java @@ -0,0 +1,382 @@ +/** + * Copyright (c) 2018, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.rectpacking.options; + +import java.util.EnumSet; +import org.eclipse.elk.alg.rectpacking.RectPackingLayoutProvider; +import org.eclipse.elk.alg.rectpacking.p1widthapproximation.WidthApproximationStrategy; +import org.eclipse.elk.alg.rectpacking.p2packing.PackingStrategy; +import org.eclipse.elk.alg.rectpacking.p3whitespaceelimination.WhiteSpaceEliminationStrategy; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.math.KVector; +import org.eclipse.elk.core.options.ContentAlignment; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.NodeLabelPlacement; +import org.eclipse.elk.core.options.PortLabelPlacement; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.core.options.SizeOptions; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +/** + * @rectpacking.md + */ +@SuppressWarnings("all") +public class RectPackingOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK Rectangle Packing algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.rectpacking"; + + /** + * Default value for {@link #ASPECT_RATIO} with algorithm "ELK Rectangle Packing". + */ + private static final double ASPECT_RATIO_DEFAULT = 1.3; + + /** + * The desired aspect ratio of the drawing, that is the quotient of width by height. + */ + public static final IProperty ASPECT_RATIO = new Property( + CoreOptions.ASPECT_RATIO, + ASPECT_RATIO_DEFAULT); + + /** + * Default value for {@link #NODE_SIZE_FIXED_GRAPH_SIZE} with algorithm "ELK Rectangle Packing". + */ + private static final boolean NODE_SIZE_FIXED_GRAPH_SIZE_DEFAULT = false; + + /** + * By default, the fixed layout provider will enlarge a graph until it is large enough to contain + * its children. If this option is set, it won't do so. + */ + public static final IProperty NODE_SIZE_FIXED_GRAPH_SIZE = new Property( + CoreOptions.NODE_SIZE_FIXED_GRAPH_SIZE, + NODE_SIZE_FIXED_GRAPH_SIZE_DEFAULT); + + /** + * Default value for {@link #PADDING} with algorithm "ELK Rectangle Packing". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(15); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "ELK Rectangle Packing". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 15; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * Specifies how the content of a node are aligned. Each node can individually control the alignment of its + * contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that + * option. + */ + public static final IProperty> CONTENT_ALIGNMENT = CoreOptions.CONTENT_ALIGNMENT; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * The minimal size to which a node can be reduced. + */ + public static final IProperty NODE_SIZE_MINIMUM = CoreOptions.NODE_SIZE_MINIMUM; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * Hints for where node labels are to be placed; if empty, the node label's position is not + * modified. + */ + public static final IProperty> NODE_LABELS_PLACEMENT = CoreOptions.NODE_LABELS_PLACEMENT; + + /** + * Node micro layout comprises the computation of node dimensions (if requested), the placement of ports + * and their labels, and the placement of node labels. + * The functionality is implemented independent of any specific layout algorithm and shouldn't have any + * negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, + * this option allows to deactivate the micro layout. + */ + public static final IProperty OMIT_NODE_MICRO_LAYOUT = CoreOptions.OMIT_NODE_MICRO_LAYOUT; + + /** + * Decides on a placement method for port labels; if empty, the node label's position is not + * modified. + */ + public static final IProperty> PORT_LABELS_PLACEMENT = CoreOptions.PORT_LABELS_PLACEMENT; + + /** + * Optimization goal for approximation of the bounding box given by the first iteration. Determines whether layout is + * sorted by the maximum scaling, aspect ratio, or area. Depending on the strategy the aspect ratio might be nearly ignored. + */ + public static final IProperty WIDTH_APPROXIMATION_OPTIMIZATION_GOAL = RectPackingMetaDataProvider.WIDTH_APPROXIMATION_OPTIMIZATION_GOAL; + + /** + * When placing a rectangle behind or below the last placed rectangle in the first iteration, it is sometimes + * possible to shift the rectangle further to the left or right, resulting in less whitespace. True (default) + * enables the shift and false disables it. Disabling the shift produces a greater approximated area by the first + * iteration and a layout, when using ONLY the first iteration (default not the case), where it is sometimes + * impossible to implement a size transformation of rectangles that will fill the bounding box and eliminate + * empty spaces. + */ + public static final IProperty WIDTH_APPROXIMATION_LAST_PLACE_SHIFT = RectPackingMetaDataProvider.WIDTH_APPROXIMATION_LAST_PLACE_SHIFT; + + /** + * Option to place the rectangles in the given target width instead of approximating the width using the desired + * aspect ratio. + * The padding is not included in this. Meaning a drawing will have width of targetwidth + + * horizontal padding. + */ + public static final IProperty WIDTH_APPROXIMATION_TARGET_WIDTH = RectPackingMetaDataProvider.WIDTH_APPROXIMATION_TARGET_WIDTH; + + /** + * Strategy for finding an initial width of the drawing. + */ + public static final IProperty WIDTH_APPROXIMATION_STRATEGY = RectPackingMetaDataProvider.WIDTH_APPROXIMATION_STRATEGY; + + /** + * Strategy for finding an initial placement on nodes. + */ + public static final IProperty PACKING_STRATEGY = RectPackingMetaDataProvider.PACKING_STRATEGY; + + /** + * During the compaction step the height of a row is normally not changed. + * If this options is set, the blocks of other rows might be added if they exceed the row height. + * If this is the case the whole row has to be packed again to be optimal regarding the new row height. + * This option should, therefore, be used with care since it might be computation heavy. + */ + public static final IProperty PACKING_COMPACTION_ROW_HEIGHT_REEVALUATION = RectPackingMetaDataProvider.PACKING_COMPACTION_ROW_HEIGHT_REEVALUATION; + + /** + * Defines the number of compaction iterations. E.g. if set to 2 the width is initially approximated, + * then the drawing is compacted and based on the resulting drawing the target width is decreased or + * increased and a second compaction step is executed and the result compared to the first one. The best + * run is used based on the scale measure. + */ + public static final IProperty PACKING_COMPACTION_ITERATIONS = RectPackingMetaDataProvider.PACKING_COMPACTION_ITERATIONS; + + /** + * Strategy for expanding nodes such that whitespace in the parent is eliminated. + */ + public static final IProperty WHITE_SPACE_ELIMINATION_STRATEGY = RectPackingMetaDataProvider.WHITE_SPACE_ELIMINATION_STRATEGY; + + /** + * Whether the algorithm should be run in interactive mode for the content of a parent node. + * What this means exactly depends on how the specific algorithm interprets this option. + * Usually in the interactive mode algorithms try to modify the current layout as little as + * possible. + */ + public static final IProperty INTERACTIVE = CoreOptions.INTERACTIVE; + + /** + * Whether the graph should be changeable interactively and by setting constraints + */ + public static final IProperty INTERACTIVE_LAYOUT = CoreOptions.INTERACTIVE_LAYOUT; + + /** + * The rectangles are ordered. Normally according to their definition the the model. + * This option allows to specify a desired position that has preference over the original position. + */ + public static final IProperty DESIRED_POSITION = RectPackingMetaDataProvider.DESIRED_POSITION; + + /** + * The rectangles are ordered. Normally according to their definition the the model. + * This option specifies the current position of a node. + */ + public static final IProperty CURRENT_POSITION = RectPackingMetaDataProvider.CURRENT_POSITION; + + /** + * If set to true this node begins in a new row. Consequently this node cannot be moved in a previous layer during + * compaction. Width approximation does does not take this into account. + */ + public static final IProperty IN_NEW_ROW = RectPackingMetaDataProvider.IN_NEW_ROW; + + /** + * Whether one should check whether the regions are stackable to see whether box layout would do the job. + * For example, nodes with the same height are not stackable inside a row. Therefore, box layout will perform + * better and faster. + */ + public static final IProperty TRYBOX = RectPackingMetaDataProvider.TRYBOX; + + /** + * Layouter-specific algorithm factory. + */ + public static class RectpackingFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new RectPackingLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.rectpacking") + .name("ELK Rectangle Packing") + .description("Algorithm for packing of unconnected boxes, i.e. graphs without edges. The given order of the boxes is always preserved and the main reading direction of the boxes is left to right. The algorithm is divided into two phases. One phase approximates the width in which the rectangles can be placed. The next phase places the rectangles in rows using the previously calculated width as bounding width and bundles rectangles with a similar height in blocks. A compaction step reduces the size of the drawing. Finally, the rectangles are expanded to fill their bounding box and eliminate empty unused spaces.") + .providerFactory(new RectpackingFactory()) + .melkBundleName(null) + .definingBundleId("org.eclipse.elk.alg.rectpacking") + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.aspectRatio", + ASPECT_RATIO_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.nodeSize.fixedGraphSize", + NODE_SIZE_FIXED_GRAPH_SIZE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.contentAlignment", + CONTENT_ALIGNMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.nodeSize.minimum", + NODE_SIZE_MINIMUM.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.nodeLabels.placement", + NODE_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.omitNodeMicroLayout", + OMIT_NODE_MICRO_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.portLabels.placement", + PORT_LABELS_PLACEMENT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.widthApproximation.optimizationGoal", + WIDTH_APPROXIMATION_OPTIMIZATION_GOAL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.widthApproximation.lastPlaceShift", + WIDTH_APPROXIMATION_LAST_PLACE_SHIFT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.widthApproximation.targetWidth", + WIDTH_APPROXIMATION_TARGET_WIDTH.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.widthApproximation.strategy", + WIDTH_APPROXIMATION_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.packing.strategy", + PACKING_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.packing.compaction.rowHeightReevaluation", + PACKING_COMPACTION_ROW_HEIGHT_REEVALUATION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.packing.compaction.iterations", + PACKING_COMPACTION_ITERATIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.whiteSpaceElimination.strategy", + WHITE_SPACE_ELIMINATION_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.interactive", + INTERACTIVE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.interactiveLayout", + INTERACTIVE_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.desiredPosition", + DESIRED_POSITION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.currentPosition", + CURRENT_POSITION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.inNewRow", + IN_NEW_ROW.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.rectpacking", + "org.eclipse.elk.rectpacking.trybox", + TRYBOX.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeCompactionOptions.java b/plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeCompactionOptions.java new file mode 100644 index 000000000..e1c123199 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeCompactionOptions.java @@ -0,0 +1,194 @@ +/** + * Copyright (c) 2017 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.spore.options; + +import org.eclipse.elk.alg.spore.ShrinkTreeLayoutProvider; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +/** + * @spore.md + */ +@SuppressWarnings("all") +public class SporeCompactionOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK SPOrE Compaction algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.sporeCompaction"; + + /** + * A layout algorithm that is applied to the graph before it is + * compacted. If this is null, nothing is applied before compaction. + */ + public static final IProperty UNDERLYING_LAYOUT_ALGORITHM = SporeMetaDataProvider.UNDERLYING_LAYOUT_ALGORITHM; + + /** + * Whether a minimum spanning tree or a maximum spanning tree should be constructed. + */ + public static final IProperty PROCESSING_ORDER_TREE_CONSTRUCTION = SporeMetaDataProvider.PROCESSING_ORDER_TREE_CONSTRUCTION; + + /** + * The cost function is used in the creation of the spanning tree. + */ + public static final IProperty PROCESSING_ORDER_SPANNING_TREE_COST_FUNCTION = SporeMetaDataProvider.PROCESSING_ORDER_SPANNING_TREE_COST_FUNCTION; + + /** + * The identifier of the node that is preferred as the root of the spanning tree. + * If this is null, the first node is chosen. + */ + public static final IProperty PROCESSING_ORDER_PREFERRED_ROOT = SporeMetaDataProvider.PROCESSING_ORDER_PREFERRED_ROOT; + + /** + * This sets the method used to select a root node for the construction of a spanning tree + */ + public static final IProperty PROCESSING_ORDER_ROOT_SELECTION = SporeMetaDataProvider.PROCESSING_ORDER_ROOT_SELECTION; + + /** + * Default value for {@link #PADDING} with algorithm "ELK SPOrE Compaction". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(8); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "ELK SPOrE Compaction". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 8; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * This option defines what kind of triangulation or other partitioning of the plane + * is applied to the vertices. + */ + public static final IProperty STRUCTURE_STRUCTURE_EXTRACTION_STRATEGY = SporeMetaDataProvider.STRUCTURE_STRUCTURE_EXTRACTION_STRATEGY; + + /** + * This option defines how the compaction is applied. + */ + public static final IProperty COMPACTION_COMPACTION_STRATEGY = SporeMetaDataProvider.COMPACTION_COMPACTION_STRATEGY; + + /** + * Restricts the translation of nodes to orthogonal directions in the compaction phase. + */ + public static final IProperty COMPACTION_ORTHOGONAL = SporeMetaDataProvider.COMPACTION_ORTHOGONAL; + + /** + * Default value for {@link #DEBUG_MODE} with algorithm "ELK SPOrE Compaction". + */ + private static final boolean DEBUG_MODE_DEFAULT = false; + + /** + * Whether additional debug information shall be generated. + */ + public static final IProperty DEBUG_MODE = new Property( + CoreOptions.DEBUG_MODE, + DEBUG_MODE_DEFAULT); + + /** + * Layouter-specific algorithm factory. + */ + public static class SporeCompactionFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new ShrinkTreeLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.sporeCompaction") + .name("ELK SPOrE Compaction") + .description("ShrinkTree is a compaction algorithm that maintains the topology of a layout. The relocation of diagram elements is based on contracting a spanning tree.") + .providerFactory(new SporeCompactionFactory()) + .melkBundleName(null) + .definingBundleId("org.eclipse.elk.alg.spore") + .imagePath("images/compaction-example.png") + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeCompaction", + "org.eclipse.elk.underlyingLayoutAlgorithm", + UNDERLYING_LAYOUT_ALGORITHM.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeCompaction", + "org.eclipse.elk.processingOrder.treeConstruction", + PROCESSING_ORDER_TREE_CONSTRUCTION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeCompaction", + "org.eclipse.elk.processingOrder.spanningTreeCostFunction", + PROCESSING_ORDER_SPANNING_TREE_COST_FUNCTION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeCompaction", + "org.eclipse.elk.processingOrder.preferredRoot", + PROCESSING_ORDER_PREFERRED_ROOT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeCompaction", + "org.eclipse.elk.processingOrder.rootSelection", + PROCESSING_ORDER_ROOT_SELECTION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeCompaction", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeCompaction", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeCompaction", + "org.eclipse.elk.structure.structureExtractionStrategy", + STRUCTURE_STRUCTURE_EXTRACTION_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeCompaction", + "org.eclipse.elk.compaction.compactionStrategy", + COMPACTION_COMPACTION_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeCompaction", + "org.eclipse.elk.compaction.orthogonal", + COMPACTION_ORTHOGONAL.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeCompaction", + "org.eclipse.elk.debugMode", + DEBUG_MODE_DEFAULT + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeMetaDataProvider.java b/plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeMetaDataProvider.java new file mode 100644 index 000000000..d9f15cb57 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeMetaDataProvider.java @@ -0,0 +1,282 @@ +/** + * Copyright (c) 2017 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.spore.options; + +import java.util.EnumSet; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class SporeMetaDataProvider implements ILayoutMetaDataProvider { + /** + * A layout algorithm that is applied to the graph before it is + * compacted. If this is null, nothing is applied before compaction. + */ + public static final IProperty UNDERLYING_LAYOUT_ALGORITHM = new Property( + "org.eclipse.elk.underlyingLayoutAlgorithm"); + + /** + * Default value for {@link #STRUCTURE_STRUCTURE_EXTRACTION_STRATEGY}. + */ + private static final StructureExtractionStrategy STRUCTURE_STRUCTURE_EXTRACTION_STRATEGY_DEFAULT = StructureExtractionStrategy.DELAUNAY_TRIANGULATION; + + /** + * This option defines what kind of triangulation or other partitioning of the plane + * is applied to the vertices. + */ + public static final IProperty STRUCTURE_STRUCTURE_EXTRACTION_STRATEGY = new Property( + "org.eclipse.elk.structure.structureExtractionStrategy", + STRUCTURE_STRUCTURE_EXTRACTION_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #PROCESSING_ORDER_TREE_CONSTRUCTION}. + */ + private static final TreeConstructionStrategy PROCESSING_ORDER_TREE_CONSTRUCTION_DEFAULT = TreeConstructionStrategy.MINIMUM_SPANNING_TREE; + + /** + * Whether a minimum spanning tree or a maximum spanning tree should be constructed. + */ + public static final IProperty PROCESSING_ORDER_TREE_CONSTRUCTION = new Property( + "org.eclipse.elk.processingOrder.treeConstruction", + PROCESSING_ORDER_TREE_CONSTRUCTION_DEFAULT, + null, + null); + + /** + * Default value for {@link #PROCESSING_ORDER_SPANNING_TREE_COST_FUNCTION}. + */ + private static final SpanningTreeCostFunction PROCESSING_ORDER_SPANNING_TREE_COST_FUNCTION_DEFAULT = SpanningTreeCostFunction.CIRCLE_UNDERLAP; + + /** + * The cost function is used in the creation of the spanning tree. + */ + public static final IProperty PROCESSING_ORDER_SPANNING_TREE_COST_FUNCTION = new Property( + "org.eclipse.elk.processingOrder.spanningTreeCostFunction", + PROCESSING_ORDER_SPANNING_TREE_COST_FUNCTION_DEFAULT, + null, + null); + + /** + * Default value for {@link #PROCESSING_ORDER_PREFERRED_ROOT}. + */ + private static final String PROCESSING_ORDER_PREFERRED_ROOT_DEFAULT = null; + + /** + * The identifier of the node that is preferred as the root of the spanning tree. + * If this is null, the first node is chosen. + */ + public static final IProperty PROCESSING_ORDER_PREFERRED_ROOT = new Property( + "org.eclipse.elk.processingOrder.preferredRoot", + PROCESSING_ORDER_PREFERRED_ROOT_DEFAULT, + null, + null); + + /** + * Default value for {@link #PROCESSING_ORDER_ROOT_SELECTION}. + */ + private static final RootSelection PROCESSING_ORDER_ROOT_SELECTION_DEFAULT = RootSelection.CENTER_NODE; + + /** + * This sets the method used to select a root node for the construction of a spanning tree + */ + public static final IProperty PROCESSING_ORDER_ROOT_SELECTION = new Property( + "org.eclipse.elk.processingOrder.rootSelection", + PROCESSING_ORDER_ROOT_SELECTION_DEFAULT, + null, + null); + + /** + * Default value for {@link #COMPACTION_COMPACTION_STRATEGY}. + */ + private static final CompactionStrategy COMPACTION_COMPACTION_STRATEGY_DEFAULT = CompactionStrategy.DEPTH_FIRST; + + /** + * This option defines how the compaction is applied. + */ + public static final IProperty COMPACTION_COMPACTION_STRATEGY = new Property( + "org.eclipse.elk.compaction.compactionStrategy", + COMPACTION_COMPACTION_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #COMPACTION_ORTHOGONAL}. + */ + private static final boolean COMPACTION_ORTHOGONAL_DEFAULT = false; + + /** + * Restricts the translation of nodes to orthogonal directions in the compaction phase. + */ + public static final IProperty COMPACTION_ORTHOGONAL = new Property( + "org.eclipse.elk.compaction.orthogonal", + COMPACTION_ORTHOGONAL_DEFAULT, + null, + null); + + /** + * Default value for {@link #OVERLAP_REMOVAL_MAX_ITERATIONS}. + */ + private static final int OVERLAP_REMOVAL_MAX_ITERATIONS_DEFAULT = 64; + + public static final IProperty OVERLAP_REMOVAL_MAX_ITERATIONS = new Property( + "org.eclipse.elk.overlapRemoval.maxIterations", + OVERLAP_REMOVAL_MAX_ITERATIONS_DEFAULT, + null, + null); + + /** + * Default value for {@link #OVERLAP_REMOVAL_RUN_SCANLINE}. + */ + private static final boolean OVERLAP_REMOVAL_RUN_SCANLINE_DEFAULT = true; + + public static final IProperty OVERLAP_REMOVAL_RUN_SCANLINE = new Property( + "org.eclipse.elk.overlapRemoval.runScanline", + OVERLAP_REMOVAL_RUN_SCANLINE_DEFAULT, + null, + null); + + /** + * Required value for dependency between {@link #PROCESSING_ORDER_PREFERRED_ROOT} and {@link #PROCESSING_ORDER_ROOT_SELECTION}. + */ + private static final RootSelection PROCESSING_ORDER_PREFERRED_ROOT_DEP_PROCESSING_ORDER_ROOT_SELECTION_0 = RootSelection.FIXED; + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.underlyingLayoutAlgorithm") + .group("") + .name("Underlying Layout Algorithm") + .description("A layout algorithm that is applied to the graph before it is compacted. If this is null, nothing is applied before compaction.") + .type(LayoutOptionData.Type.STRING) + .optionClass(String.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.structure.structureExtractionStrategy") + .group("structure") + .name("Structure Extraction Strategy") + .description("This option defines what kind of triangulation or other partitioning of the plane is applied to the vertices.") + .defaultValue(STRUCTURE_STRUCTURE_EXTRACTION_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(StructureExtractionStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.processingOrder.treeConstruction") + .group("processingOrder") + .name("Tree Construction Strategy") + .description("Whether a minimum spanning tree or a maximum spanning tree should be constructed.") + .defaultValue(PROCESSING_ORDER_TREE_CONSTRUCTION_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(TreeConstructionStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.processingOrder.spanningTreeCostFunction") + .group("processingOrder") + .name("Cost Function for Spanning Tree") + .description("The cost function is used in the creation of the spanning tree.") + .defaultValue(PROCESSING_ORDER_SPANNING_TREE_COST_FUNCTION_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(SpanningTreeCostFunction.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.processingOrder.preferredRoot") + .group("processingOrder") + .name("Root node for spanning tree construction") + .description("The identifier of the node that is preferred as the root of the spanning tree. If this is null, the first node is chosen.") + .defaultValue(PROCESSING_ORDER_PREFERRED_ROOT_DEFAULT) + .type(LayoutOptionData.Type.STRING) + .optionClass(String.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.processingOrder.preferredRoot", + "org.eclipse.elk.processingOrder.rootSelection", + PROCESSING_ORDER_PREFERRED_ROOT_DEP_PROCESSING_ORDER_ROOT_SELECTION_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.processingOrder.rootSelection") + .group("processingOrder") + .name("Root selection for spanning tree") + .description("This sets the method used to select a root node for the construction of a spanning tree") + .defaultValue(PROCESSING_ORDER_ROOT_SELECTION_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(RootSelection.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.compaction.compactionStrategy") + .group("compaction") + .name("Compaction Strategy") + .description("This option defines how the compaction is applied.") + .defaultValue(COMPACTION_COMPACTION_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(CompactionStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.compaction.orthogonal") + .group("compaction") + .name("Orthogonal Compaction") + .description("Restricts the translation of nodes to orthogonal directions in the compaction phase.") + .defaultValue(COMPACTION_ORTHOGONAL_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.overlapRemoval.maxIterations") + .group("overlapRemoval") + .name("Upper limit for iterations of overlap removal") + .description(null) + .defaultValue(OVERLAP_REMOVAL_MAX_ITERATIONS_DEFAULT) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.overlapRemoval.runScanline") + .group("overlapRemoval") + .name("Whether to run a supplementary scanline overlap check.") + .description(null) + .defaultValue(OVERLAP_REMOVAL_RUN_SCANLINE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + new org.eclipse.elk.alg.spore.options.SporeOverlapRemovalOptions().apply(registry); + new org.eclipse.elk.alg.spore.options.SporeCompactionOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeOverlapRemovalOptions.java b/plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeOverlapRemovalOptions.java new file mode 100644 index 000000000..98e42bec0 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.spore/src-gen/org/eclipse/elk/alg/spore/options/SporeOverlapRemovalOptions.java @@ -0,0 +1,150 @@ +/** + * Copyright (c) 2017 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.spore.options; + +import org.eclipse.elk.alg.spore.OverlapRemovalLayoutProvider; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class SporeOverlapRemovalOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK SPOrE Overlap Removal algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.sporeOverlap"; + + /** + * A layout algorithm that is applied to the graph before it is + * compacted. If this is null, nothing is applied before compaction. + */ + public static final IProperty UNDERLYING_LAYOUT_ALGORITHM = SporeMetaDataProvider.UNDERLYING_LAYOUT_ALGORITHM; + + /** + * Default value for {@link #PADDING} with algorithm "ELK SPOrE Overlap Removal". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(8); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "ELK SPOrE Overlap Removal". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 8; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * This option defines what kind of triangulation or other partitioning of the plane + * is applied to the vertices. + */ + public static final IProperty STRUCTURE_STRUCTURE_EXTRACTION_STRATEGY = SporeMetaDataProvider.STRUCTURE_STRUCTURE_EXTRACTION_STRATEGY; + + /** + * null + */ + public static final IProperty OVERLAP_REMOVAL_MAX_ITERATIONS = SporeMetaDataProvider.OVERLAP_REMOVAL_MAX_ITERATIONS; + + /** + * null + */ + public static final IProperty OVERLAP_REMOVAL_RUN_SCANLINE = SporeMetaDataProvider.OVERLAP_REMOVAL_RUN_SCANLINE; + + /** + * Default value for {@link #DEBUG_MODE} with algorithm "ELK SPOrE Overlap Removal". + */ + private static final boolean DEBUG_MODE_DEFAULT = false; + + /** + * Whether additional debug information shall be generated. + */ + public static final IProperty DEBUG_MODE = new Property( + CoreOptions.DEBUG_MODE, + DEBUG_MODE_DEFAULT); + + /** + * Layouter-specific algorithm factory. + */ + public static class SporeOverlapFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new OverlapRemovalLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.sporeOverlap") + .name("ELK SPOrE Overlap Removal") + .description("A node overlap removal algorithm proposed by Nachmanson et al. in \"Node overlap removal by growing a tree\".") + .providerFactory(new SporeOverlapFactory()) + .melkBundleName(null) + .definingBundleId("org.eclipse.elk.alg.spore") + .imagePath("images/overlap-removal.png") + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeOverlap", + "org.eclipse.elk.underlyingLayoutAlgorithm", + UNDERLYING_LAYOUT_ALGORITHM.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeOverlap", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeOverlap", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeOverlap", + "org.eclipse.elk.structure.structureExtractionStrategy", + STRUCTURE_STRUCTURE_EXTRACTION_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeOverlap", + "org.eclipse.elk.overlapRemoval.maxIterations", + OVERLAP_REMOVAL_MAX_ITERATIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeOverlap", + "org.eclipse.elk.overlapRemoval.runScanline", + OVERLAP_REMOVAL_RUN_SCANLINE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.sporeOverlap", + "org.eclipse.elk.debugMode", + DEBUG_MODE_DEFAULT + ); + } +} diff --git a/plugins/org.eclipse.elk.alg.topdownpacking/src-gen/org/eclipse/elk/alg/topdownpacking/options/TopdownpackingMetaDataProvider.java b/plugins/org.eclipse.elk.alg.topdownpacking/src-gen/org/eclipse/elk/alg/topdownpacking/options/TopdownpackingMetaDataProvider.java new file mode 100644 index 000000000..15fcb32e8 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.topdownpacking/src-gen/org/eclipse/elk/alg/topdownpacking/options/TopdownpackingMetaDataProvider.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2022 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.topdownpacking.options; + +import java.util.EnumSet; +import org.eclipse.elk.alg.topdownpacking.NodeArrangementStrategy; +import org.eclipse.elk.alg.topdownpacking.WhitespaceEliminationStrategy; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class TopdownpackingMetaDataProvider implements ILayoutMetaDataProvider { + /** + * Default value for {@link #NODE_ARRANGEMENT_STRATEGY}. + */ + private static final NodeArrangementStrategy NODE_ARRANGEMENT_STRATEGY_DEFAULT = NodeArrangementStrategy.LEFT_RIGHT_TOP_DOWN_NODE_PLACER; + + /** + * Strategy for node arrangement. The strategy determines the size of the resulting graph. + */ + public static final IProperty NODE_ARRANGEMENT_STRATEGY = new Property( + "org.eclipse.elk.topdownpacking.nodeArrangement.strategy", + NODE_ARRANGEMENT_STRATEGY_DEFAULT, + null, + null); + + /** + * Default value for {@link #WHITESPACE_ELIMINATION_STRATEGY}. + */ + private static final WhitespaceEliminationStrategy WHITESPACE_ELIMINATION_STRATEGY_DEFAULT = WhitespaceEliminationStrategy.BOTTOM_ROW_EQUAL_WHITESPACE_ELIMINATOR; + + /** + * Strategy for whitespace elimination. + */ + public static final IProperty WHITESPACE_ELIMINATION_STRATEGY = new Property( + "org.eclipse.elk.topdownpacking.whitespaceElimination.strategy", + WHITESPACE_ELIMINATION_STRATEGY_DEFAULT, + null, + null); + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.topdownpacking.nodeArrangement.strategy") + .group("nodeArrangement") + .name("Node arrangement strategy") + .description("Strategy for node arrangement. The strategy determines the size of the resulting graph.") + .defaultValue(NODE_ARRANGEMENT_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(NodeArrangementStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.topdownpacking.whitespaceElimination.strategy") + .group("whitespaceElimination") + .name("Whitespace elimination strategy") + .description("Strategy for whitespace elimination.") + .defaultValue(WHITESPACE_ELIMINATION_STRATEGY_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(WhitespaceEliminationStrategy.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + new org.eclipse.elk.alg.topdownpacking.options.TopdownpackingOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.alg.topdownpacking/src-gen/org/eclipse/elk/alg/topdownpacking/options/TopdownpackingOptions.java b/plugins/org.eclipse.elk.alg.topdownpacking/src-gen/org/eclipse/elk/alg/topdownpacking/options/TopdownpackingOptions.java new file mode 100644 index 000000000..e132cb610 --- /dev/null +++ b/plugins/org.eclipse.elk.alg.topdownpacking/src-gen/org/eclipse/elk/alg/topdownpacking/options/TopdownpackingOptions.java @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2022 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.alg.topdownpacking.options; + +import org.eclipse.elk.alg.topdownpacking.NodeArrangementStrategy; +import org.eclipse.elk.alg.topdownpacking.TopdownpackingLayoutProvider; +import org.eclipse.elk.alg.topdownpacking.WhitespaceEliminationStrategy; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.TopdownNodeTypes; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class TopdownpackingOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK Top-down Packing algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.topdownpacking"; + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = CoreOptions.PADDING; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = CoreOptions.SPACING_NODE_NODE; + + /** + * The fixed size of a hierarchical node when using topdown layout. If this value is set on a parallel + * node it applies to its children, when set on a hierarchical node it applies to the node itself. + */ + public static final IProperty TOPDOWN_HIERARCHICAL_NODE_WIDTH = CoreOptions.TOPDOWN_HIERARCHICAL_NODE_WIDTH; + + /** + * The fixed aspect ratio of a hierarchical node when using topdown layout. Default is 1/sqrt(2). If this + * value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to + * the node itself. + */ + public static final IProperty TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO = CoreOptions.TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO; + + /** + * Turns topdown layout on and off. If this option is enabled, hierarchical layout will be computed first for + * the root node and then for its children recursively. Layouts are then scaled down to fit the area provided by + * their parents. Graphs must follow a certain structure for topdown layout to work properly. + * {@link TopdownNodeTypes.PARALLEL_NODE} nodes must have children of type + * {@link TopdownNodeTypes.HIERARCHICAL_NODE} and must define {@link topdown.hierarchicalNodeWidth} and + * {@link topdown.hierarchicalNodeAspectRatio} for their children. Furthermore they need to be laid out using an + * algorithm that is a {@link TopdownLayoutProvider}. Hierarchical nodes can also be parents of other hierarchical + * nodes and can optionally use a {@link TopdownSizeApproximator} to dynamically set sizes during topdown layout. + * In this case {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} should be set + * on the node itself rather than the parent. The values are then used by the size approximator as base values. + * Hierarchical nodes require the layout option {@link nodeSize.fixedGraphSize} to be true to prevent the algorithm + * used there from resizing the hierarchical node. This option is not supported if 'Hierarchy Handling' is set to + * 'INCLUDE_CHILDREN' + */ + public static final IProperty TOPDOWN_LAYOUT = CoreOptions.TOPDOWN_LAYOUT; + + /** + * Default value for {@link #TOPDOWN_NODE_TYPE} with algorithm "ELK Top-down Packing". + */ + private static final TopdownNodeTypes TOPDOWN_NODE_TYPE_DEFAULT = TopdownNodeTypes.PARALLEL_NODE; + + /** + * The different node types used for topdown layout. If the node type is set + * to {@link TopdownNodeTypes.PARALLEL_NODE} the algorithm must be set to a {@link TopdownLayoutProvider} such + * as {@link TopdownPacking}. The {@link nodeSize.fixedGraphSize} option is technically only required for + * hierarchical nodes. + */ + public static final IProperty TOPDOWN_NODE_TYPE = new Property( + CoreOptions.TOPDOWN_NODE_TYPE, + TOPDOWN_NODE_TYPE_DEFAULT); + + /** + * Strategy for node arrangement. The strategy determines the size of the resulting graph. + */ + public static final IProperty NODE_ARRANGEMENT_STRATEGY = TopdownpackingMetaDataProvider.NODE_ARRANGEMENT_STRATEGY; + + /** + * Strategy for whitespace elimination. + */ + public static final IProperty WHITESPACE_ELIMINATION_STRATEGY = TopdownpackingMetaDataProvider.WHITESPACE_ELIMINATION_STRATEGY; + + /** + * Layouter-specific algorithm factory. + */ + public static class TopdownpackingFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new TopdownpackingLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.topdownpacking") + .name("ELK Top-down Packing") + .description("An algorithm for placing boxes of fixed sizes. Expands boxes horizontally to fill empty whitespace. This algorithm can be used standalone or specifically for {@link CoreOptions.TOPDOWN_LAYOUT}. In this use case it should be set for nodes whose {@link CoreOptions.TOPDOWN_NODE_TYPE} is set to {@link TopdownNodeTypes.PARALLEL_NODE}. This allows topdown layout to give children larger sizes based on their number of children.") + .providerFactory(new TopdownpackingFactory()) + .melkBundleName(null) + .definingBundleId("org.eclipse.elk.alg.topdownpacking") + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.topdownpacking", + "org.eclipse.elk.padding", + PADDING.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.topdownpacking", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.topdownpacking", + "org.eclipse.elk.topdown.hierarchicalNodeWidth", + TOPDOWN_HIERARCHICAL_NODE_WIDTH.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.topdownpacking", + "org.eclipse.elk.topdown.hierarchicalNodeAspectRatio", + TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.topdownpacking", + "org.eclipse.elk.topdownLayout", + TOPDOWN_LAYOUT.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.topdownpacking", + "org.eclipse.elk.topdown.nodeType", + TOPDOWN_NODE_TYPE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.topdownpacking", + "org.eclipse.elk.topdownpacking.nodeArrangement.strategy", + NODE_ARRANGEMENT_STRATEGY.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.topdownpacking", + "org.eclipse.elk.topdownpacking.whitespaceElimination.strategy", + WHITESPACE_ELIMINATION_STRATEGY.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.conn.gmf/src-gen/org/eclipse/elk/conn/gmf/layouter/Draw2DOptions.java b/plugins/org.eclipse.elk.conn.gmf/src-gen/org/eclipse/elk/conn/gmf/layouter/Draw2DOptions.java new file mode 100644 index 000000000..69f1a6a88 --- /dev/null +++ b/plugins/org.eclipse.elk.conn.gmf/src-gen/org/eclipse/elk/conn/gmf/layouter/Draw2DOptions.java @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2015 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.conn.gmf.layouter; + +import java.util.EnumSet; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.options.CoreOptions; +import org.eclipse.elk.core.options.Direction; +import org.eclipse.elk.core.options.SizeConstraint; +import org.eclipse.elk.graph.properties.GraphFeature; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class Draw2DOptions implements ILayoutMetaDataProvider { + /** + * The id of the Draw2D Layout algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.conn.gmf.layouter.Draw2D"; + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "Draw2D Layout". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 16; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * Default value for {@link #PADDING} with algorithm "Draw2D Layout". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(16); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #DIRECTION} with algorithm "Draw2D Layout". + */ + private static final Direction DIRECTION_DEFAULT = Direction.RIGHT; + + /** + * Overall direction of edges: horizontal (right / left) or + * vertical (down / up). + */ + public static final IProperty DIRECTION = new Property( + CoreOptions.DIRECTION, + DIRECTION_DEFAULT); + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * Layouter-specific algorithm factory. + */ + public static class Draw2DFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new Draw2DLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.conn.gmf.layouter.Draw2D") + .name("Draw2D Layout") + .description("\'Directed Graph Layout\' provided by the Draw2D framework. This is the same algorithm that is used by the standard layout button of GMF diagrams.") + .providerFactory(new Draw2DFactory()) + .category("org.eclipse.elk.layered") + .melkBundleName("GMF") + .definingBundleId("org.eclipse.elk.conn.gmf") + .imagePath("images/draw2d.png") + .supportedFeatures(EnumSet.of(GraphFeature.MULTI_EDGES)) + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.conn.gmf.layouter.Draw2D", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.conn.gmf.layouter.Draw2D", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.conn.gmf.layouter.Draw2D", + "org.eclipse.elk.direction", + DIRECTION_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.conn.gmf.layouter.Draw2D", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.conn.gmf/src-gen/org/eclipse/elk/conn/gmf/layouter/GmfMetaDataProvider.java b/plugins/org.eclipse.elk.conn.gmf/src-gen/org/eclipse/elk/conn/gmf/layouter/GmfMetaDataProvider.java new file mode 100644 index 000000000..2979e98b5 --- /dev/null +++ b/plugins/org.eclipse.elk.conn.gmf/src-gen/org/eclipse/elk/conn/gmf/layouter/GmfMetaDataProvider.java @@ -0,0 +1,22 @@ +/** + * Copyright (c) 2015 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.conn.gmf.layouter; + +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; + +/** + * Layout algorithms contributed by GMF / GEF. + */ +@SuppressWarnings("all") +public class GmfMetaDataProvider implements ILayoutMetaDataProvider { + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + new org.eclipse.elk.conn.gmf.layouter.Draw2DOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/labels/LabelManagementOptions.java b/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/labels/LabelManagementOptions.java new file mode 100644 index 000000000..faf2e53d0 --- /dev/null +++ b/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/labels/LabelManagementOptions.java @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2016 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.core.labels; + +import java.util.EnumSet; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +/** + * Label management definitions of the Eclipse Layout Kernel. + */ +@SuppressWarnings("all") +public class LabelManagementOptions implements ILayoutMetaDataProvider { + /** + * The label manager responsible for a given part of the graph. A label manager can either be + * attached to a compound node (in which case it is responsible for all labels inside) or to + * specific labels. The label manager can then be called by layout algorithms to modify labels + * that are too wide to try and shorten them to a given target width. + */ + public static final IProperty LABEL_MANAGER = new Property( + "org.eclipse.elk.labels.labelManager"); + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.labels.labelManager") + .group("") + .name("Label Manager") + .description("The label manager responsible for a given part of the graph. A label manager can either be attached to a compound node (in which case it is responsible for all labels inside) or to specific labels. The label manager can then be called by layout algorithms to modify labels that are too wide to try and shorten them to a given target width.") + .type(LayoutOptionData.Type.OBJECT) + .optionClass(ILabelManager.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS, LayoutOptionData.Target.LABELS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + } +} diff --git a/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/BoxLayouterOptions.java b/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/BoxLayouterOptions.java new file mode 100644 index 000000000..9c131a908 --- /dev/null +++ b/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/BoxLayouterOptions.java @@ -0,0 +1,213 @@ +/** + * Copyright (c) 2015, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.core.options; + +import java.util.EnumSet; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.math.KVector; +import org.eclipse.elk.core.util.BoxLayoutProvider; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class BoxLayouterOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK Box algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.box"; + + /** + * Default value for {@link #PADDING} with algorithm "ELK Box". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(15); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "ELK Box". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 15; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * Default value for {@link #PRIORITY} with algorithm "ELK Box". + */ + private static final int PRIORITY_DEFAULT = 0; + + /** + * Defines the priority of an object; its meaning depends on the specific layout algorithm + * and the context where it is used. + *

Algorithm Specific Details

+ * Priorities set on nodes determine the order in which they are placed: + * boxes with a higher priority will end up before boxes with a lower priority. + * Boxes with equal priorities are sorted from smaller to bigger + * unless the layout algorithm is set to interactive mode. + */ + public static final IProperty PRIORITY = new Property( + CoreOptions.PRIORITY, + PRIORITY_DEFAULT); + + /** + * If active, nodes are expanded to fill the area of their parent. + */ + public static final IProperty EXPAND_NODES = CoreOptions.EXPAND_NODES; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = CoreOptions.NODE_SIZE_OPTIONS; + + /** + * Default value for {@link #ASPECT_RATIO} with algorithm "ELK Box". + */ + private static final double ASPECT_RATIO_DEFAULT = 1.3f; + + /** + * The desired aspect ratio of the drawing, that is the quotient of width by height. + */ + public static final IProperty ASPECT_RATIO = new Property( + CoreOptions.ASPECT_RATIO, + ASPECT_RATIO_DEFAULT); + + /** + * Whether the algorithm should be run in interactive mode for the content of a parent node. + * What this means exactly depends on how the specific algorithm interprets this option. + * Usually in the interactive mode algorithms try to modify the current layout as little as + * possible. + */ + public static final IProperty INTERACTIVE = CoreOptions.INTERACTIVE; + + /** + * The minimal size to which a node can be reduced. + */ + public static final IProperty NODE_SIZE_MINIMUM = CoreOptions.NODE_SIZE_MINIMUM; + + /** + * Configures the packing mode used by the {@link BoxLayoutProvider}. + * If SIMPLE is not required (neither priorities are used nor the interactive mode), + * GROUP_DEC can improve the packing and decrease the area. + * GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better. + */ + public static final IProperty BOX_PACKING_MODE = CoreOptions.BOX_PACKING_MODE; + + /** + * Specifies how the content of a node are aligned. Each node can individually control the alignment of its + * contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that + * option. + */ + public static final IProperty> CONTENT_ALIGNMENT = CoreOptions.CONTENT_ALIGNMENT; + + /** + * Layouter-specific algorithm factory. + */ + public static class BoxFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new BoxLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.box") + .name("ELK Box") + .description("Algorithm for packing of unconnected boxes, i.e. graphs without edges.") + .providerFactory(new BoxFactory()) + .melkBundleName("ELK") + .definingBundleId("org.eclipse.elk.core") + .imagePath("images/box_layout.png") + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.box", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.box", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.box", + "org.eclipse.elk.priority", + PRIORITY_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.box", + "org.eclipse.elk.expandNodes", + EXPAND_NODES.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.box", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.box", + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.box", + "org.eclipse.elk.aspectRatio", + ASPECT_RATIO_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.box", + "org.eclipse.elk.interactive", + INTERACTIVE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.box", + "org.eclipse.elk.nodeSize.minimum", + NODE_SIZE_MINIMUM.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.box", + "org.eclipse.elk.box.packingMode", + BOX_PACKING_MODE.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.box", + "org.eclipse.elk.contentAlignment", + CONTENT_ALIGNMENT.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/CoreOptions.java b/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/CoreOptions.java new file mode 100644 index 000000000..8ea1c9bfa --- /dev/null +++ b/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/CoreOptions.java @@ -0,0 +1,2497 @@ +/** + * Copyright (c) 2015, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.core.options; + +import java.util.EnumSet; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.data.LayoutCategoryData; +import org.eclipse.elk.core.data.LayoutOptionData; +import org.eclipse.elk.core.labels.ILabelManager; +import org.eclipse.elk.core.math.ElkMargin; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.math.KVector; +import org.eclipse.elk.core.math.KVectorChain; +import org.eclipse.elk.core.util.BoxLayoutProvider; +import org.eclipse.elk.core.util.ExclusiveBounds; +import org.eclipse.elk.core.util.IndividualSpacings; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +/** + * Core definitions of the Eclipse Layout Kernel. + */ +@SuppressWarnings("all") +public class CoreOptions implements ILayoutMetaDataProvider { + /** + * Select a specific layout algorithm. + */ + public static final IProperty ALGORITHM = new Property( + "org.eclipse.elk.algorithm"); + + /** + * Meta data associated with the selected algorithm. + */ + public static final IProperty RESOLVED_ALGORITHM = new Property( + "org.eclipse.elk.resolvedAlgorithm"); + + /** + * Default value for {@link #ALIGNMENT}. + */ + private static final Alignment ALIGNMENT_DEFAULT = Alignment.AUTOMATIC; + + /** + * Alignment of the selected node relative to other nodes; + * the exact meaning depends on the used algorithm. + */ + public static final IProperty ALIGNMENT = new Property( + "org.eclipse.elk.alignment", + ALIGNMENT_DEFAULT, + null, + null); + + /** + * Lower bound value for {@link #ASPECT_RATIO}. + */ + private static final Comparable ASPECT_RATIO_LOWER_BOUND = ExclusiveBounds.greaterThan(0); + + /** + * The desired aspect ratio of the drawing, that is the quotient of width by height. + */ + public static final IProperty ASPECT_RATIO = new Property( + "org.eclipse.elk.aspectRatio", + null, + ASPECT_RATIO_LOWER_BOUND, + null); + + /** + * A fixed list of bend points for the edge. This is used by the 'Fixed Layout' algorithm to + * specify a pre-defined routing for an edge. The vector chain must include the source point, + * any bend points, and the target point, so it must have at least two points. + */ + public static final IProperty BEND_POINTS = new Property( + "org.eclipse.elk.bendPoints"); + + /** + * Default value for {@link #CONTENT_ALIGNMENT}. + */ + private static final EnumSet CONTENT_ALIGNMENT_DEFAULT = ContentAlignment.topLeft(); + + /** + * Specifies how the content of a node are aligned. Each node can individually control the alignment of its + * contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that + * option. + */ + public static final IProperty> CONTENT_ALIGNMENT = new Property>( + "org.eclipse.elk.contentAlignment", + CONTENT_ALIGNMENT_DEFAULT, + null, + null); + + /** + * Default value for {@link #DEBUG_MODE}. + */ + private static final boolean DEBUG_MODE_DEFAULT = false; + + /** + * Whether additional debug information shall be generated. + */ + public static final IProperty DEBUG_MODE = new Property( + "org.eclipse.elk.debugMode", + DEBUG_MODE_DEFAULT, + null, + null); + + /** + * Default value for {@link #DIRECTION}. + */ + private static final Direction DIRECTION_DEFAULT = Direction.UNDEFINED; + + /** + * Overall direction of edges: horizontal (right / left) or + * vertical (down / up). + */ + public static final IProperty DIRECTION = new Property( + "org.eclipse.elk.direction", + DIRECTION_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_ROUTING}. + */ + private static final EdgeRouting EDGE_ROUTING_DEFAULT = EdgeRouting.UNDEFINED; + + /** + * What kind of edge routing style should be applied for the content of a parent node. + * Algorithms may also set this option to single edges in order to mark them as splines. + * The bend point list of edges with this option set to SPLINES must be interpreted as control + * points for a piecewise cubic spline. + */ + public static final IProperty EDGE_ROUTING = new Property( + "org.eclipse.elk.edgeRouting", + EDGE_ROUTING_DEFAULT, + null, + null); + + /** + * Default value for {@link #EXPAND_NODES}. + */ + private static final boolean EXPAND_NODES_DEFAULT = false; + + /** + * If active, nodes are expanded to fill the area of their parent. + */ + public static final IProperty EXPAND_NODES = new Property( + "org.eclipse.elk.expandNodes", + EXPAND_NODES_DEFAULT, + null, + null); + + /** + * Default value for {@link #HIERARCHY_HANDLING}. + */ + private static final HierarchyHandling HIERARCHY_HANDLING_DEFAULT = HierarchyHandling.INHERIT; + + /** + * Determines whether separate layout runs are triggered for different compound nodes in a + * hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay + * out that node and all of its descendants in a single layout run, until a descendant is + * encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, + * `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that + * setting. Including multiple levels of hierarchy in a single layout run may allow + * cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` + * (or not set at all), the default behavior is `SEPARATE_CHILDREN`. + */ + public static final IProperty HIERARCHY_HANDLING = new Property( + "org.eclipse.elk.hierarchyHandling", + HIERARCHY_HANDLING_DEFAULT, + null, + null); + + /** + * Default value for {@link #PADDING}. + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(12); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + "org.eclipse.elk.padding", + PADDING_DEFAULT, + null, + null); + + /** + * Default value for {@link #INTERACTIVE}. + */ + private static final boolean INTERACTIVE_DEFAULT = false; + + /** + * Whether the algorithm should be run in interactive mode for the content of a parent node. + * What this means exactly depends on how the specific algorithm interprets this option. + * Usually in the interactive mode algorithms try to modify the current layout as little as + * possible. + */ + public static final IProperty INTERACTIVE = new Property( + "org.eclipse.elk.interactive", + INTERACTIVE_DEFAULT, + null, + null); + + /** + * Default value for {@link #INTERACTIVE_LAYOUT}. + */ + private static final boolean INTERACTIVE_LAYOUT_DEFAULT = false; + + /** + * Whether the graph should be changeable interactively and by setting constraints + */ + public static final IProperty INTERACTIVE_LAYOUT = new Property( + "org.eclipse.elk.interactiveLayout", + INTERACTIVE_LAYOUT_DEFAULT, + null, + null); + + /** + * Default value for {@link #OMIT_NODE_MICRO_LAYOUT}. + */ + private static final boolean OMIT_NODE_MICRO_LAYOUT_DEFAULT = false; + + /** + * Node micro layout comprises the computation of node dimensions (if requested), the placement of ports + * and their labels, and the placement of node labels. + * The functionality is implemented independent of any specific layout algorithm and shouldn't have any + * negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, + * this option allows to deactivate the micro layout. + */ + public static final IProperty OMIT_NODE_MICRO_LAYOUT = new Property( + "org.eclipse.elk.omitNodeMicroLayout", + OMIT_NODE_MICRO_LAYOUT_DEFAULT, + null, + null); + + /** + * Default value for {@link #PORT_CONSTRAINTS}. + */ + private static final PortConstraints PORT_CONSTRAINTS_DEFAULT = PortConstraints.UNDEFINED; + + /** + * Defines constraints of the position of the ports of a node. + */ + public static final IProperty PORT_CONSTRAINTS = new Property( + "org.eclipse.elk.portConstraints", + PORT_CONSTRAINTS_DEFAULT, + null, + null); + + /** + * The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to + * specify a pre-defined position. + */ + public static final IProperty POSITION = new Property( + "org.eclipse.elk.position"); + + /** + * Defines the priority of an object; its meaning depends on the specific layout algorithm + * and the context where it is used. + */ + public static final IProperty PRIORITY = new Property( + "org.eclipse.elk.priority"); + + /** + * Seed used for pseudo-random number generators to control the layout algorithm. If the + * value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time). + */ + public static final IProperty RANDOM_SEED = new Property( + "org.eclipse.elk.randomSeed"); + + /** + * Whether each connected component should be processed separately. + */ + public static final IProperty SEPARATE_CONNECTED_COMPONENTS = new Property( + "org.eclipse.elk.separateConnectedComponents"); + + /** + * Default value for {@link #JUNCTION_POINTS}. + */ + private static final KVectorChain JUNCTION_POINTS_DEFAULT = new KVectorChain(); + + /** + * This option is not used as option, but as output of the layout algorithms. It is + * attached to edges and determines the points where junction symbols should be drawn in + * order to represent hyperedges with orthogonal routing. Whether such points are computed + * depends on the chosen layout algorithm and edge routing style. The points are put into + * the vector chain with no specific order. + */ + public static final IProperty JUNCTION_POINTS = new Property( + "org.eclipse.elk.junctionPoints", + JUNCTION_POINTS_DEFAULT, + null, + null); + + /** + * Default value for {@link #COMMENT_BOX}. + */ + private static final boolean COMMENT_BOX_DEFAULT = false; + + /** + * Whether the node should be regarded as a comment box instead of a regular node. In that + * case its placement should be similar to how labels are handled. Any edges incident to a + * comment box specify to which graph elements the comment is related. + */ + public static final IProperty COMMENT_BOX = new Property( + "org.eclipse.elk.commentBox", + COMMENT_BOX_DEFAULT, + null, + null); + + /** + * Default value for {@link #HYPERNODE}. + */ + private static final boolean HYPERNODE_DEFAULT = false; + + /** + * Whether the node should be handled as a hypernode. + */ + public static final IProperty HYPERNODE = new Property( + "org.eclipse.elk.hypernode", + HYPERNODE_DEFAULT, + null, + null); + + /** + * Label managers can shorten labels upon a layout algorithm's request. + */ + public static final IProperty LABEL_MANAGER = new Property( + "org.eclipse.elk.labelManager"); + + /** + * Default value for {@link #MARGINS}. + */ + private static final ElkMargin MARGINS_DEFAULT = new ElkMargin(); + + /** + * Margins define additional space around the actual bounds of a graph element. For instance, + * ports or labels being placed on the outside of a node's border might introduce such a + * margin. The margin is used to guarantee non-overlap of other graph elements with those + * ports or labels. + */ + public static final IProperty MARGINS = new Property( + "org.eclipse.elk.margins", + MARGINS_DEFAULT, + null, + null); + + /** + * Default value for {@link #NO_LAYOUT}. + */ + private static final boolean NO_LAYOUT_DEFAULT = false; + + /** + * No layout is done for the associated element. This is used to mark parts of a diagram to + * avoid their inclusion in the layout graph, or to mark parts of the layout graph to + * prevent layout engines from processing them. If you wish to exclude the contents of a + * compound node from automatic layout, while the node itself is still considered on its own + * layer, use the 'Fixed Layout' algorithm for that node. + */ + public static final IProperty NO_LAYOUT = new Property( + "org.eclipse.elk.noLayout", + NO_LAYOUT_DEFAULT, + null, + null); + + /** + * Default value for {@link #SCALE_FACTOR}. + */ + private static final double SCALE_FACTOR_DEFAULT = 1; + + /** + * Lower bound value for {@link #SCALE_FACTOR}. + */ + private static final Comparable SCALE_FACTOR_LOWER_BOUND = ExclusiveBounds.greaterThan(0); + + /** + * The scaling factor to be applied to the corresponding node in recursive layout. It causes + * the corresponding node's size to be adjusted, and its ports and labels to be sized and + * placed accordingly after the layout of that node has been determined (and before the node + * itself and its siblings are arranged). The scaling is not reverted afterwards, so the + * resulting layout graph contains the adjusted size and position data. This option is + * currently not supported if 'Layout Hierarchy' is set. + */ + public static final IProperty SCALE_FACTOR = new Property( + "org.eclipse.elk.scaleFactor", + SCALE_FACTOR_DEFAULT, + SCALE_FACTOR_LOWER_BOUND, + null); + + /** + * The width of the area occupied by the laid out children of a node. + */ + public static final IProperty CHILD_AREA_WIDTH = new Property( + "org.eclipse.elk.childAreaWidth"); + + /** + * The height of the area occupied by the laid out children of a node. + */ + public static final IProperty CHILD_AREA_HEIGHT = new Property( + "org.eclipse.elk.childAreaHeight"); + + /** + * Default value for {@link #TOPDOWN_LAYOUT}. + */ + private static final boolean TOPDOWN_LAYOUT_DEFAULT = false; + + /** + * Turns topdown layout on and off. If this option is enabled, hierarchical layout will be computed first for + * the root node and then for its children recursively. Layouts are then scaled down to fit the area provided by + * their parents. Graphs must follow a certain structure for topdown layout to work properly. + * {@link TopdownNodeTypes.PARALLEL_NODE} nodes must have children of type + * {@link TopdownNodeTypes.HIERARCHICAL_NODE} and must define {@link topdown.hierarchicalNodeWidth} and + * {@link topdown.hierarchicalNodeAspectRatio} for their children. Furthermore they need to be laid out using an + * algorithm that is a {@link TopdownLayoutProvider}. Hierarchical nodes can also be parents of other hierarchical + * nodes and can optionally use a {@link TopdownSizeApproximator} to dynamically set sizes during topdown layout. + * In this case {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} should be set + * on the node itself rather than the parent. The values are then used by the size approximator as base values. + * Hierarchical nodes require the layout option {@link nodeSize.fixedGraphSize} to be true to prevent the algorithm + * used there from resizing the hierarchical node. This option is not supported if 'Hierarchy Handling' is set to + * 'INCLUDE_CHILDREN' + */ + public static final IProperty TOPDOWN_LAYOUT = new Property( + "org.eclipse.elk.topdownLayout", + TOPDOWN_LAYOUT_DEFAULT, + null, + null); + + /** + * Default value for {@link #ANIMATE}. + */ + private static final boolean ANIMATE_DEFAULT = true; + + /** + * Whether the shift from the old layout to the new computed layout shall be animated. + */ + public static final IProperty ANIMATE = new Property( + "org.eclipse.elk.animate", + ANIMATE_DEFAULT, + null, + null); + + /** + * Default value for {@link #ANIM_TIME_FACTOR}. + */ + private static final int ANIM_TIME_FACTOR_DEFAULT = 100; + + /** + * Lower bound value for {@link #ANIM_TIME_FACTOR}. + */ + private static final Comparable ANIM_TIME_FACTOR_LOWER_BOUND = Integer.valueOf(0); + + /** + * Factor for computation of animation time. The higher the value, the longer the animation + * time. If the value is 0, the resulting time is always equal to the minimum defined by + * 'Minimal Animation Time'. + */ + public static final IProperty ANIM_TIME_FACTOR = new Property( + "org.eclipse.elk.animTimeFactor", + ANIM_TIME_FACTOR_DEFAULT, + ANIM_TIME_FACTOR_LOWER_BOUND, + null); + + /** + * Default value for {@link #LAYOUT_ANCESTORS}. + */ + private static final boolean LAYOUT_ANCESTORS_DEFAULT = false; + + /** + * Whether the hierarchy levels on the path from the selected element to the root of the + * diagram shall be included in the layout process. + */ + public static final IProperty LAYOUT_ANCESTORS = new Property( + "org.eclipse.elk.layoutAncestors", + LAYOUT_ANCESTORS_DEFAULT, + null, + null); + + /** + * Default value for {@link #MAX_ANIM_TIME}. + */ + private static final int MAX_ANIM_TIME_DEFAULT = 4000; + + /** + * Lower bound value for {@link #MAX_ANIM_TIME}. + */ + private static final Comparable MAX_ANIM_TIME_LOWER_BOUND = Integer.valueOf(0); + + /** + * The maximal time for animations, in milliseconds. + */ + public static final IProperty MAX_ANIM_TIME = new Property( + "org.eclipse.elk.maxAnimTime", + MAX_ANIM_TIME_DEFAULT, + MAX_ANIM_TIME_LOWER_BOUND, + null); + + /** + * Default value for {@link #MIN_ANIM_TIME}. + */ + private static final int MIN_ANIM_TIME_DEFAULT = 400; + + /** + * Lower bound value for {@link #MIN_ANIM_TIME}. + */ + private static final Comparable MIN_ANIM_TIME_LOWER_BOUND = Integer.valueOf(0); + + /** + * The minimal time for animations, in milliseconds. + */ + public static final IProperty MIN_ANIM_TIME = new Property( + "org.eclipse.elk.minAnimTime", + MIN_ANIM_TIME_DEFAULT, + MIN_ANIM_TIME_LOWER_BOUND, + null); + + /** + * Default value for {@link #PROGRESS_BAR}. + */ + private static final boolean PROGRESS_BAR_DEFAULT = false; + + /** + * Whether a progress bar shall be displayed during layout computations. + */ + public static final IProperty PROGRESS_BAR = new Property( + "org.eclipse.elk.progressBar", + PROGRESS_BAR_DEFAULT, + null, + null); + + /** + * Default value for {@link #VALIDATE_GRAPH}. + */ + private static final boolean VALIDATE_GRAPH_DEFAULT = false; + + /** + * Whether the graph shall be validated before any layout algorithm is applied. If this + * option is enabled and at least one error is found, the layout process is aborted and a message + * is shown to the user. + */ + public static final IProperty VALIDATE_GRAPH = new Property( + "org.eclipse.elk.validateGraph", + VALIDATE_GRAPH_DEFAULT, + null, + null); + + /** + * Default value for {@link #VALIDATE_OPTIONS}. + */ + private static final boolean VALIDATE_OPTIONS_DEFAULT = true; + + /** + * Whether layout options shall be validated before any layout algorithm is applied. If this + * option is enabled and at least one error is found, the layout process is aborted and a message + * is shown to the user. + */ + public static final IProperty VALIDATE_OPTIONS = new Property( + "org.eclipse.elk.validateOptions", + VALIDATE_OPTIONS_DEFAULT, + null, + null); + + /** + * Default value for {@link #ZOOM_TO_FIT}. + */ + private static final boolean ZOOM_TO_FIT_DEFAULT = false; + + /** + * Whether the zoom level shall be set to view the whole diagram after layout. + */ + public static final IProperty ZOOM_TO_FIT = new Property( + "org.eclipse.elk.zoomToFit", + ZOOM_TO_FIT_DEFAULT, + null, + null); + + /** + * Default value for {@link #BOX_PACKING_MODE}. + */ + private static final BoxLayoutProvider.PackingMode BOX_PACKING_MODE_DEFAULT = BoxLayoutProvider.PackingMode.SIMPLE; + + /** + * Configures the packing mode used by the {@link BoxLayoutProvider}. + * If SIMPLE is not required (neither priorities are used nor the interactive mode), + * GROUP_DEC can improve the packing and decrease the area. + * GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better. + */ + public static final IProperty BOX_PACKING_MODE = new Property( + "org.eclipse.elk.box.packingMode", + BOX_PACKING_MODE_DEFAULT, + null, + null); + + /** + * Default value for {@link #SPACING_COMMENT_COMMENT}. + */ + private static final double SPACING_COMMENT_COMMENT_DEFAULT = 10; + + /** + * Lower bound value for {@link #SPACING_COMMENT_COMMENT}. + */ + private static final Comparable SPACING_COMMENT_COMMENT_LOWER_BOUND = Double.valueOf(0.0); + + /** + * Spacing to be preserved between a comment box and other comment boxes connected to the same node. + * The space left between comment boxes of different nodes is controlled by the node-node spacing. + */ + public static final IProperty SPACING_COMMENT_COMMENT = new Property( + "org.eclipse.elk.spacing.commentComment", + SPACING_COMMENT_COMMENT_DEFAULT, + SPACING_COMMENT_COMMENT_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_COMMENT_NODE}. + */ + private static final double SPACING_COMMENT_NODE_DEFAULT = 10; + + /** + * Lower bound value for {@link #SPACING_COMMENT_NODE}. + */ + private static final Comparable SPACING_COMMENT_NODE_LOWER_BOUND = Double.valueOf(0.0); + + /** + * Spacing to be preserved between a node and its connected comment boxes. The space left between a node + * and the comments of another node is controlled by the node-node spacing. + */ + public static final IProperty SPACING_COMMENT_NODE = new Property( + "org.eclipse.elk.spacing.commentNode", + SPACING_COMMENT_NODE_DEFAULT, + SPACING_COMMENT_NODE_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_COMPONENT_COMPONENT}. + */ + private static final double SPACING_COMPONENT_COMPONENT_DEFAULT = 20f; + + /** + * Lower bound value for {@link #SPACING_COMPONENT_COMPONENT}. + */ + private static final Comparable SPACING_COMPONENT_COMPONENT_LOWER_BOUND = Double.valueOf(0.0); + + /** + * Spacing to be preserved between pairs of connected components. + * This option is only relevant if 'separateConnectedComponents' is activated. + */ + public static final IProperty SPACING_COMPONENT_COMPONENT = new Property( + "org.eclipse.elk.spacing.componentComponent", + SPACING_COMPONENT_COMPONENT_DEFAULT, + SPACING_COMPONENT_COMPONENT_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_EDGE_EDGE}. + */ + private static final double SPACING_EDGE_EDGE_DEFAULT = 10; + + /** + * Lower bound value for {@link #SPACING_EDGE_EDGE}. + */ + private static final Comparable SPACING_EDGE_EDGE_LOWER_BOUND = Double.valueOf(0.0); + + /** + * Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied + * for the segments of orthogonally drawn edges, it is harder for general polylines or splines. + */ + public static final IProperty SPACING_EDGE_EDGE = new Property( + "org.eclipse.elk.spacing.edgeEdge", + SPACING_EDGE_EDGE_DEFAULT, + SPACING_EDGE_EDGE_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_EDGE_LABEL}. + */ + private static final double SPACING_EDGE_LABEL_DEFAULT = 2; + + /** + * Lower bound value for {@link #SPACING_EDGE_LABEL}. + */ + private static final Comparable SPACING_EDGE_LABEL_LOWER_BOUND = Double.valueOf(0.0); + + /** + * The minimal distance to be preserved between a label and the edge it is associated with. + * Note that the placement of a label is influenced by the 'edgelabels.placement' option. + */ + public static final IProperty SPACING_EDGE_LABEL = new Property( + "org.eclipse.elk.spacing.edgeLabel", + SPACING_EDGE_LABEL_DEFAULT, + SPACING_EDGE_LABEL_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_EDGE_NODE}. + */ + private static final double SPACING_EDGE_NODE_DEFAULT = 10; + + /** + * Lower bound value for {@link #SPACING_EDGE_NODE}. + */ + private static final Comparable SPACING_EDGE_NODE_LOWER_BOUND = Double.valueOf(0.0); + + /** + * Spacing to be preserved between nodes and edges. + */ + public static final IProperty SPACING_EDGE_NODE = new Property( + "org.eclipse.elk.spacing.edgeNode", + SPACING_EDGE_NODE_DEFAULT, + SPACING_EDGE_NODE_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_LABEL_LABEL}. + */ + private static final double SPACING_LABEL_LABEL_DEFAULT = 0; + + /** + * Lower bound value for {@link #SPACING_LABEL_LABEL}. + */ + private static final Comparable SPACING_LABEL_LABEL_LOWER_BOUND = Double.valueOf(0.0); + + /** + * Determines the amount of space to be left between two labels + * of the same graph element. + */ + public static final IProperty SPACING_LABEL_LABEL = new Property( + "org.eclipse.elk.spacing.labelLabel", + SPACING_LABEL_LABEL_DEFAULT, + SPACING_LABEL_LABEL_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_LABEL_NODE}. + */ + private static final double SPACING_LABEL_NODE_DEFAULT = 5; + + /** + * Lower bound value for {@link #SPACING_LABEL_NODE}. + */ + private static final Comparable SPACING_LABEL_NODE_LOWER_BOUND = Double.valueOf(0.0); + + /** + * Spacing to be preserved between labels and the border of node they are associated with. + * Note that the placement of a label is influenced by the 'nodelabels.placement' option. + */ + public static final IProperty SPACING_LABEL_NODE = new Property( + "org.eclipse.elk.spacing.labelNode", + SPACING_LABEL_NODE_DEFAULT, + SPACING_LABEL_NODE_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_LABEL_PORT_HORIZONTAL}. + */ + private static final double SPACING_LABEL_PORT_HORIZONTAL_DEFAULT = 1; + + /** + * Horizontal spacing to be preserved between labels and the ports they are associated with. + * Note that the placement of a label is influenced by the 'portlabels.placement' option. + */ + public static final IProperty SPACING_LABEL_PORT_HORIZONTAL = new Property( + "org.eclipse.elk.spacing.labelPortHorizontal", + SPACING_LABEL_PORT_HORIZONTAL_DEFAULT, + null, + null); + + /** + * Default value for {@link #SPACING_LABEL_PORT_VERTICAL}. + */ + private static final double SPACING_LABEL_PORT_VERTICAL_DEFAULT = 1; + + /** + * Vertical spacing to be preserved between labels and the ports they are associated with. + * Note that the placement of a label is influenced by the 'portlabels.placement' option. + */ + public static final IProperty SPACING_LABEL_PORT_VERTICAL = new Property( + "org.eclipse.elk.spacing.labelPortVertical", + SPACING_LABEL_PORT_VERTICAL_DEFAULT, + null, + null); + + /** + * Default value for {@link #SPACING_NODE_NODE}. + */ + private static final double SPACING_NODE_NODE_DEFAULT = 20; + + /** + * Lower bound value for {@link #SPACING_NODE_NODE}. + */ + private static final Comparable SPACING_NODE_NODE_LOWER_BOUND = Double.valueOf(0.0); + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT, + SPACING_NODE_NODE_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_NODE_SELF_LOOP}. + */ + private static final double SPACING_NODE_SELF_LOOP_DEFAULT = 10; + + /** + * Lower bound value for {@link #SPACING_NODE_SELF_LOOP}. + */ + private static final Comparable SPACING_NODE_SELF_LOOP_LOWER_BOUND = Double.valueOf(0.0); + + /** + * Spacing to be preserved between a node and its self loops. + */ + public static final IProperty SPACING_NODE_SELF_LOOP = new Property( + "org.eclipse.elk.spacing.nodeSelfLoop", + SPACING_NODE_SELF_LOOP_DEFAULT, + SPACING_NODE_SELF_LOOP_LOWER_BOUND, + null); + + /** + * Default value for {@link #SPACING_PORT_PORT}. + */ + private static final double SPACING_PORT_PORT_DEFAULT = 10; + + /** + * Lower bound value for {@link #SPACING_PORT_PORT}. + */ + private static final Comparable SPACING_PORT_PORT_LOWER_BOUND = Double.valueOf(0.0); + + /** + * Spacing between pairs of ports of the same node. + */ + public static final IProperty SPACING_PORT_PORT = new Property( + "org.eclipse.elk.spacing.portPort", + SPACING_PORT_PORT_DEFAULT, + SPACING_PORT_PORT_LOWER_BOUND, + null); + + /** + * Allows to specify individual spacing values for graph elements that shall be different from + * the value specified for the element's parent. + */ + public static final IProperty SPACING_INDIVIDUAL = new Property( + "org.eclipse.elk.spacing.individual"); + + /** + * Default value for {@link #SPACING_PORTS_SURROUNDING}. + */ + private static final ElkMargin SPACING_PORTS_SURROUNDING_DEFAULT = new ElkMargin(0); + + /** + * Additional space around the sets of ports on each node side. For each side of a node, + * this option can reserve additional space before and after the ports on each side. For + * example, a top spacing of 20 makes sure that the first port on the western and eastern + * side is 20 units away from the northern border. + */ + public static final IProperty SPACING_PORTS_SURROUNDING = new Property( + "org.eclipse.elk.spacing.portsSurrounding", + SPACING_PORTS_SURROUNDING_DEFAULT, + null, + null); + + /** + * Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower + * partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout + * direction). + */ + public static final IProperty PARTITIONING_PARTITION = new Property( + "org.eclipse.elk.partitioning.partition"); + + /** + * Default value for {@link #PARTITIONING_ACTIVATE}. + */ + private static final Boolean PARTITIONING_ACTIVATE_DEFAULT = Boolean.valueOf(false); + + /** + * Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. + * a pair of nodes with different partition indices is then placed such that the node with lower index is + * placed to the left of the other node (with left-to-right layout direction). Depending on the layout + * algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least + * if edges that cross partitions are not part of a partition-crossing cycle. + */ + public static final IProperty PARTITIONING_ACTIVATE = new Property( + "org.eclipse.elk.partitioning.activate", + PARTITIONING_ACTIVATE_DEFAULT, + null, + null); + + /** + * Default value for {@link #NODE_LABELS_PADDING}. + */ + private static final ElkPadding NODE_LABELS_PADDING_DEFAULT = new ElkPadding(5); + + /** + * Define padding for node labels that are placed inside of a node. + */ + public static final IProperty NODE_LABELS_PADDING = new Property( + "org.eclipse.elk.nodeLabels.padding", + NODE_LABELS_PADDING_DEFAULT, + null, + null); + + /** + * Default value for {@link #NODE_LABELS_PLACEMENT}. + */ + private static final EnumSet NODE_LABELS_PLACEMENT_DEFAULT = NodeLabelPlacement.fixed(); + + /** + * Hints for where node labels are to be placed; if empty, the node label's position is not + * modified. + */ + public static final IProperty> NODE_LABELS_PLACEMENT = new Property>( + "org.eclipse.elk.nodeLabels.placement", + NODE_LABELS_PLACEMENT_DEFAULT, + null, + null); + + /** + * Default value for {@link #PORT_ALIGNMENT_DEFAULT}. + */ + private static final PortAlignment PORT_ALIGNMENT_DEFAULT_DEFAULT = PortAlignment.DISTRIBUTED; + + /** + * Defines the default port distribution for a node. May be overridden for each side individually. + */ + public static final IProperty PORT_ALIGNMENT_DEFAULT = new Property( + "org.eclipse.elk.portAlignment.default", + PORT_ALIGNMENT_DEFAULT_DEFAULT, + null, + null); + + /** + * Defines how ports on the northern side are placed, overriding the node's general port alignment. + */ + public static final IProperty PORT_ALIGNMENT_NORTH = new Property( + "org.eclipse.elk.portAlignment.north"); + + /** + * Defines how ports on the southern side are placed, overriding the node's general port alignment. + */ + public static final IProperty PORT_ALIGNMENT_SOUTH = new Property( + "org.eclipse.elk.portAlignment.south"); + + /** + * Defines how ports on the western side are placed, overriding the node's general port alignment. + */ + public static final IProperty PORT_ALIGNMENT_WEST = new Property( + "org.eclipse.elk.portAlignment.west"); + + /** + * Defines how ports on the eastern side are placed, overriding the node's general port alignment. + */ + public static final IProperty PORT_ALIGNMENT_EAST = new Property( + "org.eclipse.elk.portAlignment.east"); + + /** + * Default value for {@link #NODE_SIZE_CONSTRAINTS}. + */ + private static final EnumSet NODE_SIZE_CONSTRAINTS_DEFAULT = EnumSet.noneOf(SizeConstraint.class); + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = new Property>( + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS_DEFAULT, + null, + null); + + /** + * Default value for {@link #NODE_SIZE_OPTIONS}. + */ + private static final EnumSet NODE_SIZE_OPTIONS_DEFAULT = EnumSet.of(SizeOptions.DEFAULT_MINIMUM_SIZE); + + /** + * Options modifying the behavior of the size constraints set on a node. Each member of the + * set specifies something that should be taken into account when calculating node sizes. + * The empty set corresponds to no further modifications. + */ + public static final IProperty> NODE_SIZE_OPTIONS = new Property>( + "org.eclipse.elk.nodeSize.options", + NODE_SIZE_OPTIONS_DEFAULT, + null, + null); + + /** + * Default value for {@link #NODE_SIZE_MINIMUM}. + */ + private static final KVector NODE_SIZE_MINIMUM_DEFAULT = new KVector(0, 0); + + /** + * The minimal size to which a node can be reduced. + */ + public static final IProperty NODE_SIZE_MINIMUM = new Property( + "org.eclipse.elk.nodeSize.minimum", + NODE_SIZE_MINIMUM_DEFAULT, + null, + null); + + /** + * Default value for {@link #NODE_SIZE_FIXED_GRAPH_SIZE}. + */ + private static final boolean NODE_SIZE_FIXED_GRAPH_SIZE_DEFAULT = false; + + /** + * By default, the fixed layout provider will enlarge a graph until it is large enough to contain + * its children. If this option is set, it won't do so. + */ + public static final IProperty NODE_SIZE_FIXED_GRAPH_SIZE = new Property( + "org.eclipse.elk.nodeSize.fixedGraphSize", + NODE_SIZE_FIXED_GRAPH_SIZE_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_LABELS_PLACEMENT}. + */ + private static final EdgeLabelPlacement EDGE_LABELS_PLACEMENT_DEFAULT = EdgeLabelPlacement.CENTER; + + /** + * Gives a hint on where to put edge labels. + */ + public static final IProperty EDGE_LABELS_PLACEMENT = new Property( + "org.eclipse.elk.edgeLabels.placement", + EDGE_LABELS_PLACEMENT_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_LABELS_INLINE}. + */ + private static final boolean EDGE_LABELS_INLINE_DEFAULT = false; + + /** + * If true, an edge label is placed directly on its edge. May only apply to center edge labels. + * This kind of label placement is only advisable if the label's rendering is such that it is not + * crossed by its edge and thus stays legible. + */ + public static final IProperty EDGE_LABELS_INLINE = new Property( + "org.eclipse.elk.edgeLabels.inline", + EDGE_LABELS_INLINE_DEFAULT, + null, + null); + + /** + * Font name used for a label. + */ + public static final IProperty FONT_NAME = new Property( + "org.eclipse.elk.font.name"); + + /** + * Lower bound value for {@link #FONT_SIZE}. + */ + private static final Comparable FONT_SIZE_LOWER_BOUND = Integer.valueOf(1); + + /** + * Font size used for a label. + */ + public static final IProperty FONT_SIZE = new Property( + "org.eclipse.elk.font.size", + null, + FONT_SIZE_LOWER_BOUND, + null); + + /** + * The offset to the port position where connections shall be attached. + */ + public static final IProperty PORT_ANCHOR = new Property( + "org.eclipse.elk.port.anchor"); + + /** + * The index of a port in the fixed order around a node. The order is assumed as clockwise, + * starting with the leftmost port on the top side. This option must be set if 'Port + * Constraints' is set to FIXED_ORDER and no specific positions are given for the ports. + * Additionally, the option 'Port Side' must be defined in this case. + */ + public static final IProperty PORT_INDEX = new Property( + "org.eclipse.elk.port.index"); + + /** + * Default value for {@link #PORT_SIDE}. + */ + private static final PortSide PORT_SIDE_DEFAULT = PortSide.UNDEFINED; + + /** + * The side of a node on which a port is situated. This option must be set if 'Port + * Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given + * for the ports. + */ + public static final IProperty PORT_SIDE = new Property( + "org.eclipse.elk.port.side", + PORT_SIDE_DEFAULT, + null, + null); + + /** + * The offset of ports on the node border. With a positive offset the port is moved outside + * of the node, while with a negative offset the port is moved towards the inside. An offset + * of 0 means that the port is placed directly on the node border, i.e. + * if the port side is north, the port's south border touches the nodes's north border; + * if the port side is east, the port's west border touches the nodes's east border; + * if the port side is south, the port's north border touches the node's south border; + * if the port side is west, the port's east border touches the node's west border. + */ + public static final IProperty PORT_BORDER_OFFSET = new Property( + "org.eclipse.elk.port.borderOffset"); + + /** + * Default value for {@link #PORT_LABELS_PLACEMENT}. + */ + private static final EnumSet PORT_LABELS_PLACEMENT_DEFAULT = PortLabelPlacement.outside(); + + /** + * Decides on a placement method for port labels; if empty, the node label's position is not + * modified. + */ + public static final IProperty> PORT_LABELS_PLACEMENT = new Property>( + "org.eclipse.elk.portLabels.placement", + PORT_LABELS_PLACEMENT_DEFAULT, + null, + null); + + /** + * Default value for {@link #PORT_LABELS_NEXT_TO_PORT_IF_POSSIBLE}. + */ + private static final boolean PORT_LABELS_NEXT_TO_PORT_IF_POSSIBLE_DEFAULT = false; + + /** + * Use 'portLabels.placement': NEXT_TO_PORT_OF_POSSIBLE. + */ + @Deprecated + public static final IProperty PORT_LABELS_NEXT_TO_PORT_IF_POSSIBLE = new Property( + "org.eclipse.elk.portLabels.nextToPortIfPossible", + PORT_LABELS_NEXT_TO_PORT_IF_POSSIBLE_DEFAULT, + null, + null); + + /** + * Default value for {@link #PORT_LABELS_TREAT_AS_GROUP}. + */ + private static final boolean PORT_LABELS_TREAT_AS_GROUP_DEFAULT = true; + + /** + * If this option is true (default), the labels of a port will be treated as a group when + * it comes to centering them next to their port. If this option is false, only the first label will + * be centered next to the port, with the others being placed below. This only applies to labels of + * eastern and western ports and will have no effect if labels are not placed next to their port. + */ + public static final IProperty PORT_LABELS_TREAT_AS_GROUP = new Property( + "org.eclipse.elk.portLabels.treatAsGroup", + PORT_LABELS_TREAT_AS_GROUP_DEFAULT, + null, + null); + + /** + * Default value for {@link #TOPDOWN_SCALE_FACTOR}. + */ + private static final double TOPDOWN_SCALE_FACTOR_DEFAULT = 1; + + /** + * Lower bound value for {@link #TOPDOWN_SCALE_FACTOR}. + */ + private static final Comparable TOPDOWN_SCALE_FACTOR_LOWER_BOUND = ExclusiveBounds.greaterThan(0); + + /** + * The scaling factor to be applied to the nodes laid out within the node in recursive topdown + * layout. The difference to 'Scale Factor' is that the node itself is not scaled. This value has to be set on + * hierarchical nodes. + */ + public static final IProperty TOPDOWN_SCALE_FACTOR = new Property( + "org.eclipse.elk.topdown.scaleFactor", + TOPDOWN_SCALE_FACTOR_DEFAULT, + TOPDOWN_SCALE_FACTOR_LOWER_BOUND, + null); + + /** + * Default value for {@link #TOPDOWN_SIZE_APPROXIMATOR}. + */ + private static final TopdownSizeApproximator TOPDOWN_SIZE_APPROXIMATOR_DEFAULT = null; + + /** + * The size approximator to be used to set sizes of hierarchical nodes during topdown layout. The default + * value is null, which results in nodes keeping whatever size is defined for them e.g. through parent + * parallel node or by manually setting the size. + */ + public static final IProperty TOPDOWN_SIZE_APPROXIMATOR = new Property( + "org.eclipse.elk.topdown.sizeApproximator", + TOPDOWN_SIZE_APPROXIMATOR_DEFAULT, + null, + null); + + /** + * Default value for {@link #TOPDOWN_HIERARCHICAL_NODE_WIDTH}. + */ + private static final double TOPDOWN_HIERARCHICAL_NODE_WIDTH_DEFAULT = 150; + + /** + * The fixed size of a hierarchical node when using topdown layout. If this value is set on a parallel + * node it applies to its children, when set on a hierarchical node it applies to the node itself. + */ + public static final IProperty TOPDOWN_HIERARCHICAL_NODE_WIDTH = new Property( + "org.eclipse.elk.topdown.hierarchicalNodeWidth", + TOPDOWN_HIERARCHICAL_NODE_WIDTH_DEFAULT, + null, + null); + + /** + * Default value for {@link #TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO}. + */ + private static final double TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO_DEFAULT = 1.414; + + /** + * The fixed aspect ratio of a hierarchical node when using topdown layout. Default is 1/sqrt(2). If this + * value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to + * the node itself. + */ + public static final IProperty TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO = new Property( + "org.eclipse.elk.topdown.hierarchicalNodeAspectRatio", + TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO_DEFAULT, + null, + null); + + /** + * Default value for {@link #TOPDOWN_NODE_TYPE}. + */ + private static final TopdownNodeTypes TOPDOWN_NODE_TYPE_DEFAULT = null; + + /** + * The different node types used for topdown layout. If the node type is set + * to {@link TopdownNodeTypes.PARALLEL_NODE} the algorithm must be set to a {@link TopdownLayoutProvider} such + * as {@link TopdownPacking}. The {@link nodeSize.fixedGraphSize} option is technically only required for + * hierarchical nodes. + */ + public static final IProperty TOPDOWN_NODE_TYPE = new Property( + "org.eclipse.elk.topdown.nodeType", + TOPDOWN_NODE_TYPE_DEFAULT, + null, + null); + + /** + * Default value for {@link #TOPDOWN_SCALE_CAP}. + */ + private static final double TOPDOWN_SCALE_CAP_DEFAULT = 1; + + /** + * Determines the upper limit for the topdown scale factor. The default value is 1.0 which ensures + * that nested children never end up appearing larger than their parents in terms of unit sizes such + * as the font size. If the limit is larger, nodes will fully utilize the available space, but it is + * counteriniuitive for inner nodes to have a larger scale than outer nodes. + */ + public static final IProperty TOPDOWN_SCALE_CAP = new Property( + "org.eclipse.elk.topdown.scaleCap", + TOPDOWN_SCALE_CAP_DEFAULT, + null, + null); + + /** + * Default value for {@link #INSIDE_SELF_LOOPS_ACTIVATE}. + */ + private static final boolean INSIDE_SELF_LOOPS_ACTIVATE_DEFAULT = false; + + /** + * Whether this node allows to route self loops inside of it instead of around it. If set to true, + * this will make the node a compound node if it isn't already, and will require the layout algorithm + * to support compound nodes with hierarchical ports. + */ + public static final IProperty INSIDE_SELF_LOOPS_ACTIVATE = new Property( + "org.eclipse.elk.insideSelfLoops.activate", + INSIDE_SELF_LOOPS_ACTIVATE_DEFAULT, + null, + null); + + /** + * Default value for {@link #INSIDE_SELF_LOOPS_YO}. + */ + private static final boolean INSIDE_SELF_LOOPS_YO_DEFAULT = false; + + /** + * Whether a self loop should be routed inside a node instead of around that node. + */ + public static final IProperty INSIDE_SELF_LOOPS_YO = new Property( + "org.eclipse.elk.insideSelfLoops.yo", + INSIDE_SELF_LOOPS_YO_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_THICKNESS}. + */ + private static final double EDGE_THICKNESS_DEFAULT = 1; + + /** + * The thickness of an edge. This is a hint on the line width used to draw an edge, possibly + * requiring more space to be reserved for it. + */ + public static final IProperty EDGE_THICKNESS = new Property( + "org.eclipse.elk.edge.thickness", + EDGE_THICKNESS_DEFAULT, + null, + null); + + /** + * Default value for {@link #EDGE_TYPE}. + */ + private static final EdgeType EDGE_TYPE_DEFAULT = EdgeType.NONE; + + /** + * The type of an edge. This is usually used for UML class diagrams, where associations must + * be handled differently from generalizations. + */ + public static final IProperty EDGE_TYPE = new Property( + "org.eclipse.elk.edge.type", + EDGE_TYPE_DEFAULT, + null, + null); + + /** + * Required value for dependency between {@link #PARTITIONING_PARTITION} and {@link #PARTITIONING_ACTIVATE}. + */ + private static final Boolean PARTITIONING_PARTITION_DEP_PARTITIONING_ACTIVATE_0 = Boolean.valueOf(true); + + /** + * Required value for dependency between {@link #TOPDOWN_SCALE_FACTOR} and {@link #TOPDOWN_NODE_TYPE}. + */ + private static final TopdownNodeTypes TOPDOWN_SCALE_FACTOR_DEP_TOPDOWN_NODE_TYPE_0 = TopdownNodeTypes.HIERARCHICAL_NODE; + + /** + * Required value for dependency between {@link #TOPDOWN_SIZE_APPROXIMATOR} and {@link #TOPDOWN_NODE_TYPE}. + */ + private static final TopdownNodeTypes TOPDOWN_SIZE_APPROXIMATOR_DEP_TOPDOWN_NODE_TYPE_0 = TopdownNodeTypes.HIERARCHICAL_NODE; + + /** + * Required value for dependency between {@link #TOPDOWN_SCALE_CAP} and {@link #TOPDOWN_NODE_TYPE}. + */ + private static final TopdownNodeTypes TOPDOWN_SCALE_CAP_DEP_TOPDOWN_NODE_TYPE_0 = TopdownNodeTypes.HIERARCHICAL_NODE; + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.algorithm") + .group("") + .name("Layout Algorithm") + .description("Select a specific layout algorithm.") + .type(LayoutOptionData.Type.STRING) + .optionClass(String.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.resolvedAlgorithm") + .group("") + .name("Resolved Layout Algorithm") + .description("Meta data associated with the selected algorithm.") + .type(LayoutOptionData.Type.OBJECT) + .optionClass(LayoutAlgorithmData.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.alignment") + .group("") + .name("Alignment") + .description("Alignment of the selected node relative to other nodes; the exact meaning depends on the used algorithm.") + .defaultValue(ALIGNMENT_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(Alignment.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.aspectRatio") + .group("") + .name("Aspect Ratio") + .description("The desired aspect ratio of the drawing, that is the quotient of width by height.") + .lowerBound(ASPECT_RATIO_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.bendPoints") + .group("") + .name("Bend Points") + .description("A fixed list of bend points for the edge. This is used by the \'Fixed Layout\' algorithm to specify a pre-defined routing for an edge. The vector chain must include the source point, any bend points, and the target point, so it must have at least two points.") + .type(LayoutOptionData.Type.OBJECT) + .optionClass(KVectorChain.class) + .targets(EnumSet.of(LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.contentAlignment") + .group("") + .name("Content Alignment") + .description("Specifies how the content of a node are aligned. Each node can individually control the alignment of its contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that option.") + .defaultValue(CONTENT_ALIGNMENT_DEFAULT) + .type(LayoutOptionData.Type.ENUMSET) + .optionClass(ContentAlignment.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.debugMode") + .group("") + .name("Debug Mode") + .description("Whether additional debug information shall be generated.") + .defaultValue(DEBUG_MODE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.direction") + .group("") + .name("Direction") + .description("Overall direction of edges: horizontal (right / left) or vertical (down / up).") + .defaultValue(DIRECTION_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(Direction.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.edgeRouting") + .group("") + .name("Edge Routing") + .description("What kind of edge routing style should be applied for the content of a parent node. Algorithms may also set this option to single edges in order to mark them as splines. The bend point list of edges with this option set to SPLINES must be interpreted as control points for a piecewise cubic spline.") + .defaultValue(EDGE_ROUTING_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(EdgeRouting.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.expandNodes") + .group("") + .name("Expand Nodes") + .description("If active, nodes are expanded to fill the area of their parent.") + .defaultValue(EXPAND_NODES_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.hierarchyHandling") + .group("") + .name("Hierarchy Handling") + .description("Determines whether separate layout runs are triggered for different compound nodes in a hierarchical graph. Setting a node\'s hierarchy handling to `INCLUDE_CHILDREN` will lay out that node and all of its descendants in a single layout run, until a descendant is encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that setting. Including multiple levels of hierarchy in a single layout run may allow cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` (or not set at all), the default behavior is `SEPARATE_CHILDREN`.") + .defaultValue(HIERARCHY_HANDLING_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(HierarchyHandling.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS, LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.padding") + .group("") + .name("Padding") + .description("The padding to be left to a parent element\'s border when placing child elements. This can also serve as an output option of a layout algorithm if node size calculation is setup appropriately.") + .defaultValue(PADDING_DEFAULT) + .type(LayoutOptionData.Type.OBJECT) + .optionClass(ElkPadding.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS, LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.interactive") + .group("") + .name("Interactive") + .description("Whether the algorithm should be run in interactive mode for the content of a parent node. What this means exactly depends on how the specific algorithm interprets this option. Usually in the interactive mode algorithms try to modify the current layout as little as possible.") + .defaultValue(INTERACTIVE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.interactiveLayout") + .group("") + .name("interactive Layout") + .description("Whether the graph should be changeable interactively and by setting constraints") + .defaultValue(INTERACTIVE_LAYOUT_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.omitNodeMicroLayout") + .group("") + .name("Omit Node Micro Layout") + .description("Node micro layout comprises the computation of node dimensions (if requested), the placement of ports and their labels, and the placement of node labels. The functionality is implemented independent of any specific layout algorithm and shouldn\'t have any negative impact on the layout algorithm\'s performance itself. Yet, if any unforeseen behavior occurs, this option allows to deactivate the micro layout.") + .defaultValue(OMIT_NODE_MICRO_LAYOUT_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.portConstraints") + .group("") + .name("Port Constraints") + .description("Defines constraints of the position of the ports of a node.") + .defaultValue(PORT_CONSTRAINTS_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(PortConstraints.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.position") + .group("") + .name("Position") + .description("The position of a node, port, or label. This is used by the \'Fixed Layout\' algorithm to specify a pre-defined position.") + .type(LayoutOptionData.Type.OBJECT) + .optionClass(KVector.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES, LayoutOptionData.Target.PORTS, LayoutOptionData.Target.LABELS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.priority") + .group("") + .name("Priority") + .description("Defines the priority of an object; its meaning depends on the specific layout algorithm and the context where it is used.") + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES, LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.randomSeed") + .group("") + .name("Randomization Seed") + .description("Seed used for pseudo-random number generators to control the layout algorithm. If the value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time).") + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.separateConnectedComponents") + .group("") + .name("Separate Connected Components") + .description("Whether each connected component should be processed separately.") + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.junctionPoints") + .group("") + .name("Junction Points") + .description("This option is not used as option, but as output of the layout algorithms. It is attached to edges and determines the points where junction symbols should be drawn in order to represent hyperedges with orthogonal routing. Whether such points are computed depends on the chosen layout algorithm and edge routing style. The points are put into the vector chain with no specific order.") + .defaultValue(JUNCTION_POINTS_DEFAULT) + .type(LayoutOptionData.Type.OBJECT) + .optionClass(KVectorChain.class) + .targets(EnumSet.of(LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.commentBox") + .group("") + .name("Comment Box") + .description("Whether the node should be regarded as a comment box instead of a regular node. In that case its placement should be similar to how labels are handled. Any edges incident to a comment box specify to which graph elements the comment is related.") + .defaultValue(COMMENT_BOX_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.hypernode") + .group("") + .name("Hypernode") + .description("Whether the node should be handled as a hypernode.") + .defaultValue(HYPERNODE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.labelManager") + .group("") + .name("Label Manager") + .description("Label managers can shorten labels upon a layout algorithm\'s request.") + .type(LayoutOptionData.Type.OBJECT) + .optionClass(ILabelManager.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS, LayoutOptionData.Target.LABELS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.margins") + .group("") + .name("Margins") + .description("Margins define additional space around the actual bounds of a graph element. For instance, ports or labels being placed on the outside of a node\'s border might introduce such a margin. The margin is used to guarantee non-overlap of other graph elements with those ports or labels.") + .defaultValue(MARGINS_DEFAULT) + .type(LayoutOptionData.Type.OBJECT) + .optionClass(ElkMargin.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.noLayout") + .group("") + .name("No Layout") + .description("No layout is done for the associated element. This is used to mark parts of a diagram to avoid their inclusion in the layout graph, or to mark parts of the layout graph to prevent layout engines from processing them. If you wish to exclude the contents of a compound node from automatic layout, while the node itself is still considered on its own layer, use the \'Fixed Layout\' algorithm for that node.") + .defaultValue(NO_LAYOUT_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES, LayoutOptionData.Target.EDGES, LayoutOptionData.Target.PORTS, LayoutOptionData.Target.LABELS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.scaleFactor") + .group("") + .name("Scale Factor") + .description("The scaling factor to be applied to the corresponding node in recursive layout. It causes the corresponding node\'s size to be adjusted, and its ports and labels to be sized and placed accordingly after the layout of that node has been determined (and before the node itself and its siblings are arranged). The scaling is not reverted afterwards, so the resulting layout graph contains the adjusted size and position data. This option is currently not supported if \'Layout Hierarchy\' is set.") + .defaultValue(SCALE_FACTOR_DEFAULT) + .lowerBound(SCALE_FACTOR_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.childAreaWidth") + .group("") + .name("Child Area Width") + .description("The width of the area occupied by the laid out children of a node.") + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.childAreaHeight") + .group("") + .name("Child Area Height") + .description("The height of the area occupied by the laid out children of a node.") + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.topdownLayout") + .group("") + .name("Topdown Layout") + .description("Turns topdown layout on and off. If this option is enabled, hierarchical layout will be computed first for the root node and then for its children recursively. Layouts are then scaled down to fit the area provided by their parents. Graphs must follow a certain structure for topdown layout to work properly. {@link TopdownNodeTypes.PARALLEL_NODE} nodes must have children of type {@link TopdownNodeTypes.HIERARCHICAL_NODE} and must define {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} for their children. Furthermore they need to be laid out using an algorithm that is a {@link TopdownLayoutProvider}. Hierarchical nodes can also be parents of other hierarchical nodes and can optionally use a {@link TopdownSizeApproximator} to dynamically set sizes during topdown layout. In this case {@link topdown.hierarchicalNodeWidth} and {@link topdown.hierarchicalNodeAspectRatio} should be set on the node itself rather than the parent. The values are then used by the size approximator as base values. Hierarchical nodes require the layout option {@link nodeSize.fixedGraphSize} to be true to prevent the algorithm used there from resizing the hierarchical node. This option is not supported if \'Hierarchy Handling\' is set to \'INCLUDE_CHILDREN\'") + .defaultValue(TOPDOWN_LAYOUT_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.topdownLayout", + "org.eclipse.elk.topdown.nodeType", + null + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.animate") + .group("") + .name("Animate") + .description("Whether the shift from the old layout to the new computed layout shall be animated.") + .defaultValue(ANIMATE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.animTimeFactor") + .group("") + .name("Animation Time Factor") + .description("Factor for computation of animation time. The higher the value, the longer the animation time. If the value is 0, the resulting time is always equal to the minimum defined by \'Minimal Animation Time\'.") + .defaultValue(ANIM_TIME_FACTOR_DEFAULT) + .lowerBound(ANIM_TIME_FACTOR_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.layoutAncestors") + .group("") + .name("Layout Ancestors") + .description("Whether the hierarchy levels on the path from the selected element to the root of the diagram shall be included in the layout process.") + .defaultValue(LAYOUT_ANCESTORS_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.maxAnimTime") + .group("") + .name("Maximal Animation Time") + .description("The maximal time for animations, in milliseconds.") + .defaultValue(MAX_ANIM_TIME_DEFAULT) + .lowerBound(MAX_ANIM_TIME_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.minAnimTime") + .group("") + .name("Minimal Animation Time") + .description("The minimal time for animations, in milliseconds.") + .defaultValue(MIN_ANIM_TIME_DEFAULT) + .lowerBound(MIN_ANIM_TIME_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.progressBar") + .group("") + .name("Progress Bar") + .description("Whether a progress bar shall be displayed during layout computations.") + .defaultValue(PROGRESS_BAR_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.validateGraph") + .group("") + .name("Validate Graph") + .description("Whether the graph shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user.") + .defaultValue(VALIDATE_GRAPH_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.validateOptions") + .group("") + .name("Validate Options") + .description("Whether layout options shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user.") + .defaultValue(VALIDATE_OPTIONS_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.zoomToFit") + .group("") + .name("Zoom to Fit") + .description("Whether the zoom level shall be set to view the whole diagram after layout.") + .defaultValue(ZOOM_TO_FIT_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.box.packingMode") + .group("box") + .name("Box Layout Mode") + .description("Configures the packing mode used by the {@link BoxLayoutProvider}. If SIMPLE is not required (neither priorities are used nor the interactive mode), GROUP_DEC can improve the packing and decrease the area. GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better.") + .defaultValue(BOX_PACKING_MODE_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(BoxLayoutProvider.PackingMode.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.commentComment") + .group("spacing") + .name("Comment Comment Spacing") + .description("Spacing to be preserved between a comment box and other comment boxes connected to the same node. The space left between comment boxes of different nodes is controlled by the node-node spacing.") + .defaultValue(SPACING_COMMENT_COMMENT_DEFAULT) + .lowerBound(SPACING_COMMENT_COMMENT_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.commentNode") + .group("spacing") + .name("Comment Node Spacing") + .description("Spacing to be preserved between a node and its connected comment boxes. The space left between a node and the comments of another node is controlled by the node-node spacing.") + .defaultValue(SPACING_COMMENT_NODE_DEFAULT) + .lowerBound(SPACING_COMMENT_NODE_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.componentComponent") + .group("spacing") + .name("Components Spacing") + .description("Spacing to be preserved between pairs of connected components. This option is only relevant if \'separateConnectedComponents\' is activated.") + .defaultValue(SPACING_COMPONENT_COMPONENT_DEFAULT) + .lowerBound(SPACING_COMPONENT_COMPONENT_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.edgeEdge") + .group("spacing") + .name("Edge Spacing") + .description("Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied for the segments of orthogonally drawn edges, it is harder for general polylines or splines.") + .defaultValue(SPACING_EDGE_EDGE_DEFAULT) + .lowerBound(SPACING_EDGE_EDGE_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.edgeLabel") + .group("spacing") + .name("Edge Label Spacing") + .description("The minimal distance to be preserved between a label and the edge it is associated with. Note that the placement of a label is influenced by the \'edgelabels.placement\' option.") + .defaultValue(SPACING_EDGE_LABEL_DEFAULT) + .lowerBound(SPACING_EDGE_LABEL_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.edgeNode") + .group("spacing") + .name("Edge Node Spacing") + .description("Spacing to be preserved between nodes and edges.") + .defaultValue(SPACING_EDGE_NODE_DEFAULT) + .lowerBound(SPACING_EDGE_NODE_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.labelLabel") + .group("spacing") + .name("Label Spacing") + .description("Determines the amount of space to be left between two labels of the same graph element.") + .defaultValue(SPACING_LABEL_LABEL_DEFAULT) + .lowerBound(SPACING_LABEL_LABEL_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.labelNode") + .group("spacing") + .name("Label Node Spacing") + .description("Spacing to be preserved between labels and the border of node they are associated with. Note that the placement of a label is influenced by the \'nodelabels.placement\' option.") + .defaultValue(SPACING_LABEL_NODE_DEFAULT) + .lowerBound(SPACING_LABEL_NODE_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.labelPortHorizontal") + .group("spacing") + .name("Horizontal spacing between Label and Port") + .description("Horizontal spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the \'portlabels.placement\' option.") + .defaultValue(SPACING_LABEL_PORT_HORIZONTAL_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.labelPortVertical") + .group("spacing") + .name("Vertical spacing between Label and Port") + .description("Vertical spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the \'portlabels.placement\' option.") + .defaultValue(SPACING_LABEL_PORT_VERTICAL_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.nodeNode") + .group("spacing") + .name("Node Spacing") + .description("The minimal distance to be preserved between each two nodes.") + .defaultValue(SPACING_NODE_NODE_DEFAULT) + .lowerBound(SPACING_NODE_NODE_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.nodeSelfLoop") + .group("spacing") + .name("Node Self Loop Spacing") + .description("Spacing to be preserved between a node and its self loops.") + .defaultValue(SPACING_NODE_SELF_LOOP_DEFAULT) + .lowerBound(SPACING_NODE_SELF_LOOP_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.portPort") + .group("spacing") + .name("Port Spacing") + .description("Spacing between pairs of ports of the same node.") + .defaultValue(SPACING_PORT_PORT_DEFAULT) + .lowerBound(SPACING_PORT_PORT_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS, LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.individual") + .group("spacing") + .name("Individual Spacing") + .description("Allows to specify individual spacing values for graph elements that shall be different from the value specified for the element\'s parent.") + .type(LayoutOptionData.Type.OBJECT) + .optionClass(IndividualSpacings.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES, LayoutOptionData.Target.EDGES, LayoutOptionData.Target.PORTS, LayoutOptionData.Target.LABELS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.spacing.portsSurrounding") + .group("spacing") + .name("Additional Port Space") + .description("Additional space around the sets of ports on each node side. For each side of a node, this option can reserve additional space before and after the ports on each side. For example, a top spacing of 20 makes sure that the first port on the western and eastern side is 20 units away from the northern border.") + .defaultValue(SPACING_PORTS_SURROUNDING_DEFAULT) + .type(LayoutOptionData.Type.OBJECT) + .optionClass(ElkMargin.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.partitioning.partition") + .group("partitioning") + .name("Layout Partition") + .description("Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout direction).") + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS, LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.partitioning.partition", + "org.eclipse.elk.partitioning.activate", + PARTITIONING_PARTITION_DEP_PARTITIONING_ACTIVATE_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.partitioning.activate") + .group("partitioning") + .name("Layout Partitioning") + .description("Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. a pair of nodes with different partition indices is then placed such that the node with lower index is placed to the left of the other node (with left-to-right layout direction). Depending on the layout algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least if edges that cross partitions are not part of a partition-crossing cycle.") + .defaultValue(PARTITIONING_ACTIVATE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.nodeLabels.padding") + .group("nodeLabels") + .name("Node Label Padding") + .description("Define padding for node labels that are placed inside of a node.") + .defaultValue(NODE_LABELS_PADDING_DEFAULT) + .type(LayoutOptionData.Type.OBJECT) + .optionClass(ElkPadding.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.nodeLabels.placement") + .group("nodeLabels") + .name("Node Label Placement") + .description("Hints for where node labels are to be placed; if empty, the node label\'s position is not modified.") + .defaultValue(NODE_LABELS_PLACEMENT_DEFAULT) + .type(LayoutOptionData.Type.ENUMSET) + .optionClass(NodeLabelPlacement.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES, LayoutOptionData.Target.LABELS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.portAlignment.default") + .group("portAlignment") + .name("Port Alignment") + .description("Defines the default port distribution for a node. May be overridden for each side individually.") + .defaultValue(PORT_ALIGNMENT_DEFAULT_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(PortAlignment.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.portAlignment.north") + .group("portAlignment") + .name("Port Alignment (North)") + .description("Defines how ports on the northern side are placed, overriding the node\'s general port alignment.") + .type(LayoutOptionData.Type.ENUM) + .optionClass(PortAlignment.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.portAlignment.south") + .group("portAlignment") + .name("Port Alignment (South)") + .description("Defines how ports on the southern side are placed, overriding the node\'s general port alignment.") + .type(LayoutOptionData.Type.ENUM) + .optionClass(PortAlignment.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.portAlignment.west") + .group("portAlignment") + .name("Port Alignment (West)") + .description("Defines how ports on the western side are placed, overriding the node\'s general port alignment.") + .type(LayoutOptionData.Type.ENUM) + .optionClass(PortAlignment.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.portAlignment.east") + .group("portAlignment") + .name("Port Alignment (East)") + .description("Defines how ports on the eastern side are placed, overriding the node\'s general port alignment.") + .type(LayoutOptionData.Type.ENUM) + .optionClass(PortAlignment.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.nodeSize.constraints") + .group("nodeSize") + .name("Node Size Constraints") + .description("What should be taken into account when calculating a node\'s size. Empty size constraints specify that a node\'s size is already fixed and should not be changed.") + .defaultValue(NODE_SIZE_CONSTRAINTS_DEFAULT) + .type(LayoutOptionData.Type.ENUMSET) + .optionClass(SizeConstraint.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.nodeSize.options") + .group("nodeSize") + .name("Node Size Options") + .description("Options modifying the behavior of the size constraints set on a node. Each member of the set specifies something that should be taken into account when calculating node sizes. The empty set corresponds to no further modifications.") + .defaultValue(NODE_SIZE_OPTIONS_DEFAULT) + .type(LayoutOptionData.Type.ENUMSET) + .optionClass(SizeOptions.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.nodeSize.minimum") + .group("nodeSize") + .name("Node Size Minimum") + .description("The minimal size to which a node can be reduced.") + .defaultValue(NODE_SIZE_MINIMUM_DEFAULT) + .type(LayoutOptionData.Type.OBJECT) + .optionClass(KVector.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.nodeSize.fixedGraphSize") + .group("nodeSize") + .name("Fixed Graph Size") + .description("By default, the fixed layout provider will enlarge a graph until it is large enough to contain its children. If this option is set, it won\'t do so.") + .defaultValue(NODE_SIZE_FIXED_GRAPH_SIZE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.edgeLabels.placement") + .group("edgeLabels") + .name("Edge Label Placement") + .description("Gives a hint on where to put edge labels.") + .defaultValue(EDGE_LABELS_PLACEMENT_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(EdgeLabelPlacement.class) + .targets(EnumSet.of(LayoutOptionData.Target.LABELS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.edgeLabels.inline") + .group("edgeLabels") + .name("Inline Edge Labels") + .description("If true, an edge label is placed directly on its edge. May only apply to center edge labels. This kind of label placement is only advisable if the label\'s rendering is such that it is not crossed by its edge and thus stays legible.") + .defaultValue(EDGE_LABELS_INLINE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.LABELS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.font.name") + .group("font") + .name("Font Name") + .description("Font name used for a label.") + .type(LayoutOptionData.Type.STRING) + .optionClass(String.class) + .targets(EnumSet.of(LayoutOptionData.Target.LABELS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.font.size") + .group("font") + .name("Font Size") + .description("Font size used for a label.") + .lowerBound(FONT_SIZE_LOWER_BOUND) + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.LABELS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.port.anchor") + .group("port") + .name("Port Anchor Offset") + .description("The offset to the port position where connections shall be attached.") + .type(LayoutOptionData.Type.OBJECT) + .optionClass(KVector.class) + .targets(EnumSet.of(LayoutOptionData.Target.PORTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.port.index") + .group("port") + .name("Port Index") + .description("The index of a port in the fixed order around a node. The order is assumed as clockwise, starting with the leftmost port on the top side. This option must be set if \'Port Constraints\' is set to FIXED_ORDER and no specific positions are given for the ports. Additionally, the option \'Port Side\' must be defined in this case.") + .type(LayoutOptionData.Type.INT) + .optionClass(Integer.class) + .targets(EnumSet.of(LayoutOptionData.Target.PORTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.port.side") + .group("port") + .name("Port Side") + .description("The side of a node on which a port is situated. This option must be set if \'Port Constraints\' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given for the ports.") + .defaultValue(PORT_SIDE_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(PortSide.class) + .targets(EnumSet.of(LayoutOptionData.Target.PORTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.port.borderOffset") + .group("port") + .name("Port Border Offset") + .description("The offset of ports on the node border. With a positive offset the port is moved outside of the node, while with a negative offset the port is moved towards the inside. An offset of 0 means that the port is placed directly on the node border, i.e. if the port side is north, the port\'s south border touches the nodes\'s north border; if the port side is east, the port\'s west border touches the nodes\'s east border; if the port side is south, the port\'s north border touches the node\'s south border; if the port side is west, the port\'s east border touches the node\'s west border.") + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PORTS)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.portLabels.placement") + .group("portLabels") + .name("Port Label Placement") + .description("Decides on a placement method for port labels; if empty, the node label\'s position is not modified.") + .defaultValue(PORT_LABELS_PLACEMENT_DEFAULT) + .type(LayoutOptionData.Type.ENUMSET) + .optionClass(PortLabelPlacement.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.portLabels.nextToPortIfPossible") + .group("portLabels") + .name("Port Labels Next to Port") + .description("Use \'portLabels.placement\': NEXT_TO_PORT_OF_POSSIBLE.") + .defaultValue(PORT_LABELS_NEXT_TO_PORT_IF_POSSIBLE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.portLabels.treatAsGroup") + .group("portLabels") + .name("Treat Port Labels as Group") + .description("If this option is true (default), the labels of a port will be treated as a group when it comes to centering them next to their port. If this option is false, only the first label will be centered next to the port, with the others being placed below. This only applies to labels of eastern and western ports and will have no effect if labels are not placed next to their port.") + .defaultValue(PORT_LABELS_TREAT_AS_GROUP_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.VISIBLE) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.topdown.scaleFactor") + .group("topdown") + .name("Topdown Scale Factor") + .description("The scaling factor to be applied to the nodes laid out within the node in recursive topdown layout. The difference to \'Scale Factor\' is that the node itself is not scaled. This value has to be set on hierarchical nodes.") + .defaultValue(TOPDOWN_SCALE_FACTOR_DEFAULT) + .lowerBound(TOPDOWN_SCALE_FACTOR_LOWER_BOUND) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.addDependency( + "org.eclipse.elk.topdown.scaleFactor", + "org.eclipse.elk.topdown.nodeType", + TOPDOWN_SCALE_FACTOR_DEP_TOPDOWN_NODE_TYPE_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.topdown.sizeApproximator") + .group("topdown") + .name("Topdown Size Approximator") + .description("The size approximator to be used to set sizes of hierarchical nodes during topdown layout. The default value is null, which results in nodes keeping whatever size is defined for them e.g. through parent parallel node or by manually setting the size.") + .defaultValue(TOPDOWN_SIZE_APPROXIMATOR_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(TopdownSizeApproximator.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.topdown.sizeApproximator", + "org.eclipse.elk.topdown.nodeType", + TOPDOWN_SIZE_APPROXIMATOR_DEP_TOPDOWN_NODE_TYPE_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.topdown.hierarchicalNodeWidth") + .group("topdown") + .name("Topdown Hierarchical Node Width") + .description("The fixed size of a hierarchical node when using topdown layout. If this value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to the node itself.") + .defaultValue(TOPDOWN_HIERARCHICAL_NODE_WIDTH_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS, LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.topdown.hierarchicalNodeWidth", + "org.eclipse.elk.topdown.nodeType", + null + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.topdown.hierarchicalNodeAspectRatio") + .group("topdown") + .name("Topdown Hierarchical Node Aspect Ratio") + .description("The fixed aspect ratio of a hierarchical node when using topdown layout. Default is 1/sqrt(2). If this value is set on a parallel node it applies to its children, when set on a hierarchical node it applies to the node itself.") + .defaultValue(TOPDOWN_HIERARCHICAL_NODE_ASPECT_RATIO_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS, LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.topdown.hierarchicalNodeAspectRatio", + "org.eclipse.elk.topdown.nodeType", + null + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.topdown.nodeType") + .group("topdown") + .name("Topdown Node Type") + .description("The different node types used for topdown layout. If the node type is set to {@link TopdownNodeTypes.PARALLEL_NODE} the algorithm must be set to a {@link TopdownLayoutProvider} such as {@link TopdownPacking}. The {@link nodeSize.fixedGraphSize} option is technically only required for hierarchical nodes.") + .defaultValue(TOPDOWN_NODE_TYPE_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(TopdownNodeTypes.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.topdown.nodeType", + "org.eclipse.elk.nodeSize.fixedGraphSize", + null + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.topdown.scaleCap") + .group("topdown") + .name("Topdown Scale Cap") + .description("Determines the upper limit for the topdown scale factor. The default value is 1.0 which ensures that nested children never end up appearing larger than their parents in terms of unit sizes such as the font size. If the limit is larger, nodes will fully utilize the available space, but it is counteriniuitive for inner nodes to have a larger scale than outer nodes.") + .defaultValue(TOPDOWN_SCALE_CAP_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.PARENTS)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.addDependency( + "org.eclipse.elk.topdown.scaleCap", + "org.eclipse.elk.topdown.nodeType", + TOPDOWN_SCALE_CAP_DEP_TOPDOWN_NODE_TYPE_0 + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.insideSelfLoops.activate") + .group("insideSelfLoops") + .name("Activate Inside Self Loops") + .description("Whether this node allows to route self loops inside of it instead of around it. If set to true, this will make the node a compound node if it isn\'t already, and will require the layout algorithm to support compound nodes with hierarchical ports.") + .defaultValue(INSIDE_SELF_LOOPS_ACTIVATE_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.NODES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.insideSelfLoops.yo") + .group("insideSelfLoops") + .name("Inside Self Loop") + .description("Whether a self loop should be routed inside a node instead of around that node.") + .defaultValue(INSIDE_SELF_LOOPS_YO_DEFAULT) + .type(LayoutOptionData.Type.BOOLEAN) + .optionClass(Boolean.class) + .targets(EnumSet.of(LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.ADVANCED) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.edge.thickness") + .group("edge") + .name("Edge Thickness") + .description("The thickness of an edge. This is a hint on the line width used to draw an edge, possibly requiring more space to be reserved for it.") + .defaultValue(EDGE_THICKNESS_DEFAULT) + .type(LayoutOptionData.Type.DOUBLE) + .optionClass(Double.class) + .targets(EnumSet.of(LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutOptionData.Builder() + .id("org.eclipse.elk.edge.type") + .group("edge") + .name("Edge Type") + .description("The type of an edge. This is usually used for UML class diagrams, where associations must be handled differently from generalizations.") + .defaultValue(EDGE_TYPE_DEFAULT) + .type(LayoutOptionData.Type.ENUM) + .optionClass(EdgeType.class) + .targets(EnumSet.of(LayoutOptionData.Target.EDGES)) + .visibility(LayoutOptionData.Visibility.HIDDEN) + .create() + ); + registry.register(new LayoutCategoryData.Builder() + .id("org.eclipse.elk.layered") + .name("Layered") + .description("The layer-based method was introduced by Sugiyama, Tagawa and Toda in 1981. It emphasizes the direction of edges by pointing as many edges as possible into the same direction. The nodes are arranged in layers, which are sometimes called \"hierarchies\", and then reordered such that the number of edge crossings is minimized. Afterwards, concrete coordinates are computed for the nodes and edge bend points.") + .create() + ); + registry.register(new LayoutCategoryData.Builder() + .id("org.eclipse.elk.orthogonal") + .name("Orthogonal") + .description("Orthogonal methods that follow the \"topology-shape-metrics\" approach by Batini, Nardelli and Tamassia \'86. The first phase determines the topology of the drawing by applying a planarization technique, which results in a planar representation of the graph. The orthogonal shape is computed in the second phase, which aims at minimizing the number of edge bends, and is called orthogonalization. The third phase leads to concrete coordinates for nodes and edge bend points by applying a compaction method, thus defining the metrics.") + .create() + ); + registry.register(new LayoutCategoryData.Builder() + .id("org.eclipse.elk.force") + .name("Force") + .description("Layout algorithms that follow physical analogies by simulating a system of attractive and repulsive forces. The first successful method of this kind was proposed by Eades in 1984.") + .create() + ); + registry.register(new LayoutCategoryData.Builder() + .id("org.eclipse.elk.circle") + .name("Circle") + .description("Circular layout algorithms emphasize cycles or biconnected components of a graph by arranging them in circles. This is useful if a drawing is desired where such components are clearly grouped, or where cycles are shown as prominent OPTIONS of the graph.") + .create() + ); + registry.register(new LayoutCategoryData.Builder() + .id("org.eclipse.elk.tree") + .name("Tree") + .description("Specialized layout methods for trees, i.e. acyclic graphs. The regular structure of graphs that have no undirected cycles can be emphasized using an algorithm of this type.") + .create() + ); + registry.register(new LayoutCategoryData.Builder() + .id("org.eclipse.elk.planar") + .name("Planar") + .description("Algorithms that require a planar or upward planar graph. Most of these algorithms are theoretically interesting, but not practically usable.") + .create() + ); + registry.register(new LayoutCategoryData.Builder() + .id("org.eclipse.elk.radial") + .name("Radial") + .description("Radial layout algorithms usually position the nodes of the graph on concentric circles.") + .create() + ); + new org.eclipse.elk.core.options.FixedLayouterOptions().apply(registry); + new org.eclipse.elk.core.options.BoxLayouterOptions().apply(registry); + new org.eclipse.elk.core.options.RandomLayouterOptions().apply(registry); + } +} diff --git a/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/FixedLayouterOptions.java b/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/FixedLayouterOptions.java new file mode 100644 index 000000000..e8908dfdc --- /dev/null +++ b/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/FixedLayouterOptions.java @@ -0,0 +1,130 @@ +/** + * Copyright (c) 2015, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.core.options; + +import java.util.EnumSet; +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.math.KVector; +import org.eclipse.elk.core.math.KVectorChain; +import org.eclipse.elk.core.util.FixedLayoutProvider; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class FixedLayouterOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK Fixed algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.fixed"; + + /** + * Default value for {@link #PADDING} with algorithm "ELK Fixed". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(15); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to + * specify a pre-defined position. + */ + public static final IProperty POSITION = CoreOptions.POSITION; + + /** + * A fixed list of bend points for the edge. This is used by the 'Fixed Layout' algorithm to + * specify a pre-defined routing for an edge. The vector chain must include the source point, + * any bend points, and the target point, so it must have at least two points. + */ + public static final IProperty BEND_POINTS = CoreOptions.BEND_POINTS; + + /** + * What should be taken into account when calculating a node's size. Empty size constraints + * specify that a node's size is already fixed and should not be changed. + */ + public static final IProperty> NODE_SIZE_CONSTRAINTS = CoreOptions.NODE_SIZE_CONSTRAINTS; + + /** + * The minimal size to which a node can be reduced. + */ + public static final IProperty NODE_SIZE_MINIMUM = CoreOptions.NODE_SIZE_MINIMUM; + + /** + * By default, the fixed layout provider will enlarge a graph until it is large enough to contain + * its children. If this option is set, it won't do so. + */ + public static final IProperty NODE_SIZE_FIXED_GRAPH_SIZE = CoreOptions.NODE_SIZE_FIXED_GRAPH_SIZE; + + /** + * Layouter-specific algorithm factory. + */ + public static class FixedFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new FixedLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.fixed") + .name("ELK Fixed") + .description("Keeps the current layout as it is, without any automatic modification. Optional coordinates can be given for nodes and edge bend points.") + .providerFactory(new FixedFactory()) + .melkBundleName("ELK") + .definingBundleId("org.eclipse.elk.core") + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.fixed", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.fixed", + "org.eclipse.elk.position", + POSITION.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.fixed", + "org.eclipse.elk.bendPoints", + BEND_POINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.fixed", + "org.eclipse.elk.nodeSize.constraints", + NODE_SIZE_CONSTRAINTS.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.fixed", + "org.eclipse.elk.nodeSize.minimum", + NODE_SIZE_MINIMUM.getDefault() + ); + registry.addOptionSupport( + "org.eclipse.elk.fixed", + "org.eclipse.elk.nodeSize.fixedGraphSize", + NODE_SIZE_FIXED_GRAPH_SIZE.getDefault() + ); + } +} diff --git a/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/RandomLayouterOptions.java b/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/RandomLayouterOptions.java new file mode 100644 index 000000000..fa9e0c0b6 --- /dev/null +++ b/plugins/org.eclipse.elk.core/src-gen/org/eclipse/elk/core/options/RandomLayouterOptions.java @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2015, 2020 Kiel University and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.elk.core.options; + +import org.eclipse.elk.core.AbstractLayoutProvider; +import org.eclipse.elk.core.data.ILayoutMetaDataProvider; +import org.eclipse.elk.core.data.LayoutAlgorithmData; +import org.eclipse.elk.core.math.ElkPadding; +import org.eclipse.elk.core.util.RandomLayoutProvider; +import org.eclipse.elk.graph.properties.IProperty; +import org.eclipse.elk.graph.properties.Property; + +@SuppressWarnings("all") +public class RandomLayouterOptions implements ILayoutMetaDataProvider { + /** + * The id of the ELK Randomizer algorithm. + */ + public static final String ALGORITHM_ID = "org.eclipse.elk.random"; + + /** + * Default value for {@link #PADDING} with algorithm "ELK Randomizer". + */ + private static final ElkPadding PADDING_DEFAULT = new ElkPadding(15); + + /** + * The padding to be left to a parent element's border when placing child elements. This can + * also serve as an output option of a layout algorithm if node size calculation is setup + * appropriately. + */ + public static final IProperty PADDING = new Property( + CoreOptions.PADDING, + PADDING_DEFAULT); + + /** + * Default value for {@link #SPACING_NODE_NODE} with algorithm "ELK Randomizer". + */ + private static final double SPACING_NODE_NODE_DEFAULT = 15; + + /** + * The minimal distance to be preserved between each two nodes. + */ + public static final IProperty SPACING_NODE_NODE = new Property( + CoreOptions.SPACING_NODE_NODE, + SPACING_NODE_NODE_DEFAULT); + + /** + * Default value for {@link #RANDOM_SEED} with algorithm "ELK Randomizer". + */ + private static final int RANDOM_SEED_DEFAULT = 0; + + /** + * Seed used for pseudo-random number generators to control the layout algorithm. If the + * value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time). + */ + public static final IProperty RANDOM_SEED = new Property( + CoreOptions.RANDOM_SEED, + RANDOM_SEED_DEFAULT); + + /** + * Default value for {@link #ASPECT_RATIO} with algorithm "ELK Randomizer". + */ + private static final double ASPECT_RATIO_DEFAULT = 1.6f; + + /** + * The desired aspect ratio of the drawing, that is the quotient of width by height. + */ + public static final IProperty ASPECT_RATIO = new Property( + CoreOptions.ASPECT_RATIO, + ASPECT_RATIO_DEFAULT); + + /** + * Layouter-specific algorithm factory. + */ + public static class RandomFactory implements org.eclipse.elk.core.util.IFactory { + public AbstractLayoutProvider create() { + AbstractLayoutProvider provider = new RandomLayoutProvider(); + provider.initialize(""); + return provider; + } + + public void destroy(final AbstractLayoutProvider obj) { + obj.dispose(); + } + } + + public void apply(final org.eclipse.elk.core.data.ILayoutMetaDataProvider.Registry registry) { + registry.register(new LayoutAlgorithmData.Builder() + .id("org.eclipse.elk.random") + .name("ELK Randomizer") + .description("Distributes the nodes randomly on the plane, leading to very obfuscating layouts. Can be useful to demonstrate the power of \"real\" layout algorithms.") + .providerFactory(new RandomFactory()) + .melkBundleName("ELK") + .definingBundleId("org.eclipse.elk.core") + .imagePath("images/random_layout.png") + .create() + ); + registry.addOptionSupport( + "org.eclipse.elk.random", + "org.eclipse.elk.padding", + PADDING_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.random", + "org.eclipse.elk.spacing.nodeNode", + SPACING_NODE_NODE_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.random", + "org.eclipse.elk.randomSeed", + RANDOM_SEED_DEFAULT + ); + registry.addOptionSupport( + "org.eclipse.elk.random", + "org.eclipse.elk.aspectRatio", + ASPECT_RATIO_DEFAULT + ); + } +}