Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java @ 657:af3f56758f59
merged gnv-artifacts/0.5
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:53 +0200 |
parents | bc5901bb4525 |
children | 9a828e5a2390 |
comparison
equal
deleted
inserted
replaced
590:5f5f273c8566 | 657:af3f56758f59 |
---|---|
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 public ValueAxis getDomainAxis() { | |
127 return getDomainAxis(0); | |
128 } | |
129 | |
130 public ValueAxis getDomainAxis(int index) { | |
131 return index < domainAxes.size() | |
132 ? (ValueAxis)domainAxes.get(index) | |
133 : null; | |
134 } | |
135 | |
136 public ValueAxis getRangeAxis() { | |
137 return getRangeAxis(0); | |
138 } | |
139 | |
140 public ValueAxis getRangeAxis(int index) { | |
141 return index < rangeAxes.size() | |
142 ? (ValueAxis)rangeAxes.get(index) | |
143 : null; | |
144 } | |
145 | |
146 public void configureRangeAxis() { | |
147 // we just have 1 dataset | |
148 Range rangeAxisRange = getDataset().getRangeBounds(); | |
149 | |
150 for (int i = 0; i < rangeAxes.size(); i++) { | |
151 ValueAxis axis = (ValueAxis) rangeAxes.get(i); | |
152 | |
153 if (axis != null) { | |
154 axis.configure(); | |
155 axis.setRange(rangeAxisRange); | |
156 } | |
157 } | |
158 } | |
159 | |
160 | |
161 public PolygonDataset getDataset(){ | |
162 return this.dataset; | |
163 } | |
164 | |
165 | |
166 public String getPlotType() { | |
167 return PLOT_TYPE; | |
168 } | |
169 | |
170 | |
171 public void setDataset(PolygonDataset dataset) { | |
172 this.dataset = dataset; | |
173 } | |
174 | |
175 | |
176 public void draw( | |
177 Graphics2D g2, | |
178 Rectangle2D area, | |
179 Point2D anchor, | |
180 PlotState parentState, | |
181 PlotRenderingInfo info | |
182 ) { | |
183 Graphics2D savedG2 = g2; | |
184 Rectangle2D savedDataArea = area; | |
185 | |
186 if (info != null) { | |
187 info.setPlotArea(area); | |
188 info.setDataArea(area); | |
189 } | |
190 | |
191 AxisSpace space = calculateAxisSpace(g2, area); | |
192 Rectangle2D dataArea = space.shrink(area, null); | |
193 | |
194 // draw background and outline | |
195 drawBackground(g2, area); | |
196 drawOutline(g2, area); | |
197 | |
198 Shape savedClip = g2.getClip(); | |
199 g2.clip(area); | |
200 | |
201 Composite originalComposite = g2.getComposite(); | |
202 g2.setComposite(AlphaComposite.getInstance( | |
203 AlphaComposite.SRC_OVER, | |
204 getForegroundAlpha() | |
205 )); | |
206 | |
207 // draw axis | |
208 drawAxes(g2, area, dataArea, info); | |
209 | |
210 if (!isEmptyOrNull(dataset)) { | |
211 // draw data | |
212 drawPolygons(savedG2, dataArea, info); | |
213 drawLabels(savedG2, dataArea, info); | |
214 } | |
215 | |
216 g2.setClip(savedClip); | |
217 g2.setComposite(originalComposite); | |
218 } | |
219 | |
220 | |
221 private void drawAxes( | |
222 Graphics2D g2, | |
223 Rectangle2D plotArea, | |
224 Rectangle2D dataArea, | |
225 PlotRenderingInfo plotState | |
226 ) { | |
227 AxisCollection axisCollection = new AxisCollection(); | |
228 | |
229 for (int i = 0; i < domainAxes.size(); i++) { | |
230 ValueAxis axis = (ValueAxis) domainAxes.get(i); | |
231 if (axis != null) | |
232 axisCollection.add(axis, getDomainAxisEdge(i)); | |
233 } | |
234 | |
235 for (int i = 0; i < rangeAxes.size(); i++) { | |
236 ValueAxis axis = (ValueAxis) rangeAxes.get(i); | |
237 if (axis != null) | |
238 axisCollection.add(axis, getRangeAxisEdge(i)); | |
239 } | |
240 | |
241 Map axisStateMap = new HashMap(); | |
242 | |
243 // draw the top axes | |
244 double cursor = dataArea.getMinY() - this.axisOffset.calculateTopOutset( | |
245 dataArea.getHeight()); | |
246 Iterator iterator = axisCollection.getAxesAtTop().iterator(); | |
247 while (iterator.hasNext()) { | |
248 ValueAxis axis = (ValueAxis) iterator.next(); | |
249 AxisState info = axis.draw(g2, cursor, plotArea, dataArea, | |
250 RectangleEdge.TOP, plotState); | |
251 cursor = info.getCursor(); | |
252 axisStateMap.put(axis, info); | |
253 } | |
254 | |
255 // draw the bottom axes | |
256 cursor = dataArea.getMaxY() | |
257 + this.axisOffset.calculateBottomOutset(dataArea.getHeight()); | |
258 iterator = axisCollection.getAxesAtBottom().iterator(); | |
259 while (iterator.hasNext()) { | |
260 ValueAxis axis = (ValueAxis) iterator.next(); | |
261 AxisState info = axis.draw(g2, cursor, plotArea, dataArea, | |
262 RectangleEdge.BOTTOM, plotState); | |
263 cursor = info.getCursor(); | |
264 axisStateMap.put(axis, info); | |
265 } | |
266 | |
267 // draw the left axes | |
268 cursor = dataArea.getMinX() | |
269 - this.axisOffset.calculateLeftOutset(dataArea.getWidth()); | |
270 iterator = axisCollection.getAxesAtLeft().iterator(); | |
271 while (iterator.hasNext()) { | |
272 ValueAxis axis = (ValueAxis) iterator.next(); | |
273 AxisState info = axis.draw(g2, cursor, plotArea, dataArea, | |
274 RectangleEdge.LEFT, plotState); | |
275 cursor = info.getCursor(); | |
276 axisStateMap.put(axis, info); | |
277 } | |
278 | |
279 // draw the right axes | |
280 cursor = dataArea.getMaxX() | |
281 + this.axisOffset.calculateRightOutset(dataArea.getWidth()); | |
282 iterator = axisCollection.getAxesAtRight().iterator(); | |
283 while (iterator.hasNext()) { | |
284 ValueAxis axis = (ValueAxis) iterator.next(); | |
285 AxisState info = axis.draw(g2, cursor, plotArea, dataArea, | |
286 RectangleEdge.RIGHT, plotState); | |
287 cursor = info.getCursor(); | |
288 axisStateMap.put(axis, info); | |
289 } | |
290 } | |
291 | |
292 | |
293 private void drawLabels( | |
294 Graphics2D g2, | |
295 Rectangle2D area, | |
296 PlotRenderingInfo info | |
297 ) { | |
298 renderer.drawLabels(g2, this, area, dataset); | |
299 } | |
300 | |
301 private void drawPolygons( | |
302 Graphics2D g2, | |
303 Rectangle2D area, | |
304 PlotRenderingInfo info | |
305 ) { | |
306 renderer.drawPolygons(g2, this, area, dataset); | |
307 } | |
308 | |
309 | |
310 private AxisSpace calculateAxisSpace(Graphics2D g2, Rectangle2D plotArea) { | |
311 AxisSpace space = new AxisSpace(); | |
312 space = calculateRangeAxisSpace(g2, plotArea, space); | |
313 Rectangle2D tmpPlotArea = space.shrink(plotArea, null); | |
314 space = calculateDomainAxisSpace(g2, plotArea, space); | |
315 | |
316 return space; | |
317 } | |
318 | |
319 | |
320 private AxisSpace calculateDomainAxisSpace( | |
321 Graphics2D g2, | |
322 Rectangle2D plotArea, | |
323 AxisSpace space | |
324 ) { | |
325 if (space == null) | |
326 space = new AxisSpace(); | |
327 | |
328 for (int i = 0; i < domainAxes.size(); i++) { | |
329 Axis axis = (Axis) domainAxes.get(i); | |
330 | |
331 if (axis != null) { | |
332 RectangleEdge edge = getDomainAxisEdge(i); | |
333 space = axis.reserveSpace(g2, this, plotArea, edge, space); | |
334 } | |
335 } | |
336 | |
337 return space; | |
338 } | |
339 | |
340 | |
341 private AxisSpace calculateRangeAxisSpace( | |
342 Graphics2D g2, | |
343 Rectangle2D plotArea, | |
344 AxisSpace space | |
345 ) { | |
346 if (space == null) | |
347 space = new AxisSpace(); | |
348 | |
349 for (int i = 0; i < rangeAxes.size(); i++) { | |
350 Axis axis = (Axis) rangeAxes.get(i); | |
351 | |
352 if (axis != null) { | |
353 RectangleEdge edge = getRangeAxisEdge(i); | |
354 space = axis.reserveSpace(g2, this, plotArea, edge, space); | |
355 } | |
356 } | |
357 | |
358 return space; | |
359 } | |
360 | |
361 public RectangleEdge getDomainAxisEdge() { | |
362 return Plot.resolveDomainAxisLocation( | |
363 getDomainAxisLocation(), orientation | |
364 ); | |
365 } | |
366 | |
367 | |
368 public RectangleEdge getDomainAxisEdge(int idx) { | |
369 AxisLocation location = getDomainAxisLocation(idx); | |
370 RectangleEdge result = Plot.resolveDomainAxisLocation( | |
371 location, orientation | |
372 ); | |
373 | |
374 if (result == null) | |
375 result = RectangleEdge.opposite(getDomainAxisEdge()); | |
376 | |
377 return result; | |
378 } | |
379 | |
380 | |
381 public RectangleEdge getRangeAxisEdge() { | |
382 return Plot.resolveRangeAxisLocation( | |
383 getRangeAxisLocation(), orientation | |
384 ); | |
385 } | |
386 | |
387 | |
388 public RectangleEdge getRangeAxisEdge(int idx) { | |
389 AxisLocation location = getRangeAxisLocation(idx); | |
390 RectangleEdge result = Plot.resolveRangeAxisLocation( | |
391 location, | |
392 orientation | |
393 ); | |
394 | |
395 if (result == null) | |
396 result = RectangleEdge.opposite(getRangeAxisEdge()); | |
397 | |
398 return result; | |
399 } | |
400 | |
401 | |
402 public AxisLocation getDomainAxisLocation() { | |
403 return (AxisLocation) domainAxisLocation.get(0); | |
404 } | |
405 | |
406 | |
407 public AxisLocation getDomainAxisLocation(int idx) { | |
408 if (idx < domainAxisLocation.size()) | |
409 return (AxisLocation) domainAxisLocation.get(idx); | |
410 | |
411 return null; | |
412 } | |
413 | |
414 | |
415 public AxisLocation getRangeAxisLocation() { | |
416 return (AxisLocation) rangeAxisLocation.get(0); | |
417 } | |
418 | |
419 | |
420 public AxisLocation getRangeAxisLocation(int idx) { | |
421 if (idx < rangeAxisLocation.size()) | |
422 return (AxisLocation) rangeAxisLocation.get(idx); | |
423 | |
424 return null; | |
425 } | |
426 | |
427 | |
428 private boolean isEmptyOrNull(PolygonDataset dataset) { | |
429 if (dataset != null) { | |
430 int seriesCount = dataset.getSeriesCount(); | |
431 for (int s = 0; s < seriesCount; s++) { | |
432 PolygonSeries series = dataset.getSeries(s); | |
433 if (series.getItemCount() > 0) { | |
434 return false; | |
435 } | |
436 } | |
437 } | |
438 return true; | |
439 } | |
440 } |