changeset 924:f7761914f745

An initial implementation to render chart series based on the XML configuration in themes.xml. flys-artifacts/trunk@2276 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Fri, 01 Jul 2011 14:46:13 +0000
parents 7ca4a287cd0e
children 0cb1a70b8b92
files flys-artifacts/ChangeLog flys-artifacts/doc/conf/themes.xml flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeCurveGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/StyledXYSeries.java flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java
diffstat 9 files changed, 297 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Fri Jul 01 11:16:11 2011 +0000
+++ b/flys-artifacts/ChangeLog	Fri Jul 01 14:46:13 2011 +0000
@@ -1,3 +1,32 @@
+2011-07-01  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/StyledXYSeries.java: New. This
+	  XYSeries stores the style information that should be used to render this
+	  series. These information are stored as raw XML documents. A public
+	  method can be used to apply those style information to a
+	  XYLineAndShapeRenderer.
+
+	  Note: The only two attributes currently supported by StyledXYSeries
+	  items are "linesize" and "linecolor".
+
+	* doc/conf/themes.xml: Added some more basic themes for the four
+	  calculation methods.
+
+	* src/main/java/de/intevation/flys/exports/XYChartGenerator.java: This
+	  generator now tries to apply themes for all series contained in the
+	  chart. If a series is no instance of StyledXYSeries, the default
+	  renderer is used.
+
+	* src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java,
+	  src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/DischargeCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java:
+	  Removed the code that had been introduced to adapt renderers statically.
+	  Now, each of these concrete ChartGenerators instantiates StyledXYSeries
+	  items to put the curves into the chart. Those items contain style
+	  information now!
+
 2011-07-01  Ingo Weinzierl <ingo@intevation.de>
 
 	flys/issue135 (Diagramm: Trotz abgeschalteter Themen bleiben Beschriftungen bestehen)
--- a/flys-artifacts/doc/conf/themes.xml	Fri Jul 01 11:16:11 2011 +0000
+++ b/flys-artifacts/doc/conf/themes.xml	Fri Jul 01 14:46:13 2011 +0000
@@ -5,21 +5,103 @@
         <inherits>
             <inherit from="HiddenColorLines"/>
         </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe" default="0, 0, 153"/>
+            <field name="linesize"  type="int"   display="Liniendicke" default="2" hints="h"/>
+        </fields>
     </theme>
 
+    <!--
+        Discharge Longitudinal Section
+    -->
     <theme name="LongitudinalSectionW">
         <inherits>
             <inherit from="HiddenColorLines"/>
         </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe" default="204, 204, 204"/>
+        </fields>
     </theme>
 
     <theme name="LongitudinalSectionQ">
         <inherits>
             <inherit from="HiddenColorLines"/>
         </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe" default="204, 204, 204"/>
+        </fields>
     </theme>
 
 
+    <!--
+        Computed Discharge Curves
+    -->
+    <theme name="ComputedDischargeCurve">
+        <inherits>
+            <inherit from="HiddenColorLines"/>
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe" default="0, 0, 153"/>
+            <field name="linesize"  type="int"   display="Liniendicke" default="2" hints="h"/>
+        </fields>
+    </theme>
+
+
+    <!--
+        Duration Curves
+    -->
+    <theme name="DurationCurveW">
+        <inherits>
+            <inherit from="HiddenColorLines"/>
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe" default="0,51,204"/>
+            <field name="linesize"  type="int"   display="Liniendicke" default="2" hints="h"/>
+        </fields>
+    </theme>
+
+    <theme name="DurationCurveQ">
+        <inherits>
+            <inherit from="HiddenColorLines"/>
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe" default="0,204,0"/>
+            <field name="linesize"  type="int"   display="Liniendicke" default="2" hints="h"/>
+        </fields>
+    </theme>
+
+
+    <!--
+        Discharge Longitudinal Section
+    -->
+    <theme name="DischargeLongitudinalSectionW">
+        <inherits>
+            <inherit from="HiddenColorLines"/>
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe" default="204, 204, 204"/>
+        </fields>
+    </theme>
+
+
+    <theme name="DischargeLongitudinalSectionC">
+        <inherits>
+            <inherit from="HiddenColorLines"/>
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe" default="255, 0 , 0"/>
+        </fields>
+    </theme>
+
+    <theme name="DischargeLongitudinalSectionQ">
+        <inherits>
+            <inherit from="HiddenColorLines"/>
+        </inherits>
+        <fields>
+            <field name="linecolor" type="Color" display="Linienfarbe" default="204, 204, 204"/>
+        </fields>
+    </theme>
+
 
     <!-- Virtual themes are following now! -->
     <theme name="Lines" type="virtual">
@@ -55,8 +137,14 @@
     <!-- Mappings are following now. A mapping maps between a name of a facet
          and a theme. -->
     <mappings>
-        <mapping from="discharge_curve.curve" to="DischargeCurve"/>
         <mapping from="longitudinal_section.w" to="LongitudinalSectionW"/>
         <mapping from="longitudinal_section.q" to="LongitudinalSectionQ"/>
+        <mapping from="discharge_curve.curve" to="DischargeCurve"/>
+        <mapping from="computed_discharge_curve.q" to="ComputedDischargeCurve"/>
+        <mapping from="duration_curve.w" to="DurationCurveW"/>
+        <mapping from="duration_curve.q" to="DurationCurveQ"/>
+        <mapping from="discharge_longitudinal_section.w" to="DischargeLongitudinalSectionW"/>
+        <mapping from="discharge_longitudinal_section.c" to="DischargeLongitudinalSectionC"/>
+        <mapping from="discharge_longitudinal_section.q" to="DischargeLongitudinalSectionQ"/>
     </mappings>
 </themes>
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java	Fri Jul 01 11:16:11 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java	Fri Jul 01 14:46:13 2011 +0000
@@ -80,7 +80,7 @@
         Facet        f    = flys.getNativeFacet(facet);
 
         if (name != null && name.equals(COMPUTED_DISCHARGE_Q)) {
-            doQOut((WQKms) f.getData(artifact, context));
+            doQOut((WQKms) f.getData(artifact, context), attr);
         }
         else {
             logger.warn("Unknown facet type for computed discharge: " + name);
@@ -89,12 +89,12 @@
     }
 
 
-    protected void doQOut(WQKms wqkms) {
+    protected void doQOut(WQKms wqkms, Document theme) {
         int size = wqkms.size();
 
         double[]   res  = new double[3];
 
-        XYSeries series = new XYSeries(getSeriesName(wqkms));
+        XYSeries series = new StyledXYSeries(getSeriesName(wqkms), theme);
         for (int i = 0; i < size; i++) {
             res = wqkms.get(i, res);
             series.add(res[1], res[0]);
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeCurveGenerator.java	Fri Jul 01 11:16:11 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeCurveGenerator.java	Fri Jul 01 14:46:13 2011 +0000
@@ -136,7 +136,7 @@
 
         int size = values != null ? values[0].length : 0;
 
-        XYSeries series = new XYSeries(seriesName);
+        XYSeries series = new StyledXYSeries(seriesName, attr);
 
         for (int i = 0; i < size; i++) {
             series.add(values[0][i], values[1][i]);
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java	Fri Jul 01 11:16:11 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java	Fri Jul 01 14:46:13 2011 +0000
@@ -1,11 +1,7 @@
 package de.intevation.flys.exports;
 
-import java.awt.Color;
-
 import org.apache.log4j.Logger;
 
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
 import org.jfree.data.xy.XYSeries;
 
 import org.w3c.dom.Document;
@@ -38,32 +34,6 @@
 
 
     @Override
-    protected void adjustPlot(XYPlot plot) {
-        super.adjustPlot(plot);
-
-        //// TODO REMOVE THIS CODE, IF WE HAVE INTRODUCED THEMES!
-        //XYLineAndShapeRenderer rw = (XYLineAndShapeRenderer)
-        //    plot.getRendererForDataset(w);
-
-        //XYLineAndShapeRenderer rcw = null;
-        //try {
-        //    rcw = (XYLineAndShapeRenderer) rw.clone();
-        //}
-        //catch (Exception e) {
-        //    logger.error(e, e);
-        //}
-
-        //int cwNum = cw.getSeriesCount();
-
-        //for (int i = 0; i < cwNum; i++) {
-        //    rcw.setSeriesPaint(i, Color.RED);
-        //}
-
-        //plot.setRenderer(2, rcw);
-    }
-
-
-    @Override
     public void doOut(Artifact artifact, Facet facet, Document attr) {
         logger.debug("DischargeLongitudinalSectionGenerator.doOut");
 
@@ -81,13 +51,13 @@
         Facet        f    = flys.getNativeFacet(facet);
 
         if (name.equals(DISCHARGE_LONGITUDINAL_W)) {
-            doWOut((WQKms) f.getData(artifact, context));
+            doWOut((WQKms) f.getData(artifact, context), attr);
         }
         else if (name.equals(DISCHARGE_LONGITUDINAL_Q)) {
-            doQOut((WQKms) f.getData(artifact, context));
+            doQOut((WQKms) f.getData(artifact, context), attr);
         }
         else if (name.equals(DISCHARGE_LONGITUDINAL_C)) {
-            doCorrectedWOut((WQCKms) f.getData(artifact, context));
+            doCorrectedWOut((WQCKms) f.getData(artifact, context), attr);
         }
         else {
             logger.warn("Unknown facet name: " + name);
@@ -99,14 +69,18 @@
      * Adds a new series for the corrected W curve.
      *
      * @param wqckms The object that contains the corrected W values.
+     * @param theme The theme that contains styling information.
      */
-    protected void doCorrectedWOut(WQCKms wqckms) {
+    protected void doCorrectedWOut(WQCKms wqckms, Document theme) {
         logger.debug("DischargeLongitudinalSectionGenerator.doCorrectedWOut");
 
         int size = wqckms.size();
 
         if (size > 0) {
-            XYSeries series = new XYSeries(getSeriesNameForCorrected(wqckms, "W"));
+            XYSeries series = new StyledXYSeries(
+                getSeriesNameForCorrected(wqckms, "W"),
+                theme);
+
             for (int i = 0; i < size; i++) {
                 series.add(wqckms.getKms(i), wqckms.getC(i));
             }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java	Fri Jul 01 11:16:11 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java	Fri Jul 01 14:46:13 2011 +0000
@@ -1,7 +1,5 @@
 package de.intevation.flys.exports;
 
-import java.awt.Color;
-
 import org.w3c.dom.Document;
 
 import org.apache.log4j.Logger;
@@ -10,7 +8,6 @@
 import org.jfree.chart.axis.NumberAxis;
 import org.jfree.chart.axis.ValueAxis;
 import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
 import org.jfree.chart.title.TextTitle;
 import org.jfree.data.Range;
 import org.jfree.data.xy.XYSeries;
@@ -112,37 +109,6 @@
     }
 
 
-    protected void adjustPlot(XYPlot plot) {
-        super.adjustPlot(plot);
-
-        // TODO REMOVE THIS CODE, IF WE HAVE INTRODUCED THEMES!
-        //XYLineAndShapeRenderer rw = (XYLineAndShapeRenderer)
-        //    plot.getRendererForDataset(w);
-
-        //XYLineAndShapeRenderer rq = null;
-        //try {
-        //    rq = (XYLineAndShapeRenderer) rw.clone();
-        //}
-        //catch (Exception e) {
-        //    logger.error(e, e);
-        //}
-
-        //int wNum = w.getSeriesCount();
-        //int qNum = q.getSeriesCount();
-
-        //for (int i = 0; i < wNum; i++) {
-        //    rw.setSeriesPaint(i, Color.BLUE);
-        //}
-
-        //for (int i = 0; i < qNum; i++) {
-        //    rq.setSeriesPaint(i, Color.GREEN);
-        //}
-
-        //plot.setRenderer(0, rw);
-        //plot.setRenderer(1, rq);
-    }
-
-
     protected void adjustAxes(XYPlot plot) {
         super.adjustAxes(plot);
 
@@ -167,10 +133,10 @@
         Facet        f    = flys.getNativeFacet(facet);
 
         if (name.equals(DURATION_W)) {
-            doWOut((WQDay) f.getData(artifact, context));
+            doWOut((WQDay) f.getData(artifact, context), attr);
         }
         else if (name.equals(DURATION_Q)) {
-            doQOut((WQDay) f.getData(artifact, context));
+            doQOut((WQDay) f.getData(artifact, context), attr);
         }
         else {
             logger.warn("Unknown facet name: " + name);
@@ -183,14 +149,14 @@
      * Creates the series for a duration curve's W facet.
      *
      * @param wqdays The WQDay store that contains the Ws.
-     * @param river The name of the river.
+     * @param theme
      */
-    protected void doWOut(WQDay wqdays) {
+    protected void doWOut(WQDay wqdays, Document theme) {
         logger.debug("DurationCurveGenerator.doWOut");
 
         // TODO find the correct series name
-        XYSeries series = new XYSeries(
-            getSeriesName(getRiverName(), DURATION_W));
+        XYSeries series = new StyledXYSeries(
+            getSeriesName(getRiverName(), DURATION_W), theme);
 
         int size = wqdays.size();
         for (int i = 0; i < size; i++) {
@@ -208,14 +174,14 @@
      * Creates the series for a duration curve's Q facet.
      *
      * @param wqdays The WQDay store that contains the Qs.
-     * @param river The name of the river.
+     * @param theme
      */
-    protected void doQOut(WQDay wqdays) {
+    protected void doQOut(WQDay wqdays, Document theme) {
         logger.debug("DurationCurveGenerator.doQOut");
 
         // TODO find the correct series name
-        XYSeries series = new XYSeries(
-            getSeriesName(getRiverName(), DURATION_Q));
+        XYSeries series = new StyledXYSeries(
+            getSeriesName(getRiverName(), DURATION_Q), theme);
 
         int size = wqdays.size();
         for (int i = 0; i < size; i++) {
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java	Fri Jul 01 11:16:11 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java	Fri Jul 01 14:46:13 2011 +0000
@@ -1,14 +1,11 @@
 package de.intevation.flys.exports;
 
-import java.awt.Color;
-
 import org.apache.log4j.Logger;
 
 import org.jfree.chart.JFreeChart;
 import org.jfree.chart.axis.NumberAxis;
 import org.jfree.chart.axis.ValueAxis;
 import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
 import org.jfree.chart.title.TextTitle;
 import org.jfree.data.Range;
 import org.jfree.data.xy.XYSeries;
@@ -104,37 +101,6 @@
     }
 
 
-    protected void adjustPlot(XYPlot plot) {
-        super.adjustPlot(plot);
-
-        //// TODO REMOVE THIS CODE, IF WE HAVE INTRODUCED THEMES!
-        //XYLineAndShapeRenderer rw = (XYLineAndShapeRenderer)
-        //    plot.getRendererForDataset(w);
-
-        //XYLineAndShapeRenderer rq = null;
-        //try {
-        //    rq = (XYLineAndShapeRenderer) rw.clone();
-        //}
-        //catch (Exception e) {
-        //    logger.error(e, e);
-        //}
-
-        //int wNum = w.getSeriesCount();
-        //int qNum = q.getSeriesCount();
-
-        //for (int i = 0; i < wNum; i++) {
-        //    rw.setSeriesPaint(i, Color.BLUE);
-        //}
-
-        //for (int i = 0; i < qNum; i++) {
-        //    rq.setSeriesPaint(i, Color.GREEN);
-        //}
-
-        //plot.setRenderer(0, rw);
-        //plot.setRenderer(1, rq);
-    }
-
-
     protected void adjustAxes(XYPlot plot) {
         super.adjustAxes(plot);
 
@@ -196,10 +162,10 @@
         }
 
         if (name.equals(LONGITUDINAL_W)) {
-            doWOut((WQKms) f.getData(artifact, context));
+            doWOut((WQKms) f.getData(artifact, context), attr);
         }
         else if (name.equals(LONGITUDINAL_Q)) {
-            doQOut((WQKms) f.getData(artifact, context));
+            doQOut((WQKms) f.getData(artifact, context), attr);
         }
         else {
             logger.warn("Unknown facet name: " + name);
@@ -212,11 +178,12 @@
      * Process the output for W facets in a longitudinal section curve.
      *
      * @param wqkms An array of WQKms values.
+     * @param theme The theme that contains styling information.
      */
-    protected void doWOut(WQKms wqkms) {
+    protected void doWOut(WQKms wqkms, Document theme) {
         logger.debug("LongitudinalSectionGenerator.doWOut");
 
-        XYSeries series = new XYSeries(getSeriesName(wqkms, "W"));
+        XYSeries series = new StyledXYSeries(getSeriesName(wqkms, "W"), theme);
 
         int size = wqkms.size();
 
@@ -245,11 +212,12 @@
      * Process the output for Q facets in a longitudinal section curve.
      *
      * @param wqkms An array of WQKms values.
+     * @param theme The theme that contains styling information.
      */
-    protected void doQOut(WQKms wqkms) {
+    protected void doQOut(WQKms wqkms, Document theme) {
         logger.debug("LongitudinalSectionGenerator.doQOut");
 
-        XYSeries series = new XYSeries(getSeriesName(wqkms, "Q"));
+        XYSeries series = new StyledXYSeries(getSeriesName(wqkms, "Q"), theme);
 
         int size = wqkms.size();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/StyledXYSeries.java	Fri Jul 01 14:46:13 2011 +0000
@@ -0,0 +1,91 @@
+package de.intevation.flys.exports;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+
+import org.apache.log4j.Logger;
+
+import org.w3c.dom.Document;
+
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.data.xy.XYSeries;
+
+import de.intevation.artifacts.common.utils.XMLUtils;
+
+
+public class StyledXYSeries extends XYSeries {
+
+    public static final String XPATH_LINE_COLOR =
+        "/theme/field[@name='linecolor']/@default";
+
+    public static final String XPATH_LINE_SIZE =
+        "/theme/field[@name='linesize']/@default";
+
+
+    protected Document theme;
+
+
+    private static final Logger logger = Logger.getLogger(StyledXYSeries.class);
+
+
+
+    public StyledXYSeries(String key, Document theme) {
+        super(key);
+        this.theme = theme;
+    }
+
+
+    public XYLineAndShapeRenderer applyTheme(XYLineAndShapeRenderer r, int idx){
+        applyLineColor(r, idx);
+        applyLineSize(r, idx);
+
+        r.setSeriesLinesVisible(idx, true);
+        r.setSeriesShapesVisible(idx, false);
+
+        return r;
+    }
+
+
+    protected void applyLineColor(XYLineAndShapeRenderer r, int idx) {
+        String color = XMLUtils.xpathString(theme, XPATH_LINE_COLOR, null);
+
+        if (color == null || color.length() == 0) {
+            return;
+        }
+
+        String[] rgb = color.split(",");
+
+        try {
+            Color c = new Color(
+                Integer.valueOf(rgb[0].trim()),
+                Integer.valueOf(rgb[1].trim()),
+                Integer.valueOf(rgb[2].trim()));
+
+            logger.debug("Set series paint color: " + c.toString());
+
+            r.setSeriesPaint(idx, c);
+        }
+        catch (NumberFormatException nfe) {
+            logger.warn("Unable to set color from string: '" + color + "'");
+        }
+    }
+
+
+    protected void applyLineSize(XYLineAndShapeRenderer r, int idx) {
+        String size = XMLUtils.xpathString(theme, XPATH_LINE_SIZE, null);
+
+        if (size == null || size.length() == 0) {
+            return;
+        }
+
+        try {
+            r.setSeriesStroke(
+                idx,
+                new BasicStroke(Integer.valueOf(size)));
+        }
+        catch (NumberFormatException nfe) {
+            logger.warn("Unable to set line size from string: '" + size + "'");
+        }
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Fri Jul 01 11:16:11 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Fri Jul 01 14:46:13 2011 +0000
@@ -14,6 +14,7 @@
 import org.jfree.chart.axis.ValueAxis;
 import org.jfree.chart.plot.PlotOrientation;
 import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
 import org.jfree.data.Range;
 import org.jfree.data.xy.XYDataset;
 import org.jfree.data.xy.XYSeries;
@@ -112,6 +113,8 @@
 
         autoZoom(plot);
 
+        applyThemes(plot);
+
         return chart;
     }
 
@@ -329,5 +332,59 @@
     protected void addSubtitles(JFreeChart chart) {
         // override this method in subclasses that need subtitles
     }
+
+
+    protected void applyThemes(XYPlot plot) {
+        if (first != null) {
+            applyThemes(plot, first, 0);
+        }
+
+        if (second != null) {
+            applyThemes(plot, second, 1);
+        }
+    }
+
+
+    protected void applyThemes(XYPlot plot, XYSeriesCollection dataset, int i) {
+        XYLineAndShapeRenderer r = getRenderer(plot, i);
+
+        for (int s = 0, num = dataset.getSeriesCount(); s < num; s++) {
+            XYSeries series = dataset.getSeries(s);
+
+            if (series instanceof StyledXYSeries) {
+                ((StyledXYSeries) series).applyTheme(r, s);
+            }
+        }
+
+        plot.setRenderer(i, r);
+    }
+
+
+    protected XYLineAndShapeRenderer getRenderer(XYPlot plot, int idx) {
+        XYLineAndShapeRenderer r =
+            (XYLineAndShapeRenderer) plot.getRenderer(idx);
+
+        if (r != null) {
+            return r;
+        }
+
+        if (idx == 0) {
+            logger.warn("No default renderer set!");
+            return new XYLineAndShapeRenderer();
+        }
+
+        r = (XYLineAndShapeRenderer) plot.getRenderer(0);
+
+        try {
+            return (XYLineAndShapeRenderer) r.clone();
+        }
+        catch (CloneNotSupportedException cnse) {
+            logger.warn(cnse, cnse);
+        }
+
+        logger.warn("No applicalable renderer found!");
+
+        return new XYLineAndShapeRenderer();
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org