1
14 package demo.layout.module;
15
16 import y.module.LayoutModule;
17 import y.module.YModule;
18
19 import y.layout.circular.CircularLayouter;
20 import y.layout.circular.SingleCycleLayouter;
21 import y.layout.tree.BalloonLayouter;
22 import y.option.OptionHandler;
23 import y.option.ConstraintManager;
24 import y.option.OptionItem;
25 import y.view.Graph2D;
26
27
34 public class CircularLayoutModule extends LayoutModule {
35 private static final String CIRCULAR = "CIRCULAR";
36 private static final String ALLOW_OVERLAPS = "ALLOW_OVERLAPS";
37 private static final String COMPACTNESS_FACTOR = "COMPACTNESS_FACTOR";
38 private static final String MAXIMAL_DEVIATION_ANGLE = "MAXIMAL_DEVIATION_ANGLE";
39 private static final String MINIMAL_EDGE_LENGTH = "MINIMAL_EDGE_LENGTH";
40 private static final String PREFERRED_CHILD_WEDGE = "PREFERRED_CHILD_WEDGE";
41 private static final String TREE = "TREE";
42 private static final String FIXED_RADIUS = "FIXED_RADIUS";
43 private static final String CHOOSE_RADIUS_AUTOMATICALLY = "CHOOSE_RADIUS_AUTOMATICALLY";
44 private static final String MINIMAL_NODE_DISTANCE = "MINIMAL_NODE_DISTANCE";
45 private static final String MINIMAL_TREE_NODE_DISTANCE = "MINIMAL_TREE_NODE_DISTANCE";
46 private static final String CYCLE = "CYCLE";
47 private static final String ACT_ON_SELECTION_ONLY = "ACT_ON_SELECTION_ONLY";
48 private static final String LAYOUT_STYLE = "LAYOUT_STYLE";
49 private static final String GENERAL = "GENERAL";
50 private static final String SINGLE_CYCLE = "SINGLE_CYCLE";
51 private static final String BCC_ISOLATED = "BCC_ISOLATED";
52 private static final String BCC_COMPACT = "BCC_COMPACT";
53 private static final String CIRCULAR_CUSTOM_GROUPS = "CIRCULAR_CUSTOM_GROUPS";
54 private static final String FROM_SKETCH = "FROM_SKETCH";
55 private static final String HANDLE_NODE_LABELS = "HANDLE_NODE_LABELS";
56 private static final String PLACE_CHILDREN_ON_COMMON_RADIUS = "PLACE_CHILDREN_ON_COMMON_RADIUS";
57
58 private final static String[] layoutStyles = {BCC_COMPACT, BCC_ISOLATED, CIRCULAR_CUSTOM_GROUPS, SINGLE_CYCLE};
59 private final static String PARTITION_LAYOUT_STYLE = "PARTITION_LAYOUT_STYLE";
60 private final static String PARTITION_LAYOUTSTYLE_CYCLIC = "PARTITION_LAYOUTSTYLE_CYCLIC";
61 private final static String PARTITION_LAYOUTSTYLE_DISK = "PARTITION_LAYOUTSTYLE_DISK";
62 private final static String PARTITION_LAYOUTSTYLE_ORGANIC = "PARTITION_LAYOUTSTYLE_ORGANIC";
63
64 private final static String[] partitionLayoutStyles = {PARTITION_LAYOUTSTYLE_CYCLIC, PARTITION_LAYOUTSTYLE_DISK, PARTITION_LAYOUTSTYLE_ORGANIC};
65
66 public CircularLayoutModule() {
67 super( CIRCULAR, "yFiles Layout Team",
68 "Circular Layout" );
69 }
70
71 public OptionHandler createOptionHandler() {
72 CircularLayouter layouter = new CircularLayouter();
73 SingleCycleLayouter cycleLayouter = layouter.getSingleCycleLayouter();
74 BalloonLayouter treeLayouter = layouter.getBalloonLayouter();
75
76
77 OptionHandler op = new OptionHandler( getModuleName() );
78
79 op.useSection( GENERAL );
80 op.addEnum( LAYOUT_STYLE, layoutStyles, layouter.getLayoutStyle() );
81 op.addBool( ACT_ON_SELECTION_ONLY, false );
82 op.addBool( FROM_SKETCH, false );
83 op.addBool(HANDLE_NODE_LABELS, false);
84
85 op.useSection( CYCLE );
86 op.addEnum( PARTITION_LAYOUT_STYLE, partitionLayoutStyles, layouter.getPartitionLayoutStyle() );
87 OptionItem mndi = op.addInt( MINIMAL_NODE_DISTANCE, ( int ) cycleLayouter.getMinimalNodeDistance(), 0, 999 );
88 OptionItem crai = op.addBool( CHOOSE_RADIUS_AUTOMATICALLY, cycleLayouter.getAutomaticRadius() );
89 OptionItem fri = op.addInt( FIXED_RADIUS, ( int ) cycleLayouter.getFixedRadius(), 50, 800 );
90
91 ConstraintManager cm = new ConstraintManager(op);
92 cm.setEnabledOnValueEquals(crai, Boolean.FALSE, fri );
93 cm.setEnabledOnValueEquals(crai, Boolean.TRUE, mndi );
94
95 op.useSection( TREE );
96 op.addInt( PREFERRED_CHILD_WEDGE, treeLayouter.getPreferredChildWedge(), 1, 359 );
97 op.addInt( MINIMAL_EDGE_LENGTH, treeLayouter.getMinimalEdgeLength(), 5, 400 );
98 op.addInt( MAXIMAL_DEVIATION_ANGLE, layouter.getMaximalDeviationAngle(), 10, 360 );
99 op.addDouble( COMPACTNESS_FACTOR, treeLayouter.getCompactnessFactor(), 0.1, 0.9 );
100 op.addInt( MINIMAL_TREE_NODE_DISTANCE, treeLayouter.getMinimalNodeDistance(), 0, 100 );
101 op.addBool( ALLOW_OVERLAPS, treeLayouter.getAllowOverlaps() );
102 op.addBool(PLACE_CHILDREN_ON_COMMON_RADIUS, true );
103 cm.setEnabledOnValueEquals( op.getItem( GENERAL, LAYOUT_STYLE), SINGLE_CYCLE, op.getItem( TREE, MINIMAL_TREE_NODE_DISTANCE), true);
104 cm.setEnabledOnValueEquals( op.getItem( GENERAL, LAYOUT_STYLE), SINGLE_CYCLE, op.getItem( TREE, PLACE_CHILDREN_ON_COMMON_RADIUS), true);
105 cm.setEnabledOnValueEquals( op.getItem( GENERAL, LAYOUT_STYLE), SINGLE_CYCLE, op.getItem( TREE, PREFERRED_CHILD_WEDGE), true);
106 cm.setEnabledOnValueEquals( op.getItem( GENERAL, LAYOUT_STYLE), SINGLE_CYCLE, op.getItem( TREE, MINIMAL_EDGE_LENGTH), true);
107 cm.setEnabledOnValueEquals( op.getItem( GENERAL, LAYOUT_STYLE), SINGLE_CYCLE, op.getItem( TREE, MAXIMAL_DEVIATION_ANGLE), true);
108 cm.setEnabledOnValueEquals( op.getItem( GENERAL, LAYOUT_STYLE), SINGLE_CYCLE, op.getItem( TREE, COMPACTNESS_FACTOR), true);
109 cm.setEnabledOnValueEquals( op.getItem( GENERAL, LAYOUT_STYLE), SINGLE_CYCLE, op.getItem( TREE, ALLOW_OVERLAPS), true);
110 return op;
111 }
112
113
114 public void mainrun() {
115 OptionHandler op = getOptionHandler();
116
117 CircularLayouter layouter = new CircularLayouter();
118
119 BalloonLayouter treeLayouter = layouter.getBalloonLayouter();
120
121 if ( op.getString( LAYOUT_STYLE ).equals( BCC_COMPACT ) ) {
122 layouter.setLayoutStyle( CircularLayouter.BCC_COMPACT );
123 } else if ( op.getString( LAYOUT_STYLE ).equals( BCC_ISOLATED ) ) {
124 layouter.setLayoutStyle( CircularLayouter.BCC_ISOLATED );
125 } else if ( op.getString( LAYOUT_STYLE ).equals( CIRCULAR_CUSTOM_GROUPS ) ) {
126 layouter.setLayoutStyle( CircularLayouter.CIRCULAR_CUSTOM_GROUPS );
127 } else {
128 layouter.setLayoutStyle( CircularLayouter.SINGLE_CYCLE );
129 }
130
131 layouter.setSubgraphLayouterEnabled( op.getBool( ACT_ON_SELECTION_ONLY ) );
132 layouter.setMaximalDeviationAngle( op.getInt( MAXIMAL_DEVIATION_ANGLE ) );
133 layouter.setFromSketchModeEnabled( op.getBool( FROM_SKETCH));
134 layouter.setPlaceChildrenOnCommonRadiusEnabled(op.getBool(PLACE_CHILDREN_ON_COMMON_RADIUS));
135 layouter.setConsiderNodeLabelsEnabled(op.getBool(HANDLE_NODE_LABELS));
136
137 if ( op.getString( PARTITION_LAYOUT_STYLE ).equals( PARTITION_LAYOUTSTYLE_CYCLIC ) ) {
138 layouter.setPartitionLayoutStyle( CircularLayouter.PARTITION_LAYOUTSTYLE_CYCLIC );
139 } else if ( op.getString( PARTITION_LAYOUT_STYLE ).equals( PARTITION_LAYOUTSTYLE_DISK ) ) {
140 layouter.setPartitionLayoutStyle( CircularLayouter.PARTITION_LAYOUTSTYLE_DISK );
141 }
142 else if ( op.getString( PARTITION_LAYOUT_STYLE ).equals( PARTITION_LAYOUTSTYLE_ORGANIC ) ) {
143 layouter.setPartitionLayoutStyle( CircularLayouter.PARTITION_LAYOUTSTYLE_ORGANIC );
144 }
145
146 SingleCycleLayouter cycleLayouter = layouter.getSingleCycleLayouter();
147 cycleLayouter.setMinimalNodeDistance( op.getInt( MINIMAL_NODE_DISTANCE ) );
148 cycleLayouter.setAutomaticRadius( op.getBool( CHOOSE_RADIUS_AUTOMATICALLY ) );
149 cycleLayouter.setFixedRadius( op.getInt( FIXED_RADIUS ) );
150
151 treeLayouter.setPreferredChildWedge( op.getInt( PREFERRED_CHILD_WEDGE ) );
152 treeLayouter.setMinimalEdgeLength( op.getInt( MINIMAL_EDGE_LENGTH ) );
153 treeLayouter.setCompactnessFactor( op.getDouble( COMPACTNESS_FACTOR ) );
154 treeLayouter.setAllowOverlaps( op.getBool( ALLOW_OVERLAPS ) );
155 treeLayouter.setMinimalNodeDistance(op.getInt(MINIMAL_TREE_NODE_DISTANCE));
156
157 Graph2D graph = getGraph2D();
158 if ( op.getString( LAYOUT_STYLE ).equals( CIRCULAR_CUSTOM_GROUPS ) ) {
159 if ( graph.getHierarchyManager() != null ) {
162 graph.addDataProvider( CircularLayouter.CIRCULAR_CUSTOM_GROUPS_DPKEY,
163 graph.getHierarchyManager().getParentNodeIdDataProvider() );
164 }
165 }
166 try {
167 launchLayouter( layouter );
168 } finally {
169 if ( op.getString( LAYOUT_STYLE ).equals( CIRCULAR_CUSTOM_GROUPS ) ) {
171 graph.removeDataProvider( CircularLayouter.CIRCULAR_CUSTOM_GROUPS_DPKEY );
173 }
174 }
175 }
176 }