changeset 2242:7e8e1d5384c0

Further refactoring of XYChartGenerator / ChartGenerator with the result, that timerange charts are now able to display lines. flys-artifacts/trunk@3890 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Fri, 03 Feb 2012 09:39:22 +0000
parents 2b232871ba28
children d70a04cad84d
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java
diffstat 4 files changed, 394 insertions(+), 206 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Fri Feb 03 09:35:46 2012 +0000
+++ b/flys-artifacts/ChangeLog	Fri Feb 03 09:39:22 2012 +0000
@@ -1,3 +1,14 @@
+2012-02-03  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/exports/XYChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChartGenerator.java: Refactoring:
+	  moved addDatasets(), applyThemes() and some other methods into
+	  ChartGenerator; enhanced the AxisDataset interface.
+
+	* src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java:
+	  Implemented necessary abstract methods and improved internal AxisDataset
+	  class (added new methods).
+
 2012-02-03  Ingo Weinzierl <ingo@intevation.de>
 
 	* src/main/java/de/intevation/flys/exports/ChartHelper.java: Added a
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java	Fri Feb 03 09:35:46 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java	Fri Feb 03 09:39:22 2012 +0000
@@ -2,6 +2,10 @@
 
 import java.awt.Color;
 import java.awt.Font;
+import java.awt.Paint;
+import java.awt.TexturePaint;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
 
 import java.io.IOException;
 import java.io.OutputStream;
@@ -9,6 +13,7 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.TreeMap;
 import java.util.SortedMap;
 
@@ -21,8 +26,12 @@
 
 import org.jfree.chart.JFreeChart;
 import org.jfree.chart.LegendItem;
+import org.jfree.chart.LegendItemCollection;
 import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
 import org.jfree.data.Range;
+import org.jfree.data.general.Series;
 import org.jfree.data.xy.XYDataset;
 
 import de.intevation.artifacts.Artifact;
@@ -40,6 +49,10 @@
 
 import de.intevation.flys.artifacts.FLYSArtifact;
 import de.intevation.flys.artifacts.resources.Resources;
+import de.intevation.flys.jfree.EnhancedLineAndShapeRenderer;
+import de.intevation.flys.jfree.StableXYDifferenceRenderer;
+import de.intevation.flys.jfree.StyledAreaSeriesCollection;
+import de.intevation.flys.jfree.StyledXYSeries;
 import de.intevation.flys.utils.FLYSUtils;
 import de.intevation.flys.utils.ThemeAccess;
 
@@ -113,8 +126,20 @@
 
         void addDataset(XYDataset dataset);
 
+        XYDataset[] getDatasets();
+
         boolean isEmpty();
 
+        void setRange(Range range);
+
+        Range getRange();
+
+        boolean isArea(XYDataset dataset);
+
+        void setPlotAxisIndex(int idx);
+
+        int getPlotAxisIndex();
+
     } // end of AxisDataset interface
 
 
@@ -146,6 +171,27 @@
     protected abstract YAxisWalker getYAxisWalker();
 
 
+    protected abstract Series getSeriesOf(XYDataset dataset, int idx);
+
+
+    /**
+     * This method is used to set the range of the X axis at index <i>axis</i>.
+     *
+     * @param axis The index of an X axis.
+     * @param range The new range for the X axis at index <i>axis</i>.
+     */
+    protected abstract void setXRange(int axis, Range range);
+
+
+    /**
+     * This method is used to set the range of the Y axis at index <i>axis</i>.
+     *
+     * @param axis The index of an Y axis.
+     * @param range The new range for the Y axis at index <i>axis</i>.
+     */
+    protected abstract void setYRange(int axis, Range range);
+
+
     /**
      * Returns the default title of a chart.
      *
@@ -794,8 +840,18 @@
 
         Range[] xyRanges = ChartHelper.getRanges(dataset);
 
+        if (xyRanges == null) {
+            logger.warn("Skip XYDataset for Axis (invalid ranges): " + idx);
+            return;
+        }
+
         if (visible) {
-            logger.debug("Add new AxisDataset at index: " + idx);
+            if (logger.isDebugEnabled()) {
+                logger.debug("Add new AxisDataset at index: " + idx);
+                logger.debug("X extent: " + xyRanges[0]);
+                logger.debug("Y extent: " + xyRanges[1]);
+            }
+
             axisDataset.addDataset(dataset);
             combineXRanges(xyRanges[0], 0);
         }
@@ -1033,6 +1089,208 @@
 
 
     /**
+     * Add datasets stored in instance variable <i>datasets</i> to plot.
+     * <i>datasets</i> actually stores instances of AxisDataset, so each of this
+     * datasets is mapped to a specific axis as well.
+     *
+     * @param plot plot to add datasets to.
+     */
+    protected void addDatasets(XYPlot plot) {
+        // AxisDatasets are sorted, but some might be empty.
+        // Thus, generate numbering on the fly.
+        int axisIndex    = 0;
+        int datasetIndex = 0;
+
+        for (Map.Entry<Integer, AxisDataset> entry: datasets.entrySet()) {
+            if (!entry.getValue().isEmpty()) {
+                // Add axis and range information.
+                AxisDataset axisDataset = entry.getValue();
+                NumberAxis    axis      = createYAxis(entry.getKey());
+
+                plot.setRangeAxis(axisIndex, axis);
+
+                if (axis.getAutoRangeIncludesZero()) {
+                    axisDataset.setRange(
+                        Range.expandToInclude(axisDataset.getRange(), 0d));
+                }
+
+                setYRange(axisIndex, expandPointRange(axisDataset.getRange()));
+
+                // Add contained datasets, mapping to axis.
+                for (XYDataset dataset: axisDataset.getDatasets()) {
+                    plot.setDataset(datasetIndex, dataset);
+                    plot.mapDatasetToRangeAxis(datasetIndex, axisIndex);
+
+                    applyThemes(plot, (XYDataset) dataset,
+                        datasetIndex,
+                        axisDataset.isArea((XYDataset) dataset));
+
+                    datasetIndex++;
+                }
+
+                axisDataset.setPlotAxisIndex(axisIndex);
+                axisIndex++;
+            }
+        }
+    }
+
+
+        /**
+     * @param idx "index" of dataset/series (first dataset to be drawn has
+     *            index 0), correlates with renderer index.
+     * @param isArea true if the series describes an area and shall be rendered
+     *                as such.
+     * @return idx increased by number of items addded.
+     */
+    protected void applyThemes(
+        XYPlot    plot,
+        XYDataset series,
+        int       idx,
+        boolean   isArea
+    ) {
+        if (isArea) {
+            applyAreaTheme(plot, (StyledAreaSeriesCollection) series, idx);
+        }
+        else {
+            applyLineTheme(plot, series, idx);
+        }
+    }
+
+
+    /**
+     * This method applies the themes defined in the series itself. Therefore,
+     * <i>StyledXYSeries.applyTheme()</i> is called, which modifies the renderer
+     * for the series.
+     *
+     * @param plot The plot.
+     * @param dataset The XYDataset which needs to support Series objects.
+     * @param idx The index of the renderer / dataset.
+     */
+    protected void applyLineTheme(XYPlot plot, XYDataset dataset, int idx) {
+        LegendItemCollection lic  = new LegendItemCollection();
+        LegendItemCollection anno = plot.getFixedLegendItems();
+
+        Font legendFont = createLegendLabelFont();
+
+        XYLineAndShapeRenderer renderer = createRenderer(plot, idx);
+
+        for (int s = 0, num = dataset.getSeriesCount(); s < num; s++) {
+            Series series = getSeriesOf(dataset, s);
+
+            if (series instanceof StyledXYSeries) {
+                ((StyledXYSeries) series).applyTheme(renderer, s);
+            }
+
+            // special case: if there is just one single item, we need to enable
+            // points for this series, otherwise we would not see anything in
+            // the chart area.
+            if (series.getItemCount() == 1) {
+                renderer.setSeriesShapesVisible(s, true);
+            }
+
+            LegendItem legendItem = renderer.getLegendItem(idx, s);
+            if (legendItem != null) {
+                legendItem.setLabelFont(legendFont);
+                lic.add(legendItem);
+            }
+            else {
+                logger.warn("Could not get LegentItem for renderer: "
+                    + idx + ", series-idx " + s);
+            }
+        }
+
+        if (anno != null) {
+            lic.addAll(anno);
+        }
+
+        plot.setFixedLegendItems(lic);
+
+        plot.setRenderer(idx, renderer);
+    }
+
+
+    /**
+     * @param plot The plot.
+     * @param area A StyledAreaSeriesCollection object.
+     * @param idx The index of the dataset.
+     *
+     * @return
+     */
+    protected void applyAreaTheme(
+        XYPlot                     plot,
+        StyledAreaSeriesCollection area,
+        int                        idx
+    ) {
+        LegendItemCollection lic  = new LegendItemCollection();
+        LegendItemCollection anno = plot.getFixedLegendItems();
+
+        Font legendFont = createLegendLabelFont();
+
+        logger.debug("Registering an 'area'renderer at idx: " + idx);
+
+        StableXYDifferenceRenderer dRenderer =
+            new StableXYDifferenceRenderer();
+
+        if (area.getMode() == StyledAreaSeriesCollection.FILL_MODE.UNDER) {
+            dRenderer.setPositivePaint(createTransparentPaint());
+        }
+
+        plot.setRenderer(idx, dRenderer);
+
+        area.applyTheme(dRenderer);
+
+        LegendItem legendItem = dRenderer.getLegendItem(idx, 0);
+        if (legendItem != null) {
+            legendItem.setLabelFont(legendFont);
+            lic.add(legendItem);
+        }
+        else {
+            logger.warn("Could not get LegentItem for renderer: "
+                + idx + ", series-idx " + 0);
+        }
+
+        if (anno != null) {
+            lic.addAll(anno);
+        }
+
+        plot.setFixedLegendItems(lic);
+    }
+
+
+    /**
+     * Expands a given range if it collapses into one point.
+     *
+     * @param Range to be expanded if upper == lower bound.
+     */
+    private Range expandPointRange(Range range) {
+        if (range != null && range.getLowerBound() == range.getUpperBound()) {
+            return ChartHelper.expandRange(range, 5);
+        }
+        return range;
+    }
+
+
+    /**
+     * Creates a new instance of EnhancedLineAndShapeRenderer.
+     *
+     * @param plot The plot which is set for the new renderer.
+     * @param idx This value is not used in the current implementation.
+     *
+     * @return a new instance of EnhancedLineAndShapeRenderer.
+     */
+    protected XYLineAndShapeRenderer createRenderer(XYPlot plot, int idx) {
+        logger.debug("Create EnhancedLineAndShapeRenderer for idx: " + idx);
+
+        EnhancedLineAndShapeRenderer r =
+            new EnhancedLineAndShapeRenderer(true, false);
+
+        r.setPlot(plot);
+
+        return r;
+    }
+
+
+    /**
      * Creates a new instance of <i>IdentifiableNumberAxis</i>.
      *
      * @param idx The index of the new axis.
@@ -1106,6 +1364,21 @@
     }
 
 
+    /**
+     * Returns a transparently textured paint.
+     *
+     * @return a transparently textured paint.
+     */
+    protected static Paint createTransparentPaint() {
+        // TODO why not use a transparent color?
+        BufferedImage texture = new BufferedImage(
+            1, 1, BufferedImage.TYPE_4BYTE_ABGR);
+
+        return new TexturePaint(
+            texture, new Rectangle2D.Double(0d, 0d, 0d, 0d));
+    }
+
+
     protected void preparePDFContext(CallContext context) {
         int[] dimension = getExportDimension();
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java	Fri Feb 03 09:35:46 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java	Fri Feb 03 09:39:22 2012 +0000
@@ -11,11 +11,11 @@
 
 import org.jfree.chart.ChartFactory;
 import org.jfree.chart.JFreeChart;
-import org.jfree.chart.axis.NumberAxis;
 import org.jfree.chart.plot.XYPlot;
 
 import org.jfree.data.Range;
 import org.jfree.data.time.TimeSeriesCollection;
+import org.jfree.data.general.Series;
 import org.jfree.data.xy.XYDataset;
 
 
@@ -60,11 +60,49 @@
 
 
         @Override
+        public XYDataset[] getDatasets() {
+            return (XYDataset[])
+                datasets.toArray(new XYDataset[datasets.size()]);
+        }
+
+
+        @Override
         public boolean isEmpty() {
             return datasets.isEmpty();
         }
 
 
+        @Override
+        public void setRange(Range range) {
+            this.range = range;
+        }
+
+
+        @Override
+        public Range getRange() {
+            return range;
+        }
+
+
+        @Override
+        public void setPlotAxisIndex(int plotAxisIndex) {
+            this.plotAxisIndex = plotAxisIndex;
+        }
+
+
+        @Override
+        public int getPlotAxisIndex() {
+            return plotAxisIndex;
+        }
+
+
+        @Override
+        public boolean isArea(XYDataset dataset) {
+            logger.warn("This AxisDataset doesn't support Areas yet!");
+            return false;
+        }
+
+
         protected void mergeRanges(TimeSeriesCollection dataset) {
             logger.debug("Range after merging: " + range);
 
@@ -84,6 +122,8 @@
 
     protected Map<Integer, Range> xRanges;
 
+    protected Map<Integer, Range> yRanges;
+
 
 
     /**
@@ -93,6 +133,7 @@
         super();
 
         xRanges = new HashMap<Integer, Range>();
+        yRanges = new HashMap<Integer, Range>();
     }
 
 
@@ -124,6 +165,24 @@
     }
 
 
+    @Override
+    protected Series getSeriesOf(XYDataset dataset, int idx) {
+        return ((TimeSeriesCollection) dataset).getSeries(idx);
+    }
+
+
+    @Override
+    protected void setXRange(int axis, Range range) {
+        xRanges.put(Integer.valueOf(axis), range);
+    }
+
+
+    @Override
+    protected void setYRange(int axis, Range range) {
+        yRanges.put(Integer.valueOf(axis), range);
+    }
+
+
     /**
      * This method creates new instances of TimeseriesAxisDataset.
      *
@@ -153,10 +212,5 @@
             xRanges.put(index, range);
         }
     }
-
-
-    protected void addDatasets(XYPlot plot) {
-        logger.warn("TODO: IMPLEMENT ME!");
-    }
 }
 // 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 Feb 03 09:35:46 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Fri Feb 03 09:39:22 2012 +0000
@@ -5,21 +5,13 @@
 import java.awt.Font;
 import java.awt.Paint;
 import java.awt.Stroke;
-import java.awt.TexturePaint;
-
-import java.awt.geom.Rectangle2D;
-
-import java.awt.image.BufferedImage;
-
 
 import java.text.NumberFormat;
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.TreeMap;
 import java.util.List;
 import java.util.Map;
-import java.util.SortedMap;
 
 import org.w3c.dom.Document;
 
@@ -27,7 +19,6 @@
 
 import org.jfree.chart.ChartFactory;
 import org.jfree.chart.JFreeChart;
-import org.jfree.chart.LegendItem;
 import org.jfree.chart.LegendItemCollection;
 import org.jfree.chart.annotations.XYBoxAnnotation;
 import org.jfree.chart.annotations.XYLineAnnotation;
@@ -36,8 +27,8 @@
 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.general.Series;
 import org.jfree.data.xy.XYSeries;
 import org.jfree.data.xy.XYSeriesCollection;
 import org.jfree.data.xy.XYDataset;
@@ -45,13 +36,9 @@
 import org.jfree.ui.RectangleInsets;
 import org.jfree.ui.TextAnchor;
 
-
 import de.intevation.artifactdatabase.state.Facet;
 
-
-import de.intevation.flys.jfree.EnhancedLineAndShapeRenderer;
 import de.intevation.flys.jfree.FLYSAnnotation;
-import de.intevation.flys.jfree.StableXYDifferenceRenderer;
 import de.intevation.flys.jfree.StickyAxisAnnotation;
 import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
 import de.intevation.flys.jfree.StyledAreaSeriesCollection;
@@ -126,12 +113,32 @@
             addDataset(new XYSeriesCollection(series));
         }
 
+
+        @Override
+        public void setRange(Range range) {
+            this.range = range;
+        }
+
+
+        @Override
+        public Range getRange() {
+            return range;
+        }
+
+
+        @Override
+        public XYDataset[] getDatasets() {
+            return (XYDataset[])
+                datasets.toArray(new XYDataset[datasets.size()]);
+        }
+
         public void addArea(StyledAreaSeriesCollection series) {
             this.datasets.add(series);
         }
 
         /** True if to be renedered as area. */
-        public boolean isArea(XYSeriesCollection series) {
+        @Override
+        public boolean isArea(XYDataset series) {
             return (series instanceof StyledAreaSeriesCollection);
         }
 
@@ -141,16 +148,19 @@
         }
 
         /** True if no datasets given. */
+        @Override
         public boolean isEmpty() {
             return this.datasets.isEmpty();
         }
 
         /** Set the 'real' axis index that this axis is mapped to. */
+        @Override
         public void setPlotAxisIndex(int axisIndex) {
             this.plotAxisIndex = axisIndex;
         }
 
         /** Get the 'real' axis index that this axis is mapped to. */
+        @Override
         public int getPlotAxisIndex() {
             return this.plotAxisIndex;
         }
@@ -241,6 +251,24 @@
 
 
     @Override
+    protected Series getSeriesOf(XYDataset dataset, int idx) {
+        return ((XYSeriesCollection) dataset).getSeries(idx);
+    }
+
+
+    @Override
+    protected void setXRange(int axis, Range range) {
+        xRanges.put(Integer.valueOf(axis), range);
+    }
+
+
+    @Override
+    protected void setYRange(int axis, Range range) {
+        yRanges.put(Integer.valueOf(axis), range);
+    }
+
+
+    @Override
     protected AxisDataset createAxisDataset(int idx) {
         logger.debug("Create new XYAxisDataset for index: " + idx);
         return new XYAxisDataset(idx);
@@ -288,43 +316,6 @@
 
 
     /**
-     * Add datasets to plot.
-     * @param plot plot to add datasets to.
-     */
-    protected void addDatasets(XYPlot plot) {
-        // AxisDatasets are sorted, but some might be empty.
-        // Thus, generate numbering on the fly.
-        int axisIndex    = 0;
-        int datasetIndex = 0;
-        for (Map.Entry<Integer, AxisDataset> entry: datasets.entrySet()) {
-            if (!entry.getValue().isEmpty()) {
-                // Add axis and range information.
-                XYAxisDataset axisDataset = (XYAxisDataset) entry.getValue();
-                NumberAxis axis = createYAxis(entry.getKey());
-
-                plot.setRangeAxis(axisIndex, axis);
-                if (axis.getAutoRangeIncludesZero()) {
-                    axisDataset.range = Range.expandToInclude(axisDataset.range, 0d);
-                }
-                yRanges.put(axisIndex, expandPointRange(axisDataset.range));
-
-                // Add contained datasets, mapping to axis.
-                for (XYDataset dataset: axisDataset.datasets) {
-                    plot.setDataset(datasetIndex, dataset);
-                    plot.mapDatasetToRangeAxis(datasetIndex, axisIndex);
-                    applyThemes(plot, (XYSeriesCollection) dataset,
-                        datasetIndex,
-                        axisDataset.isArea((XYSeriesCollection)dataset));
-                    datasetIndex++;
-                }
-                axisDataset.setPlotAxisIndex(axisIndex);
-                axisIndex++;
-            }
-        }
-    }
-
-
-    /**
      * Registers an area to be drawn.
      * @param area Area to be drawn.
      * @param index 'axis index'
@@ -356,12 +347,15 @@
      * @param visible whether or not the data should be plotted.
      */
     public void addAxisSeries(XYSeries series, int index, boolean visible) {
-        addAxisDataset(new XYSeriesCollection(series), index, visible);
-
         if (series == null) {
             return;
         }
 
+        logger.debug("Y Range of XYSeries: " +
+            series.getMinY() + " | " + series.getMaxY());
+
+        addAxisDataset(new XYSeriesCollection(series), index, visible);
+
         XYAxisDataset axisDataset = (XYAxisDataset) getAxisDataset(index);
 
         if (!visible) {
@@ -423,18 +417,6 @@
 
 
     /**
-     * Expands a given range if it collapses into one point.
-     * @param Range to be expanded if upper == lower bound.
-     */
-    private Range expandPointRange(Range range) {
-        if (range != null && range.getLowerBound() == range.getUpperBound()) {
-            return expandRange(range, 5);
-        }
-        return range;
-    }
-
-
-    /**
      * Expands X axes if only a point is shown.
      */
     private void preparePointRanges(XYPlot plot) {
@@ -444,30 +426,13 @@
 
             Range r = xRanges.get(key);
             if (r != null && r.getLowerBound() == r.getUpperBound()) {
-                xRanges.put(key, expandRange(r, 5));
+                setXRange(key, ChartHelper.expandRange(r, 5));
             }
         }
     }
 
 
     /**
-     * Expand range by percent.
-     */
-    public static Range expandRange(Range range, double percent) {
-        if (range == null) {
-            return null;
-        }
-
-        double value  = range.getLowerBound();
-        double expand = Math.abs(value / 100 * percent);
-
-        return expand != 0
-            ? new Range(value-expand, value+expand)
-            : new Range(-0.01 * percent, 0.01 * percent);
-    }
-
-
-    /**
      * This method zooms the plot to the specified ranges in the attribute
      * document or to the ranges specified by the min/max values in the
      * datasets. <b>Note:</b> We determine the range manually if no zoom ranges
@@ -922,121 +887,6 @@
 
 
     /**
-     * @param idx "index" of dataset/series (first dataset to be drawn has
-     *            index 0), correlates with renderer index.
-     * @param isArea true if the series describes an area and shall be rendered
-     *                as such.
-     * @return idx increased by number of items addded.
-     */
-    protected int applyThemes(
-        XYPlot plot,
-        XYSeriesCollection series,
-        int idx,
-        boolean isArea
-    ) {
-        LegendItemCollection lic  = new LegendItemCollection();
-        LegendItemCollection anno = plot.getFixedLegendItems();
-
-        Font legendFont = createLegendLabelFont();
-
-        int retidx = idx;
-
-        if (isArea) {
-            logger.debug("Registering an 'area'renderer at idx: " + idx);
-            StyledAreaSeriesCollection area = (StyledAreaSeriesCollection) series;
-            
-            StableXYDifferenceRenderer dRenderer = new StableXYDifferenceRenderer();
-            if (area.getMode() == StyledAreaSeriesCollection.FILL_MODE.UNDER) {
-                dRenderer.setPositivePaint(createTransparentPaint());
-            }
-            plot.setRenderer(idx, dRenderer);
-
-            area.applyTheme(dRenderer);
-
-            LegendItem legendItem = dRenderer.getLegendItem(idx, 0);
-            if (legendItem != null) {
-                legendItem.setLabelFont(legendFont);
-                lic.add(legendItem);
-            }
-            else {
-                logger.warn("Could not get LegentItem for renderer: "
-                    + idx + ", series-idx " + 0);
-            }
-            if (anno != null) {
-                lic.addAll(anno);
-            }
-            plot.setFixedLegendItems(lic);
-            return retidx + 1;
-        }
-
-        XYLineAndShapeRenderer renderer = getRenderer(plot, idx);
-
-        for (int s = 0, num = series.getSeriesCount(); s < num; s++) {
-            XYSeries serie = series.getSeries(s);
-
-            if (serie instanceof StyledXYSeries) {
-                ((StyledXYSeries) serie).applyTheme(renderer, s);
-            }
-
-            // special case: if there is just one single item, we need to enable
-            // points for this series, otherwise we would not see anything in
-            // the chart area.
-            if (serie.getItemCount() == 1) {
-                renderer.setSeriesShapesVisible(s, true);
-            }
-
-            LegendItem legendItem = renderer.getLegendItem(idx, s);
-            if (legendItem != null) {
-                legendItem.setLabelFont(legendFont);
-                lic.add(legendItem);
-            }
-            else {
-                logger.warn("Could not get LegentItem for renderer: "
-                    + idx + ", series-idx " + s);
-            }
-            // TODO: why that? isnt renderer set per dataset not per series?
-            retidx++;
-        }
-
-        if (anno != null) {
-            lic.addAll(anno);
-        }
-
-        plot.setFixedLegendItems(lic);
-
-        plot.setRenderer(idx, renderer);
-
-        return retidx;
-    }
-
-
-    /** Returns a transparently textured paint. */
-    // TODO why not use a transparent color?
-    protected static Paint createTransparentPaint() {
-        BufferedImage texture = new BufferedImage(
-            1, 1, BufferedImage.TYPE_4BYTE_ABGR);
-
-        return new TexturePaint(
-            texture, new Rectangle2D.Double(0d, 0d, 0d, 0d));
-    }
-
-
-    /**
-     * Returns a new instance of EnhancedLineAndShapeRenderer always.
-     */
-    protected XYLineAndShapeRenderer getRenderer(XYPlot plot, int idx) {
-        logger.debug("getRenderer: " + idx);
-
-        EnhancedLineAndShapeRenderer r =
-            new EnhancedLineAndShapeRenderer(true, false);
-
-        r.setPlot(plot);
-
-        return r;
-    }
-
-
-    /**
      * Register annotations like MainValues for later plotting
      *
      * @param o     list of annotations (data of facet).

http://dive4elements.wald.intevation.org