1
28 package demo.layout.radial;
29
30 import y.base.Node;
31 import y.base.NodeCursor;
32 import y.base.NodeMap;
33 import y.geom.YPoint;
34 import y.layout.radial.RadialLayouter;
35 import y.view.Drawable;
36 import y.view.Graph2D;
37 import y.view.Graph2DView;
38
39 import java.awt.BasicStroke;
40 import java.awt.Color;
41 import java.awt.Graphics2D;
42 import java.awt.Rectangle;
43 import java.awt.Stroke;
44 import java.awt.geom.Arc2D;
45 import java.awt.geom.Ellipse2D;
46 import java.util.ArrayList;
47 import java.util.Arrays;
48 import java.util.Collections;
49 import java.util.Comparator;
50 import java.util.HashSet;
51 import java.util.Iterator;
52
53
58 public final class SectorDrawable implements Drawable {
59
60 private final Graph2DView view;
61 private final NodeMap nodeInfoMap;
62 private Rectangle bounds;
63
64 private final Stroke stroke;
65 private Color[][] colors;
66 private boolean drawingCircles;
67 private boolean drawingSectors;
68
69 private double[] radii;
70 private YPoint center;
71 private ArrayList nodeInfos;
72
73
79 public SectorDrawable(final Graph2DView view, final NodeMap nodeInfoMap
80 ) {
81 this.view = view;
82 this.nodeInfoMap = nodeInfoMap;
83 this.bounds = new Rectangle(0, 0, 0, 0);
84
85 this.drawingCircles = true;
86 this.drawingSectors = false;
87
88 this.stroke = new BasicStroke(1.25f);
89 this.colors = new Color[][]{
90 {new Color(180, 200, 255), new Color(120, 150, 220)},
91 {new Color(180, 255, 200), new Color(120, 220, 150)}};
92 }
93
94
102 public boolean isDrawingCircles() {
103 return drawingCircles;
104 }
105
106
111 public void setDrawingCircles(boolean drawingCircles) {
112 this.drawingCircles = drawingCircles;
113 }
114
115
123 public boolean isDrawingSectors() {
124 return drawingSectors;
125 }
126
127
132 public void setDrawingSectors(boolean drawingSectors) {
133 this.drawingSectors = drawingSectors;
134 }
135
136
140 public Rectangle getBounds() {
141 return bounds;
142 }
143
144
147 public void updateSectors() {
148 final Graph2D g = view.getGraph2D();
149
150 if (g.N() < 1) {
151 return;
152 }
153
154 center = null;
156 nodeInfos = new ArrayList(g.N());
158
159 HashSet radiiSet = new HashSet();
161 for (NodeCursor nc = g.nodes(); nc.ok(); nc.next()) {
162 Node node = nc.node();
163 RadialLayouter.NodeInfo info = (RadialLayouter.NodeInfo) nodeInfoMap.get(node);
164 if (info != null) {
165 if (center == null) { YPoint nodeCenter = g.getCenter(node);
168 center = new YPoint(info.getCenterOffset().getX() - nodeCenter.getX(), info.getCenterOffset().getY() - nodeCenter.getY());
171 }
172 nodeInfos.add(info);
173
174 radiiSet.add(new Double(info.getRadius()));
176 }
177 }
178 radii = new double[radiiSet.size()];
179
180 if (center == null) {
181 bounds.setFrame(0, 0, 0, 0);
183 } else {
184 int index = 0;
186 for (Iterator it = radiiSet.iterator(); it.hasNext(); index++) {
187 radii[index] = ((Double) it.next()).doubleValue();
188 }
189 Arrays.sort(radii);
190
191 Collections.sort(nodeInfos, new Comparator() {
193 public int compare(Object o1, Object o2) {
194 RadialLayouter.NodeInfo info1 = (RadialLayouter.NodeInfo) o1;
195 RadialLayouter.NodeInfo info2 = (RadialLayouter.NodeInfo) o2;
196 if (info1.getCircleIndex() != info2.getCircleIndex()) {
197 return info2.getCircleIndex() - info1.getCircleIndex();
198 } else {
199 double dWedgeStart = info1.getSectorStart() - info2.getSectorStart();
200 return dWedgeStart < 0 ? -1 : dWedgeStart > 0 ? 1 : 0;
201 }
202 }
203 });
204
205 double maxRadius = radii[radii.length - 1];
207 bounds.setFrame(center.getX() - maxRadius, center.getY() - maxRadius, 2 * maxRadius, 2 * maxRadius);
208 }
209 g.updateViews();
210 }
211
212 public void paint(final Graphics2D g) {
213 if (radii == null || radii.length == 0) {
214 return;
216 }
217
218 final Color oldColor = g.getColor();
219 final Stroke oldStroke = g.getStroke();
220
221 g.setStroke(stroke);
222 if (isDrawingSectors()) {
223 int colorIndex = 0;
224 for (int i = 0; i < nodeInfos.size(); i++) {
225
226 RadialLayouter.NodeInfo info = (RadialLayouter.NodeInfo) nodeInfos.get(i);
227 double radius = info.getRadius();
228
229 g.setColor(colors[info.getCircleIndex() % 2][colorIndex]);
232 colorIndex = (colorIndex + 1) % 2;
233
234 g.fill(new Arc2D.Double(center.getX() - radius, center.getY() - radius, 2 * radius, 2 * radius,
235 info.getSectorStart(), info.getSectorSize(), Arc2D.PIE));
236 }
237 }
238
239 if (isDrawingCircles()) {
240 g.setColor(colors[0][0]);
241
242 for (int i = 0; i < radii.length; i++) {
243 double radius = radii[i];
244
245 g.draw(new Ellipse2D.Double(center.getX() - radius, center.getY() - radius, 2 * radius, 2 * radius));
246 }
247 }
248
249 g.setStroke(oldStroke);
250 g.setColor(oldColor);
251 }
252 }
253