Changes for page Configuring Automatic Layout
Last modified by Alexander Schulz-Rosengarten on 2023/07/11 10:33
To version 15.1
edited by msp
on 2014/03/05 15:49
on 2014/03/05 15:49
Change comment:
There is no comment for this version
Summary
-
Page properties (3 modified, 0 added, 0 removed)
-
Objects (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Parent
-
... ... @@ -1,1 +1,0 @@ 1 -KIELER.Home.Discontinued Projects.Infrastructure for Meta Layout (KIML).WebHome - Author
-
... ... @@ -1,1 +1,1 @@ 1 -XWiki. uru1 +XWiki.msp - Content
-
... ... @@ -7,7 +7,7 @@ 7 7 * How do layout options end up in KGraph elements? 8 8 * How can I set layout options on elements programmatically? 9 9 10 -This page does not list the available layout options, and neither does it explain any of them. You can find a list of layout options provided by KIML [[over here>>doc:KI ELER.KIML Layout Options]].10 +This page does not list the available layout options, and neither does it explain any of them. You can find a list of layout options provided by KIML [[over here>>doc:KIML Layout Options]]. 11 11 12 12 13 13 ... ... @@ -36,7 +36,7 @@ 36 36 </extension> 37 37 {{/code}} 38 38 39 -(% style="line-height: 1.4285715;" %) Such declarations are provided by layout algorithm developers, but not by tool developers who merely want to connect the layout infrastructure to their diagram viewers.Let's walk through the attributes available for layout options (not every available attribute appears in the example above):39 +(% style="line-height: 1.4285715;" %)Let's walk through the attributes available for layout options (not every available attribute appears in the example above): 40 40 41 41 * (% style="line-height: 1.4285715;" %){{code language="none"}}id{{/code}} – A unique identifier for this layout option. It is recommended that the identifier be prefixed by the plug-in name, to guarantee uniqueness.(%%)\\ 42 42 * {{code language="none"}}type{{/code}} – Defines the data type of this option; must be either {{code language="none"}}boolean{{/code}}, {{code language="none"}}string{{/code}}, {{code language="none"}}int{{/code}}, {{code language="none"}}float{{/code}}, {{code language="none"}}enum{{/code}}, {{code language="none"}}enumset{{/code}}, or {{code language="none"}}object{{/code}}. The types {{code language="none"}}enum{{/code}}, {{code language="none"}}enumset{{/code}}, and {{code language="none"}}object{{/code}} require the {{code language="none"}}class{{/code}} attribute to be set. ... ... @@ -54,6 +54,7 @@ 54 54 * (% style="line-height: 1.4285715;" %){{code language="none"}}upperBound{{/code}} – An optional upper bound on the values of this layout option. 55 55 * (% style="line-height: 1.4285715;" %){{code language="none"}}variance{{/code}} – An optional variance for values of this layout option. The variance is taken as multiplier for Gaussian distributions when new values are determined. Options with uniform distibution, such as Boolean or enumeration types, do not need a variance value, since all values have equal probability. A variance of 0 implies that the option shall not be used in automatic configuration, regardless of its type. 56 56 57 + 57 57 (% style="line-height: 1.4285715;" %)The latter three attributes are used when a layout configuration is determined automatically, e.g. with an evolutionary algorithm. They are mainly meant for scientific experiments and can be ignored in most applications. 58 58 59 59 (% style="line-height: 1.4285715;" %)If a layout algorithm supports a particular layout option, it must tell KIML so. Here's an example: ... ... @@ -71,16 +71,14 @@ 71 71 72 72 (% style="line-height: 1.4285715;" %)This tells KIML that the defined layout algorithm supports the border spacing option. And even more, it overrides the default value declared by the layout option and sets it to 20. 73 73 74 -(% style="line-height: 1.4285715;" %)The meta data gathered from the extension point are made available through [[LayoutMetaDataService>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/LayoutMetaDataService.java||shape="rect"]].For direct programmatic access, some of that information is duplicated with constants in the class [[LayoutOptions>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/options/LayoutOptions.java||shape="rect"]].The layout optiondeclared above, for example, is available as {{code language="none"}}LayoutOptions.{{/code}}(% style="line-height: 1.4286; color: rgb(0, 0, 0)"%){{codelanguage="none"}}NODE_LABEL_PLACEMENT{{/code}}.75 += (% style="line-height: 1.4285715;" %)The Layout Options Manager(%%) = 75 75 76 - =(% style="line-height: 1.4285715;" %)The LayoutOptionManager(%%)=77 +(% style="line-height: 1.4285715;" %)By now, we have an idea of what layout options do and why they are important in the first place. However, we haven't looked at how layout options end up on [[KGraph>>doc:KGraph Meta Model]] elements yet. This is where the [[{{code language="none"}}LayoutOptionsManager{{/code}}>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml.ui/src/de/cau/cs/kieler/kiml/ui/service/LayoutOptionManager.java||shape="rect"]] comes in. 77 77 78 -(% style="line-height: 1.4285715;" %) By now, wehavean ideaof whatlayoutoptions doandwhytheyareimportantin thefirstplace.However,wehaven'tlooked athow layout options endupon[[KGraph>>doc:KIELER.Home.DiscontinuedProjects.InfrastructureforMetaLayout(KIML).KGraphMetaModel.WebHome]]elementsyet.This iswhere the[[{{codelanguage="none"}}LayoutOptionManager{{/code}}>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml.service/src/de/cau/cs/kieler/kiml/service/LayoutOptionManager.java||shape="rect"]]comesin.Ifyouare notinterested in the internaldetails,but want toconfigureautomaticlayoutfor yourdiagram vieweror editor,youmayskipthissectionand proceedto[[programmaticallysettinglayout options>>doc:||anchor="programmatic-config"]].79 +(% style="line-height: 1.4285715;" %)After a diagram layout manager has finished turning a given diagram into its KGraph representation, the layout options manager is asked to enrich the KGraph elements with layout options. The option values can come from different sources: the user might have set some using the layout view; there might be some defaults for certain kinds of diagrams; or the programmer might have decided to attach some layout options to certain elements for just this one layout run. Whatever the source, the options manager is in charge of collecting all these layout option values and making sure they find their way to the correct KGraph element. To start off with a clean plate, it first makes sure there are no layout options attached to the KGraph elements. It then does two things: collect every eligible source of layout options, and transfer values of layout options to the associated KGraph elements. Sounds easy enough. 79 79 80 -(% style="line-height: 1.4285715;" %) Aftera diagram layout manager hasfinishedturninga given diagraminto itsKGraphrepresentation,the layout optionmanager isasked toenrich theKGraphelementswith layoutoptions.Theoptionvaluescancomefromdifferentsources:theusermight haveset some using thelayoutview; there might be somedefaultsforcertainkinds of diagrams;ortheprogrammer might have decidedto attachsomelayout optionsto certainelementsforjust this onelayoutrun.Whatever thesource,theoptions manageris in chargeofcollectingalltheselayout optionvalues and makingsure they find their waytothecorrect KGraph element.To startoff with a clean plate, it firstmakes surethereare no layout options attachedto the KGraphelements. It thendoestwo things:collectevery eligiblesource of layout options,andtransfervaluesof layout optionstotheassociatedKGraphelements. Sounds easy enough.81 +(% style="line-height: 1.4285715;" %)The question remains how the layout options sources work. Each source is represented by a class that implements the [[{{code language="none"}}ILayoutConfig{{/code}}>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/ILayoutConfig.java||shape="rect"]] interface, called a //layout configurator//. KIML currently provides the following layout configurators, each representing a particular source of layout options, listed here in order of increasing priority: 81 81 82 -(% style="line-height: 1.4285715;" %)The question remains how the layout options sources work. Each source is represented by a class that implements the [[ILayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/ILayoutConfig.java||shape="rect"]] interface, called a //layout configurator//. KIML currently provides the following layout configurators, each representing a particular source of layout options, listed here in order of increasing priority: 83 - 84 84 * [[DefaultLayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/DefaultLayoutConfig.java||shape="rect"]]{{code language="none"}}{{/code}} – Applies fixed default values defined in the meta data of layout options. This is important for the Layout View, which displays the default values if nothing else has been specified. 85 85 * [[EclipseLayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml.service/src/de/cau/cs/kieler/kiml/service/EclipseLayoutConfig.java||shape="rect"]]{{code language="none"}}{{/code}} – Users can define default layout options to be set on elements that meet certain criteria via the KIML preference page. This layout configurator takes these options and applies them. Furthermore, it also applies options configured through the extension point. 86 86 * [[SemanticLayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/SemanticLayoutConfig.java||shape="rect"]]{{code language="none"}}{{/code}} – An abstract superclass for configurators that base their computation of layout option values on the //semantic// model, a.k.a. //domain// model. ... ... @@ -89,200 +89,47 @@ 89 89 90 90 The options manager collects all available and applicable layout configurators and sorts them by priority. For every graph element, each configurator is asked to provide layout options, starting with the one with lowest priority and working through the priority chain. Hereby configurators with higher priority are able to override values set by those with lower priority. 91 91 92 -== A Few Details on Layout Configurato rs ==91 +== A Few Details on Layout Configurations == 93 93 94 -What we just learned is a bit of a simplification of what happens. Before we look at the details, let's take a look at the methods each layout configurato rprovides:93 +What we just learned is a bit of a simplification of what happens. Before we look at the details, let's take a look at the methods each layout configuration provides: 95 95 96 96 {{code language="java"}} 97 97 public interface ILayoutConfig { 98 98 int getPriority(); 99 - ObjectgetOptionValue(LayoutOptionData optionData, LayoutContext context);100 - Collection<IProperty<?>>getAffectedOptions(LayoutContext context);101 - ObjectgetContextValue(IProperty<?>property, LayoutContext context);98 + void enrich(LayoutContext context); 99 + Object getValue(LayoutOptionData<?> optionData, LayoutContext context); 100 + void transferValues(KLayoutData layoutData, LayoutContext context); 102 102 } 103 103 {{/code}} 104 104 105 -It is not hard to guess what {{code language="none"}}getPriority(){{/code}} does: it returns the priority a given layout configuration has. If two layout configurations set a layout option to different values on a given graph element, the value set by the configuration with higher priority wins. 104 +It is not hard to guess what {{code language="none"}}getPriority(){{/code}} does: it returns the priority a given layout configuration has. If two layout configurations set a layout option to different values on a given graph element, the value set by the configuration with higher priority wins. The other three methods look a bit more obscure, so we have to provide more details on what the options manager does, exactly. 106 106 107 - The interface discerns between //option// values and //context// values. Option values are what we have been talking about all the time, values assigned to layout options. Which particular values the configurator should apply depends on the given [[LayoutContext>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/LayoutContext.java||shape="rect"]], which is a property holder with references to the diagram element currently in focus. For instance, the object representing an element in the diagram viewer is accessed with {{code language="none"}}context.getProperty(LayoutContext.DIAGRAM_PART){{/code}}. Similarly, the corresponding KGraph element is mapped to the property {{code language="none"}}LayoutContext.GRAPH_ELEM{{/code}}, and the domain model element is mapped to {{code language="none"}}LayoutContext.DOMAIN_MODEL{{/code}}.Each configurator is free to put additional information into the context, caching it for faster access and enabling to communicate it to other configurators. {{code language="none"}}getAffectedOptions(LayoutContext){{/code}}should return a collection of layout options for which the configurator yields non-null values with respect to the given context.Theoptions can be referenced either with [[LayoutOptionData>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/LayoutOptionData.java||shape="rect"]] instances obtained from the [[LayoutMetaDataService>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/LayoutMetaDataService.java||shape="rect"]]orwith [[Property>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.core/src/de/cau/cs/kieler/core/properties/Property.java||shape="rect"]] instances from the constants defined in [[LayoutOptions>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/options/LayoutOptions.java||shape="rect"]].Theactual value for a layout option is queried with {{code language="none"}}getOptionValue(LayoutOptionData, LayoutContext){{/code}}. The method {{code language="none"}}getContextValue(IProperty, LayoutContext){{/code}}, in contrast, is used to obtain more detailed information on the given context. For instance, the context may contain a reference to an element of the diagram viewer; only a specialized configurator made for that diagram viewer knows how to extract a reference to the corresponding domain model element from the given diagram element, so it can encode this knowledge in {{code language="none"}}getContextValue(…){{/code}} by returning the domain model element when the given property corresponds to LayoutContext.DOMAIN_MODEL.106 +ENRICHING (+ WHAT IS A LAYOUT CONTEXT) 108 108 109 -Th ismayseemcomplicated,andit is,but the goodnewsis thatthe vastmajorityof developerswillnotneedtodigthatdeepintothelayout configurationinfrastructure.Thereare easier waystospecifyconfigurations,asdescribed inthefollowing section.108 +The {{code language="none"}}transferValues(...){{/code}} method is the main workhorse of the interface. This is where a KGraph element, identified by the given layout context, is equipped with the layout option values a layout configuration deems necessary. It thus becomes the most important part of a layout configuration that you absolutely have to implement, no excuses. If for example every {{code language="none"}}KNode{{/code}} should have its port constraints set to {{code language="none"}}FIXED_POS{{/code}}, this is the place to do it. 110 110 111 - =(%style="line-height:1.4285715;"%)ProgrammaticallySetting LayoutOptions(%%)=110 +With all these layout configurations active, it's by no means clear which layout option values KGraph elements will end up with during the layout process. Enter the {{code language="none"}}getValue(...){{/code}} method. For a given element and layout option, it returns the value it would set on the element if {{code language="none"}}transferValues(...){{/code}} was called. This method is mainly used by the Layout view to inform the user about the layout option values of whatever graph element he (or she) has clicked on. It is also the method you can safely neglect to implement if your final product won't include the layout view anyway. 112 112 113 - {{idname="programmatic-config"/}}112 +== (% style="line-height: 1.4285715;" %)Implementing a Layout Configuration(%%) == 114 114 115 -(% style="line-height: 1.4285715;" %)So with all these layout configurators available, how do you actually go about setting values for layout options programmatically? Well, as always: it depends. 114 +{{warning title="ToDo"}} 115 +deciding what options are applicable depending on the context object; setting the options; 116 +{{/warning}} 116 116 117 - ==(% style="line-height: 1.4285715;" %)Using the Extension Point(%%) ==118 +(% style="line-height: 1.4285715;" %) 118 118 119 -(% style="line-height: 1.4285715;" %)The recommended way to configure your layout is to use the {{code language="none"}}layoutConfigs{{/code}} extension point. It offers three different kinds of configurations, explained in the following. 120 120 121 -= ==(% style="line-height: 1.4285715;" %)staticConfig(%%) ===121 += (% style="line-height: 1.4285715;" %)Programmatically Setting Layout Options(%%) = 122 122 123 -(% style="line-height: 1.4285715;" %) A {{code language="none"}}staticConfig{{/code}} element can setonevalueforonelayout optioninthe contextof aparticulardiagramelementtype.Let'sseeanexample:123 +(% style="line-height: 1.4285715;" %)So with all these layout configurations available, how do you actually go about setting layout options programmatically? Well, as always: it depends. 124 124 125 -{{code language="xml"}} 126 - <staticConfig 127 - class="org.eclipse.emf.ecore.EReference" 128 - option="de.cau.cs.kieler.edgeType" 129 - value="ASSOCIATION"> 130 - </staticConfig> 131 -{{/code}} 132 132 133 -(% style="line-height: 1.4285715;" %) Here {{code language="none"}}class{{/code}} refers to a domain model class, in this case the {{code language="none"}}EReference{{/code}} class from the Ecore meta model defined by EMF, and {{code language="none"}}option{{/code}} refers to a layout option through its identifier. The meaning of this declaration is that whenever automatic layout is requested for an Ecore class diagram, the {{code language="none"}}edgeType{{/code}} option is set to {{code language="none"}}ASSOCIATION{{/code}}(%%) for all edges linked to instances of {{code language="none"}}EReference{{/code}}. Since the domain model (//abstract syntax//) is independent of the specific diagram viewer (//concrete syntax//), this configuration is applied to all diagram viewers that use the Ecore meta model.126 +(% style="line-height: 1.4285715;" %) 134 134 135 -Alternatively to domain model elements, {{code language="none"}}staticConfig{{/code}} may also reference concrete syntax elements: 136 136 137 -{{code language="xml"}} 138 - <staticConfig 139 - class="org.eclipse.emf.ecoretools.diagram.edit.parts.EClassESuperTypesEditPart" 140 - option="de.cau.cs.kieler.edgeType" 141 - value="GENERALIZATION"> 142 - </staticConfig> 143 -{{/code}} 129 +{{warning title="ToDo"}} 130 +Write this section. This will be about when to use the different kinds of layout configurations, mainly {{code language="none"}}SemanticLayoutConfig{{/code}} and {{code language="none"}}VolatileLayoutConfig{{/code}}. 131 +{{/warning}} 144 144 145 - Thislayout option value isapplied onlyto edgeslinked to instances of {{code language="none"}}EClassESuperTypesEditPart{{/code}}, which is a concrete syntax element of theEcore Tools class diagram editor. Other Ecore metamodel editors are not affected by this declaration.This distinction is particularly useful for meta models that are accessed with multiple different editors, as is often the case for UML tools.133 +(% style="line-height: 1.4285715;" %) 146 146 147 -A third variant is the use of //diagram types//, as in this example: 148 - 149 -{{code language="xml"}} 150 - <diagramType 151 - id="de.cau.cs.kieler.layout.diagrams.classDiagram" 152 - name="Class Diagram"> 153 - </diagramType> 154 - <staticConfig 155 - class="org.eclipse.emf.ecore.EPackage" 156 - option="de.cau.cs.kieler.diagramType" 157 - value="de.cau.cs.kieler.layout.diagrams.classDiagram"> 158 - </staticConfig> 159 - <staticConfig 160 - class="de.cau.cs.kieler.layout.diagrams.classDiagram" 161 - option="de.cau.cs.kieler.edgeRouting" 162 - value="SPLINES"> 163 - </staticConfig> 164 -{{/code}} 165 - 166 -A diagram type can be declared with a {{code language="none"}}diagramType{{/code}} element and can be associated with an abstract syntax or concrete syntax class using the {{code language="none"}}diagramType{{/code}} option, as shown in the first {{code language="none"}}staticConfig{{/code}} declaration in the example above. The second {{code language="none"}}staticConfig{{/code}} sets an option for the declared diagram type by using its identifier in the {{code language="none"}}class{{/code}} attribute. This kind of indirection is very useful when you have //n// model classes and you want to set //m// layout options for each of those classes. Instead of writing //n// × //m// static declarations, you assign a diagram type //t// to each of the //n// classes and then declare the //m// layout options for //t//, resulting in //n// + //m// option declarations (in many cases //n// + //m// < //n// × //m//). 167 - 168 -A further use of diagram types is for the selection of layout algorithms: a layout algorithm may declare that is is especially suited to process diagrams of certain type //t//. If the diagram type //t// is assigned to a diagram viewer, the most suitable layout algorithm is chosen automatically for that viewer. 169 - 170 -The following diagram types are predefined in KIML: 171 - 172 -* de.cau.cs.kieler.layout.diagrams.stateMachine – All kinds of state machines, statecharts, etc. 173 -* de.cau.cs.kieler.layout.diagrams.dataFlow – All kinds of data flow diagrams, e.g. actor diagrams, block diagrams, certain component diagrams, etc. 174 -* de.cau.cs.kieler.layout.diagrams.classDiagram – Class diagrams as defined by the UML, but also meta model diagrams such as the Ecore format. 175 -* de.cau.cs.kieler.layout.diagrams.usecaseDiagram – UML use case diagrams. 176 -* de.cau.cs.kieler.layout.diagrams.boxes – Unconnected boxes (graphs with no edges), e.g. parallel regions in statecharts. 177 - 178 -=== semanticConfig === 179 - 180 -A {{code language="none"}}semanticConfig{{/code}} element registers a subclass of [[SemanticLayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/SemanticLayoutConfig.java||shape="rect"]]: 181 - 182 -{{code language="xml"}} 183 - <semanticOption 184 - class="de.cau.cs.kieler.synccharts.Scope" 185 - config="de.cau.cs.kieler.synccharts.diagram.custom.AnnotationsLayoutConfig"> 186 - </semanticOption> 187 -{{/code}} 188 - 189 -Similarly to {{code language="none"}}staticConfig{{/code}} entries, the {{code language="none"}}class{{/code}} attribute refers to which model elements the configuration is applied. However, only domain model (a.k.a. //semantic// model) classes may be referenced. The {{code language="none"}}config{{/code}} attribute names a concrete implementation of the semantic layout configurator. 190 - 191 -The advantage of this kind of configuration compared to {{code language="none"}}staticConfig{{/code}} declarations is that it may perform arbitrary analyses of the domain model. For instance, different option values may be computed depending on certain properties of the domain model elements. This approach can be used to enable annotations of domain model elements. When the domain model is stored with a textual format, e.g. defined with [[Xtext>>url:http://www.eclipse.org/Xtext/||shape="rect"]], such annotations can be written in the source file that specifies the model: 192 - 193 -{{code}} 194 -@portConstraints FIXED_SIDE 195 -@minWidth 20.0 196 -@minHeight 15.0 197 -entity IdentityActor 198 -{ 199 - @portSide WEST 200 - port Input; 201 - 202 - @portSide EAST 203 - port Output; 204 -} 205 -{{/code}} 206 - 207 -The source file annotations can be translated to KIML layout options with a semantic layout configurator, which is registered to each domain model class where annotations can occur. 208 - 209 -=== customConfig === 210 - 211 -This extension element can be used to register arbitrary implementations of [[ILayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/ILayoutConfig.java||shape="rect"]]. However, this is required only for some experimental configurators used in research. Tool developers normally do not need to use this kind of extension element. 212 - 213 -== Using Volatile Configurators == 214 - 215 -The class [[VolatileLayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/VolatileLayoutConfig.java||shape="rect"]] is meant for programmatic layout configuration. It stores layout option values in a hash map. Values are either set globally, that means they are applied to all graph elements, or with a specific context. Global values are easy to configure: 216 - 217 -{{code theme="Eclipse" language="java"}} 218 -DiagramLayoutEngine.INSTANCE.layout(workbenchPart, diagramPart, 219 - new VolatileLayoutConfig() 220 - .setValue(LayoutOptions.ALGORITHM, "de.cau.cs.kieler.klay.layered") 221 - .setValue(LayoutOptions.SPACING, 30.0f) 222 - .setValue(LayoutOptions.ANIMATE, true)); 223 -{{/code}} 224 - 225 -If multiple configurators are passed to the [[DiagramLayoutEngine>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml.service/src/de/cau/cs/kieler/kiml/service/DiagramLayoutEngine.java||shape="rect"]], the layout is computed multiple times: once for each configurator. This behavior can be used to apply different layout algorithms one after another, e.g. first a node placer algorithm and then an edge router algorithm, as in this example: 226 - 227 -{{code theme="Eclipse" language="java"}} 228 -DiagramLayoutEngine.INSTANCE.layout(workbenchPart, diagramPart, 229 - new VolatileLayoutConfig() 230 - .setValue(LayoutOptions.ALGORITHM, "de.cau.cs.kieler.klay.force"), 231 - new VolatileLayoutConfig() 232 - .setValue(LayoutOptions.ALGORITHM, "de.cau.cs.kieler.kiml.libavoid")); 233 -{{/code}} 234 - 235 -If you want to use multiple configurators in the same layout computation, use a [[CompoundLayoutConfig>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/CompoundLayoutConfig.java||shape="rect"]]: 236 - 237 -{{code theme="Eclipse" language="java"}} 238 -DiagramLayoutEngine.INSTANCE.layout(workbenchPart, diagramPart, 239 - CompoundLayoutConfig.of(config1, config2, ...)); 240 -{{/code}} 241 - 242 -Setting layout option values with a specific context is done with this method of [[VolatileLayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/VolatileLayoutConfig.java||shape="rect"]]: 243 - 244 -{{code theme="Eclipse" language="java"}} 245 -public <T, C> VolatileLayoutConfig setValue(final IProperty<? super T> option, final C contextObj, 246 - final IProperty<? super C> contextKey, final T value) 247 -{{/code}} 248 - 249 -Don't be scared by the rather cryptic declaration. The arguments {{code language="none"}}contextKey{{/code}} and {{code language="none"}}contextObj{{/code}} determine in which context the option value is to be applied. For instance, using {{code language="none"}}LayoutContext.DOMAIN_MODEL{{/code}} as context key and a specific domain model element as context object, the value is applied exactly to the graph element that is linked to that model element. If you want to refer to an element of the diagram viewer, i.e. the concrete syntax, use {{code language="none"}}LayoutContext.DIAGRAM_PART{{/code}} as context key. The return value is the volatile layout configurator itself, allowing for a builder pattern. 250 - 251 -=== Configuration During Layout Graph Construction === 252 - 253 -Volatile configurators are also useful for the implementation of diagram layout managers ([[IDiagramLayoutManager>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml.service/src/de/cau/cs/kieler/kiml/service/IDiagramLayoutManager.java||shape="rect"]]). These implementations are responsible for creating layout graphs following the KGraph meta model from a given diagram viewer (method {{code language="none"}}buildLayoutGraph({{/code}}…{{code language="none"}}){{/code}}). For some layout options it is reasonable to determine concrete values while the layout graph is built, e.g. for the minimal width and height of nodes: 254 - 255 -{{code theme="Eclipse" language="java"}} 256 -KNode childLayoutNode = KimlUtil.createInitializedNode(); 257 -KShapeLayout nodeLayout = childLayoutNode.getData(KShapeLayout.class); 258 -Dimension minSize = nodeEditPart.getFigure().getMinimumSize(); 259 -nodeLayout.setProperty(LayoutOptions.MIN_WIDTH, (float) minSize.width); 260 -nodeLayout.setProperty(LayoutOptions.MIN_HEIGHT, (float) minSize.height); 261 -{{/code}} 262 - 263 -The problem is that the layout option manager that applies all configurators to the layout graph removes any option values that have been set directly on the graph elements, hence the configuration done in the previous example has no effect on the layout process. But do not fear, for salvation is near: 264 - 265 -{{code theme="Eclipse" language="java"}} 266 -mapping.getLayoutConfigs().add(VolatileLayoutConfig.fromProperties(mapping.getLayoutGraph(), PRIORITY)); 267 -{{/code}} 268 - 269 -The variable {{code language="none"}}mapping{{/code}} refers to the [[LayoutMapping>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml.service/src/de/cau/cs/kieler/kiml/service/LayoutMapping.java||shape="rect"]] instance created in buildLayoutGraph({{code language="none"}}{{/code}}…){{code language="none"}}{{/code}}. The static method {{code language="none"}}fromProperties({{/code}}…{{code language="none"}}){{/code}} offered by [[VolatileLayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/VolatileLayoutConfig.java||shape="rect"]] creates a configuration that contains all the layout option values that have previously been seen directly on the graph elements. By adding this configuration to the layout mapping, we make sure it is considered by the layout option manager and the options are applied to the graph elements exactly as we have specified. Happy end. 270 - 271 -If you are uncertain about which value to use for {{code language="none"}}PRIORITY{{/code}}, take something like 25. 272 - 273 -== Adding Support for the Layout View == 274 - 275 -The Layout View empowers users to directly modify the layout configuration for the currently viewed diagram. This power, however, comes with a price. Tool developers implementing a [[IDiagramLayoutManager>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml.service/src/de/cau/cs/kieler/kiml/service/IDiagramLayoutManager.java||shape="rect"]] additionally have to provide an implementation of [[IMutableLayoutConfig>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/IMutableLayoutConfig.java||shape="rect"]] that loads and saves layout option values in a way that they can be stored persistently with the respective diagram. Good examples of such configurators are [[GmfLayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml.gmf/src/de/cau/cs/kieler/kiml/gmf/GmfLayoutConfig.java||shape="rect"]] and [[GraphitiLayoutConfig>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml.graphiti/src/de/cau/cs/kieler/kiml/graphiti/GraphitiLayoutConfig.java||shape="rect"]] for GMF and Graphiti diagrams, respectively. The GMF implementation stores option values as //styles// in the GMF //Notation// model, while the Graphiti implementation stores the values as //properties// in the Graphiti //Pictogram// model. If you are developing an editor based on GMF or Graphiti, simply reuse these implementations and you're fine. Otherwise, read this section to learn how to implement a suitable configurator. 276 - 277 -A //mutable// layout configurator is one that can not only read option values, but also write them. Most interface methods are rather self-explanatory, therefore we will consider only the {{code language="none"}}getContextValue(IProperty, LayoutContext){{/code}} method here. This method receives a [[LayoutContext>>url:https://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/config/LayoutContext.java||shape="rect"]] and should return a value that corresponds to the given property, if possible, and {{code language="none"}}null{{/code}} otherwise. The starting point is usually the current value of {{code language="none"}}LayoutContext.DIAGRAM_PART{{/code}} in the given context, called the //diagram part//, which refers to the currently selected diagram element in the viewer (the abstract syntax element). From this the method should extract more information considering the following other context properties: 278 - 279 -* {{code language="none"}}LayoutContext.DOMAIN_MODEL{{/code}} – The domain model element linked to the current diagram part. 280 -* {{code language="none"}}LayoutContext.CONTAINER_DIAGRAM_PART{{/code}} – The diagram part that corresponds to the graph or subgraph that contains the current diagram part. This is called the //container//. If The current diagram part is already the top-level element of the diagram, then there is no container and {{code language="none"}}null{{/code}} should be returned. 281 -* {{code language="none"}}LayoutContext.CONTAINER_DOMAIN_MODEL{{/code}} – The domain model element linked to the container. 282 -* {{code language="none"}}LayoutContext.OPT_TARGETS{{/code}} – A set containing the kind of graph element that corresponds to the current diagram part, referenced with the enumeration [[LayoutOptionData.Target>>url:http://git.rtsys.informatik.uni-kiel.de/projects/KIELER/repos/pragmatics/browse/plugins/de.cau.cs.kieler.kiml/src/de/cau/cs/kieler/kiml/LayoutOptionData.java||shape="rect"]]. If the diagram part is a node, for example, the set should contain the value {{code language="none"}}NODES{{/code}}. If the node is also a container for a subgraph, the set should additionally contain the value {{code language="none"}}PARENTS{{/code}}. 283 -* {{code language="none"}}DefaultLayoutConfig.HAS_PORTS{{/code}} – If the current diagram part is a node, the returned value for this property should be {{code language="none"}}true{{/code}} or {{code language="none"}}false{{/code}} depending on whether the node has any ports or not. Ports are explicit connection points for edges; they occur frequently in data flow diagrams. 284 -* {{code language="none"}}DefaultLayoutConfig.CONTENT_HINT{{/code}} – If the diagram contains an annotation about which layout algorithm to use for the content of the current diagram part, the returned value for this property should be the identifier of that algorithm. This is the same kind of annotation that is accessed through {{code language="none"}}getOptionValue({{/code}}…{{code language="none"}}){{/code}}, i.e. a value set by the user with the Layout View. 285 -* {{code language="none"}}DefaultLayoutConfig.CONTAINER_HINT{{/code}} – The same as for CONTENT_HINT{{code language="none"}}{{/code}}, but referring to the container. 286 -* {{code language="none"}}EclipseLayoutConfig.EDITING_DOMAIN{{/code}} – If your diagram editor needs an EMF editing domain in order to modify annotations of layout options, then such an editing domain should be returned for this property. 287 - 288 -An instance of your self-made configurator should be returned by the {{code language="none"}}getDiagramConfig(){{/code}} method of your diagram layout manager.
- Confluence.Code.ConfluencePageClass[0]
-
- Id
-
... ... @@ -1,1 +1,1 @@ 1 - 77009441 +9469979 - URL
-
... ... @@ -1,1 +1,1 @@ 1 -https://rtsys.informatik.uni-kiel.de/confluence//wiki/spaces/KIELER/pages/ 7700944/Configuring Automatic Layout1 +https://rtsys.informatik.uni-kiel.de/confluence//wiki/spaces/KIELER/pages/9469979/Configuring Automatic Layout