diff artifacts/src/main/java/org/dive4elements/river/jfree/StyledAreaSeriesCollection.java @ 9496:d8e753d0fdb9

stripedArea introduced for Assessment Scheme/Bewertungsschema
author gernotbelger
date Wed, 26 Sep 2018 15:48:05 +0200
parents eec4df8165a1
children ef5754ba5573
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/jfree/StyledAreaSeriesCollection.java	Tue Sep 25 16:43:51 2018 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/jfree/StyledAreaSeriesCollection.java	Wed Sep 26 15:48:05 2018 +0200
@@ -10,6 +10,7 @@
 
 import java.awt.BasicStroke;
 import java.awt.Color;
+import java.awt.Font;
 import java.awt.Paint;
 import java.awt.Stroke;
 import java.awt.TexturePaint;
@@ -17,7 +18,15 @@
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 
+import org.apache.log4j.Logger;
+import org.dive4elements.artifacts.CallMeta;
+import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.java2d.ShapeUtils;
 import org.dive4elements.river.themes.ThemeDocument;
+import org.dive4elements.river.utils.Formatter;
+import org.jfree.chart.LegendItem;
+import org.jfree.chart.LegendItemCollection;
+import org.jfree.chart.plot.XYPlot;
 import org.jfree.data.xy.XYSeriesCollection;
 
 /**
@@ -27,12 +36,17 @@
  * The display options can be used to control the z-order and the axis of the
  * dataset.
  */
-// FIXME:  bad abstraction: the only purpose of this derivation is to apply specific styles. This should rather be solved similar to the XYSTyle.
-public class StyledAreaSeriesCollection extends XYSeriesCollection {
+// FIXME: bad abstraction: the only purpose of this derivation is to apply specific styles. This should rather be solved
+// similar to the XYSTyle.
+public class StyledAreaSeriesCollection extends XYSeriesCollection implements StyledXYDataset {
     private static final long serialVersionUID = 5274940965666948237L;
 
+    private static final Logger log = Logger.getLogger(StyledAreaSeriesCollection.class);
+
     /** Mode, how to draw/which areas to fill. */
-    public enum FILL_MODE {UNDER, ABOVE, BETWEEN}
+    public enum FILL_MODE {
+        UNDER, ABOVE, BETWEEN
+    }
 
     /** MODE in use. */
     private FILL_MODE mode;
@@ -41,35 +55,83 @@
     private final ThemeDocument theme;
 
     /**
-     * @param theme the theme-document.
+     * @param theme
+     *            the theme-document.
      */
     public StyledAreaSeriesCollection(final ThemeDocument theme) {
         this.theme = theme;
         this.mode = FILL_MODE.BETWEEN;
     }
 
-
     /** Gets the Fill mode. */
-    public FILL_MODE getMode() {
+    private FILL_MODE getMode() {
         return this.mode;
     }
 
-
     /** Sets the Fill mode. */
     public void setMode(final FILL_MODE fMode) {
         this.mode = fMode;
     }
 
+    @Override
+    public void applyTheme(final CallMeta callMeta, final XYPlot plot, final int datasetIndex, final Font legendFont) {
+
+        final LegendItemCollection lic = new LegendItemCollection();
+        final LegendItemCollection anno = plot.getFixedLegendItems();
+
+        log.debug("Registering an 'area'renderer at idx: " + datasetIndex);
+
+        final StableXYDifferenceRenderer dRenderer = new StableXYDifferenceRenderer();
+
+        if (getMode() == StyledAreaSeriesCollection.FILL_MODE.UNDER) {
+            dRenderer.setPositivePaint(createTransparentPaint());
+        }
+
+        plot.setRenderer(datasetIndex, dRenderer);
+
+        applyTheme(dRenderer);
+
+        // i18n
+        dRenderer.setAreaLabelNumberFormat(Formatter.getFormatter(callMeta, 2, 4));
+
+        dRenderer.setAreaLabelTemplate(Resources.getMsg(callMeta, "area.label.template", "Area=%sm2"));
+
+        final LegendItem legendItem = dRenderer.getLegendItem(datasetIndex, 0);
+        if (legendItem != null) {
+            legendItem.setLabelFont(legendFont);
+            lic.add(legendItem);
+        } else {
+            log.warn("Could not get LegentItem for renderer: " + datasetIndex + ", series-idx " + 0);
+        }
+
+        if (anno != null) {
+            lic.addAll(anno);
+        }
+
+        plot.setFixedLegendItems(lic);
+    }
+
+    /**
+     * Returns a transparently textured paint.
+     *
+     * @return a transparently textured paint.
+     */
+    private static Paint createTransparentPaint() {
+        // TODO why not use a transparent color?
+        final BufferedImage texture = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
+
+        return new TexturePaint(texture, new Rectangle2D.Double(0d, 0d, 0d, 0d));
+    }
 
     /**
      * Applies line color, size and type attributes to renderer, also
      * whether to draw lines and/or points.
-     * @param renderer Renderer to apply theme to.
+     *
+     * @param renderer
+     *            Renderer to apply theme to.
      * @return \param renderer
      */
-    public StableXYDifferenceRenderer applyTheme(
-            final StableXYDifferenceRenderer renderer
-            ) {
+    private StableXYDifferenceRenderer applyTheme(final StableXYDifferenceRenderer renderer) {
         applyFillColor(renderer);
         applyShowBorder(renderer);
         applyShowArea(renderer);
@@ -81,16 +143,11 @@
         applyPointStyle(renderer);
         applyShowMinimumMaximum(renderer);
         if (this.mode == FILL_MODE.UNDER) {
-            renderer.setAreaCalculationMode(
-                    StableXYDifferenceRenderer.CALCULATE_NEGATIVE_AREA);
-        }
-        else if (this.mode == FILL_MODE.ABOVE) {
-            renderer.setAreaCalculationMode(
-                    StableXYDifferenceRenderer.CALCULATE_POSITIVE_AREA);
-        }
-        else {
-            renderer.setAreaCalculationMode(
-                    StableXYDifferenceRenderer.CALCULATE_ALL_AREA);
+            renderer.setAreaCalculationMode(StableXYDifferenceRenderer.CALCULATE_NEGATIVE_AREA);
+        } else if (this.mode == FILL_MODE.ABOVE) {
+            renderer.setAreaCalculationMode(StableXYDifferenceRenderer.CALCULATE_POSITIVE_AREA);
+        } else {
+            renderer.setAreaCalculationMode(StableXYDifferenceRenderer.CALCULATE_ALL_AREA);
         }
 
         // Apply text style.
@@ -115,13 +172,11 @@
 
         if (paint != null && this.getMode() == FILL_MODE.ABOVE) {
             renderer.setPositivePaint(paint);
-            renderer.setNegativePaint(new Color(0,0,0,0));
-        }
-        else if (paint != null && this.getMode() == FILL_MODE.UNDER) {
+            renderer.setNegativePaint(new Color(0, 0, 0, 0));
+        } else if (paint != null && this.getMode() == FILL_MODE.UNDER) {
             renderer.setNegativePaint(paint);
-            renderer.setPositivePaint(new Color(0,0,0,0));
-        }
-        else {
+            renderer.setPositivePaint(new Color(0, 0, 0, 0));
+        } else {
             if (paint == null)
                 paint = new Color(177, 117, 102);
 
@@ -134,31 +189,19 @@
         final Color paint = this.theme.parseAreaBackgroundColor();
         final int transparency = this.theme.parseAreaTransparency();
 
-        final Color alphaPaint = withAlpha(paint, transparency);
+        final Color alphaPaint = ShapeUtils.withAlpha(paint, transparency);
 
         final AreaFillPattern pattern = this.theme.parseAreaBackgroundPattern();
 
-        if( pattern == null || pattern == AreaFillPattern.patternFill )
+        if (pattern == null || pattern == AreaFillPattern.patternFill)
             return alphaPaint;
 
         final BufferedImage image = pattern.getImage(alphaPaint);
 
-        final Rectangle2D anchor = new Rectangle2D.Double(0,0, image.getWidth(), image.getHeight());
+        final Rectangle2D anchor = new Rectangle2D.Double(0, 0, image.getWidth(), image.getHeight());
         return new TexturePaint(image, anchor);
     }
 
-    private Color withAlpha(final Color color, final int transparency) {
-
-        if (transparency <= 0 || color == null)
-            return color;
-
-        return new Color(
-                color.getRed(),
-                color.getGreen(),
-                color.getBlue(),
-                (int)((100 - transparency) * 2.55f));
-    }
-
     private void applyShowBorder(final StableXYDifferenceRenderer renderer) {
         final boolean show = this.theme.parseAreaShowBorder();
         renderer.setDrawOutline(show);
@@ -195,20 +238,14 @@
 
     private void applyOutlineStyle(final StableXYDifferenceRenderer renderer) {
         final float[] dashes = this.theme.parseLineStyle();
-        final int size       = this.theme.parseLineWidth();
+        final int size = this.theme.parseLineWidth();
 
         Stroke stroke = null;
 
         if (dashes.length <= 1) {
             stroke = new BasicStroke(Integer.valueOf(size));
-        }
-        else {
-            stroke = new BasicStroke(Integer.valueOf(size),
-                    BasicStroke.CAP_BUTT,
-                    BasicStroke.JOIN_ROUND,
-                    1.0f,
-                    dashes,
-                    0.0f);
+        } else {
+            stroke = new BasicStroke(Integer.valueOf(size), BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 1.0f, dashes, 0.0f);
         }
 
         renderer.setOutlineStroke(stroke);
@@ -219,10 +256,9 @@
         final boolean showPoints = this.theme.parseShowPoints();
         renderer.setShapesVisible(showPoints);
 
-        if( showPoints )
-        {
+        if (showPoints) {
             final int size = this.theme.parsePointWidth();
-            final int dim  = 2 * size;
+            final int dim = 2 * size;
 
             final Ellipse2D pointShape = new Ellipse2D.Double(-size, -size, dim, dim);
             final Color pointColor = this.theme.parsePointColor();

http://dive4elements.wald.intevation.org