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