1
28 package demo.layout.module;
29
30 import y.module.LayoutModule;
31 import y.module.YModule;
32
33 import y.layout.EdgeBundleDescriptor;
34 import y.layout.EdgeBundling;
35 import y.layout.radial.RadialLayouter;
36 import y.option.ConstraintManager;
37 import y.option.OptionHandler;
38 import y.option.OptionItem;
39
40
45 public class RadialLayoutModule extends LayoutModule {
46 private static final int MAXIMUM_SMOOTHNESS = 10;
47 private static final int MINIMUM_SMOOTHNESS = 1;
48 private static final int SMOOTHNESS_ANGLE_FACTOR = 4;
49
50 protected static final String MODULE_RADIAL = "RADIAL";
52
53 protected static final String SECTION_GENERAL = "GENERAL";
55 protected static final String ITEM_CENTER_STRATEGY = "CENTER_STRATEGY";
57 protected static final String VALUE_CENTER_DIRECTED = "CENTER_DIRECTED";
58 protected static final String VALUE_CENTER_CENTRAL = "CENTER_CENTRAL";
59 protected static final String VALUE_CENTER_WEIGHTED_CENTRAL = "CENTER_WEIGHTED_CENTRAL";
60 protected static final String VALUE_CENTER_SELECTED = "CENTER_SELECTED";
61 protected static final String ITEM_LAYERING_STRATEGY = "LAYERING_STRATEGY";
62 protected static final String VALUE_LAYERING_BFS = "LAYERING_BFS";
63 protected static final String VALUE_LAYERING_HIERARCHICAL = "LAYERING_HIERARCHICAL";
64 protected static final String ITEM_MINIMAL_LAYER_DISTANCE = "MINIMAL_LAYER_DISTANCE";
65 protected static final String ITEM_MINIMAL_NODE_DISTANCE = "MINIMAL_NODE_DISTANCE";
66 protected static final String ITEM_MAXIMAL_CHILD_SECTOR_SIZE = "MAXIMAL_CHILD_SECTOR_SIZE";
67 protected static final String ITEM_EDGE_ROUTING_STRATEGY = "EDGE_ROUTING_STRATEGY";
68 protected static final String VALUE_EDGE_POLYLINE = "EDGE_POLYLINE";
69 protected static final String VALUE_EDGE_ARC = "EDGE_ARC";
70 protected static final String VALUE_EDGE_BUNDLES = "EDGE_BUNDLES";
71 protected static final String ITEM_EDGE_SMOOTHNESS = "EDGE_SMOOTHNESS";
72 protected static final String ITEM_CONSIDER_NODE_LABELS = "CONSIDER_NODE_LABELS";
73 protected static final String ITEM_EDGE_BUNDLING_STRENGTH = "EDGE_BUNDLING_STRENGTH";
74
75
78 public RadialLayoutModule() {
79 super(MODULE_RADIAL);
80 }
81
82
86 protected OptionHandler createOptionHandler() {
87 final OptionHandler options = new OptionHandler(getModuleName());
88 final ConstraintManager optionConstraints = new ConstraintManager(options);
89 final RadialLayouter defaults = new RadialLayouter();
91
92 options.useSection(SECTION_GENERAL);
94 options.addEnum(ITEM_CENTER_STRATEGY, new String[]{
96 VALUE_CENTER_DIRECTED,
97 VALUE_CENTER_CENTRAL,
98 VALUE_CENTER_WEIGHTED_CENTRAL,
99 VALUE_CENTER_SELECTED
100 }, defaults.getCenterNodesPolicy());
101 options.addEnum(ITEM_LAYERING_STRATEGY, new String[]{
102 VALUE_LAYERING_BFS,
103 VALUE_LAYERING_HIERARCHICAL
104 }, defaults.getLayeringStrategy() == RadialLayouter.LAYERING_STRATEGY_BFS ? 0 : 1);
105 options.addInt(ITEM_MINIMAL_LAYER_DISTANCE, (int) defaults.getMinimalLayerDistance(), 1, 1000);
106 options.addInt(ITEM_MINIMAL_NODE_DISTANCE, (int) defaults.getMinimalNodeToNodeDistance(), 0, 300);
107 options.addInt(ITEM_MAXIMAL_CHILD_SECTOR_SIZE, (int) (defaults.getMaximalChildSectorAngle()), 15, 360);
108 final OptionItem itemEdgeRoutingStrategy = options.addEnum(ITEM_EDGE_ROUTING_STRATEGY, new String[]{
109 VALUE_EDGE_POLYLINE,
110 VALUE_EDGE_ARC,
111 VALUE_EDGE_BUNDLES
112 }, defaults.getEdgeRoutingStrategy() == RadialLayouter.EDGE_ROUTING_STRATEGY_POLYLINE ? 0 : 1);
113 final int smoothness = (int) Math.min(MAXIMUM_SMOOTHNESS,
114 (1 + MAXIMUM_SMOOTHNESS * SMOOTHNESS_ANGLE_FACTOR - defaults.getMinimalBendAngle()) / SMOOTHNESS_ANGLE_FACTOR);
115 final OptionItem smoothnessItem =
116 options.addInt(ITEM_EDGE_SMOOTHNESS, smoothness, MINIMUM_SMOOTHNESS, MAXIMUM_SMOOTHNESS);
117 optionConstraints.setEnabledOnCondition(
119 optionConstraints.createConditionValueEquals(itemEdgeRoutingStrategy, VALUE_EDGE_ARC), smoothnessItem);
120
121 final OptionItem itemBundlingStrength = options.addDouble(ITEM_EDGE_BUNDLING_STRENGTH, 0.99, 0.0, 1.0);
123
124 final ConstraintManager.Condition bundlingCondition =
126 optionConstraints.createConditionValueEquals(itemEdgeRoutingStrategy, VALUE_EDGE_BUNDLES);
127 optionConstraints.setEnabledOnCondition(bundlingCondition, itemBundlingStrength);
128 options.addBool(ITEM_CONSIDER_NODE_LABELS, defaults.isConsiderNodeLabelsEnabled());
129
130 return options;
131 }
132
133
134
138 protected void mainrun() {
139 final RadialLayouter radial = new RadialLayouter();
140
141 final OptionHandler options = getOptionHandler();
142 configure(radial, options);
143
144 launchLayouter(radial);
145 }
146
147
152 protected void configure(final RadialLayouter radial, final OptionHandler options) {
153 radial.setMinimalNodeToNodeDistance(options.getInt(ITEM_MINIMAL_NODE_DISTANCE));
154
155 if (options.getString(ITEM_EDGE_ROUTING_STRATEGY).equals(VALUE_EDGE_POLYLINE)) {
156 radial.setEdgeRoutingStrategy(RadialLayouter.EDGE_ROUTING_STRATEGY_POLYLINE);
157 } else if (options.getString(ITEM_EDGE_ROUTING_STRATEGY).equals(VALUE_EDGE_ARC)) {
158 radial.setEdgeRoutingStrategy(RadialLayouter.EDGE_ROUTING_STRATEGY_ARC);
159 } else if (options.getString(ITEM_EDGE_ROUTING_STRATEGY).equals(VALUE_EDGE_BUNDLES)) {
160 final EdgeBundling ebc = radial.getEdgeBundling();
162 final EdgeBundleDescriptor descriptor = new EdgeBundleDescriptor();
163 descriptor.setBundled(true);
164 ebc.setDefaultBundleDescriptor(descriptor);
165 ebc.setBundlingStrength(options.getDouble(ITEM_EDGE_BUNDLING_STRENGTH));
166 }
167
168 final double minimalBendAngle = 1 + (MAXIMUM_SMOOTHNESS - options.getInt(ITEM_EDGE_SMOOTHNESS)) * SMOOTHNESS_ANGLE_FACTOR;
169 radial.setMinimalBendAngle(minimalBendAngle);
170
171 radial.setMinimalLayerDistance(options.getInt(ITEM_MINIMAL_LAYER_DISTANCE));
172 radial.setMaximalChildSectorAngle(options.getInt(ITEM_MAXIMAL_CHILD_SECTOR_SIZE));
173
174 if (options.getString(ITEM_CENTER_STRATEGY).equals(VALUE_CENTER_CENTRAL)) {
175 radial.setCenterNodesPolicy(RadialLayouter.CENTER_NODES_POLICY_CENTRALITY);
176 } else if (options.getString(ITEM_CENTER_STRATEGY).equals(VALUE_CENTER_WEIGHTED_CENTRAL)) {
177 radial.setCenterNodesPolicy(RadialLayouter.CENTER_NODES_POLICY_WEIGHTED_CENTRALITY);
178 } else if (options.getString(ITEM_CENTER_STRATEGY).equals(VALUE_CENTER_SELECTED)) {
179 radial.setCenterNodesPolicy(RadialLayouter.CENTER_NODES_POLICY_SELECTED_NODES);
180 } else {
181 radial.setCenterNodesPolicy(RadialLayouter.CENTER_NODES_POLICY_DIRECTED);
182 }
183
184 if (options.getString(ITEM_LAYERING_STRATEGY).equals(VALUE_LAYERING_HIERARCHICAL)) {
185 radial.setLayeringStrategy(RadialLayouter.LAYERING_STRATEGY_HIERARCHICAL);
186 } else {
187 radial.setLayeringStrategy(RadialLayouter.LAYERING_STRATEGY_BFS);
188 }
189
190 radial.setConsiderNodeLabelsEnabled(options.getBool(ITEM_CONSIDER_NODE_LABELS));
191 }
192 }