Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/chart/XMLChartTheme.java @ 774:d0a39efbfd96
Removed race-condition when trying to access the index of the next line color used in charts (applied patch in issue211).
gnv-artifacts/trunk@834 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Fri, 26 Mar 2010 10:06:36 +0000 |
parents | 79401c871da4 |
children | 9a828e5a2390 |
line wrap: on
line source
package de.intevation.gnv.chart; import java.awt.Font; import java.awt.Color; import java.awt.Paint; import java.awt.geom.Ellipse2D; import java.lang.NumberFormatException; 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; import de.intevation.artifactdatabase.Config; /** * 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 */ 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); } }