Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java @ 1119:7c4f81f74c47
merged gnv-artifacts
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:00 +0200 |
parents | f953c9a559d8 |
children |
comparison
equal
deleted
inserted
replaced
1027:fca4b5eb8d2f | 1119:7c4f81f74c47 |
---|---|
1 /* | |
2 * Copyright (c) 2010 by Intevation GmbH | |
3 * | |
4 * This program is free software under the LGPL (>=v2.1) | |
5 * Read the file LGPL.txt coming with the software for details | |
6 * or visit http://www.gnu.org/licenses/ if it does not exist. | |
7 */ | |
8 | |
9 package de.intevation.gnv.chart; | |
10 | |
11 import de.intevation.gnv.jfreechart.PolygonDataset; | |
12 import de.intevation.gnv.jfreechart.PolygonPlot; | |
13 import de.intevation.gnv.jfreechart.PolygonRenderer; | |
14 import de.intevation.gnv.jfreechart.PolygonSeries; | |
15 | |
16 import de.intevation.gnv.math.AttributedXYColumns; | |
17 | |
18 import de.intevation.gnv.raster.Palette; | |
19 | |
20 import java.awt.Color; | |
21 import java.awt.Paint; | |
22 | |
23 import java.text.NumberFormat; | |
24 | |
25 import java.util.HashSet; | |
26 import java.util.Locale; | |
27 import java.util.Map; | |
28 | |
29 import org.jfree.chart.JFreeChart; | |
30 | |
31 import org.jfree.chart.axis.NumberAxis; | |
32 import org.jfree.chart.axis.SymbolAxis; | |
33 import org.jfree.chart.axis.ValueAxis; | |
34 | |
35 import org.jfree.chart.plot.PlotOrientation; | |
36 | |
37 import org.jfree.chart.renderer.LookupPaintScale; | |
38 | |
39 import org.jfree.chart.title.PaintScaleLegend; | |
40 import org.jfree.chart.title.TextTitle; | |
41 | |
42 import org.jfree.data.Range; | |
43 | |
44 import org.jfree.ui.RectangleEdge; | |
45 import org.jfree.ui.RectangleInsets; | |
46 | |
47 /** | |
48 * This class represents a 2D chart containing polygon data. | |
49 * | |
50 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> | |
51 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> | |
52 */ | |
53 public class VerticalCrossSectionChart | |
54 implements Chart | |
55 { | |
56 /** | |
57 * Lookup class for retrieving a color which corresponds to a specific | |
58 * integer value. | |
59 */ | |
60 public static final class PalettePaintLookup | |
61 implements PolygonRenderer.PaintLookup | |
62 { | |
63 /** | |
64 * Object storing information about value ranges and its coresponding | |
65 * colors and descriptions. | |
66 */ | |
67 private Palette palette; | |
68 | |
69 /** | |
70 * Map containing some special <code>Paint</code> like ground fillcolor. | |
71 */ | |
72 private Map<Integer, Paint> special; | |
73 | |
74 /** | |
75 * Constructor | |
76 * | |
77 * @param palette See {@link #palette} | |
78 */ | |
79 public PalettePaintLookup(Palette palette) { | |
80 this(palette, null); | |
81 } | |
82 | |
83 /** | |
84 * Constructor | |
85 * | |
86 * @param palette See {@link #palette} | |
87 * @param special See {@link #special} | |
88 */ | |
89 public PalettePaintLookup( | |
90 Palette palette, | |
91 Map<Integer, Paint> special | |
92 ) { | |
93 this.palette = palette; | |
94 this.special = special; | |
95 } | |
96 | |
97 /** | |
98 * @param index Index of a <code>Paint</code> | |
99 * | |
100 * @return <code>Paint</code> object for a given index. | |
101 */ | |
102 public Paint getPaint(int index) { | |
103 if (special != null) { | |
104 Paint paint = special.get(index); | |
105 if (paint != null) { | |
106 return paint; | |
107 } | |
108 } | |
109 return index < 0 | |
110 ? Color.black | |
111 : palette.getColor(index); | |
112 } | |
113 } // class PalettePaintLookup | |
114 | |
115 /** | |
116 * This class is used to turn labels which represent a number into a | |
117 * specific format. | |
118 */ | |
119 public static class LocalizedLabelGenerator | |
120 extends PolygonRenderer.DefaultLabelGenerator | |
121 { | |
122 /** | |
123 * <code>NumberFormat</code> which is used to turn a number into a | |
124 * specific format. | |
125 */ | |
126 protected NumberFormat format; | |
127 | |
128 /** | |
129 * Constructor | |
130 */ | |
131 public LocalizedLabelGenerator() { | |
132 } | |
133 | |
134 /** | |
135 * Constructor | |
136 * | |
137 * @param format See {@link #format} | |
138 */ | |
139 public LocalizedLabelGenerator(NumberFormat format) { | |
140 this.format = format; | |
141 } | |
142 | |
143 /** | |
144 * If label is a <code>Number</code>, it is turned into a format | |
145 * specified by {@link #format}. | |
146 * | |
147 * @param label Label to format. | |
148 * | |
149 * @return String representation of label. | |
150 */ | |
151 @Override | |
152 protected String toString(Object label) { | |
153 return label instanceof Number | |
154 ? format.format(((Number)label).doubleValue()) | |
155 : super.toString(label); | |
156 } | |
157 } // class LocalizedLabelGenerator | |
158 | |
159 public static double MARGIN_TOP = 0.05d; | |
160 public static double MARGIN_BOTTOM = 0.00d; | |
161 public static double MARGIN_LEFT = 0.00d; | |
162 public static double MARGIN_RIGHT = 0.05d; | |
163 | |
164 /** | |
165 * JFreeChart object stored at this place after chart creation. | |
166 */ | |
167 protected JFreeChart chart; | |
168 | |
169 /** | |
170 * Stores {@link de.intevation.gnv.jfreechart.PolygonDataset} which is used | |
171 * to create a vertical cross chart. | |
172 */ | |
173 protected AttributedXYColumns columns; | |
174 | |
175 /** | |
176 * Map which contains colors to fill polygons draw by this chart. | |
177 */ | |
178 protected Map<Integer, Paint> special; | |
179 | |
180 /** | |
181 * Object used to map value intervals to specific colors and descriptions. | |
182 */ | |
183 protected Palette palette; | |
184 | |
185 /** | |
186 * Locale object used for i18n support. | |
187 */ | |
188 protected Locale locale; | |
189 | |
190 /** | |
191 * Labels for decorating the chart. | |
192 */ | |
193 protected ChartLabels labels; | |
194 | |
195 /** | |
196 * Default Constructor | |
197 */ | |
198 public VerticalCrossSectionChart() { | |
199 } | |
200 | |
201 /** | |
202 * Constructor for VerticalCrossSectionChart creation. | |
203 * | |
204 * @param columns See {@link #columns} | |
205 * @param palette See {@link #palette} | |
206 * @param locale See {@link #locale} | |
207 * @param labels See {@link #labels} | |
208 */ | |
209 public VerticalCrossSectionChart( | |
210 AttributedXYColumns columns, | |
211 Palette palette, | |
212 Locale locale, | |
213 ChartLabels labels | |
214 ) { | |
215 this(columns, palette, null, locale, labels); | |
216 } | |
217 | |
218 /** | |
219 * Constructor for VerticalCrossSectionChart creation. | |
220 * | |
221 * @param columns See {@link #columns} | |
222 * @param palette See {@link #palette} | |
223 * @param special See {@link #special} | |
224 * @param locale See {@link #locale} | |
225 * @param labels See {@link #labels} | |
226 */ | |
227 public VerticalCrossSectionChart( | |
228 AttributedXYColumns columns, | |
229 Palette palette, | |
230 Map<Integer, Paint> special, | |
231 Locale locale, | |
232 ChartLabels labels | |
233 ) { | |
234 this.columns = columns; | |
235 this.palette = palette; | |
236 this.special = special; | |
237 this.locale = locale; | |
238 this.labels = labels; | |
239 } | |
240 | |
241 /** | |
242 * This method is used to create a JFreeChart from this object. A 2D plot is | |
243 * drawn and a legend panel is created containing each value range. | |
244 * | |
245 * @return JFreeChart object | |
246 */ | |
247 protected JFreeChart createChart() { | |
248 | |
249 boolean legendB = false; | |
250 boolean tooltips = false; | |
251 boolean urls = false; | |
252 | |
253 PlotOrientation po = PlotOrientation.HORIZONTAL; | |
254 PolygonDataset data = columns.getPolygonDataset(); | |
255 | |
256 HashSet<Integer> usedColors = new HashSet<Integer>(); | |
257 | |
258 for (int i = data.getSeriesCount()-1; i >= 0; --i) { | |
259 PolygonSeries ps = data.getSeries(i); | |
260 Integer fill = (Integer)ps.getAttribute("fill"); | |
261 if (fill != null | |
262 && (special != null && !special.containsKey(fill))) { | |
263 usedColors.add(fill); | |
264 } | |
265 } | |
266 | |
267 NumberFormat format = NumberFormat.getInstance(locale); | |
268 format.setMinimumFractionDigits(0); | |
269 format.setMaximumFractionDigits(2); | |
270 | |
271 PolygonRenderer renderer = new PolygonRenderer( | |
272 new PalettePaintLookup(palette, special), | |
273 new LocalizedLabelGenerator(format)); | |
274 | |
275 ValueAxis domainAxis = new NumberAxis(this.labels.getDomainAxisLabel()); | |
276 ValueAxis rangeAxis = new NumberAxis(this.labels.getRangeAxisLabel()); | |
277 | |
278 PolygonPlot plot = new PolygonPlot( | |
279 data, | |
280 renderer, | |
281 domainAxis, | |
282 rangeAxis, | |
283 null); | |
284 | |
285 plot.setOutlinePaint(Color.WHITE); | |
286 | |
287 String [] labels = new String[usedColors.size()]; | |
288 | |
289 int colors = palette.getSize(); | |
290 LookupPaintScale lookupPaint = | |
291 new LookupPaintScale(-0.5d, labels.length-0.5d, Color.white); | |
292 | |
293 Color color = null; | |
294 | |
295 for (int i = 0, j = labels.length-1; i < colors && j >= 0; i++) { | |
296 if (usedColors.contains(i)) { | |
297 Palette.Entry entry = palette.getEntryByIndex(i); | |
298 color = entry.getColor(); | |
299 labels[j] = entry.getDescription(); | |
300 lookupPaint.add(j-0.5d, color); | |
301 --j; | |
302 } | |
303 } | |
304 | |
305 JFreeChart chart = new JFreeChart( | |
306 this.labels.getTitle(), | |
307 JFreeChart.DEFAULT_TITLE_FONT, | |
308 plot, | |
309 legendB); | |
310 | |
311 chart.removeLegend(); | |
312 chart.addSubtitle(new TextTitle(this.labels.getSubtitle())); | |
313 | |
314 SymbolAxis scale = new SymbolAxis(this.labels.getParameterName(), labels); | |
315 scale.setRange(-1.5d, labels.length+0.5d); | |
316 scale.setGridBandsVisible(false); | |
317 scale.setPlot(plot); | |
318 | |
319 PaintScaleLegend legend = new PaintScaleLegend( | |
320 lookupPaint, scale); | |
321 legend.setMargin(new RectangleInsets(3d, 10d, 3d, 10d)); | |
322 legend.setPosition(RectangleEdge.LEFT); | |
323 legend.setAxisOffset(5d); | |
324 | |
325 chart.addSubtitle(legend); | |
326 | |
327 // XXX Workaround, because Axes labels are cut at the | |
328 // left/right/top/bottom edge. The following lines add a white border | |
329 // between data area and plot border. | |
330 // see http://www.jfree.org/phpBB2/viewtopic.php?f=3&t=22177&start=0&hilit=axis+labels+cut | |
331 ValueAxis xAxis = plot.getDomainAxis(); | |
332 Range xRange = xAxis.getRange(); | |
333 xRange = Range.expand(xRange, MARGIN_LEFT, MARGIN_RIGHT); | |
334 xAxis.setRange(xRange); | |
335 plot.setDomainAxis(xAxis); | |
336 | |
337 ValueAxis yAxis = plot.getRangeAxis(); | |
338 Range yRange = yAxis.getRange(); | |
339 yRange = Range.expand(yRange, MARGIN_BOTTOM, MARGIN_TOP); | |
340 yAxis.setRange(yRange); | |
341 plot.setRangeAxis(yAxis); | |
342 | |
343 chart.setPadding(new RectangleInsets(10d, 10d, 10d, 10d)); | |
344 | |
345 return chart; | |
346 } | |
347 | |
348 /** | |
349 * @see de.intevation.gnv.chart.Chart#generateChart() | |
350 */ | |
351 public JFreeChart generateChart() { | |
352 if (chart == null) { | |
353 chart = createChart(); | |
354 } | |
355 | |
356 return chart; | |
357 } | |
358 | |
359 /** | |
360 * Set the background paint of {@link #chart}. | |
361 * @param paint | |
362 */ | |
363 public void setBackgroundPaint(Paint paint) { | |
364 chart.setBackgroundPaint(paint); | |
365 } | |
366 } | |
367 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : |