comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/XMLChartTheme.java @ 1119:7c4f81f74c47

merged gnv-artifacts
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:00 +0200
parents dec4257ad570
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.artifacts.common.utils.Config;
12
13 import java.awt.Color;
14 import java.awt.Font;
15 import java.awt.Paint;
16
17 import java.awt.geom.Ellipse2D;
18
19 import org.apache.log4j.Logger;
20
21 import org.jfree.chart.StandardChartTheme;
22
23 import org.jfree.chart.plot.XYPlot;
24
25 import org.jfree.chart.renderer.xy.AbstractXYItemRenderer;
26 import org.jfree.chart.renderer.xy.XYBarRenderer;
27 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
28
29 import org.jfree.ui.RectangleInsets;
30
31 import org.jfree.util.UnitType;
32
33 import org.w3c.dom.Document;
34
35 /**
36 * Implementation of JFreeChart's default implementation
37 * <code>StandardChartTheme</code>. This class takes an xml document with a
38 * bunch of parameters and turns it into a <code>ChartTheme</code> to change
39 * the appearance of charts.
40 *
41 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
42 */
43 public class XMLChartTheme
44 extends StandardChartTheme
45 {
46 /**
47 * Default color.
48 */
49 private static final Color DEFAULT_COLOR = Color.BLACK;
50
51 /**
52 * Logger used for logging with log4j.
53 */
54 private Logger log = Logger.getLogger(XMLChartTheme.class);
55
56 /**
57 * Field storing the visibility of the domain crosshair
58 */
59 protected boolean domainCrosshairVisible;
60
61 /**
62 * Field storing the visibility of the range crosshair
63 */
64 protected boolean rangeCrosshairVisible;
65
66 /**
67 * Field storing the visiblity of lines.
68 */
69 protected boolean renderLines;
70
71 /**
72 * Field storing the visibility of data points
73 */
74 protected boolean renderShapes;
75
76 /**
77 * Field storing the width of a data point
78 */
79 protected int pointWidth;
80
81 /**
82 * Field storing the height of a data point.
83 */
84 protected int pointHeight;
85
86 /**
87 * Field storing the base color of a bin in a histogram chart
88 */
89 protected Paint histogramBasePaint;
90
91
92 /**
93 * Constructor
94 *
95 * @param name Name for this theme.
96 */
97 public XMLChartTheme(String name) {
98 super(name);
99 }
100
101
102 /**
103 * Setter method for the visibility of the domain crosshair.
104 *
105 * @param visible True, if domain crosshair should be visible
106 */
107 public void setDomainCrosshairVisible(boolean visible) {
108 this.domainCrosshairVisible = visible;
109 }
110
111
112 /**
113 * Getter method for retrieving the visibility of the domain crosshair.
114 *
115 * @return Visibility of the domain crosshair.
116 */
117 public boolean getDomainCrosshairVisible() {
118 return domainCrosshairVisible;
119 }
120
121
122 /**
123 * Getter method for retrieving the visibility of the range crosshair.
124 *
125 * @return Visibility of the range crosshair.
126 */
127 public boolean getRangeCrosshairVisible() {
128 return rangeCrosshairVisible;
129 }
130
131
132 /**
133 * Setter method for the visibility of the range crosshair.
134 *
135 * @param visible True, if range crosshair should be visible
136 */
137 public void setRangeCrosshairVisible(boolean visible) {
138 this.rangeCrosshairVisible = visible;
139 }
140
141
142 /**
143 * Method to set the bin color of histograms.
144 *
145 * @param c Bin color
146 */
147 public void setHistogramBasePaint(Color c) {
148 this.histogramBasePaint = c;
149 }
150
151
152 /**
153 * Getter method for retrieving the bin color.
154 *
155 * @return Bin color
156 */
157 public Paint getHistogramBasePaint() {
158 return histogramBasePaint;
159 }
160
161
162 /**
163 * Take a given xml document and read the configuration of a chart
164 * appearance.
165 *
166 * @param document XML document
167 */
168 public void applyXMLConfiguration(Document document) {
169 log.debug("create XMLChartTheme");
170
171 init(document);
172 }
173
174
175 /**
176 * Start parsing the different settings from <code>document</code>.
177 *
178 * @param document XML document
179 */
180 private void init(Document document) {
181 log.debug("init XMLChartTheme parameters");
182
183 initChartParameters(document);
184 initTitleParameters(document);
185 initSubtitleParameters(document);
186 initPlotParameters(document);
187 initAxisParameters(document);
188 initLegendParameters(document);
189 initRenderer(document);
190 initHistogramColor(document);
191 }
192
193
194 /**
195 * Read parameters configuring the title of a chart.
196 *
197 * @param document XML document
198 */
199 private void initTitleParameters(Document document) {
200 log.debug("init title parameters.");
201
202 int size = getInt(document, "theme/title/font/size/@value");
203 String type = getString(document, "theme/title/font/type/@value");
204 boolean bold = getBool(document, "theme/title/font/bold/@value");
205
206 setExtraLargeFont(createFont(type, size, bold));
207
208 String color = getString(document, "theme/title/font/color/@value");
209 Color c = decodeColor(color);
210 if (c != null)
211 setTitlePaint(c);
212 }
213
214
215 /**
216 * Read parameters configuring the subtitle of a chart.
217 *
218 * @param document XML document
219 */
220 private void initSubtitleParameters(Document document) {
221 log.debug("init title parameters.");
222
223 int size = getInt(document, "theme/subtitle/font/size/@value");
224 String type = getString(document, "theme/subtitle/font/type/@value");
225 boolean bold = getBool(document, "theme/subtitle/font/bold/@value");
226
227 setLargeFont(createFont(type, size, bold));
228
229 String col = getString(document, "theme/subtitle/font/color/@value");
230 setSubtitlePaint(Color.decode(col));
231 }
232
233
234 /**
235 * Read parameters configuring the background color of a chart.
236 *
237 * @param document XML document
238 */
239 private void initChartParameters(Document document) {
240 log.debug("init chart parameters.");
241
242 String bg = getString(document, "theme/chart/background/color/@value");
243 Color c = decodeColor(bg);
244 if (c != null)
245 setChartBackgroundPaint(c);
246 }
247
248
249 /**
250 * Read parameters configuring the plot of a chart.
251 *
252 * @param document XML document
253 */
254 private void initPlotParameters(Document document) {
255 log.debug("init plot parameters.");
256
257 String tmp = null;
258 tmp = getString(document, "theme/plot/background/color/@value");
259 Color c = decodeColor(tmp);
260 if (c != null)
261 setPlotBackgroundPaint(c);
262
263 tmp = getString(document, "theme/plot/outline/color/@value");
264 c = decodeColor(tmp);
265 if (c != null)
266 setPlotOutlinePaint(c);
267
268 tmp = getString(document, "theme/plot/domaingridline/color/@value");
269 c = decodeColor(tmp);
270 if (c != null)
271 setDomainGridlinePaint(c);
272
273 tmp = getString(document, "theme/plot/rangegridline/color/@value");
274 c = decodeColor(tmp);
275 if (c != null)
276 setRangeGridlinePaint(c);
277
278 boolean rangeCrosshairVisible = getBool(
279 document, "theme/plot/rangecrosshair/visible/@value");
280 setRangeCrosshairVisible(rangeCrosshairVisible);
281
282 boolean domainCrosshairVisible = getBool(
283 document, "theme/plot/domaincrosshair/visible/@value");
284 setDomainCrosshairVisible(domainCrosshairVisible);
285
286 int top = getInt(document, "theme/plot/offset/top/@value");
287 int bottom = getInt(document, "theme/plot/offset/bottom/@value");
288 int left = getInt(document, "theme/plot/offset/left/@value");
289 int right = getInt(document, "theme/plot/offset/right/@value");
290 setAxisOffset(new RectangleInsets(
291 UnitType.RELATIVE,
292 top, left, bottom, right)
293 );
294 }
295
296
297 /**
298 * Read parameters configuring the axes of a plot.
299 *
300 * @param document XML document
301 */
302 private void initAxisParameters(Document document) {
303 log.debug("init axis parameters.");
304
305 String tmp = null;
306 tmp = getString(document, "theme/axis/label/color/@value");
307 Color c = decodeColor(tmp);
308 if (c != null)
309 setAxisLabelPaint(c);
310
311 tmp = getString(document, "theme/axis/ticklabel/color/@value");
312 c = decodeColor(tmp);
313 if (c != null)
314 setTickLabelPaint(c);
315 }
316
317
318 /**
319 * Read parameters configuring the legend of a chart.
320 *
321 * @param document XML document
322 */
323 private void initLegendParameters(Document document) {
324 log.debug("init legend parameters.");
325
326 String tmp = null;
327 tmp = getString(document, "theme/legend/font/color/@value");
328 Color c = decodeColor(tmp);
329 if (c != null)
330 setLegendItemPaint(c);
331
332 tmp = getString(document, "theme/legend/background/color/@value");
333 c = decodeColor(tmp);
334 if (c != null)
335 setLegendBackgroundPaint(c);
336 }
337
338
339 /**
340 * Read parameters configuring the renderer of a plot.
341 *
342 * @param document XML document
343 */
344 private void initRenderer(Document document) {
345 log.debug("init renderer parameters.");
346
347 pointWidth = getInt(document, "theme/plot/itemrenderer/width/@value");
348 log.debug("Read point width of " + pointWidth);
349 pointHeight = getInt(document, "theme/plot/itemrenderer/height/@value");
350 log.debug("Read point height of " + pointHeight);
351 renderLines = getBool(
352 document, "theme/plot/itemrenderer/renderLines/@value"
353 );
354 renderShapes = getBool(
355 document, "theme/plot/itemrenderer/renderPoints/@value"
356 );
357 }
358
359
360 /**
361 * Read base color of bins in histogram charts.
362 *
363 * @param document XML document
364 */
365 private void initHistogramColor(Document document) {
366 log.debug("init histogram color");
367 String tmp = getString(document, "theme/histogram/bar/color/@value");
368 Color c = decodeColor(tmp);
369
370 if (c != null)
371 setHistogramBasePaint(c);
372 }
373
374
375 /**
376 * Read a xpath expression and return the matched string.
377 *
378 * @param document Document
379 * @param xpath XPath expression
380 *
381 * @return Matched string
382 */
383 private static String getString(Document document, String xpath) {
384 return Config.getStringXPath(document, xpath);
385 }
386
387
388 /**
389 * Read a xpath and turn it into an integer.
390 *
391 * @param document Document
392 * @param xpath XPath expression
393 *
394 * @return Matched string as integer representation. Return 0 if no integer
395 * have been found at <code>xpath</code>.
396 */
397 private static int getInt(Document document, String xpath) {
398 String tmp = getString(document, xpath);
399
400 if (tmp != null)
401 return Integer.parseInt(tmp);
402 else
403 return 0;
404 }
405
406
407 /**
408 * Read a xpath and turn it into a boolean.
409 *
410 * @param document Document
411 * @param xpath XPath expression
412 *
413 * @return Matched string as boolean representation. Return false if no
414 * boolean have been found at <code>xpath</code>.
415 */
416 private static boolean getBool(Document document, String xpath) {
417 String tmp = getString(document, xpath);
418
419 if (tmp != null)
420 return Boolean.parseBoolean(tmp);
421 else
422 return false;
423 }
424
425
426 /**
427 * Turns a string into a color using {@link java.awt.Color}.
428 *
429 * @param color as string
430 *
431 * @return Color
432 */
433 protected Color decodeColor(String color) {
434 try {
435 if (color == null)
436 return null;
437
438 return Color.decode(color);
439 }
440 catch (NumberFormatException nfe) {
441 log.warn("Error while parsing color: " + color, nfe);
442 }
443
444 return null;
445 }
446
447
448 /**
449 * Create a font with the given parameters.
450 *
451 * @param type Font type
452 * @param size Font size
453 * @param bold Font weight
454 *
455 * @return Font
456 */
457 protected Font createFont(String type, int size, boolean bold) {
458 Font font = null;
459 if (bold)
460 font = new Font(type, Font.BOLD, size);
461 else
462 font = new Font(type, Font.PLAIN, size);
463
464 return font;
465 }
466
467
468 /**
469 * Apply settings of this <code>ChartTheme</code> to the given
470 * <code>XYPlot</code>.
471 *
472 * @param plot XYPlot
473 */
474 @Override
475 protected void applyToXYPlot(XYPlot plot) {
476 log.debug("apply theme parameter to XYPlot");
477
478 super.applyToXYPlot(plot);
479 plot.setDomainCrosshairVisible(this.domainCrosshairVisible);
480 plot.setRangeCrosshairVisible(this.rangeCrosshairVisible);
481
482 AbstractXYItemRenderer renderer = (AbstractXYItemRenderer)
483 plot.getRenderer();
484
485 if (renderer instanceof XYLineAndShapeRenderer)
486 applyToXYLineAndShapeRenderer(plot);
487
488 if (renderer instanceof XYBarRenderer)
489 applyToXYBarRenderer(plot);
490 }
491
492
493 /**
494 * Apply settings of this <code>ChartTheme</code> to the
495 * <code>XYLineAndShapeRenderer</code> of the given <code>XYPlot</code>.
496 *
497 * @param plot XYPlot
498 */
499 protected void applyToXYLineAndShapeRenderer(XYPlot plot) {
500 if (plot == null)
501 return;
502
503 XYLineAndShapeRenderer renderer =
504 (XYLineAndShapeRenderer) plot.getRenderer();
505
506 Ellipse2D.Double point = new Ellipse2D.Double(
507 -(pointWidth/2), -(pointHeight/2), pointWidth, pointHeight
508 );
509
510 renderer.setSeriesShape(0, point);
511 renderer.setSeriesShapesVisible(0, renderShapes);
512 renderer.setSeriesLinesVisible(0, renderLines);
513
514 plot.setRenderer(renderer);
515 }
516
517
518 /**
519 * Apply settings of this <code>ChartTheme</code> to the
520 * <code>XYBarRenderer</code> of the given <code>XYPlot</code>.
521 *
522 * @param plot XYPlot
523 */
524 protected void applyToXYBarRenderer(XYPlot plot) {
525 if (plot == null)
526 return;
527
528 XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer();
529
530 renderer.setSeriesPaint(0, histogramBasePaint);
531 }
532 }
533 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org