Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java @ 422:f426f55d4f7a
Added Ingo Weinzierl's special JFreeChart classes.
gnv-artifacts/trunk@470 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 21 Dec 2009 16:47:45 +0000 |
parents | |
children | f5a041000357 |
comparison
equal
deleted
inserted
replaced
421:fd71ee76fa58 | 422:f426f55d4f7a |
---|---|
1 package de.intevation.gnv.jfreechart; | |
2 | |
3 import java.awt.AlphaComposite; | |
4 import java.awt.Composite; | |
5 import java.awt.Graphics2D; | |
6 import java.awt.Shape; | |
7 | |
8 import java.awt.geom.Point2D; | |
9 import java.awt.geom.Rectangle2D; | |
10 | |
11 import java.util.HashMap; | |
12 import java.util.Iterator; | |
13 import java.util.Map; | |
14 | |
15 import org.jfree.chart.axis.Axis; | |
16 import org.jfree.chart.axis.AxisCollection; | |
17 import org.jfree.chart.axis.AxisLocation; | |
18 import org.jfree.chart.axis.AxisSpace; | |
19 import org.jfree.chart.axis.AxisState; | |
20 import org.jfree.chart.axis.ValueAxis; | |
21 | |
22 import org.jfree.chart.plot.Plot; | |
23 import org.jfree.chart.plot.PlotRenderingInfo; | |
24 import org.jfree.chart.plot.PlotState; | |
25 import org.jfree.chart.plot.PlotOrientation; | |
26 | |
27 import org.jfree.data.Range; | |
28 | |
29 import org.jfree.ui.RectangleEdge; | |
30 import org.jfree.ui.RectangleInsets; | |
31 | |
32 import org.jfree.util.ObjectList; | |
33 | |
34 /** | |
35 * @author Ingo Weinzierl <ingo.weinzierl@intevation.de> | |
36 */ | |
37 // TODO implement cloneable | |
38 public class PolygonPlot | |
39 extends Plot | |
40 { | |
41 public static final String PLOT_TYPE = "PolygonPlot"; | |
42 | |
43 public static final PlotOrientation DEFAULT_PLOT_ORIENTATION = | |
44 PlotOrientation.VERTICAL; | |
45 | |
46 private PolygonDataset dataset; | |
47 private transient PolygonRenderer renderer; | |
48 | |
49 private PlotOrientation orientation; | |
50 | |
51 private RectangleInsets axisOffset; | |
52 | |
53 private ObjectList domainAxisLocation; | |
54 private ObjectList rangeAxisLocation; | |
55 private ObjectList domainAxes; | |
56 private ObjectList rangeAxes; | |
57 | |
58 | |
59 public PolygonPlot(PolygonDataset dataset, PolygonRenderer renderer) { | |
60 this(dataset, renderer, null, null, PlotOrientation.HORIZONTAL); | |
61 } | |
62 | |
63 | |
64 public PolygonPlot( | |
65 PolygonDataset dataset, | |
66 PolygonRenderer renderer, | |
67 PlotOrientation orientation | |
68 ) { | |
69 this(dataset, renderer, null, null, orientation); | |
70 } | |
71 | |
72 | |
73 public PolygonPlot( | |
74 PolygonDataset dataset, | |
75 PolygonRenderer renderer, | |
76 ValueAxis domainAxis, | |
77 ValueAxis rangeAxis, | |
78 PlotOrientation orientation | |
79 ) { | |
80 super(); | |
81 | |
82 this.dataset = dataset; | |
83 this.renderer = renderer; | |
84 this.domainAxes = new ObjectList(); | |
85 this.rangeAxes = new ObjectList(); | |
86 this.domainAxisLocation = new ObjectList(); | |
87 this.rangeAxisLocation = new ObjectList(); | |
88 this.axisOffset = RectangleInsets.ZERO_INSETS; | |
89 | |
90 if (orientation != null) | |
91 this.orientation = orientation; | |
92 else | |
93 this.orientation = DEFAULT_PLOT_ORIENTATION; | |
94 | |
95 if (domainAxis != null) { | |
96 this.domainAxes.set(0, domainAxis); | |
97 domainAxis.setPlot(this); | |
98 } | |
99 domainAxisLocation.set(0, AxisLocation.BOTTOM_OR_LEFT); | |
100 | |
101 if (rangeAxis != null) { | |
102 this.rangeAxes.set(0, rangeAxis); | |
103 rangeAxis.setPlot(this); | |
104 } | |
105 rangeAxisLocation.set(0, AxisLocation.BOTTOM_OR_LEFT); | |
106 | |
107 configureDomainAxis(); | |
108 configureRangeAxis(); | |
109 } | |
110 | |
111 | |
112 public void configureDomainAxis() { | |
113 // we just have 1 dataset | |
114 Range domainAxisRange = getDataset().getDomainBounds(); | |
115 | |
116 for (int i = 0; i < domainAxes.size(); i++) { | |
117 ValueAxis axis = (ValueAxis) domainAxes.get(i); | |
118 | |
119 if (axis != null) { | |
120 axis.configure(); | |
121 axis.setRange(domainAxisRange); | |
122 } | |
123 } | |
124 } | |
125 | |
126 | |
127 public void configureRangeAxis() { | |
128 // we just have 1 dataset | |
129 Range rangeAxisRange = getDataset().getRangeBounds(); | |
130 | |
131 for (int i = 0; i < rangeAxes.size(); i++) { | |
132 ValueAxis axis = (ValueAxis) rangeAxes.get(i); | |
133 | |
134 if (axis != null) { | |
135 axis.configure(); | |
136 axis.setRange(rangeAxisRange); | |
137 } | |
138 } | |
139 } | |
140 | |
141 | |
142 public PolygonDataset getDataset(){ | |
143 return this.dataset; | |
144 } | |
145 | |
146 | |
147 public String getPlotType() { | |
148 return PLOT_TYPE; | |
149 } | |
150 | |
151 | |
152 public void setDataset(PolygonDataset dataset) { | |
153 this.dataset = dataset; | |
154 } | |
155 | |
156 | |
157 public void draw( | |
158 Graphics2D g2, | |
159 Rectangle2D area, | |
160 Point2D anchor, | |
161 PlotState parentState, | |
162 PlotRenderingInfo info | |
163 ) { | |
164 System.out.println("Start drawing plot."); | |
165 | |
166 Graphics2D savedG2 = g2; | |
167 Rectangle2D savedDataArea = area; | |
168 | |
169 if (info != null) { | |
170 info.setPlotArea(area); | |
171 info.setDataArea(area); | |
172 } | |
173 | |
174 AxisSpace space = calculateAxisSpace(g2, area); | |
175 Rectangle2D dataArea = space.shrink(area, null); | |
176 | |
177 // draw background and outline | |
178 drawBackground(g2, area); | |
179 drawOutline(g2, area); | |
180 | |
181 Shape savedClip = g2.getClip(); | |
182 g2.clip(area); | |
183 | |
184 Composite originalComposite = g2.getComposite(); | |
185 g2.setComposite(AlphaComposite.getInstance( | |
186 AlphaComposite.SRC_OVER, | |
187 getForegroundAlpha() | |
188 )); | |
189 | |
190 // draw axis | |
191 drawAxes(g2, area, dataArea, info); | |
192 | |
193 if (!isEmptyOrNull(dataset)) { | |
194 // draw data | |
195 drawPolygons(savedG2, dataArea, info); | |
196 } | |
197 | |
198 g2.setClip(savedClip); | |
199 g2.setComposite(originalComposite); | |
200 | |
201 System.out.println("Finished drawing plot."); | |
202 } | |
203 | |
204 | |
205 private void drawAxes( | |
206 Graphics2D g2, | |
207 Rectangle2D plotArea, | |
208 Rectangle2D dataArea, | |
209 PlotRenderingInfo plotState | |
210 ) { | |
211 AxisCollection axisCollection = new AxisCollection(); | |
212 | |
213 for (int i = 0; i < domainAxes.size(); i++) { | |
214 ValueAxis axis = (ValueAxis) domainAxes.get(i); | |
215 if (axis != null) | |
216 axisCollection.add(axis, getDomainAxisEdge(i)); | |
217 } | |
218 | |
219 for (int i = 0; i < rangeAxes.size(); i++) { | |
220 ValueAxis axis = (ValueAxis) rangeAxes.get(i); | |
221 if (axis != null) | |
222 axisCollection.add(axis, getRangeAxisEdge(i)); | |
223 } | |
224 | |
225 Map axisStateMap = new HashMap(); | |
226 | |
227 // draw the top axes | |
228 double cursor = dataArea.getMinY() - this.axisOffset.calculateTopOutset( | |
229 dataArea.getHeight()); | |
230 Iterator iterator = axisCollection.getAxesAtTop().iterator(); | |
231 while (iterator.hasNext()) { | |
232 ValueAxis axis = (ValueAxis) iterator.next(); | |
233 AxisState info = axis.draw(g2, cursor, plotArea, dataArea, | |
234 RectangleEdge.TOP, plotState); | |
235 cursor = info.getCursor(); | |
236 axisStateMap.put(axis, info); | |
237 } | |
238 | |
239 // draw the bottom axes | |
240 cursor = dataArea.getMaxY() | |
241 + this.axisOffset.calculateBottomOutset(dataArea.getHeight()); | |
242 iterator = axisCollection.getAxesAtBottom().iterator(); | |
243 while (iterator.hasNext()) { | |
244 ValueAxis axis = (ValueAxis) iterator.next(); | |
245 AxisState info = axis.draw(g2, cursor, plotArea, dataArea, | |
246 RectangleEdge.BOTTOM, plotState); | |
247 cursor = info.getCursor(); | |
248 axisStateMap.put(axis, info); | |
249 } | |
250 | |
251 // draw the left axes | |
252 cursor = dataArea.getMinX() | |
253 - this.axisOffset.calculateLeftOutset(dataArea.getWidth()); | |
254 iterator = axisCollection.getAxesAtLeft().iterator(); | |
255 while (iterator.hasNext()) { | |
256 ValueAxis axis = (ValueAxis) iterator.next(); | |
257 AxisState info = axis.draw(g2, cursor, plotArea, dataArea, | |
258 RectangleEdge.LEFT, plotState); | |
259 cursor = info.getCursor(); | |
260 axisStateMap.put(axis, info); | |
261 } | |
262 | |
263 // draw the right axes | |
264 cursor = dataArea.getMaxX() | |
265 + this.axisOffset.calculateRightOutset(dataArea.getWidth()); | |
266 iterator = axisCollection.getAxesAtRight().iterator(); | |
267 while (iterator.hasNext()) { | |
268 ValueAxis axis = (ValueAxis) iterator.next(); | |
269 AxisState info = axis.draw(g2, cursor, plotArea, dataArea, | |
270 RectangleEdge.RIGHT, plotState); | |
271 cursor = info.getCursor(); | |
272 axisStateMap.put(axis, info); | |
273 } | |
274 } | |
275 | |
276 | |
277 private void drawPolygons( | |
278 Graphics2D g2, | |
279 Rectangle2D area, | |
280 PlotRenderingInfo info | |
281 ) { | |
282 renderer.draw(g2, area, dataset); | |
283 } | |
284 | |
285 | |
286 private AxisSpace calculateAxisSpace(Graphics2D g2, Rectangle2D plotArea) { | |
287 AxisSpace space = new AxisSpace(); | |
288 space = calculateRangeAxisSpace(g2, plotArea, space); | |
289 Rectangle2D tmpPlotArea = space.shrink(plotArea, null); | |
290 space = calculateDomainAxisSpace(g2, plotArea, space); | |
291 | |
292 return space; | |
293 } | |
294 | |
295 | |
296 private AxisSpace calculateDomainAxisSpace( | |
297 Graphics2D g2, | |
298 Rectangle2D plotArea, | |
299 AxisSpace space | |
300 ) { | |
301 if (space == null) | |
302 space = new AxisSpace(); | |
303 | |
304 for (int i = 0; i < domainAxes.size(); i++) { | |
305 Axis axis = (Axis) domainAxes.get(i); | |
306 | |
307 if (axis != null) { | |
308 RectangleEdge edge = getDomainAxisEdge(i); | |
309 space = axis.reserveSpace(g2, this, plotArea, edge, space); | |
310 } | |
311 } | |
312 | |
313 return space; | |
314 } | |
315 | |
316 | |
317 private AxisSpace calculateRangeAxisSpace( | |
318 Graphics2D g2, | |
319 Rectangle2D plotArea, | |
320 AxisSpace space | |
321 ) { | |
322 if (space == null) | |
323 space = new AxisSpace(); | |
324 | |
325 for (int i = 0; i < rangeAxes.size(); i++) { | |
326 Axis axis = (Axis) rangeAxes.get(i); | |
327 | |
328 if (axis != null) { | |
329 RectangleEdge edge = getRangeAxisEdge(i); | |
330 space = axis.reserveSpace(g2, this, plotArea, edge, space); | |
331 } | |
332 } | |
333 | |
334 return space; | |
335 } | |
336 | |
337 private RectangleEdge getDomainAxisEdge() { | |
338 return Plot.resolveDomainAxisLocation( | |
339 getDomainAxisLocation(), orientation | |
340 ); | |
341 } | |
342 | |
343 | |
344 private RectangleEdge getDomainAxisEdge(int idx) { | |
345 AxisLocation location = getDomainAxisLocation(idx); | |
346 RectangleEdge result = Plot.resolveDomainAxisLocation( | |
347 location, orientation | |
348 ); | |
349 | |
350 if (result == null) | |
351 result = RectangleEdge.opposite(getDomainAxisEdge()); | |
352 | |
353 return result; | |
354 } | |
355 | |
356 | |
357 private RectangleEdge getRangeAxisEdge() { | |
358 return Plot.resolveRangeAxisLocation( | |
359 getRangeAxisLocation(), orientation | |
360 ); | |
361 } | |
362 | |
363 | |
364 private RectangleEdge getRangeAxisEdge(int idx) { | |
365 AxisLocation location = getRangeAxisLocation(idx); | |
366 RectangleEdge result = Plot.resolveRangeAxisLocation( | |
367 location, | |
368 orientation | |
369 ); | |
370 | |
371 if (result == null) | |
372 result = RectangleEdge.opposite(getRangeAxisEdge()); | |
373 | |
374 return result; | |
375 } | |
376 | |
377 | |
378 public AxisLocation getDomainAxisLocation() { | |
379 return (AxisLocation) domainAxisLocation.get(0); | |
380 } | |
381 | |
382 | |
383 public AxisLocation getDomainAxisLocation(int idx) { | |
384 if (idx < domainAxisLocation.size()) | |
385 return (AxisLocation) domainAxisLocation.get(idx); | |
386 | |
387 return null; | |
388 } | |
389 | |
390 | |
391 public AxisLocation getRangeAxisLocation() { | |
392 return (AxisLocation) rangeAxisLocation.get(0); | |
393 } | |
394 | |
395 | |
396 public AxisLocation getRangeAxisLocation(int idx) { | |
397 if (idx < rangeAxisLocation.size()) | |
398 return (AxisLocation) rangeAxisLocation.get(idx); | |
399 | |
400 return null; | |
401 } | |
402 | |
403 | |
404 private boolean isEmptyOrNull(PolygonDataset dataset) { | |
405 if (dataset != null) { | |
406 int seriesCount = dataset.getSeriesCount(); | |
407 for (int s = 0; s < seriesCount; s++) { | |
408 PolygonSeries series = dataset.getSeries(s); | |
409 if (series.getItemCount() > 0) { | |
410 return false; | |
411 } | |
412 } | |
413 } | |
414 return true; | |
415 } | |
416 } |