Mercurial > dive4elements > gnv-client
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 : |