1
14 package demo.layout.module;
15
16 import y.module.LayoutModule;
17 import y.module.YModule;
18
19
20 import y.base.DataMap;
21 import y.base.Edge;
22 import y.base.EdgeCursor;
23 import y.base.NodeCursor;
24 import y.layout.CanonicMultiStageLayouter;
25 import y.layout.LabelLayoutConstants;
26 import y.layout.LabelRanking;
27 import y.layout.OrientationLayouter;
28 import y.layout.hierarchic.AsIsLayerer;
29 import y.layout.hierarchic.BFSLayerer;
30 import y.layout.hierarchic.IncrementalHierarchicLayouter;
31 import y.layout.hierarchic.incremental.EdgeLayoutDescriptor;
32 import y.layout.hierarchic.incremental.IncrementalHintsFactory;
33 import y.layout.hierarchic.incremental.NodeLayoutDescriptor;
34 import y.layout.hierarchic.incremental.OldLayererWrapper;
35 import y.layout.hierarchic.incremental.SimplexNodePlacer;
36 import y.layout.hierarchic.incremental.TopLevelGroupToSwimlaneStage;
37 import y.layout.labeling.GreedyMISLabeling;
38 import y.option.ConstraintManager;
39 import y.option.ConstraintManager.Condition;
40 import y.option.DefaultEditorFactory;
41 import y.option.DoubleOptionItem;
42 import y.option.EnumOptionItem;
43 import y.option.OptionGroup;
44 import y.option.OptionHandler;
45 import y.option.OptionItem;
46 import y.util.Maps;
47 import y.view.EdgeLabel;
48 import y.view.EdgeRealizer;
49 import y.view.Graph2D;
50 import y.view.Selections;
51
52
60 public class IncrementalHierarchicLayoutModule extends LayoutModule {
61 private static final String INCREMENTAL_HIERARCHIC = "INCREMENTAL_HIERARCHIC";
62
63 private static final String GENERAL = "GENERAL";
64 private static final String INTERACTION = "INTERACTION";
65 private static final String SELECTED_ELEMENTS_INCREMENTALLY = "SELECTED_ELEMENTS_INCREMENTALLY";
66 private static final String USE_DRAWING_AS_SKETCH = "USE_DRAWING_AS_SKETCH";
67 private static final String ORIENTATION = "ORIENTATION";
68 private static final String RIGHT_TO_LEFT = "RIGHT_TO_LEFT";
69 private static final String BOTTOM_TO_TOP = "BOTTOM_TO_TOP";
70 private static final String LEFT_TO_RIGHT = "LEFT_TO_RIGHT";
71 private static final String TOP_TO_BOTTOM = "TOP_TO_BOTTOM";
72 private static final String LAYOUT_COMPONENTS_SEPARATELY = "LAYOUT_COMPONENTS_SEPARATELY";
73 private static final String SYMMETRIC_PLACEMENT = "SYMMETRIC_PLACEMENT";
74 private static final String MINIMUM_DISTANCES = "MINIMUM_DISTANCES";
75 private static final String NODE_TO_NODE_DISTANCE = "NODE_TO_NODE_DISTANCE";
76 private static final String NODE_TO_EDGE_DISTANCE = "NODE_TO_EDGE_DISTANCE";
77 private static final String EDGE_TO_EDGE_DISTANCE = "EDGE_TO_EDGE_DISTANCE";
78 private static final String MINIMUM_LAYER_DISTANCE = "MINIMUM_LAYER_DISTANCE";
79 private static final String MAXIMAL_DURATION = "MAXIMAL_DURATION";
80
81 private static final String EDGE_SETTINGS = "EDGE_SETTINGS";
82 private static final String EDGE_ROUTING = "EDGE_ROUTING";
83 private static final String EDGE_ROUTING_ORTHOGONAL = "EDGE_ROUTING_ORTHOGONAL";
84 private static final String EDGE_ROUTING_POLYLINE = "EDGE_ROUTING_POLYLINE";
85 private static final String BACKLOOP_ROUTING = "BACKLOOP_ROUTING";
86 private static final String MINIMUM_FIRST_SEGMENT_LENGTH = "MINIMUM_FIRST_SEGMENT_LENGTH";
87 private static final String MINIMUM_LAST_SEGMENT_LENGTH = "MINIMUM_LAST_SEGMENT_LENGTH";
88 private static final String MINIMUM_EDGE_LENGTH = "MINIMUM_EDGE_LENGTH";
89 private static final String MINIMUM_EDGE_DISTANCE = "MINIMUM_EDGE_DISTANCE";
90 private static final String MINIMUM_SLOPE = "MINIMUM_SLOPE";
91 private static final String PC_OPTIMIZATION_ENABLED = "PC_OPTIMIZATION_ENABLED";
92 private static final String AUTOMATIC_EDGE_GROUPING_ENABLED = "AUTOMATIC_EDGE_GROUPING_ENABLED";
93
94 private static final String RANKS = "RANKS";
95 private static final String RANKING_POLICY = "RANKING_POLICY";
96 private static final String HIERARCHICAL_OPTIMAL = "HIERARCHICAL_OPTIMAL";
97 private static final String HIERARCHICAL_TIGHT_TREE_HEURISTIC = "HIERARCHICAL_TIGHT_TREE_HEURISTIC";
98 private static final String HIERARCHICAL_TOPMOST = "HIERARCHICAL_TOPMOST";
99 private static final String BFS_LAYERS = "BFS_LAYERS";
100 private static final String FROM_SKETCH = "FROM_SKETCH";
101 private static final String LAYER_ALIGNMENT = "LAYER_ALIGNMENT";
102 private static final String TOP = "TOP";
103 private static final String CENTER = "CENTER";
104 private static final String BOTTOM = "BOTTOM";
105 private static final String FROM_SKETCH_PROPERTIES = "FROM_SKETCH_PROPERTIES";
106 private static final String SCALE = "SCALE";
107 private static final String HALO = "HALO";
108 private static final String MINIMUM_SIZE = "MINIMUM_SIZE";
109 private static final String MAXIMUM_SIZE = "MAXIMUM_SIZE";
110 private static final String COMPONENT_ARRANGEMENT_POLICY = "COMPONENT_ARRANGEMENT_POLICY";
111 private static final String POLICY_TOPMOST = "POLICY_TOPMOST";
112 private static final String POLICY_COMPACT = "POLICY_COMPACT";
113
114 private static final String LABELING = "LABELING";
115 private static final String NODE_PROPERTIES = "NODE_PROPERTIES";
116 private static final String CONSIDER_NODE_LABELS = "CONSIDER_NODE_LABELS";
117 private static final String EDGE_PROPERTIES = "EDGE_PROPERTIES";
118 private static final String EDGE_LABELING = "EDGE_LABELING";
119 private static final String EDGE_LABELING_NONE = "EDGE_LABELING_NONE";
120 private static final String EDGE_LABELING_HIERARCHIC = "EDGE_LABELING_HIERARCHIC";
121 private static final String EDGE_LABELING_GENERIC = "EDGE_LABELING_GENERIC";
122 private static final String EDGE_LABEL_MODEL = "EDGE_LABEL_MODEL";
123 private static final String EDGE_LABEL_MODEL_FREE = "EDGE_LABEL_MODEL_FREE";
124 private static final String EDGE_LABEL_MODEL_BEST = "EDGE_LABEL_MODEL_BEST";
125 private static final String EDGE_LABEL_MODEL_AS_IS = "EDGE_LABEL_MODEL_AS_IS";
126 private static final String EDGE_LABEL_MODEL_SIDE_SLIDER = "EDGE_LABEL_MODEL_SIDE_SLIDER";
127 private static final String EDGE_LABEL_MODEL_CENTER_SLIDER = "EDGE_LABEL_MODEL_CENTER_SLIDER";
128
129 private static final String GROUPING = "GROUPING";
130 private static final String SWIMLANES = "SWIMLANES";
131 private static final String TREAT_ROOT_GROUPS_AS_SWIMLANES = "TREAT_ROOT_GROUPS_AS_SWIMLANES";
132 private static final String USE_ORDER_FROM_SKETCH = "USE_ORDER_FROM_SKETCH";
133 private static final String SWIMLANE_SPACING = "SWIMLANE_SPACING";
134 private static final String GROUP_LAYERING_STRATEGY = "GROUP_LAYERING_STRATEGY";
135 private static final String GLOBAL_LAYERING = "GLOBAL_LAYERING";
136 private static final String RECURSIVE_LAYERING = "RECURSIVE_LAYERING";
137 private static final String GROUP_ALIGNMENT = "GROUP_ALIGNMENT";
138 private static final String GROUP_ALIGN_TOP = "GROUP_ALIGN_TOP";
139 private static final String GROUP_ALIGN_CENTER = "GROUP_ALIGN_CENTER";
140 private static final String GROUP_ALIGN_BOTTOM = "GROUP_ALIGN_BOTTOM";
141
142 private static final String GROUP_ENABLE_COMPACTION = "GROUP_ENABLE_COMPACTION";
143 private static final String GROUP_HORIZONTAL_COMPACTION = "GROUP_HORIZONTAL_COMPACTION";
144 private static final String GROUP_HORIZONTAL_COMPACTION_NONE = "GROUP_HORIZONTAL_COMPACTION_NONE";
145 private static final String GROUP_HORIZONTAL_COMPACTION_MAX = "GROUP_HORIZONTAL_COMPACTION_MAX";
146
147 private static final Object[] edgeRoutingEnum = new Object[]{EDGE_ROUTING_ORTHOGONAL, EDGE_ROUTING_POLYLINE};
148
149 private static final Object[] orientEnum = {TOP_TO_BOTTOM, LEFT_TO_RIGHT, BOTTOM_TO_TOP, RIGHT_TO_LEFT};
150
151 private static final Object[] alignmentEnum = {TOP, CENTER, BOTTOM};
152 private static final Object[] componentAlignmentEnum = {POLICY_COMPACT, POLICY_TOPMOST};
153 private static final String[] rankingPolicies = {HIERARCHICAL_OPTIMAL, HIERARCHICAL_TIGHT_TREE_HEURISTIC, BFS_LAYERS,
154 FROM_SKETCH, HIERARCHICAL_TOPMOST};
155
156 private static final String[] edgeLabeling = {EDGE_LABELING_NONE, EDGE_LABELING_GENERIC, EDGE_LABELING_HIERARCHIC};
157
158 private static final String[] edgeLabelModel = {
159 EDGE_LABEL_MODEL_BEST,
160 EDGE_LABEL_MODEL_AS_IS,
161 EDGE_LABEL_MODEL_CENTER_SLIDER,
162 EDGE_LABEL_MODEL_SIDE_SLIDER,
163 EDGE_LABEL_MODEL_FREE,
164 };
165
166 private static final Object[] groupStrategyEnum = {GLOBAL_LAYERING, RECURSIVE_LAYERING};
167 private static final Object[] groupAlignmentEnum = {GROUP_ALIGN_TOP, GROUP_ALIGN_CENTER, GROUP_ALIGN_BOTTOM};
168 private static final Object[] groupHorizCompactionEnum = {GROUP_HORIZONTAL_COMPACTION_NONE, GROUP_HORIZONTAL_COMPACTION_MAX};
169
170 public IncrementalHierarchicLayoutModule() {
171 super(INCREMENTAL_HIERARCHIC, "yFiles Layout Team", "A sophisticated hierarchic layout algorithm");
172 setPortIntersectionCalculatorEnabled(true);
173 }
174
175 public OptionHandler createOptionHandler() {
176 OptionHandler op = new OptionHandler(getModuleName());
177
178 OptionGroup og;
179
180 op.useSection(GENERAL);
181
182 og = new OptionGroup();
183 og.setAttribute(OptionGroup.ATTRIBUTE_TITLE, INTERACTION);
184
185 og.addItem(op.addBool(SELECTED_ELEMENTS_INCREMENTALLY, false));
186 OptionItem useDrawingItem = og.addItem(op.addBool(USE_DRAWING_AS_SKETCH, false));
187
188 op.addEnum(ORIENTATION, orientEnum, 0);
189
190 op.addBool(LAYOUT_COMPONENTS_SEPARATELY, false);
191 op.addBool(SYMMETRIC_PLACEMENT, true);
192 op.addInt(MAXIMAL_DURATION, 5);
193
194 og = new OptionGroup();
195 og.setAttribute(OptionGroup.ATTRIBUTE_TITLE, MINIMUM_DISTANCES);
196 og.addItem(op.addDouble(NODE_TO_NODE_DISTANCE, 30.0d));
197 og.addItem(op.addDouble(NODE_TO_EDGE_DISTANCE, 15.0d));
198 og.addItem(op.addDouble(EDGE_TO_EDGE_DISTANCE, 15.0d));
199 og.addItem(op.addDouble(MINIMUM_LAYER_DISTANCE, 10.0d));
200
201 op.useSection(EDGE_SETTINGS);
202
203 EnumOptionItem eoi = op.addEnum(EDGE_ROUTING, edgeRoutingEnum, 0);
204 eoi.setAttribute(DefaultEditorFactory.ATTRIBUTE_ENUM_STYLE,
205 DefaultEditorFactory.STYLE_RADIO_BUTTONS);
206 eoi.setAttribute(DefaultEditorFactory.ATTRIBUTE_ENUM_ALIGNMENT,
207 DefaultEditorFactory.ALIGNMENT_VERTICAL);
208
209 op.addBool(BACKLOOP_ROUTING, false);
210 op.addBool(AUTOMATIC_EDGE_GROUPING_ENABLED, false);
211 op.addDouble(MINIMUM_FIRST_SEGMENT_LENGTH, 10.0d);
212 op.addDouble(MINIMUM_LAST_SEGMENT_LENGTH, 15.0d);
213 op.addDouble(MINIMUM_EDGE_LENGTH, 20.0d);
214 op.addDouble(MINIMUM_EDGE_DISTANCE, 15.0d);
215
216 ConstraintManager cm = new ConstraintManager(op);
217 cm.setEnabledOnValueEquals(eoi, EDGE_ROUTING_POLYLINE,
218 op.addDouble(MINIMUM_SLOPE, 0.25d, 0.0d, 5.0d, 2));
219
220 op.addBool(PC_OPTIMIZATION_ENABLED, false);
221
222 op.useSection(RANKS);
223 op.addEnum(RANKING_POLICY, rankingPolicies, 0);
224 op.addEnum(LAYER_ALIGNMENT, alignmentEnum, 1);
225 op.addEnum(COMPONENT_ARRANGEMENT_POLICY, componentAlignmentEnum, 1);
226
227 og = new OptionGroup();
228 og.setAttribute(OptionGroup.ATTRIBUTE_TITLE, FROM_SKETCH_PROPERTIES);
229 og.addItem(op.addDouble(SCALE, 1.0d, 0.0d, 5.0d, 1));
230 og.addItem(op.addDouble(HALO, 0.0d));
231 og.addItem(op.addDouble(MINIMUM_SIZE, 0.0d));
232 op.getItem(RANKS, MINIMUM_SIZE)
233 .setAttribute(DoubleOptionItem.ATTRIBUTE_MIN_VALUE, new Double(0.0));
234 og.addItem(op.addDouble(MAXIMUM_SIZE, 1000.0d));
235 op.getItem(RANKS, MAXIMUM_SIZE)
236 .setAttribute(DoubleOptionItem.ATTRIBUTE_MIN_VALUE, new Double(0.0));
237
238 Condition c =
239 cm.createConditionValueEquals(USE_DRAWING_AS_SKETCH, Boolean.FALSE).and(
240 cm.createConditionValueEquals(SELECTED_ELEMENTS_INCREMENTALLY, Boolean.FALSE));
241 cm.setEnabledOnCondition(c, op.getItem(RANKING_POLICY));
242
243 c = c.inverse().or(cm.createConditionValueEquals(RANKING_POLICY, FROM_SKETCH));
244 cm.setEnabledOnCondition(c, og);
245
246 op.useSection(LABELING);
247 og = new OptionGroup();
248 og.setAttribute(OptionGroup.ATTRIBUTE_TITLE, NODE_PROPERTIES);
249 og.addItem(op.addBool(CONSIDER_NODE_LABELS, true));
250 og = new OptionGroup();
251 og.setAttribute(OptionGroup.ATTRIBUTE_TITLE, EDGE_PROPERTIES);
252 og.addItem(op.addEnum(EDGE_LABELING, edgeLabeling, 0));
253 cm.setEnabledOnValueEquals(op.getItem(EDGE_LABELING), EDGE_LABELING_NONE,
254 og.addItem(op.addEnum(EDGE_LABEL_MODEL, edgeLabelModel, 0)), true);
255
256 op.useSection(GROUPING);
257 OptionItem groupLayeringItem = op.addEnum(GROUP_LAYERING_STRATEGY, groupStrategyEnum, 0);
258 OptionItem layerCompactionItem = op.addBool(GROUP_ENABLE_COMPACTION, true);
259 OptionItem groupAlignementItem = op.addEnum(GROUP_ALIGNMENT, groupAlignmentEnum, 0);
260 cm.setEnabledOnValueEquals(useDrawingItem, Boolean.FALSE, groupLayeringItem);
261 cm.setEnabledOnValueEquals(groupLayeringItem, RECURSIVE_LAYERING, layerCompactionItem);
262 cm.setEnabledOnValueEquals(groupLayeringItem, RECURSIVE_LAYERING, groupAlignementItem);
263 cm.setEnabledOnCondition(cm.createConditionValueEquals(groupLayeringItem, RECURSIVE_LAYERING).and(
264 cm.createConditionValueEquals(layerCompactionItem, Boolean.TRUE).inverse()), groupAlignementItem);
265
266 cm.setEnabledOnCondition(cm.createConditionValueEquals(groupLayeringItem, RECURSIVE_LAYERING).and(
267 cm.createConditionValueEquals(useDrawingItem, Boolean.FALSE)), layerCompactionItem);
268 op.addEnum(GROUP_HORIZONTAL_COMPACTION, groupHorizCompactionEnum, 1);
269
270 op.useSection(SWIMLANES);
271 final OptionItem swimlaneOption = op.addBool(TREAT_ROOT_GROUPS_AS_SWIMLANES, false);
272 final OptionItem fromSketchOption = op.addBool(USE_ORDER_FROM_SKETCH, false);
273 final OptionItem spacingOption = op.addDouble(SWIMLANE_SPACING, 0.0d);
274 spacingOption.setAttribute(DoubleOptionItem.ATTRIBUTE_MIN_VALUE, new Double(0.0));
275 cm.setEnabledOnValueEquals(swimlaneOption, Boolean.TRUE, fromSketchOption);
276 cm.setEnabledOnValueEquals(swimlaneOption, Boolean.TRUE, spacingOption);
277 return op;
278 }
279
280 public void mainrun() {
281 CanonicMultiStageLayouter layouter = null;
282 Graph2D graph = getGraph2D();
283
284 OptionHandler op = getOptionHandler();
285
286 final IncrementalHierarchicLayouter ihl = new IncrementalHierarchicLayouter();
287 layouter = ihl;
288
289 DataMap incrementalElements = null;
291 boolean fromSketch = op.getBool(USE_DRAWING_AS_SKETCH);
292 boolean incrementalLayout = op.getBool(SELECTED_ELEMENTS_INCREMENTALLY);
293 boolean selectedElements = !Selections.isEdgeSelectionEmpty(graph) || !Selections.isNodeSelectionEmpty(graph);
294
295 if (incrementalLayout && selectedElements) {
296 incrementalElements = Maps.createHashedDataMap();
298 ihl.setLayoutMode(IncrementalHierarchicLayouter.LAYOUT_MODE_INCREMENTAL);
300 final IncrementalHintsFactory ihf = ihl.createIncrementalHintsFactory();
301
302 for (NodeCursor nc = graph.selectedNodes(); nc.ok(); nc.next()) {
303 incrementalElements.set(nc.node(), ihf.createLayerIncrementallyHint(nc.node()));
304 }
305
306 for (EdgeCursor ec = graph.selectedEdges(); ec.ok(); ec.next()) {
307 incrementalElements.set(ec.edge(), ihf.createSequenceIncrementallyHint(ec.edge()));
308 }
309 graph.addDataProvider(IncrementalHierarchicLayouter.INCREMENTAL_HINTS_DPKEY, incrementalElements);
310 } else if (fromSketch) {
311 ihl.setLayoutMode(IncrementalHierarchicLayouter.LAYOUT_MODE_INCREMENTAL);
312 } else {
313 ihl.setLayoutMode(IncrementalHierarchicLayouter.LAYOUT_MODE_FROM_SCRATCH);
314 }
315
316 ((SimplexNodePlacer) ihl.getNodePlacer()).setBaryCenterModeEnabled(op.getBool(SYMMETRIC_PLACEMENT));
318
319 if (GROUP_HORIZONTAL_COMPACTION_NONE.equals(op.getString(GROUP_HORIZONTAL_COMPACTION))) {
320 ((SimplexNodePlacer) ihl.getNodePlacer()).setGroupCompactionStrategy(SimplexNodePlacer.GROUP_COMPACTION_NONE);
321 } else if (GROUP_HORIZONTAL_COMPACTION_MAX.equals(op.getString(GROUP_HORIZONTAL_COMPACTION))) {
322 ((SimplexNodePlacer) ihl.getNodePlacer()).setGroupCompactionStrategy(SimplexNodePlacer.GROUP_COMPACTION_MAX);
323 }
324
325
326 ihl.setComponentLayouterEnabled(op.getBool(LAYOUT_COMPONENTS_SEPARATELY));
327
328 ihl.setMinimumLayerDistance(op.getDouble(MINIMUM_LAYER_DISTANCE));
329 ihl.setNodeToEdgeDistance(op.getDouble(NODE_TO_EDGE_DISTANCE));
330 ihl.setNodeToNodeDistance(op.getDouble(NODE_TO_NODE_DISTANCE));
331 ihl.setEdgeToEdgeDistance(op.getDouble(EDGE_TO_EDGE_DISTANCE));
332 ihl.setAutomaticEdgeGroupingEnabled(op.getBool(AUTOMATIC_EDGE_GROUPING_ENABLED));
333
334 final NodeLayoutDescriptor nld = ihl.getNodeLayoutDescriptor();
335 final EdgeLayoutDescriptor eld = ihl.getEdgeLayoutDescriptor();
336
337 eld.setOrthogonallyRouted(op.getEnum(EDGE_ROUTING) == 0);
338 eld.setMinimumFirstSegmentLength(op.getDouble(MINIMUM_FIRST_SEGMENT_LENGTH));
339 eld.setMinimumLastSegmentLength(op.getDouble(MINIMUM_LAST_SEGMENT_LENGTH));
340
341 eld.setMinimumDistance(op.getDouble(MINIMUM_EDGE_DISTANCE));
342 eld.setMinimumLength(op.getDouble(MINIMUM_EDGE_LENGTH));
343
344 eld.setMinimumSlope(op.getDouble(MINIMUM_SLOPE));
345
346 eld.setSourcePortOptimizationEnabled(op.getBool(PC_OPTIMIZATION_ENABLED));
347 eld.setTargetPortOptimizationEnabled(op.getBool(PC_OPTIMIZATION_ENABLED));
348
349 nld.setMinimumDistance(Math.min(ihl.getNodeToNodeDistance(), ihl.getNodeToEdgeDistance()));
350 nld.setMinimumLayerHeight(0);
351
352 if (op.get(LAYER_ALIGNMENT).equals(TOP)) {
353 nld.setLayerAlignment(0.0);
354 } else if (op.get(LAYER_ALIGNMENT).equals(CENTER)) {
355 nld.setLayerAlignment(0.5);
356 } else if (op.get(LAYER_ALIGNMENT).equals(BOTTOM)) {
357 nld.setLayerAlignment(1.0);
358 }
359
360 final OrientationLayouter ol = (OrientationLayouter) ihl.getOrientationLayouter();
361 if (op.get(ORIENTATION).equals(TOP_TO_BOTTOM)) {
362 ol.setOrientation(OrientationLayouter.TOP_TO_BOTTOM);
363 } else if (op.get(ORIENTATION).equals(LEFT_TO_RIGHT)) {
364 ol.setOrientation(OrientationLayouter.LEFT_TO_RIGHT);
365 } else if (op.get(ORIENTATION).equals(BOTTOM_TO_TOP)) {
366 ol.setOrientation(OrientationLayouter.BOTTOM_TO_TOP);
367 } else if (op.get(ORIENTATION).equals(RIGHT_TO_LEFT)) {
368 ol.setOrientation(OrientationLayouter.RIGHT_TO_LEFT);
369 }
370
371 final String el = op.getString(EDGE_LABELING);
372 if (!el.equals(EDGE_LABELING_NONE)) {
373 setupEdgeLabelModel(el, op.getString(EDGE_LABEL_MODEL));
374 if (el.equals(EDGE_LABELING_GENERIC)) {
375 GreedyMISLabeling la = new GreedyMISLabeling();
376 la.setPlaceNodeLabels(false);
377 la.setPlaceEdgeLabels(true);
378 la.setProfitModel(new LabelRanking());
379 ihl.setLabelLayouter(la);
380 ihl.setLabelLayouterEnabled(true);
381 } else if (el.equals(EDGE_LABELING_HIERARCHIC)) {
382 ihl.setIntegratedEdgeLabelingEnabled(true);
383 }
384 } else {
385 ihl.setIntegratedEdgeLabelingEnabled(false);
386 }
387
388 if (op.getBool(CONSIDER_NODE_LABELS)) {
389 ihl.setConsiderNodeLabelsEnabled(true);
390 ihl.getNodeLayoutDescriptor().setNodeLabelMode(NodeLayoutDescriptor.NODE_LABEL_MODE_CONSIDER_FOR_DRAWING);
391 } else {
392 ihl.setConsiderNodeLabelsEnabled(false);
393 }
394
395
396 final String rp = op.getString(RANKING_POLICY);
397
398 if (rp.equals(FROM_SKETCH)) {
399 ihl.setFromScratchLayeringStrategy(IncrementalHierarchicLayouter.LAYERING_STRATEGY_FROM_SKETCH);
400 } else if (rp.equals(HIERARCHICAL_OPTIMAL)) {
401 ihl.setFromScratchLayeringStrategy(IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_OPTIMAL);
402 } else if (rp.equals(HIERARCHICAL_TIGHT_TREE_HEURISTIC)) {
403 ihl.setFromScratchLayeringStrategy(IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_TIGHT_TREE);
404 } else if (rp.equals(HIERARCHICAL_TOPMOST)) {
405 ihl.setFromScratchLayeringStrategy(IncrementalHierarchicLayouter.LAYERING_STRATEGY_HIERARCHICAL_TOPMOST);
406 } else if (rp.equals(BFS_LAYERS)) {
407 ihl.setFromScratchLayeringStrategy(IncrementalHierarchicLayouter.LAYERING_STRATEGY_BFS);
408 getGraph2D().addDataProvider(BFSLayerer.CORE_NODES, Selections.createSelectionNodeMap(getGraph2D()));
409 }
410
411 if (op.getString(COMPONENT_ARRANGEMENT_POLICY).equals(POLICY_COMPACT)) {
412 ihl.setComponentArrangementPolicy(IncrementalHierarchicLayouter.COMPONENT_ARRANGEMENT_COMPACT);
413 } else {
414 ihl.setComponentArrangementPolicy(IncrementalHierarchicLayouter.COMPONENT_ARRANGEMENT_TOPMOST);
415 }
416
417 Object layerer = (ihl.getLayoutMode() == IncrementalHierarchicLayouter.LAYOUT_MODE_FROM_SCRATCH) ?
419 ihl.getFromScratchLayerer() : ihl.getFixedElementsLayerer();
420
421 if (layerer instanceof OldLayererWrapper) {
422 layerer = ((OldLayererWrapper) layerer).getOldLayerer();
423 }
424 if (layerer instanceof AsIsLayerer) {
425 AsIsLayerer ail = (AsIsLayerer) layerer;
426 ail.setNodeHalo(op.getDouble(HALO));
427 ail.setNodeScalingFactor(op.getDouble(SCALE));
428 ail.setMinimumNodeSize(op.getDouble(MINIMUM_SIZE));
429 ail.setMaximumNodeSize(op.getDouble(MAXIMUM_SIZE));
430 }
431
432 if (!fromSketch && op.getString(GROUP_LAYERING_STRATEGY).equals(RECURSIVE_LAYERING)) {
433 byte alignmentPolicy = IncrementalHierarchicLayouter.POLICY_ALIGN_GROUPS_TOP;
434 if (op.getString(GROUP_ALIGNMENT).equals(GROUP_ALIGN_CENTER)) {
435 alignmentPolicy = IncrementalHierarchicLayouter.POLICY_ALIGN_GROUPS_CENTER;
436 } else if (op.getString(GROUP_ALIGNMENT).equals(GROUP_ALIGN_BOTTOM)) {
437 alignmentPolicy = IncrementalHierarchicLayouter.POLICY_ALIGN_GROUPS_BOTTOM;
438 }
439 ihl.setGroupCompactionEnabled(op.getBool(GROUP_ENABLE_COMPACTION));
440 ihl.setGroupAlignmentPolicy(alignmentPolicy);
441 ihl.setRecursiveGroupLayeringEnabled(true);
442 } else {
443 ihl.setRecursiveGroupLayeringEnabled(false);
444 }
445
446 if (op.getBool(SWIMLANES, TREAT_ROOT_GROUPS_AS_SWIMLANES)){
447 final TopLevelGroupToSwimlaneStage stage = new TopLevelGroupToSwimlaneStage();
448 stage.setFromSketchSwimlaneOrderingEnabled(op.getBool(SWIMLANES, USE_ORDER_FROM_SKETCH));
449 stage.setSpacing(op.getDouble(SWIMLANES, SWIMLANE_SPACING));
450 ihl.appendStage(stage);
451 }
452
453 ihl.setBackloopRoutingEnabled(op.getBool(BACKLOOP_ROUTING));
454 ihl.setMaximalDuration(op.getInt(MAXIMAL_DURATION) * 1000);
455
456 try {
457 launchLayouter(layouter);
459 } finally {
460 if (incrementalElements != null) {
462 graph.removeDataProvider(IncrementalHierarchicLayouter.INCREMENTAL_HINTS_DPKEY);
463 incrementalElements = null;
464 }
465
466 }
467 }
468
469 void setupEdgeLabelModel(String edgeLabeling, String edgeLabelModel) {
470 if (edgeLabeling.equals(EDGE_LABELING_NONE) || edgeLabelModel.equals(EDGE_LABEL_MODEL_AS_IS)) {
471 return; }
473
474 if (edgeLabelModel.equals(EDGE_LABEL_MODEL_BEST)) {
475 if (edgeLabeling.equals(EDGE_LABELING_GENERIC)) {
476 edgeLabelModel = EDGE_LABEL_MODEL_SIDE_SLIDER;
477 } else if (edgeLabeling.equals(EDGE_LABELING_HIERARCHIC)) {
478 edgeLabelModel = EDGE_LABEL_MODEL_FREE;
479 }
480 }
481
482 byte model = EdgeLabel.SIDE_SLIDER;
483 int preferredSide = LabelLayoutConstants.PLACE_RIGHT_OF_EDGE;
484 if (edgeLabelModel.equals(EDGE_LABEL_MODEL_CENTER_SLIDER)) {
485 model = EdgeLabel.CENTER_SLIDER;
486 preferredSide = LabelLayoutConstants.PLACE_ON_EDGE;
487 } else if (edgeLabelModel.equals(EDGE_LABEL_MODEL_FREE)) {
488 model = EdgeLabel.FREE;
489 preferredSide = LabelLayoutConstants.PLACE_ON_EDGE;
490 }
491
492 Graph2D graph = getGraph2D();
493 for (EdgeCursor ec = graph.edges(); ec.ok(); ec.next()) {
494 Edge e = ec.edge();
495 EdgeRealizer er = graph.getRealizer(e);
496 for (int i = 0; i < er.labelCount(); i++) {
497 EdgeLabel el = er.getLabel(i);
498 el.setModel(model);
499 if (!edgeLabelModel.equals(EDGE_LABEL_MODEL_FREE)) {
500 int prefAlongEdge = el.getPreferredPlacement() & LabelLayoutConstants.PLACEMENT_ALONG_EDGE_MASK;
501 el.setPreferredPlacement((byte) (preferredSide | prefAlongEdge));
502 }
503 }
504 }
505 }
506 }
507