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