1
14 package demo.layout.module;
15
16 import y.module.LayoutModule;
17 import y.module.YModule;
18
19 import y.option.OptionHandler;
20 import y.layout.partial.PartialLayouter;
21 import y.layout.organic.SmartOrganicLayouter;
22 import y.layout.Layouter;
23 import y.layout.orthogonal.OrthogonalLayouter;
24 import y.layout.circular.CircularLayouter;
25 import y.layout.hierarchic.IncrementalHierarchicLayouter;
26 import y.view.Graph2D;
27 import y.view.Selections;
28
29
36 public class PartialLayoutModule extends LayoutModule {
37 private static final String PARTIAL = "PARTIAL";
38 private static final String GENERAL = "GENERAL";
39 public static final String SUBGRAPH_LAYOUTER = "SUBGRAPH_LAYOUTER";
40 public static final String SUBGRAPH_LAYOUTER_IHL = "SUBGRAPH_LAYOUTER_IHL";
41 public static final String SUBGRAPH_LAYOUTER_ORGANIC = "SUBGRAPH_LAYOUTER_ORGANIC";
42 public static final String SUBGRAPH_LAYOUTER_CIRCULAR = "SUBGRAPH_LAYOUTER_CIRCULAR";
43 public static final String SUBGRAPH_LAYOUTER_ORTHOGONAL = "SUBGRAPH_LAYOUTER_ORTHOGONAL";
44 private static final String SUBGRAPH_LAYOUTER_NO_LAYOUT = "SUBGRAPH_LAYOUTER_NO_LAYOUT";
45 private static final String MIN_NODE_DIST = "MIN_NODE_DIST";
46
47 public static final String SUBGRAPH_POSITION_STRATEGY = "SUBGRAPH_POSITION_STRATEGY";
48 public static final String SUBGRAPH_POSITIONING_STRATEGY_BARYCENTER = "SUBGRAPH_POSITION_STRATEGY_BARYCENTER";
49 public static final String SUBGRAPH_POSITIONING_STRATEGY_FROM_SKETCH = "SUBGRAPH_POSITION_STRATEGY_FROM_SKETCH";
50
51 public static final String ROUTING_TO_SUBGRAPH = "ROUTING_TO_SUBGRAPH";
52 public static final String ROUTING_TO_SUBGRAPH_STRAIGHT_LINE = "ROUTING_TO_SUBGRAPH_STRAIGHT_LINE";
53 public static final String ROUTING_TO_SUBGRAPH_POLYLINE = "ROUTING_TO_SUBGRAPH_POLYLINE";
54 public static final String ROUTING_TO_SUBGRAPH_ORTHOGONALLY = "ROUTING_TO_SUBGRAPH_ORTHOGONALLY";
55 public static final String ROUTING_TO_SUBGRAPH_ORGANIC = "ROUTING_TO_SUBGRAPH_ORGANIC";
56 public static final String ROUTING_TO_SUBGRAPH_AUTO = "ROUTING_TO_SUBGRAPH_AUTO";
57
58 public static final String MODE_COMPONENT_ASSIGNMENT = "MODE_COMPONENT_ASSIGNMENT";
59 public static final String MODE_COMPONENT_CLUSTERING = "MODE_COMPONENT_CLUSTERING";
60 public static final String MODE_COMPONENT_CONNECTED = "MODE_COMPONENT_CONNECTED";
61 public static final String MODE_COMPONENT_CUSTOMIZED = "MODE_COMPONENT_CUSTOMIZED";
62 public static final String MODE_COMPONENT_SINGLE = "MODE_COMPONENT_SINGLE";
63
64 public static final String HIERARCHY_REORGANIZATION = "HIERARCHY_REORGANIZATION";
65
66 public static final String ORIENTATION_MAIN_GRAPH = "ORIENTATION_MAIN_GRAPH";
67 public static final String ORIENTATION_MAIN_GRAPH_NONE = "ORIENTATION_MAIN_GRAPH_NONE";
68 public static final String ORIENTATION_MAIN_GRAPH_AUTO_DETECT = "ORIENTATION_MAIN_GRAPH_AUTO_DETECT";
69 public static final String ORIENTATION_MAIN_GRAPH_TOP_TO_DOWN = "ORIENTATION_MAIN_GRAPH_TOP_TO_DOWN";
70 public static final String ORIENTATION_MAIN_GRAPH_DOWN_TO_TOP = "ORIENTATION_MAIN_GRAPH_DOWN_TO_TOP";
71 public static final String ORIENTATION_MAIN_GRAPH_LEFT_TO_RIGHT = "ORIENTATION_MAIN_GRAPH_LEFT_TO_RIGHT";
72 public static final String ORIENTATION_MAIN_GRAPH_RIGHT_TO_LEFT = "ORIENTATION_MAIN_GRAPH_RIGHT_TO_LEFT";
73
74 public static final String CONSIDER_SNAPLINES = "CONSIDER_SNAPLINES";
75
76 private static final String[] subgraphLayouterEnum = {SUBGRAPH_LAYOUTER_IHL, SUBGRAPH_LAYOUTER_ORGANIC,
77 SUBGRAPH_LAYOUTER_CIRCULAR, SUBGRAPH_LAYOUTER_ORTHOGONAL,
78 SUBGRAPH_LAYOUTER_NO_LAYOUT};
79 private static final String[] subgraphPositionStrategyEnum = {SUBGRAPH_POSITIONING_STRATEGY_BARYCENTER,
80 SUBGRAPH_POSITIONING_STRATEGY_FROM_SKETCH};
81 private static final String[] routerToSubgraphEnum = {ROUTING_TO_SUBGRAPH_AUTO, ROUTING_TO_SUBGRAPH_STRAIGHT_LINE,
82 ROUTING_TO_SUBGRAPH_POLYLINE, ROUTING_TO_SUBGRAPH_ORTHOGONALLY
83 , ROUTING_TO_SUBGRAPH_ORGANIC};
84 private static final String[] modeComponentAsignmentEnum = {MODE_COMPONENT_CONNECTED,
85 MODE_COMPONENT_SINGLE, MODE_COMPONENT_CUSTOMIZED};
86 private static final String[] orientationMainGraphEnum = {ORIENTATION_MAIN_GRAPH_AUTO_DETECT,
87 ORIENTATION_MAIN_GRAPH_TOP_TO_DOWN, ORIENTATION_MAIN_GRAPH_DOWN_TO_TOP, ORIENTATION_MAIN_GRAPH_LEFT_TO_RIGHT,
88 ORIENTATION_MAIN_GRAPH_RIGHT_TO_LEFT, ORIENTATION_MAIN_GRAPH_NONE};
89
90
91 private static final byte EDGE_ROUTING_ORTHOGONAL = 0;
92 private static final byte EDGE_ROUTING_STRAIGHTLINE = 1;
93 private static final byte EDGE_ROUTING_AUTOMATIC = 2;
94 private static final byte EDGE_ROUTING_ORGANIC = 3;
95 private static final byte EDGE_ROUTING_POLYLINE = 4;
96
97 public PartialLayoutModule() {
98 super(PARTIAL, "yFiles Layout Team", "An algorithm that lays out only a subset of a graph.");
99 }
100
101 public OptionHandler createOptionHandler() {
102 OptionHandler op = new OptionHandler(getModuleName());
103 op.useSection(GENERAL);
104 op.addEnum(ROUTING_TO_SUBGRAPH, routerToSubgraphEnum, 0);
105 op.addEnum(MODE_COMPONENT_ASSIGNMENT, modeComponentAsignmentEnum, 0);
106 op.addEnum(SUBGRAPH_LAYOUTER, subgraphLayouterEnum, 0);
107 op.addEnum(SUBGRAPH_POSITION_STRATEGY, subgraphPositionStrategyEnum, 0);
108 op.addInt(MIN_NODE_DIST, 30, 1, 100);
109 op.addEnum(ORIENTATION_MAIN_GRAPH, orientationMainGraphEnum, 0);
110 op.addBool(CONSIDER_SNAPLINES, true);
111 return op;
112 }
113
114 protected void mainrun() {
115 final Graph2D graph = getGraph2D();
116 if (graph.selectedNodes().size() + graph.selectedEdges().size() == 0) {
117 return; }
119
120 OptionHandler op = getOptionHandler();
121
122 graph.addDataProvider(PartialLayouter.PARTIAL_NODES_DPKEY, Selections.createSelectionDataProvider(graph));
124 graph.addDataProvider(PartialLayouter.PARTIAL_EDGES_DPKEY, Selections.createSelectionDataProvider(graph));
125
126 final PartialLayouter partialLayouter = new PartialLayouter();
128 partialLayouter.setMinimalNodeDistance(op.getInt(MIN_NODE_DIST));
129 partialLayouter.setConsiderNodeAlignment(op.getBool(CONSIDER_SNAPLINES));
130
131 final byte subgraphPositioningStrategy = subgraphPositioningStrategyAsByte(
132 subgraphPositionStrategyEnum[op.getEnum(SUBGRAPH_POSITION_STRATEGY)]);
133 partialLayouter.setPositioningStrategy(subgraphPositioningStrategy);
134
135 final byte componentAssignment = componentAssignmentAsByte(
136 modeComponentAsignmentEnum[op.getEnum(MODE_COMPONENT_ASSIGNMENT)]);
137 partialLayouter.setComponentAssignmentStrategy(componentAssignment);
138
139 final byte mainGraphOrientation = graphOrientationAsByte(
140 orientationMainGraphEnum[op.getEnum(ORIENTATION_MAIN_GRAPH)]);
141 partialLayouter.setLayoutOrientation(mainGraphOrientation);
142
143 final byte routingToSubGraph = routingToSubGraphAsByte(routerToSubgraphEnum[op.getEnum(ROUTING_TO_SUBGRAPH)]);
144 partialLayouter.setEdgeRoutingStrategy((routingToSubGraph == EDGE_ROUTING_POLYLINE) ?
145 EDGE_ROUTING_STRAIGHTLINE : routingToSubGraph);
146
147 final String subgraphLayouterString = subgraphLayouterEnum[op.getEnum(SUBGRAPH_LAYOUTER)];
149 Layouter subgraphLayouter = null;
150 if (PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_SINGLE == componentAssignment) {
151 subgraphLayouter = null;
153 } else if (SUBGRAPH_LAYOUTER_IHL.equals(subgraphLayouterString)) {
154 subgraphLayouter = new IncrementalHierarchicLayouter();
155 ((IncrementalHierarchicLayouter) subgraphLayouter).setIntegratedEdgeLabelingEnabled(true);
156 if (PartialLayouter.EDGE_ROUTING_STRATEGY_ORTHOGONAL == routingToSubGraph) {
157 ((IncrementalHierarchicLayouter) subgraphLayouter).setOrthogonallyRouted(true);
158 } else {
159 ((IncrementalHierarchicLayouter) subgraphLayouter).setOrthogonallyRouted(false);
160 }
161 } else if (SUBGRAPH_LAYOUTER_ORGANIC.equals(subgraphLayouterString)) {
162 subgraphLayouter = new SmartOrganicLayouter();
163 ((SmartOrganicLayouter) subgraphLayouter).setDeterministic(true);
164 } else if (SUBGRAPH_LAYOUTER_CIRCULAR.equals(subgraphLayouterString)) {
165 subgraphLayouter = new CircularLayouter();
166 } else if (SUBGRAPH_LAYOUTER_ORTHOGONAL.equals(subgraphLayouterString)) {
167 subgraphLayouter = new OrthogonalLayouter();
168 } else if (SUBGRAPH_LAYOUTER_NO_LAYOUT.equals(subgraphLayouterString)) {
169 subgraphLayouter = null;
170 }
171 partialLayouter.setCoreLayouter(subgraphLayouter);
172
173 getLayoutExecutor().setConfiguringTableNodeRealizers(true);
174 final boolean horizontalLayout = (mainGraphOrientation == PartialLayouter.ORIENTATION_LEFT_TO_RIGHT)
175 || (mainGraphOrientation == PartialLayouter.ORIENTATION_RIGHT_TO_LEFT);
176 getLayoutExecutor().getTableLayoutConfigurator().setHorizontalLayoutConfiguration(horizontalLayout);
177
178 launchLayouter(partialLayouter);
179 }
180
181
182 private static byte routingToSubGraphAsByte(final String routingToSubGraphString) {
183 if (ROUTING_TO_SUBGRAPH_ORTHOGONALLY.equals(routingToSubGraphString)) {
184 return EDGE_ROUTING_ORTHOGONAL;
185 } else if (ROUTING_TO_SUBGRAPH_STRAIGHT_LINE.equals(routingToSubGraphString)) {
186 return EDGE_ROUTING_STRAIGHTLINE;
187 } else if (ROUTING_TO_SUBGRAPH_AUTO.equals(routingToSubGraphString)) {
188 return EDGE_ROUTING_AUTOMATIC;
189 } else if (ROUTING_TO_SUBGRAPH_ORGANIC.equals(routingToSubGraphString)) {
190 return EDGE_ROUTING_ORGANIC;
191 } else if (ROUTING_TO_SUBGRAPH_POLYLINE.equals(routingToSubGraphString)) {
192 return EDGE_ROUTING_POLYLINE;
193 } else {
194 return PartialLayouter.EDGE_ROUTING_STRATEGY_STRAIGHTLINE;
195 }
196 }
197
198
199 private static byte subgraphPositioningStrategyAsByte(final String subgraphPositioningStrategyString) {
200 if (SUBGRAPH_POSITIONING_STRATEGY_FROM_SKETCH.equals(subgraphPositioningStrategyString)) {
201 return PartialLayouter.SUBGRAPH_POSITIONING_STRATEGY_FROM_SKETCH;
202 } else {
203 return PartialLayouter.SUBGRAPH_POSITIONING_STRATEGY_BARYCENTER;
204 }
205 }
206
207
208 private static byte componentAssignmentAsByte(final String componentAssignmentString) {
209 if (MODE_COMPONENT_SINGLE.equals(componentAssignmentString)) {
210 return PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_SINGLE;
211 } else if (MODE_COMPONENT_CONNECTED.equals(componentAssignmentString)) {
212 return PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_CONNECTED;
213 } else if (MODE_COMPONENT_CLUSTERING.equals(componentAssignmentString)) {
214 return PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_CLUSTERING;
215 } else {
216 return PartialLayouter.COMPONENT_ASSIGNMENT_STRATEGY_CUSTOMIZED;
217 }
218 }
219
220
221 private static byte graphOrientationAsByte(final String graphOrientationString) {
222 if (ORIENTATION_MAIN_GRAPH_AUTO_DETECT.equals(graphOrientationString)) {
223 return PartialLayouter.ORIENTATION_AUTO_DETECTION;
224 } else if (ORIENTATION_MAIN_GRAPH_TOP_TO_DOWN.equals(graphOrientationString)) {
225 return PartialLayouter.ORIENTATION_TOP_TO_BOTTOM;
226 } else if (ORIENTATION_MAIN_GRAPH_DOWN_TO_TOP.equals(graphOrientationString)) {
227 return PartialLayouter.ORIENTATION_BOTTOM_TO_TOP;
228 } else if (ORIENTATION_MAIN_GRAPH_LEFT_TO_RIGHT.equals(graphOrientationString)) {
229 return PartialLayouter.ORIENTATION_LEFT_TO_RIGHT;
230 } else if (ORIENTATION_MAIN_GRAPH_RIGHT_TO_LEFT.equals(graphOrientationString)) {
231 return PartialLayouter.ORIENTATION_RIGHT_TO_LEFT;
232 } else if (ORIENTATION_MAIN_GRAPH_NONE.equals(graphOrientationString)) {
233 return PartialLayouter.ORIENTATION_NONE;
234 } else {
235 return PartialLayouter.ORIENTATION_AUTO_DETECTION;
236 }
237 }
238 }
239