1
28 package demo.layout.module;
29
30 import y.module.LayoutModule;
31 import y.module.YModule;
32
33 import y.layout.ComponentLayouter;
34 import y.layout.organic.OrganicLayouter;
35 import y.option.OptionHandler;
36 import y.view.Graph2D;
37 import y.view.Selections;
38 import y.view.hierarchy.HierarchyManager;
39
40
45 public class OrganicLayoutModule extends LayoutModule {
46 protected static final String MODULE_ORGANIC = "ORGANIC";
48
49 protected static final String SECTION_VISUAL = "VISUAL";
51 protected static final String ITEM_SPHERE_OF_ACTION = "SPHERE_OF_ACTION";
53 protected static final String VALUE_ALL = "ALL";
54 protected static final String VALUE_MAINLY_SELECTION = "MAINLY_SELECTION";
55 protected static final String VALUE_ONLY_SELECTION = "ONLY_SELECTION";
56 protected static final String ITEM_INITIAL_PLACEMENT = "INITIAL_PLACEMENT";
57 protected static final String VALUE_RANDOM = "RANDOM";
58 protected static final String VALUE_AT_ORIGIN = "AT_ORIGIN";
59 protected static final String VALUE_AS_IS = "AS_IS";
60 protected static final String ITEM_PREFERRED_EDGE_LENGTH = "PREFERRED_EDGE_LENGTH";
61 protected static final String ITEM_OBEY_NODE_SIZES = "OBEY_NODE_SIZES";
62 protected static final String ITEM_ATTRACTION = "ATTRACTION";
63 protected static final String ITEM_REPULSION = "REPULSION";
64 protected static final String ITEM_GRAVITY_FACTOR = "GRAVITY_FACTOR";
65 protected static final String ITEM_ACTIVATE_TREE_BEAUTIFIER = "ACTIVATE_TREE_BEAUTIFIER";
66
67 protected static final String SECTION_ALGORITHM = "ALGORITHM";
69 protected static final String ITEM_ITERATION_FACTOR = "ITERATION_FACTOR";
71 protected static final String ITEM_MAXIMAL_DURATION = "MAXIMAL_DURATION";
72 protected static final String ITEM_ACTIVATE_DETERMINISTIC_MODE = "ACTIVATE_DETERMINISTIC_MODE";
73 protected static final String ITEM_ALLOW_MULTI_THREADING = "ALLOW_MULTI_THREADING";
74
75 protected static final String SECTION_GROUPING = "GROUPING";
77 protected static final String ITEM_GROUP_LAYOUT_POLICY = "GROUP_LAYOUT_POLICY";
79 protected static final String VALUE_LAYOUT_GROUPS = "LAYOUT_GROUPS";
80 protected static final String VALUE_FIX_GROUPS = "FIX_GROUPS";
81 protected static final String VALUE_IGNORE_GROUPS = "IGNORE_GROUPS";
82 protected static final String ITEM_GROUP_NODE_COMPACTNESS = "GROUP_NODE_COMPACTNESS";
83
84
87 public OrganicLayoutModule() {
88 super(MODULE_ORGANIC, "yFiles Layout Team", "Wrapper for OrganicLayouter");
89 }
90
91
95 protected OptionHandler createOptionHandler() {
96 final OptionHandler options = new OptionHandler(getModuleName());
97 final OrganicLayouter defaults = new OrganicLayouter();
99
100 options.useSection(SECTION_VISUAL);
102 options.addEnum(ITEM_SPHERE_OF_ACTION, new String[]{
104 VALUE_ALL,
105 VALUE_MAINLY_SELECTION,
106 VALUE_ONLY_SELECTION
107 }, defaults.getSphereOfAction());
108 options.addEnum(ITEM_INITIAL_PLACEMENT, new String[]{
109 VALUE_RANDOM,
110 VALUE_AT_ORIGIN,
111 VALUE_AS_IS
112 }, defaults.getInitialPlacement());
113 options.addInt(ITEM_PREFERRED_EDGE_LENGTH, (int) defaults.getPreferredEdgeLength(), 0, 500);
114 options.addBool(ITEM_OBEY_NODE_SIZES, defaults.getObeyNodeSize());
115 options.addInt(ITEM_ATTRACTION, defaults.getAttraction(), 0, 2);
116 options.addInt(ITEM_REPULSION, defaults.getRepulsion(), 0, 2);
117 options.addDouble(ITEM_GRAVITY_FACTOR, defaults.getGravityFactor(), -0.2, 2, 1);
118 options.addBool(ITEM_ACTIVATE_TREE_BEAUTIFIER, defaults.getActivateTreeBeautifier());
119
120 options.useSection(SECTION_ALGORITHM);
122 options.addDouble(ITEM_ITERATION_FACTOR, defaults.getIterationFactor());
124 options.addInt(ITEM_MAXIMAL_DURATION, (int) (defaults.getMaximumDuration() / 1000));
125 options.addBool(ITEM_ACTIVATE_DETERMINISTIC_MODE, defaults.getActivateDeterministicMode());
126 options.addBool(ITEM_ALLOW_MULTI_THREADING, true);
127
128 options.useSection(SECTION_GROUPING);
130 options.addEnum(ITEM_GROUP_LAYOUT_POLICY, new String[]{
132 VALUE_LAYOUT_GROUPS,
133 VALUE_FIX_GROUPS,
134 VALUE_IGNORE_GROUPS
135 }, 0);
136 options.addDouble(ITEM_GROUP_NODE_COMPACTNESS, defaults.getGroupNodeCompactness(), 0, 1);
137
138 return options;
139 }
140
141
145 protected void mainrun() {
146 final OrganicLayouter organic = new OrganicLayouter();
147
148 final OptionHandler options = getOptionHandler();
149 configure(organic, options);
150
151 final Graph2D graph = getGraph2D();
152 prepareGraph(graph, options);
153 try{
154 launchLayouter(organic);
155 } finally {
156 restoreGraph(graph, options);
157 }
158 }
159
160
170 protected void prepareGraph(final Graph2D graph, final OptionHandler options) {
171 backupDataProvider(graph, OrganicLayouter.SPHERE_OF_ACTION_NODES);
173 graph.addDataProvider(OrganicLayouter.SPHERE_OF_ACTION_NODES, Selections.createSelectionNodeMap(graph));
174 }
175
176
182 protected void restoreGraph(final Graph2D graph, final OptionHandler options) {
183 restoreDataProvider(graph, OrganicLayouter.SPHERE_OF_ACTION_NODES);
185 }
186
187
196 protected void configure(final OrganicLayouter organic, final OptionHandler options) {
197 organic.setPreferredEdgeLength(options.getInt(SECTION_VISUAL, ITEM_PREFERRED_EDGE_LENGTH));
198 organic.setMaximumDuration(1000 * options.getInt(SECTION_ALGORITHM, ITEM_MAXIMAL_DURATION));
199
200 final String ip = options.getString(SECTION_VISUAL, ITEM_INITIAL_PLACEMENT);
201 if (VALUE_RANDOM.equals(ip)) {
202 organic.setInitialPlacement(OrganicLayouter.RANDOM);
203 } else if (VALUE_AT_ORIGIN.equals(ip)) {
204 organic.setInitialPlacement(OrganicLayouter.ZERO);
205 } else {
206 organic.setInitialPlacement(OrganicLayouter.AS_IS);
208 }
209
210 final String sp = options.getString(SECTION_VISUAL, ITEM_SPHERE_OF_ACTION);
211 if (VALUE_ALL.equals(sp)) {
212 organic.setSphereOfAction(OrganicLayouter.ALL);
213 } else if (VALUE_MAINLY_SELECTION.equals(sp)) {
214 organic.setSphereOfAction(OrganicLayouter.MAINLY_SELECTION);
215 } else {
216 organic.setSphereOfAction(OrganicLayouter.ONLY_SELECTION);
218 }
219
220 organic.setGravityFactor(options.getDouble(SECTION_VISUAL, ITEM_GRAVITY_FACTOR));
221 organic.setObeyNodeSize(options.getBool(SECTION_VISUAL, ITEM_OBEY_NODE_SIZES));
222 organic.setIterationFactor(options.getDouble(SECTION_ALGORITHM, ITEM_ITERATION_FACTOR));
223 organic.setActivateTreeBeautifier(options.getBool(SECTION_VISUAL, ITEM_ACTIVATE_TREE_BEAUTIFIER));
224 organic.setActivateDeterministicMode(options.getBool(SECTION_ALGORITHM, ITEM_ACTIVATE_DETERMINISTIC_MODE));
225 organic.setMultiThreadingAllowed(options.getBool(SECTION_ALGORITHM, ITEM_ALLOW_MULTI_THREADING));
226 organic.setAttraction(options.getInt(SECTION_VISUAL, ITEM_ATTRACTION));
227 organic.setRepulsion(2-options.getInt(SECTION_VISUAL, ITEM_REPULSION));
228 organic.setGroupNodeCompactness(options.getDouble(SECTION_GROUPING, ITEM_GROUP_NODE_COMPACTNESS));
229 ((ComponentLayouter) organic.getComponentLayouter()).setStyle(ComponentLayouter.STYLE_MULTI_ROWS);
230
231 if (HierarchyManager.containsGroupNodes(getGraph2D())) {
232 if (options.get(SECTION_GROUPING, ITEM_GROUP_LAYOUT_POLICY).equals(VALUE_FIX_GROUPS)) {
233 organic.setGroupNodePolicy(OrganicLayouter.FIXED_GROUPS_POLICY);
234 } else if (options.get(SECTION_GROUPING, ITEM_GROUP_LAYOUT_POLICY).equals(VALUE_IGNORE_GROUPS)) {
235 organic.setGroupNodePolicy(OrganicLayouter.IGNORE_GROUPS_POLICY);
236 } else {
237 organic.setGroupNodePolicy(OrganicLayouter.LAYOUT_GROUPS_POLICY);
238 }
239 }
240 }
241 }
242