1
28 package demo.layout.module;
29
30 import y.module.LayoutModule;
31 import y.module.YModule;
32
33 import y.layout.LayoutOrientation;
34 import y.layout.router.OrganicEdgeRouter;
35 import y.layout.router.StraightLineEdgeRouter;
36 import y.layout.router.polyline.EdgeRouter;
37 import y.layout.seriesparallel.DefaultPortAssignment;
38 import y.layout.seriesparallel.EdgeLayoutDescriptor;
39 import y.layout.seriesparallel.SeriesParallelLayouter;
40 import y.option.ConstraintManager;
41 import y.option.OptionGroup;
42 import y.option.OptionHandler;
43 import y.option.OptionItem;
44
45
49 public class SeriesParallelLayoutModule extends LayoutModule {
50
51 protected static final String MODULE_SERIES_PARALLEL = "SERIES_PARALLEL";
53
54 protected static final String SECTION_GENERAL = "GENERAL";
56 protected static final String ITEM_ORIENTATION = "ORIENTATION";
58 protected static final String VALUE_RIGHT_TO_LEFT = "RIGHT_TO_LEFT";
59 protected static final String VALUE_BOTTOM_TO_TOP = "BOTTOM_TO_TOP";
60 protected static final String VALUE_LEFT_TO_RIGHT = "LEFT_TO_RIGHT";
61 protected static final String VALUE_TOP_TO_BOTTOM = "TOP_TO_BOTTOM";
62 protected static final String ITEM_VERTICAL_ALIGNMENT = "VERTICAL_ALIGNMENT";
63 protected static final String VALUE_ALIGNMENT_TOP = "ALIGNMENT_TOP";
64 protected static final String VALUE_ALIGNMENT_CENTER = "ALIGNMENT_CENTER";
65 protected static final String VALUE_ALIGNMENT_BOTTOM = "ALIGNMENT_BOTTOM";
66 protected static final String ITEM_FROM_SKETCH_MODE = "FROM_SKETCH_MODE";
67 protected static final String ITEM_ROUTING_STYLE_FOR_NON_SERIES_PARALLEL_EDGES = "ROUTING_STYLE_FOR_NON_SERIES_PARALLEL_EDGES";
68 protected static final String VALUE_ROUTE_ORGANIC = "ROUTE_ORGANIC";
69 protected static final String VALUE_ROUTE_ORTHOGONAL = "ROUTE_ORTHOGONAL";
70 protected static final String VALUE_ROUTE_STRAIGHTLINE = "ROUTE_STRAIGHTLINE";
71 protected static final String TITLE_MINIMUM_DISTANCES = "MINIMUM_DISTANCES";
72 protected static final String ITEM_NODE_TO_NODE_DISTANCE = "NODE_TO_NODE_DISTANCE";
73 protected static final String ITEM_NODE_TO_EDGE_DISTANCE = "NODE_TO_EDGE_DISTANCE";
74 protected static final String ITEM_EDGE_TO_EDGE_DISTANCE = "EDGE_TO_EDGE_DISTANCE";
75 protected static final String TITLE_LABELING = "LABELING";
76 protected static final String ITEM_CONSIDER_NODE_LABELS = "CONSIDER_NODE_LABELS";
77 protected static final String ITEM_INTEGRATED_EDGE_LABELING = "INTEGRATED_EDGE_LABELING";
78
79
80 protected static final String SECTION_EDGE_SETTINGS = "EDGE_SETTINGS";
82 protected static final String ITEM_PORT_STYLE = "PORT_STYLE";
84 protected static final String VALUE_CENTER_PORTS = "CENTER_PORTS";
85 protected static final String VALUE_DISTRIBUTED_PORTS = "DISTRIBUTED_PORTS";
86 protected static final String ITEM_MINIMUM_FIRST_SEGMENT_LENGTH = "MINIMUM_FIRST_SEGMENT_LENGTH";
87 protected static final String ITEM_MINIMUM_LAST_SEGMENT_LENGTH = "MINIMUM_LAST_SEGMENT_LENGTH";
88 protected static final String ITEM_MINIMUM_EDGE_LENGTH = "MINIMUM_EDGE_LENGTH";
89 protected static final String ITEM_ROUTING_STYLE = "ROUTING_STYLE";
90 protected static final String VALUE_ROUTING_STYLE_ORTHOGONAL = "ROUTING_STYLE_ORTHOGONAL";
91 protected static final String VALUE_ROUTING_STYLE_OCTILINEAR = "ROUTING_STYLE_OCTILINEAR";
92 protected static final String VALUE_ROUTING_STYLE_POLYLINE = "ROUTING_STYLE_POLYLINE";
93 protected static final String ITEM_PREFERRED_OCTILINEAR_SEGMENT_LENGTH = "PREFERRED_OCTILINEAR_SEGMENT_LENGTH";
94 protected static final String ITEM_POLYLINE_DISTANCE = "POLYLINE_DISTANCE";
95 protected static final String ITEM_MINIMUM_SLOPE = "MINIMUM_SLOPE";
96 protected static final String ITEM_ROUTE_IN_FLOW = "ROUTE_IN_FLOW";
97
98
101 public SeriesParallelLayoutModule() {
102 super(MODULE_SERIES_PARALLEL);
103 }
104
105
108 protected OptionHandler createOptionHandler() {
109 final OptionHandler options = new OptionHandler(getModuleName());
110
111 final SeriesParallelLayouter defaults = new SeriesParallelLayouter();
112 final EdgeLayoutDescriptor eld = defaults.getDefaultEdgeLayoutDescriptor();
113
114 options.useSection(SECTION_GENERAL);
116 options.addEnum(ITEM_ORIENTATION, new Object[]{
118 VALUE_TOP_TO_BOTTOM,
119 VALUE_LEFT_TO_RIGHT,
120 VALUE_BOTTOM_TO_TOP,
121 VALUE_RIGHT_TO_LEFT,
122 }, 0);
123 options.addEnum(ITEM_VERTICAL_ALIGNMENT, new String[]{
124 VALUE_ALIGNMENT_TOP,
125 VALUE_ALIGNMENT_CENTER,
126 VALUE_ALIGNMENT_BOTTOM,
127 }, 1);
128 options.addBool(ITEM_FROM_SKETCH_MODE, defaults.isFromSketchModeEnabled());
129 options.addEnum(ITEM_ROUTING_STYLE_FOR_NON_SERIES_PARALLEL_EDGES, new String[]{
130 VALUE_ROUTE_ORGANIC,
131 VALUE_ROUTE_ORTHOGONAL,
132 VALUE_ROUTE_STRAIGHTLINE
133 }, 0);
134
135 final OptionGroup minDistGroup = new OptionGroup();
137 minDistGroup.setAttribute(OptionGroup.ATTRIBUTE_TITLE, TITLE_MINIMUM_DISTANCES);
138 minDistGroup.addItem(options.addDouble(ITEM_NODE_TO_NODE_DISTANCE, 30.0d));
140 minDistGroup.addItem(options.addDouble(ITEM_NODE_TO_EDGE_DISTANCE, 15.0d));
141 minDistGroup.addItem(options.addDouble(ITEM_EDGE_TO_EDGE_DISTANCE, 15.0d));
142
143 final OptionGroup labelingGroup = new OptionGroup();
145 labelingGroup.setAttribute(OptionGroup.ATTRIBUTE_TITLE, TITLE_LABELING);
147 labelingGroup.addItem(options.addBool(ITEM_CONSIDER_NODE_LABELS, true));
148 labelingGroup.addItem(options.addBool(ITEM_INTEGRATED_EDGE_LABELING, true));
149
150 options.useSection(SECTION_EDGE_SETTINGS);
152 options.addEnum(ITEM_PORT_STYLE, new String[]{
154 VALUE_CENTER_PORTS,
155 VALUE_DISTRIBUTED_PORTS,
156 }, 0);
157 options.addDouble(ITEM_MINIMUM_FIRST_SEGMENT_LENGTH, eld.getMinimumFirstSegmentLength());
158 options.addDouble(ITEM_MINIMUM_LAST_SEGMENT_LENGTH, eld.getMinimumLastSegmentLength());
159 options.addDouble(ITEM_MINIMUM_EDGE_LENGTH, 20.0d);
160 final OptionItem itemRoutingStyle = options.addEnum(ITEM_ROUTING_STYLE, new String[]{
161 VALUE_ROUTING_STYLE_ORTHOGONAL,
162 VALUE_ROUTING_STYLE_OCTILINEAR,
163 VALUE_ROUTING_STYLE_POLYLINE,
164 }, 0);
165 final OptionItem itemSegmentLength = options.addDouble(ITEM_PREFERRED_OCTILINEAR_SEGMENT_LENGTH, defaults.getPreferredOctilinearSegmentLength());
166 final OptionItem itemDistance = options.addDouble(ITEM_POLYLINE_DISTANCE, defaults.getMinimumPolylineSegmentLength());
167 final OptionItem itemMinimumSlope = options.addDouble(ITEM_MINIMUM_SLOPE, defaults.getMinimumSlope(), 0, 5);
168 options.addBool(ITEM_ROUTE_IN_FLOW, true);
169 final ConstraintManager optionConstraints = new ConstraintManager(options);
171 optionConstraints.setEnabledOnValueEquals(itemRoutingStyle, VALUE_ROUTING_STYLE_OCTILINEAR, itemSegmentLength);
172 optionConstraints.setEnabledOnValueEquals(itemRoutingStyle, VALUE_ROUTING_STYLE_POLYLINE, itemDistance);
173 optionConstraints.setEnabledOnValueEquals(itemRoutingStyle, VALUE_ROUTING_STYLE_POLYLINE, itemMinimumSlope);
174
175 return options;
176 }
177
178
181 protected void mainrun() {
182 final SeriesParallelLayouter series = new SeriesParallelLayouter();
183
184 final OptionHandler options = getOptionHandler();
185
186 configure(series, options);
187
188 launchLayouter(series);
189 }
190
191
196 protected void configure( final SeriesParallelLayouter series, final OptionHandler options ) {
197 series.setGeneralGraphHandlingEnabled(true);
198
199 final Object orientation = options.get(ITEM_ORIENTATION);
200 if (VALUE_LEFT_TO_RIGHT.equals(orientation)) {
201 series.setLayoutOrientation(LayoutOrientation.LEFT_TO_RIGHT);
202 } else if (VALUE_BOTTOM_TO_TOP.equals(orientation)) {
203 series.setLayoutOrientation(LayoutOrientation.BOTTOM_TO_TOP);
204 } else if (VALUE_RIGHT_TO_LEFT.equals(orientation)) {
205 series.setLayoutOrientation(LayoutOrientation.RIGHT_TO_LEFT);
206 } else {
207 series.setLayoutOrientation(LayoutOrientation.TOP_TO_BOTTOM);
208 }
209
210 final String verticalAlignment = options.getString(ITEM_VERTICAL_ALIGNMENT);
211 if (VALUE_ALIGNMENT_TOP.equals(verticalAlignment)) {
212 series.setVerticalAlignment(0);
213 } else if (VALUE_ALIGNMENT_CENTER.equals(verticalAlignment)) {
214 series.setVerticalAlignment(0.5);
215 } else { series.setVerticalAlignment(1);
217 }
218
219 final String routingStyle = options.getString(ITEM_ROUTING_STYLE);
220 if (VALUE_ROUTING_STYLE_ORTHOGONAL.equals(routingStyle)) {
221 series.setRoutingStyle(SeriesParallelLayouter.ROUTING_STYLE_ORTHOGONAL);
222 } else if (VALUE_ROUTING_STYLE_OCTILINEAR.equals(routingStyle)) {
223 series.setRoutingStyle(SeriesParallelLayouter.ROUTING_STYLE_OCTILINEAR);
224 series.setPreferredOctilinearSegmentLength(options.getDouble(ITEM_PREFERRED_OCTILINEAR_SEGMENT_LENGTH));
225 } else { series.setRoutingStyle(SeriesParallelLayouter.ROUTING_STYLE_POLYLINE);
227 series.setMinimumPolylineSegmentLength(options.getDouble(ITEM_POLYLINE_DISTANCE));
228 series.setMinimumSlope(options.getDouble(ITEM_MINIMUM_SLOPE));
229 }
230
231 final DefaultPortAssignment defaultPortAssignment = (DefaultPortAssignment) series.getDefaultPortAssignment();
232 if (options.getBool(ITEM_ROUTE_IN_FLOW)) {
233 defaultPortAssignment.setForkStyle(DefaultPortAssignment.FORK_STYLE_OUTSIDE_NODE);
234 } else {
235 defaultPortAssignment.setForkStyle(DefaultPortAssignment.FORK_STYLE_AT_NODE);
236 }
237
238 series.setFromSketchModeEnabled(options.getBool(ITEM_FROM_SKETCH_MODE));
239
240 final Object nonSeriesParallelRoutingStyle = options.get(ITEM_ROUTING_STYLE_FOR_NON_SERIES_PARALLEL_EDGES);
241 if (VALUE_ROUTE_ORGANIC.equals(nonSeriesParallelRoutingStyle)) {
242 final OrganicEdgeRouter organic = new OrganicEdgeRouter();
243 series.setNonSeriesParallelEdgeRouter(organic);
244 series.setNonSeriesParallelEdgesDpKey(OrganicEdgeRouter.ROUTE_EDGE_DPKEY);
245 } else if (VALUE_ROUTE_ORTHOGONAL.equals(nonSeriesParallelRoutingStyle)) {
246 final EdgeRouter orthogonal = new EdgeRouter();
247 orthogonal.setReroutingEnabled(true);
248 orthogonal.setSphereOfAction(EdgeRouter.ROUTE_SELECTED_EDGES);
249 series.setNonSeriesParallelEdgeRouter(orthogonal);
250 series.setNonSeriesParallelEdgesDpKey(orthogonal.getSelectedEdgesDpKey());
251 } else if (VALUE_ROUTE_STRAIGHTLINE.equals(nonSeriesParallelRoutingStyle)) {
252 final StraightLineEdgeRouter straightLine = new StraightLineEdgeRouter();
253 straightLine.setSphereOfAction(StraightLineEdgeRouter.ROUTE_SELECTED_EDGES);
254 series.setNonSeriesParallelEdgeRouter(straightLine);
255 series.setNonSeriesParallelEdgesDpKey(straightLine.getSelectedEdgesDpKey());
256 }
257
258 series.setMinimumNodeToNodeDistance(options.getDouble(ITEM_NODE_TO_NODE_DISTANCE));
259 series.setMinimumNodeToEdgeDistance(options.getDouble(ITEM_NODE_TO_EDGE_DISTANCE));
260 series.setMinimumEdgeToEdgeDistance(options.getDouble(ITEM_EDGE_TO_EDGE_DISTANCE));
261
262 final Object portStyle = options.get(ITEM_PORT_STYLE);
263 if (VALUE_CENTER_PORTS.equals(portStyle)) {
264 defaultPortAssignment.setMode(DefaultPortAssignment.PORT_ASSIGNMENT_MODE_CENTER);
265 } else {
266 defaultPortAssignment.setMode(DefaultPortAssignment.PORT_ASSIGNMENT_MODE_DISTRIBUTED);
267 }
268 final EdgeLayoutDescriptor eld = series.getDefaultEdgeLayoutDescriptor();
269 eld.setMinimumFirstSegmentLength(options.getDouble(ITEM_MINIMUM_FIRST_SEGMENT_LENGTH));
270 eld.setMinimumLastSegmentLength(options.getDouble(ITEM_MINIMUM_LAST_SEGMENT_LENGTH));
271 eld.setMinimumLength(options.getDouble(ITEM_MINIMUM_EDGE_LENGTH));
272
273 series.setConsiderNodeLabelsEnabled(options.getBool(ITEM_CONSIDER_NODE_LABELS));
274 series.setIntegratedEdgeLabelingEnabled(options.getBool(ITEM_INTEGRATED_EDGE_LABELING));
275 }
276 }
277