diff flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java @ 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 23c7c51df772
children 99ef93ce18bd
line wrap: on
line diff
--- 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