comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/XMLChartTheme.java @ 875:5e9efdda6894

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

http://dive4elements.wald.intevation.org