changeset 304:a16d337c5678

The style of charts can be configured with ChartThemes using XML configuration files. gnv-artifacts/trunk@362 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Mon, 23 Nov 2009 17:01:28 +0000
parents 9ba2cf8cad8d
children 91c37bf28c0e
files gnv-artifacts/ChangeLog gnv-artifacts/doc/conf/charttemplate.xml gnv-artifacts/src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java gnv-artifacts/src/main/java/de/intevation/gnv/chart/XMLChartTheme.java gnv-artifacts/src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java
diffstat 5 files changed, 367 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/gnv-artifacts/ChangeLog	Fri Nov 20 15:45:25 2009 +0000
+++ b/gnv-artifacts/ChangeLog	Mon Nov 23 17:01:28 2009 +0000
@@ -1,3 +1,21 @@
+2009-11-23  Ingo Weinzierl <ingo.weinzierl@intevation.de>
+
+	* doc/conf/charttemplate.xml: Added configuration file for chart themes.
+
+	* src/main/java/de/intevation/gnv/chart/XMLChartTheme.java: Theme class for
+	  reading xml files which describe chart styles. It extends the
+	  StandardChartTheme class of JFreeChart which defines default values for
+	  chart parameters. It is possible to apply different xml configurations for
+	  different charts.
+
+	* src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java,
+	  src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java:
+	  Before creating a new chart, an instance of XMLChartTheme is initialized 
+	  which is responsible for the chart style.
+
+	  NOTE: 'charttemplate.xml' is used by artifact server and has to be placed
+	  in the config directory.
+
 2009-11-20  Ingo Weinzierl <ingo.weinzierl@intevation.de>
 
 	* src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/doc/conf/charttemplate.xml	Mon Nov 23 17:01:28 2009 +0000
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<theme>
+    <name value="Default Theme" />
+    <!-- ========================= chart =======================!-->
+    <chart>
+        <background>
+            <color value="0xFFFFFF" />
+        </background>
+    </chart>
+    <!-- ========================= title ==========================!-->
+    <title>
+        <font>
+            <size value="20" />
+            <type value="Tahoma" />
+            <color value="0x000000" />
+            <bold value="true" />
+        </font>
+    </title>
+    <!-- ========================= subtitle =======================!-->
+    <subtitle>
+        <font>
+            <size value="14" />
+            <type value="Tahoma" />
+            <color value="0x000000" />
+            <bold value="false" />
+        </font>
+    </subtitle>
+    <!-- ========================= legend =======================!-->
+    <legend>
+        <font>
+            <size value="12" />
+            <color value="0x000000" />
+        </font>
+        <background>
+            <color value="0xFFFFFF" />
+        </background>
+    </legend>
+    <!-- ========================= plot =======================!-->
+    <plot>
+        <background>
+            <color value="0xDDDDDD" />
+        </background>
+        <outline>
+            <color value="0xAAAAAA" />
+        </outline>
+        <domaingridline>
+            <color value="0xFFFFFF" />
+        </domaingridline>
+        <rangegridline>
+            <color value="0xFFFFFF" />
+        </rangegridline>
+        <domaincrosshair>
+            <visible value="true" />
+        </domaincrosshair>
+        <rangecrosshair>
+            <visible value="true" />
+        </rangecrosshair>
+        <offset>
+            <top>5</top>
+            <bottom>5</bottom>
+            <left>5</left>
+            <right>5</right>
+        </offset>
+    </plot>
+    <!-- ========================= axis =======================!-->
+    <axis>
+        <label>
+            <color value="0x000000" />
+        </label>
+        <ticklabel>
+            <color value="0x000000" />
+        </ticklabel>
+    </axis>
+</theme>
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java	Fri Nov 20 15:45:25 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/AbstractXYLineChart.java	Mon Nov 23 17:01:28 2009 +0000
@@ -60,7 +60,9 @@
             false
         );
 
+        theme.apply(chart);
         initData();
+
         return chart;
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/XMLChartTheme.java	Mon Nov 23 17:01:28 2009 +0000
@@ -0,0 +1,250 @@
+package de.intevation.gnv.chart;
+
+import java.awt.Font;
+import java.awt.Color;
+import java.lang.NumberFormatException;
+
+import org.apache.log4j.Logger;
+
+import org.jfree.chart.StandardChartTheme;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.ui.RectangleInsets;
+import org.jfree.util.UnitType;
+
+
+import org.w3c.dom.Document;
+
+import de.intevation.artifactdatabase.Config;
+
+/**
+ * @author Ingo Weinzierl <ingo.weinzierl@intevation.de>
+ */
+public class XMLChartTheme
+extends      StandardChartTheme
+{
+    private static final Color DEFAULT_COLOR = Color.BLACK;
+
+    private Logger log = Logger.getLogger(XMLChartTheme.class);
+
+    protected boolean domainCrosshairVisible;
+    protected boolean rangeCrosshairVisible;
+
+
+    public XMLChartTheme(String name) {
+        super(name);
+    }
+
+
+    public void setDomainCrosshairVisible(boolean visible) {
+        this.domainCrosshairVisible = visible;
+    }
+
+
+    public boolean getDomainCrosshairVisible() {
+        return domainCrosshairVisible;
+    }
+
+
+    public boolean getRangeCrosshairVisible() {
+        return rangeCrosshairVisible;
+    }
+
+
+    public void setRangeCrosshairVisible(boolean visible) {
+        this.rangeCrosshairVisible = visible;
+    }
+
+
+    public void applyXMLConfiguration(Document document) {
+        log.debug("create XMLChartTheme");
+
+        init(document);
+    }
+
+
+    private void init(Document document) {
+        log.debug("init XMLChartTheme parameters");
+
+        initChartParameters(document);
+        initTitleParameters(document);
+        initSubtitleParameters(document);
+        initPlotParameters(document);
+        initAxisParameters(document);
+        initLegendParameters(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);
+    }
+
+
+    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));
+    }
+
+
+    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);
+    }
+
+
+    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)
+        );
+    }
+
+
+    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);
+    }
+
+
+    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);
+    }
+
+
+    private static String getString(Document document, String xpath) {
+        return Config.getStringXPath(document, xpath);
+    }
+
+
+    private static int getInt(Document document, String xpath) {
+        String tmp = getString(document, xpath);
+
+        if (tmp != null)
+            return Integer.parseInt(tmp);
+        else
+            return 0;
+    }
+
+
+    private static boolean getBool(Document document, String xpath) {
+        String tmp = getString(document, xpath);
+
+        if (tmp != null)
+            return Boolean.parseBoolean(tmp);
+        else
+            return false;
+    }
+
+
+    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;
+    }
+
+
+    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;
+    }
+
+
+    protected void applyToXYPlot(XYPlot plot) {
+        log.debug("apply theme parameter to XYPlot");
+
+        super.applyToXYPlot(plot);
+        plot.setDomainCrosshairVisible(this.domainCrosshairVisible);
+        plot.setRangeCrosshairVisible(this.rangeCrosshairVisible);
+    }
+}
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java	Fri Nov 20 15:45:25 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/transition/timeseries/TimeSeriesOutputTransition.java	Mon Nov 23 17:01:28 2009 +0000
@@ -3,9 +3,8 @@
  */
 package de.intevation.gnv.transition.timeseries;
 
-import java.awt.Color;
-import java.awt.Dimension;
 import java.io.IOException;
+import java.io.File;
 import java.io.OutputStream;
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
@@ -39,8 +38,8 @@
 import de.intevation.gnv.artifacts.ressource.RessourceFactory;
 import de.intevation.gnv.chart.Chart;
 import de.intevation.gnv.chart.ChartLabels;
-import de.intevation.gnv.chart.ChartStyle;
 import de.intevation.gnv.chart.TimeSeriesChart;
+import de.intevation.gnv.chart.XMLChartTheme;
 import de.intevation.gnv.chart.exception.TechnicalChartException;
 import de.intevation.gnv.exports.DefaultExport;
 import de.intevation.gnv.exports.DefaultDataCollector;
@@ -213,8 +212,6 @@
                 Collection<KeyValueDescibeData> parameters = this.getParameters(uuid);
                 Collection<KeyValueDescibeData> measurements = this.getMeasurements(uuid);
                 Collection<KeyValueDescibeData> dates = this.getDates(uuid);
-                ChartStyle chartStyle = this
-                        .creatStyle(chartWidth, chartHeight);
                 ChartLabels chartLables = new ChartLabels(this.getFisName(callMeta.getLanguages())+" "+this
                         .getSelectedFeatureName(uuid), this.domainLable);
 
@@ -225,10 +222,11 @@
                     parameters,
                     measurements,
                     dates,
-                    chartStyle,
                     chartLables,
                     uuid,
-                    exportFormat
+                    exportFormat,
+                    chartWidth,
+                    chartHeight
                 );
             } else if (outputMode.equalsIgnoreCase("csv")) {
                 log.debug("CSV-File will be generated.");
@@ -398,17 +396,17 @@
         Collection   parameters,
         Collection   measurements,
         Collection   dates,
-        ChartStyle   chartStyle,
         ChartLabels  chartLables,
         String       uuid,
-        String       exportFormat
+        String       exportFormat,
+        int          width,
+        int          height
     )
     throws IOException, TechnicalChartException
     {
         log.debug("Create chart.");
         Chart chart = getChart(
             chartLables,
-            null, // ChartTheme
             parameters,
             measurements,
             getChartResult(uuid),
@@ -422,10 +420,6 @@
             return;
         }
 
-        Dimension dim    = chartStyle.getChartSize();
-        int       width  = new Double(dim.getWidth()).intValue();
-        int       height = new Double(dim.getHeight()).intValue();
-
         log.debug(
             "export chart as " + exportFormat +
             " in " + width + "x" + height
@@ -440,7 +434,6 @@
 
     protected Chart getChart(
         ChartLabels  chartLables,
-        ChartTheme   chartTheme,
         Collection   parameters,
         Collection   measurements,
         Collection   result,
@@ -461,7 +454,7 @@
         log.info("Chart not in cache yet.");
         chart = new TimeSeriesChart(
             chartLables,
-            null,
+            createStyle(),
             parameters,
             measurements,
             result,
@@ -478,15 +471,21 @@
         return chart;
     }
 
-    protected ChartStyle creatStyle(int witdh, int height) {
-        // TODO Konfigurierbar machen
-        de.intevation.gnv.chart.Insets lInsets = new de.intevation.gnv.chart.Insets(
-                5d, 5d, 5d, 5d);
-        Dimension lChartSize = new Dimension(witdh, height);
-        return new ChartStyle(Color.white, new Color(230, 230, 230),
-                Color.white, Color.white, true, true, lInsets, lChartSize);
+    protected ChartTheme createStyle() {
+        XMLChartTheme theme = null;
+
+        Document template = Config.getChartTemplate();
+        String   name     = Config.getStringXPath(
+            template,
+            "theme/name/@value"
+        );
+
+        theme  = new XMLChartTheme(name);
+        theme.applyXMLConfiguration(template);
+
+        return theme;
     }
-    
+
     protected String getFisName(PreferredLocale[] preferredLocales){
         String returnValue = "";
         InputData inputData = this.inputData.get("fisname");

http://dive4elements.wald.intevation.org