Mercurial > dive4elements > gnv-client
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/XMLChartTheme.java Fri Sep 28 12:14:00 2012 +0200 @@ -0,0 +1,533 @@ +/* + * Copyright (c) 2010 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ + +package de.intevation.gnv.chart; + +import de.intevation.artifacts.common.utils.Config; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Paint; + +import java.awt.geom.Ellipse2D; + +import org.apache.log4j.Logger; + +import org.jfree.chart.StandardChartTheme; + +import org.jfree.chart.plot.XYPlot; + +import org.jfree.chart.renderer.xy.AbstractXYItemRenderer; +import org.jfree.chart.renderer.xy.XYBarRenderer; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; + +import org.jfree.ui.RectangleInsets; + +import org.jfree.util.UnitType; + +import org.w3c.dom.Document; + +/** + * Implementation of JFreeChart's default implementation + * <code>StandardChartTheme</code>. This class takes an xml document with a + * bunch of parameters and turns it into a <code>ChartTheme</code> to change + * the appearance of charts. + * + * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> + */ +public class XMLChartTheme +extends StandardChartTheme +{ + /** + * Default color. + */ + private static final Color DEFAULT_COLOR = Color.BLACK; + + /** + * Logger used for logging with log4j. + */ + private Logger log = Logger.getLogger(XMLChartTheme.class); + + /** + * Field storing the visibility of the domain crosshair + */ + protected boolean domainCrosshairVisible; + + /** + * Field storing the visibility of the range crosshair + */ + protected boolean rangeCrosshairVisible; + + /** + * Field storing the visiblity of lines. + */ + protected boolean renderLines; + + /** + * Field storing the visibility of data points + */ + protected boolean renderShapes; + + /** + * Field storing the width of a data point + */ + protected int pointWidth; + + /** + * Field storing the height of a data point. + */ + protected int pointHeight; + + /** + * Field storing the base color of a bin in a histogram chart + */ + protected Paint histogramBasePaint; + + + /** + * Constructor + * + * @param name Name for this theme. + */ + public XMLChartTheme(String name) { + super(name); + } + + + /** + * Setter method for the visibility of the domain crosshair. + * + * @param visible True, if domain crosshair should be visible + */ + public void setDomainCrosshairVisible(boolean visible) { + this.domainCrosshairVisible = visible; + } + + + /** + * Getter method for retrieving the visibility of the domain crosshair. + * + * @return Visibility of the domain crosshair. + */ + public boolean getDomainCrosshairVisible() { + return domainCrosshairVisible; + } + + + /** + * Getter method for retrieving the visibility of the range crosshair. + * + * @return Visibility of the range crosshair. + */ + public boolean getRangeCrosshairVisible() { + return rangeCrosshairVisible; + } + + + /** + * Setter method for the visibility of the range crosshair. + * + * @param visible True, if range crosshair should be visible + */ + public void setRangeCrosshairVisible(boolean visible) { + this.rangeCrosshairVisible = visible; + } + + + /** + * Method to set the bin color of histograms. + * + * @param c Bin color + */ + public void setHistogramBasePaint(Color c) { + this.histogramBasePaint = c; + } + + + /** + * Getter method for retrieving the bin color. + * + * @return Bin color + */ + public Paint getHistogramBasePaint() { + return histogramBasePaint; + } + + + /** + * Take a given xml document and read the configuration of a chart + * appearance. + * + * @param document XML document + */ + public void applyXMLConfiguration(Document document) { + log.debug("create XMLChartTheme"); + + init(document); + } + + + /** + * Start parsing the different settings from <code>document</code>. + * + * @param document XML document + */ + private void init(Document document) { + log.debug("init XMLChartTheme parameters"); + + initChartParameters(document); + initTitleParameters(document); + initSubtitleParameters(document); + initPlotParameters(document); + initAxisParameters(document); + initLegendParameters(document); + initRenderer(document); + initHistogramColor(document); + } + + + /** + * Read parameters configuring the title of a chart. + * + * @param document XML document + */ + private void initTitleParameters(Document document) { + log.debug("init title parameters."); + + int size = getInt(document, "theme/title/font/size/@value"); + String type = getString(document, "theme/title/font/type/@value"); + boolean bold = getBool(document, "theme/title/font/bold/@value"); + + setExtraLargeFont(createFont(type, size, bold)); + + String color = getString(document, "theme/title/font/color/@value"); + Color c = decodeColor(color); + if (c != null) + setTitlePaint(c); + } + + + /** + * Read parameters configuring the subtitle of a chart. + * + * @param document XML document + */ + private void initSubtitleParameters(Document document) { + log.debug("init title parameters."); + + int size = getInt(document, "theme/subtitle/font/size/@value"); + String type = getString(document, "theme/subtitle/font/type/@value"); + boolean bold = getBool(document, "theme/subtitle/font/bold/@value"); + + setLargeFont(createFont(type, size, bold)); + + String col = getString(document, "theme/subtitle/font/color/@value"); + setSubtitlePaint(Color.decode(col)); + } + + + /** + * Read parameters configuring the background color of a chart. + * + * @param document XML document + */ + private void initChartParameters(Document document) { + log.debug("init chart parameters."); + + String bg = getString(document, "theme/chart/background/color/@value"); + Color c = decodeColor(bg); + if (c != null) + setChartBackgroundPaint(c); + } + + + /** + * Read parameters configuring the plot of a chart. + * + * @param document XML document + */ + private void initPlotParameters(Document document) { + log.debug("init plot parameters."); + + String tmp = null; + tmp = getString(document, "theme/plot/background/color/@value"); + Color c = decodeColor(tmp); + if (c != null) + setPlotBackgroundPaint(c); + + tmp = getString(document, "theme/plot/outline/color/@value"); + c = decodeColor(tmp); + if (c != null) + setPlotOutlinePaint(c); + + tmp = getString(document, "theme/plot/domaingridline/color/@value"); + c = decodeColor(tmp); + if (c != null) + setDomainGridlinePaint(c); + + tmp = getString(document, "theme/plot/rangegridline/color/@value"); + c = decodeColor(tmp); + if (c != null) + setRangeGridlinePaint(c); + + boolean rangeCrosshairVisible = getBool( + document, "theme/plot/rangecrosshair/visible/@value"); + setRangeCrosshairVisible(rangeCrosshairVisible); + + boolean domainCrosshairVisible = getBool( + document, "theme/plot/domaincrosshair/visible/@value"); + setDomainCrosshairVisible(domainCrosshairVisible); + + int top = getInt(document, "theme/plot/offset/top/@value"); + int bottom = getInt(document, "theme/plot/offset/bottom/@value"); + int left = getInt(document, "theme/plot/offset/left/@value"); + int right = getInt(document, "theme/plot/offset/right/@value"); + setAxisOffset(new RectangleInsets( + UnitType.RELATIVE, + top, left, bottom, right) + ); + } + + + /** + * Read parameters configuring the axes of a plot. + * + * @param document XML document + */ + private void initAxisParameters(Document document) { + log.debug("init axis parameters."); + + String tmp = null; + tmp = getString(document, "theme/axis/label/color/@value"); + Color c = decodeColor(tmp); + if (c != null) + setAxisLabelPaint(c); + + tmp = getString(document, "theme/axis/ticklabel/color/@value"); + c = decodeColor(tmp); + if (c != null) + setTickLabelPaint(c); + } + + + /** + * Read parameters configuring the legend of a chart. + * + * @param document XML document + */ + private void initLegendParameters(Document document) { + log.debug("init legend parameters."); + + String tmp = null; + tmp = getString(document, "theme/legend/font/color/@value"); + Color c = decodeColor(tmp); + if (c != null) + setLegendItemPaint(c); + + tmp = getString(document, "theme/legend/background/color/@value"); + c = decodeColor(tmp); + if (c != null) + setLegendBackgroundPaint(c); + } + + + /** + * Read parameters configuring the renderer of a plot. + * + * @param document XML document + */ + private void initRenderer(Document document) { + log.debug("init renderer parameters."); + + pointWidth = getInt(document, "theme/plot/itemrenderer/width/@value"); + log.debug("Read point width of " + pointWidth); + pointHeight = getInt(document, "theme/plot/itemrenderer/height/@value"); + log.debug("Read point height of " + pointHeight); + renderLines = getBool( + document, "theme/plot/itemrenderer/renderLines/@value" + ); + renderShapes = getBool( + document, "theme/plot/itemrenderer/renderPoints/@value" + ); + } + + + /** + * Read base color of bins in histogram charts. + * + * @param document XML document + */ + private void initHistogramColor(Document document) { + log.debug("init histogram color"); + String tmp = getString(document, "theme/histogram/bar/color/@value"); + Color c = decodeColor(tmp); + + if (c != null) + setHistogramBasePaint(c); + } + + + /** + * Read a xpath expression and return the matched string. + * + * @param document Document + * @param xpath XPath expression + * + * @return Matched string + */ + private static String getString(Document document, String xpath) { + return Config.getStringXPath(document, xpath); + } + + + /** + * Read a xpath and turn it into an integer. + * + * @param document Document + * @param xpath XPath expression + * + * @return Matched string as integer representation. Return 0 if no integer + * have been found at <code>xpath</code>. + */ + private static int getInt(Document document, String xpath) { + String tmp = getString(document, xpath); + + if (tmp != null) + return Integer.parseInt(tmp); + else + return 0; + } + + + /** + * Read a xpath and turn it into a boolean. + * + * @param document Document + * @param xpath XPath expression + * + * @return Matched string as boolean representation. Return false if no + * boolean have been found at <code>xpath</code>. + */ + private static boolean getBool(Document document, String xpath) { + String tmp = getString(document, xpath); + + if (tmp != null) + return Boolean.parseBoolean(tmp); + else + return false; + } + + + /** + * Turns a string into a color using {@link java.awt.Color}. + * + * @param color as string + * + * @return Color + */ + protected Color decodeColor(String color) { + try { + if (color == null) + return null; + + return Color.decode(color); + } + catch (NumberFormatException nfe) { + log.warn("Error while parsing color: " + color, nfe); + } + + return null; + } + + + /** + * Create a font with the given parameters. + * + * @param type Font type + * @param size Font size + * @param bold Font weight + * + * @return Font + */ + protected Font createFont(String type, int size, boolean bold) { + Font font = null; + if (bold) + font = new Font(type, Font.BOLD, size); + else + font = new Font(type, Font.PLAIN, size); + + return font; + } + + + /** + * Apply settings of this <code>ChartTheme</code> to the given + * <code>XYPlot</code>. + * + * @param plot XYPlot + */ + @Override + protected void applyToXYPlot(XYPlot plot) { + log.debug("apply theme parameter to XYPlot"); + + super.applyToXYPlot(plot); + plot.setDomainCrosshairVisible(this.domainCrosshairVisible); + plot.setRangeCrosshairVisible(this.rangeCrosshairVisible); + + AbstractXYItemRenderer renderer = (AbstractXYItemRenderer) + plot.getRenderer(); + + if (renderer instanceof XYLineAndShapeRenderer) + applyToXYLineAndShapeRenderer(plot); + + if (renderer instanceof XYBarRenderer) + applyToXYBarRenderer(plot); + } + + + /** + * Apply settings of this <code>ChartTheme</code> to the + * <code>XYLineAndShapeRenderer</code> of the given <code>XYPlot</code>. + * + * @param plot XYPlot + */ + protected void applyToXYLineAndShapeRenderer(XYPlot plot) { + if (plot == null) + return; + + XYLineAndShapeRenderer renderer = + (XYLineAndShapeRenderer) plot.getRenderer(); + + Ellipse2D.Double point = new Ellipse2D.Double( + -(pointWidth/2), -(pointHeight/2), pointWidth, pointHeight + ); + + renderer.setSeriesShape(0, point); + renderer.setSeriesShapesVisible(0, renderShapes); + renderer.setSeriesLinesVisible(0, renderLines); + + plot.setRenderer(renderer); + } + + + /** + * Apply settings of this <code>ChartTheme</code> to the + * <code>XYBarRenderer</code> of the given <code>XYPlot</code>. + * + * @param plot XYPlot + */ + protected void applyToXYBarRenderer(XYPlot plot) { + if (plot == null) + return; + + XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer(); + + renderer.setSeriesPaint(0, histogramBasePaint); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :