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 :

http://dive4elements.wald.intevation.org