changeset 2161:c68f4f227c09

Somewhat unified Annotation handling, use jfreechart-house-toolkit instead of custom StickyAxisAnnotation. flys-artifacts/trunk@3747 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Mon, 23 Jan 2012 10:44:34 +0000
parents 8428de5846e8
children df70f14af981
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java flys-artifacts/src/main/java/de/intevation/flys/jfree/CollisionFreeXYTextAnnotation.java flys-artifacts/src/main/java/de/intevation/flys/jfree/FLYSAnnotation.java flys-artifacts/src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeAccess.java
diffstat 9 files changed, 282 insertions(+), 401 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Mon Jan 23 07:55:17 2012 +0000
+++ b/flys-artifacts/ChangeLog	Mon Jan 23 10:44:34 2012 +0000
@@ -1,3 +1,41 @@
+2012-01-23  Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Some unification of Annotation handling.
+
+	* src/main/java/de/intevation/flys/jfree/FLYSAnnotation.java:
+	  Add a third annotation type (now have text, hyk and sticky).
+
+	* src/main/java/de/intevation/flys/jfree/CollisionFreeXYTextAnnotation.java:
+	  Use double instead of float values, removed commented code.
+
+	* src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java:
+	  Reduced to keep information about placements etc only. Not a
+	  Annotation (in JFreeChart sense) anymore.
+
+	* src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java,
+	  src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java:
+	  Use StickyAxisAnnotations instead of XYTextAnnotations.
+
+	* src/main/java/de/intevation/flys/themes/ThemeAccess.java:
+	  Added new LineStyle class.
+	
+	* src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
+	  Call addAnnotationsToRenderer later, where positioning information
+	  is already known.
+	  (addAnnotationsToRenderer): Deal with the three Annotation types.
+				      Instead of StickyAnnotations, add
+				      CollisionFreeXYText- and
+				      XYLineAnnotations.
+	  (Area): Helper class.
+	  
+
+2012-01-23  Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Some unification of Annotation handling.
+
+	* src/main/java/de/intevation/flys/exports/ChartExportHelper.java:
+
 2012-01-23  Felix Wolfsteller	<felix.wolfsteller@intevation.de>
 
 	Fix flys/issue395 (SVG/PDF-Export: Längsschitt enthält keine
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java	Mon Jan 23 07:55:17 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java	Mon Jan 23 10:44:34 2012 +0000
@@ -3,8 +3,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.jfree.chart.annotations.XYTextAnnotation;
-
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
 
@@ -17,6 +15,7 @@
 
 /**
  * Facet to show Main Q Values.
+ * TODO Join with W implementation.
  */
 public class MainValuesQFacet
 extends      DefaultFacet
@@ -47,7 +46,7 @@
         MainValuesArtifact mvArtifact = (MainValuesArtifact) artifact;
 
         List<NamedDouble>      qs = mvArtifact.getMainValuesQ(isAtGauge);
-        List<XYTextAnnotation> xy = new ArrayList<XYTextAnnotation>();
+        List<StickyAxisAnnotation> xy = new ArrayList<StickyAxisAnnotation>();
 
         for (NamedDouble q: qs) {
             xy.add(new StickyAxisAnnotation(
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java	Mon Jan 23 07:55:17 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java	Mon Jan 23 10:44:34 2012 +0000
@@ -3,8 +3,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.jfree.chart.annotations.XYTextAnnotation;
-
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
 
@@ -15,6 +13,7 @@
 import de.intevation.flys.jfree.FLYSAnnotation;
 import de.intevation.flys.jfree.StickyAxisAnnotation;
 
+
 /**
  * Facet to show Main W Values.
  */
@@ -47,7 +46,7 @@
         MainValuesArtifact mvArtifact = (MainValuesArtifact) artifact;
 
         List<NamedDouble>      ws = mvArtifact.getMainValuesW(isAtGauge);
-        List<XYTextAnnotation> xy = new ArrayList<XYTextAnnotation>();
+        List<StickyAxisAnnotation> xy = new ArrayList<StickyAxisAnnotation>();
 
         for (NamedDouble w: ws) {
             xy.add(new StickyAxisAnnotation(
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java	Mon Jan 23 07:55:17 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java	Mon Jan 23 10:44:34 2012 +0000
@@ -7,8 +7,6 @@
 
 import org.w3c.dom.Document;
 
-import org.jfree.chart.annotations.XYTextAnnotation;
-
 import org.jfree.chart.JFreeChart;
 import org.jfree.chart.title.TextTitle;
 import org.jfree.data.xy.XYSeries;
@@ -183,7 +181,7 @@
         Document theme,
         boolean  visible
     ) {
-        List<XYTextAnnotation> xy = new ArrayList<XYTextAnnotation>();
+        List<StickyAxisAnnotation> xy = new ArrayList<StickyAxisAnnotation>();
         double [][] data = (double [][]) wqkms;
         for (int i = 0; i< data[0].length; i++) {
             xy.add(new StickyAxisAnnotation(facet.getDescription(),
@@ -208,7 +206,7 @@
         Document theme,
         boolean  visible
     ) {
-        List<XYTextAnnotation> xy = new ArrayList<XYTextAnnotation>();
+        List<StickyAxisAnnotation> xy = new ArrayList<StickyAxisAnnotation>();
         double [][] data = (double [][]) wqkms;
         for (int i = 0; i< data[0].length; i++) {
             xy.add(new StickyAxisAnnotation(facet.getDescription(),
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Mon Jan 23 07:55:17 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Mon Jan 23 10:44:34 2012 +0000
@@ -31,12 +31,12 @@
 import org.jfree.chart.LegendItem;
 import org.jfree.chart.LegendItemCollection;
 import org.jfree.chart.annotations.XYBoxAnnotation;
+import org.jfree.chart.annotations.XYLineAnnotation;
 import org.jfree.chart.annotations.XYTextAnnotation;
 import org.jfree.chart.axis.NumberAxis;
 import org.jfree.chart.axis.ValueAxis;
 import org.jfree.chart.plot.PlotOrientation;
 import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.XYItemRenderer;
 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
 import org.jfree.data.Range;
 import org.jfree.data.xy.XYSeries;
@@ -44,6 +44,7 @@
 import org.jfree.data.xy.XYDataset;
 
 import org.jfree.ui.RectangleInsets;
+import org.jfree.ui.TextAnchor;
 
 import de.intevation.artifacts.CallContext;
 
@@ -56,6 +57,7 @@
 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;
 import de.intevation.flys.jfree.StyledXYSeries;
 
@@ -507,8 +509,6 @@
         recoverEmptyPlot(plot);
         preparePointRanges(plot);
 
-        addAnnotationsToRenderer(plot);
-
         //debugAxis(plot);
 
         localizeAxes(plot);
@@ -516,7 +516,7 @@
         autoZoom(plot);
 
         // These have to go after the autozoom.
-        addBoxAnnotations(plot);
+        addAnnotationsToRenderer(plot);
 
         return chart;
     }
@@ -972,61 +972,41 @@
         return null;
     }
 
+    public LegendItem createLegendItem(Document theme, String name) {
+        // OPTIMIZE Pass font, parsed Theme items.
+        ThemeAccess themeAccess = new ThemeAccess(theme);
+        Color color = themeAccess.parseLineColorField();
+        LegendItem li = new LegendItem(name, color);
+        li.setLabelFont(createLegendLabelFont());
+        return li;
+    }
+
 
     /**
-     * Add annotations to Renderer.
+     * Get "lowest" X Value for first axis. This value is exactly at the
+     * border of the plot.
+     * @return lowest value on first 'x'-axis.
      */
-    protected void addAnnotationsToRenderer(XYPlot plot) {
-        plot.clearAnnotations();
-
-        if (annotations == null) {
-            logger.debug("No Annotations given.");
-            return;
+    protected double getLowestXValue(XYPlot plot) {
+        ValueAxis axis = plot.getDomainAxis();
+        if (axis == null) {
+            logger.warn("No X-Axis to find lowest value for.");
         }
-
-        Font labelFont = createLegendLabelFont();
-
-        LegendItemCollection lic = new LegendItemCollection();
-        LegendItemCollection old = plot.getFixedLegendItems();
-
-        XYItemRenderer renderer = plot.getRenderer(0);
-
-        for (FLYSAnnotation fa: annotations) {
-            Document theme = fa.getTheme();
-
-            ThemeAccess themeAccess = new ThemeAccess(theme);
-
-            Color color   = themeAccess.parseLineColorField();
-            int lineWidth = themeAccess.parseLineWidth();
+        return axis.getRange().getLowerBound();
+    }
 
-            LegendItem li = new LegendItem(fa.getLabel(), color);
-            li.setLabelFont(labelFont);
-
-            lic.add(li);
 
-            for (XYTextAnnotation ta: fa.getTextAnnotations()) {
-                if(ta instanceof StickyAxisAnnotation) {
-                    StickyAxisAnnotation sta = (StickyAxisAnnotation)ta;
-                    sta.applyTheme(themeAccess);
-                    renderer.addAnnotation(sta);
-                }
-                else {
-                    ta.setPaint(color);
-                    ta.setOutlineStroke(new BasicStroke((float) lineWidth));
-                    renderer.addAnnotation(ta);
-                }
-            }
+    /**
+     * Get "lowest" X Value for first axis. This value is exactly at the
+     * border of the plot.
+     * @return highest value on first 'x'-axis.
+     */
+    protected double getUppestXValue(XYPlot plot) {
+        ValueAxis axis = plot.getDomainAxis();
+        if (axis == null) {
+            logger.warn("No first Y-Axis to find uppest value for.");
         }
-
-        // (Re-)Add prior legend entries.
-        if (old != null) {
-            old.addAll(lic);
-        }
-        else {
-            old = lic;
-        }
-
-        plot.setFixedLegendItems(old);
+        return axis.getRange().getUpperBound();
     }
 
 
@@ -1084,9 +1064,74 @@
     }
 
 
-    /** Add box annotations (currently, only hyk zones). */
-    public void addBoxAnnotations(XYPlot plot) {
-        logger.debug("XYChartGenerator.addBoxAnnotations");
+    /**
+     * Add a text and a line annotation.
+     */
+    public void addStickyAnnotation(
+        StickyAxisAnnotation annotation,
+        XYPlot plot,
+        Area area,
+        ThemeAccess.LineStyle lineStyle,
+        ThemeAccess.TextStyle textStyle
+    ) {
+        // OPTIMIZE pre-calculate area-related values
+        final float TEXT_OFF = 0.03f;
+        final float LINE_OFF = 0.02f;
+
+        XYLineAnnotation lineAnnotation = null;
+        XYTextAnnotation textAnnotation = null;
+
+        if (annotation.atX()) {
+            textAnnotation = new CollisionFreeXYTextAnnotation(
+                annotation.getText(), annotation.getPos(), area.ofGround(TEXT_OFF));
+            // OPTIMIZE externalize the calculation involving PI.
+            textAnnotation.setRotationAngle(270f*Math.PI/180f);
+            // Style the line.
+            if (lineStyle != null) {
+                lineAnnotation = new XYLineAnnotation(annotation.getPos(),
+                    area.atGround(), annotation.getPos(), area.ofGround(LINE_OFF),
+                    new BasicStroke(lineStyle.getWidth()),lineStyle.getColor());
+            }
+            else {
+                lineAnnotation = new XYLineAnnotation(annotation.getPos(),
+                    area.atGround(), annotation.getPos(), area.ofGround(LINE_OFF));
+            }
+        }
+        else {
+            textAnnotation = new CollisionFreeXYTextAnnotation(
+                annotation.getText(), area.ofLeft(TEXT_OFF), annotation.getPos());
+            // Style the line.
+            if (lineStyle != null) {
+                lineAnnotation = new XYLineAnnotation(area.atLeft(),
+                    annotation.getPos(), area.ofLeft(LINE_OFF),
+                    annotation.getPos(), new BasicStroke(lineStyle.getWidth()),
+                    lineStyle.getColor());
+            }
+            else {
+                lineAnnotation = new XYLineAnnotation(area.atLeft(),
+                    annotation.getPos(), area.ofLeft(LINE_OFF), annotation.getPos());
+            }
+        }
+
+        // Style the text.
+        if (textStyle != null) {
+            textStyle.apply(textAnnotation);
+        }
+
+        // Add the Annotations to renderer.
+        textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT);
+        textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT);
+
+        plot.getRenderer().addAnnotation(textAnnotation,
+            org.jfree.ui.Layer.BACKGROUND);
+        plot.getRenderer().addAnnotation(lineAnnotation,
+            org.jfree.ui.Layer.BACKGROUND);
+    }
+
+
+    /** Add annotations (Sticky, Text and hyk zones). */
+    public void addAnnotationsToRenderer(XYPlot plot) {
+        logger.debug("XYChartGenerator.addAnnotationsToRenderer");
 
         if (annotations == null) {
             logger.debug("XYChartGenerator.addBoxAnnotations: no annotations.");
@@ -1096,47 +1141,72 @@
         // Paints for the boxes/lines.
         Stroke basicStroke = new BasicStroke(1.0f);
 
-        Paint linePaint = new Color(255,0,0,60);
-        Paint fillPaint = new Color(0,255,0,60);
-        Paint tranPaint = new Color(0,0,0,0);
+        Paint linePaint = new Color(255,  0,0,60);
+        Paint fillPaint = new Color(0,  255,0,60);
+        Paint tranPaint = new Color(0,    0,0, 0);
 
-        // Pre-calculated positions on y axis.
-        double fillPercent = 0.03;
-        double low = getLowestYValue(plot);
-        double up  = getUppestYValue(plot);
-        double upb = low + (up - low) * fillPercent;
-        double upt = low + (up - low) * fillPercent/2.0d;
+        // OPTMIMIZE: Pre-calculate positions
+        Area area = new Area(
+            plot.getDomainAxis(0).getRange(),
+            plot.getRangeAxis().getRange());
 
+        // Walk over all Annotation sets.
+        for (FLYSAnnotation fa: annotations) {
 
-        for (FLYSAnnotation fa: annotations) {
             // Access text styling, if any.
             Document theme = fa.getTheme();
             ThemeAccess.TextStyle textStyle = null;
+            ThemeAccess.LineStyle lineStyle = null;
+
+            // Get Themeing information and add legend item.
             if (theme != null) {
                 ThemeAccess themeAccess = new ThemeAccess(theme);
                 textStyle = themeAccess.parseTextStyle();
+                lineStyle = themeAccess.parseLineStyle();
+                LegendItemCollection lic = new LegendItemCollection();
+                LegendItemCollection old = plot.getFixedLegendItems();
+                lic.add(createLegendItem(theme, fa.getLabel()));
+                // (Re-)Add prior legend entries.
+                if (old != null) {
+                    old.addAll(lic);
+                }
+                else {
+                    old = lic;
+                }
+                plot.setFixedLegendItems(old);
             }
 
-            // For each zone, create a box to fill with color, a box to draw
-            // the lines and a text to display the type.
+            // The 'Sticky' Annotations (at axis, with line and text).
+            for (StickyAxisAnnotation sta: fa.getAxisTextAnnotations()) {
+                addStickyAnnotation(sta, plot, area, lineStyle, textStyle);
+            }
+
+            // The not yet implemented other Text Annotations.
+            for (XYTextAnnotation ta: fa.getTextAnnotations()) {
+                // TODO implement, one we have textannotations
+            }
+
+            // Hyks.
             for (HYKFactory.Zone zone: fa.getBoxes()) {
+                // For each zone, create a box to fill with color, a box to draw
+                // the lines and a text to display the type.
                 fillPaint = colorForHYKZone(zone.getName());
 
-                XYBoxAnnotation boxA = new XYBoxAnnotation(zone.getFrom(), low,
-                    zone.getTo(), upb, basicStroke, tranPaint, fillPaint);
-                XYBoxAnnotation boxB = new XYBoxAnnotation(zone.getFrom(), low,
-                    zone.getTo(), up, basicStroke, fillPaint, tranPaint);
+                XYBoxAnnotation boxA = new XYBoxAnnotation(zone.getFrom(), area.atGround(),
+                    zone.getTo(), area.ofGround(0.03f), basicStroke, tranPaint, fillPaint);
+                XYBoxAnnotation boxB = new XYBoxAnnotation(zone.getFrom(), area.atGround(),
+                    zone.getTo(), area.atTop(), basicStroke, fillPaint, tranPaint);
 
                 XYTextAnnotation tex = new XYTextAnnotation(zone.getName(),
                     zone.getFrom() + (zone.getTo() - zone.getFrom()) / 2.0d,
-                    upt);
+                    area.ofGround(0.015f));
                 if (textStyle != null) {
                     textStyle.apply(tex);
                 }
 
-                plot.getRenderer().addAnnotation(boxA);
-                plot.getRenderer().addAnnotation(boxB);
-                plot.getRenderer().addAnnotation(tex);
+                plot.getRenderer().addAnnotation(boxA, org.jfree.ui.Layer.BACKGROUND);
+                plot.getRenderer().addAnnotation(boxB, org.jfree.ui.Layer.BACKGROUND);
+                plot.getRenderer().addAnnotation(tex,  org.jfree.ui.Layer.BACKGROUND);
             }
         }
     }
@@ -1553,5 +1623,39 @@
 
         return axisSections;
     }
+
+
+    /** Two Ranges that span a rectangular area. */
+    public static class Area {
+        protected Range xRange;
+        protected Range yRange;
+
+        public Area(Range rangeX, Range rangeY) {
+            this.xRange = rangeX;
+            this.yRange = rangeY;
+        }
+
+        public double ofLeft(double percent) {
+            return xRange.getLowerBound()
+                + xRange.getLength() * percent;
+        }
+
+        public double ofGround(double percent) {
+            return yRange.getLowerBound()
+                + yRange.getLength() * percent;
+        }
+
+        public double atTop() {
+            return yRange.getUpperBound();
+        }
+
+        public double atGround() {
+            return yRange.getLowerBound();
+        }
+
+        public double atLeft() {
+            return xRange.getLowerBound();
+        }
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/CollisionFreeXYTextAnnotation.java	Mon Jan 23 07:55:17 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/CollisionFreeXYTextAnnotation.java	Mon Jan 23 10:44:34 2012 +0000
@@ -6,9 +6,6 @@
 
 import java.awt.Shape;
 import java.awt.geom.Rectangle2D;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.BasicStroke;
 
 import org.jfree.chart.annotations.XYTextAnnotation;
 import org.jfree.chart.axis.ValueAxis;
@@ -22,7 +19,6 @@
 
 import org.jfree.ui.RectangleEdge;
 
-import de.intevation.flys.utils.ThemeAccess;
 
 /**
  * Custom Annotations class that is drawn only if no collisions with other
@@ -34,7 +30,8 @@
     private static Logger logger =
         Logger.getLogger(CollisionFreeXYTextAnnotation.class);
 
-    public CollisionFreeXYTextAnnotation(String text, float x, double y) {
+
+    public CollisionFreeXYTextAnnotation(String text, double x, double y) {
         super(text, x, y);
     }
 
@@ -88,6 +85,7 @@
 
         // Deviation from superclass: prevent collision.
         Rectangle2D hotspotBox = hotspot.getBounds2D();
+
         for (Iterator i = info.getOwner().getEntityCollection().iterator();
                 i.hasNext(); ) {
             Object next = i.next();
@@ -125,18 +123,5 @@
                 "CollisionFreeXYTextAnnotation");
         }
     }
-
-
-    /*
-    public void applyTheme(ThemeAccess ta) {
-        lineWidth       = ta.parseLineWidth();
-        lineColor       = ta.parseLineColorField();
-        textColor       = ta.parseTextColor();
-        font            = ta.parseTextFont();
-        textOrientation = ta.parseTextOrientation();
-        textBackground  = ta.parseTextBackground();
-        showBackground  = ta.parseShowTextBackground();
-    }
-    */
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/FLYSAnnotation.java	Mon Jan 23 07:55:17 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/FLYSAnnotation.java	Mon Jan 23 10:44:34 2012 +0000
@@ -7,6 +7,8 @@
 
 import org.jfree.chart.annotations.XYTextAnnotation;
 
+import de.intevation.flys.jfree.StickyAxisAnnotation;
+
 import de.intevation.flys.artifacts.model.HYKFactory;
 
 
@@ -15,8 +17,11 @@
  */
 public class FLYSAnnotation {
 
+    // TODO this will likely be used, soon.
     protected List<XYTextAnnotation> textAnnotations;
 
+    protected List<StickyAxisAnnotation> axisTextAnnotations;
+
     protected List<HYKFactory.Zone> boxes;
 
     protected Document theme;
@@ -24,13 +29,13 @@
     protected String label;
 
 
-    public FLYSAnnotation(String label, List<XYTextAnnotation> annotations) {
+    public FLYSAnnotation(String label, List<StickyAxisAnnotation> annotations) {
         this(label, annotations, null, null);
     }
 
 
     /** Create annotations, parameter might be null. */
-    public FLYSAnnotation(String label, List<XYTextAnnotation> annotations,
+    public FLYSAnnotation(String label, List<StickyAxisAnnotation> annotations,
         List<HYKFactory.Zone> bAnnotations
     ) {
         this(label, annotations, bAnnotations, null);
@@ -38,16 +43,17 @@
 
 
     /** Create annotations, parameter might be null. */
-    public FLYSAnnotation(String label, List<XYTextAnnotation> annotations,
+    public FLYSAnnotation(String label, List<StickyAxisAnnotation> annotations,
         List<HYKFactory.Zone> bAnnotations, Document theme
     ) {
         this.label           = label;
-        this.textAnnotations = (annotations != null)
+        this.axisTextAnnotations = (annotations != null)
                                ? annotations
-                               : Collections.<XYTextAnnotation>emptyList();
+                               : Collections.<StickyAxisAnnotation>emptyList();
         this.boxes  = (bAnnotations != null)
                                ? bAnnotations
                                : Collections.<HYKFactory.Zone>emptyList();
+        this.textAnnotations = Collections.<XYTextAnnotation>emptyList();
         this.setTheme(theme);
     }
 
@@ -60,6 +66,10 @@
         return label;
     }
 
+    public List<StickyAxisAnnotation> getAxisTextAnnotations() {
+        return axisTextAnnotations;
+    }
+
     public List<XYTextAnnotation> getTextAnnotations() {
         return textAnnotations;
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java	Mon Jan 23 07:55:17 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/StickyAxisAnnotation.java	Mon Jan 23 10:44:34 2012 +0000
@@ -2,33 +2,6 @@
 
 import org.apache.log4j.Logger;
 
-import java.util.Iterator;
-
-import java.awt.Shape;
-import java.awt.geom.Rectangle2D;
-import java.awt.geom.Line2D;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.BasicStroke;
-
-import org.jfree.chart.annotations.XYTextAnnotation;
-import org.jfree.chart.axis.ValueAxis;
-import org.jfree.chart.util.LineUtilities;
-import org.jfree.chart.plot.PlotOrientation;
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.entity.XYAnnotationEntity;
-import org.jfree.chart.plot.PlotRenderingInfo;
-import org.jfree.chart.ChartRenderingInfo;
-import org.jfree.chart.plot.Plot;
-
-import org.jfree.data.Range;
-
-import org.jfree.text.TextUtilities;
-
-import org.jfree.ui.RectangleEdge;
-import org.jfree.ui.TextAnchor;
-
-import de.intevation.flys.utils.ThemeAccess;
 
 /**
  * Custom Annotations class that is drawn only if no collisions with other
@@ -36,7 +9,7 @@
  * the axis is shown in all cases, though.
  * Draws a given text and a line to it from either axis.
  */
-public class StickyAxisAnnotation extends XYTextAnnotation {
+public class StickyAxisAnnotation {
 
     /** Logger for this class. */    
     private static Logger logger =
@@ -54,29 +27,7 @@
     /** The 1-dimensional position of this annotation. */
     protected float pos;
 
-    /** Theme attributes. */
-    protected Color textColor;
-    protected Color lineColor;
-    protected Font font;
-    protected int lineWidth;
-    protected String textOrientation = "vertical";
-    protected Color textBackground;
-    protected boolean showBackground;
-
-
-    /**
-     * Trivial constructor.
-     *
-     * @param text Text to display.
-     * @param x    X-position in dataspace (typical horizontal, in km).
-     * @param y    Y-position in dataspace (typical vertical, in m).
-     * @deprecated
-     */
-    public StickyAxisAnnotation(String text, float x, float y) {
-        super(text, x, y);
-        setStickyAxis(SimpleAxis.X_AXIS);
-    }
-
+    String text;
 
     /**
      * Constructor with implicit sticky x-axis.
@@ -84,7 +35,7 @@
      * @param pos        the position at which to draw the text and mark.
      */
     public StickyAxisAnnotation(String text, float pos) {
-        this(text, pos, pos, SimpleAxis.X_AXIS);
+        this(text, pos, SimpleAxis.X_AXIS);
     }
 
 
@@ -94,23 +45,13 @@
      * @param pos        the position at which to draw the text and mark.
      * @param stickyAxis the axis at which to stick (and to which 'pos' is
      *                   relative).
+     * @param lineTo     upto where to draw a line (NaN for none).
      */
-    public StickyAxisAnnotation(String text, float pos, SimpleAxis stickAxis) {
-        super(text, pos, pos);
+    public StickyAxisAnnotation(String text, float pos, SimpleAxis stickAxis
+    ) {
         setStickyAxis(stickAxis);
-        this.pos = pos;
-    }
-
-
-    /**
-     * Legacy-Constructor.
-     * @deprecated
-     */
-    public StickyAxisAnnotation(String text, float x, float y,
-            SimpleAxis stickAxis) {
-        super(text, x, y);
-        setStickyAxis(stickAxis);
-        this.pos = x;
+        this.text   = text;
+        this.pos    = pos;
     }
 
 
@@ -122,238 +63,23 @@
      */
     public void setStickyAxis(SimpleAxis stickyAxis) {
         this.stickyAxis = stickyAxis;
-        if (stickyAxis == SimpleAxis.X_AXIS){
-            float o = 270f;
-            if(textOrientation.equals("horizontal")) {
-                o = 0f;
-            }
-            this.setRotationAngle(o * (Math.PI / 180f));
-            this.setRotationAnchor(TextAnchor.CENTER_LEFT);
-            this.setTextAnchor(TextAnchor.CENTER_LEFT);
-        } else {
-            this.setRotationAngle(0f * (Math.PI / 180f));
-            this.setRotationAnchor(TextAnchor.CENTER_LEFT);
-            this.setTextAnchor(TextAnchor.CENTER_LEFT);
-        }
-    }
-
-
-    /**
-     * Draws a small line at axis where this annotation resides.
-     *
-     * @param g2          the graphics device.
-     * @param dataArea    the data area.
-     * @param domainAxis  the domain axis.
-     * @param rangeAxis   the range axis.
-     * @param domainEdge  the domain edge.
-     * @param rangeEdge   the range edge.
-     * @param orientation the plot orientation.
-     */
-    protected void drawAxisMark(
-            java.awt.Graphics2D g2,
-            java.awt.geom.Rectangle2D dataArea,
-            ValueAxis domainAxis,
-            ValueAxis rangeAxis,
-            RectangleEdge domainEdge,
-            RectangleEdge rangeEdge,
-            PlotOrientation orientation) {
-        float j2DX1 = 0.0f;
-        float j2DX2 = 0.0f;
-        float j2DY1 = 0.0f;
-        float j2DY2 = 0.0f;
-        float x = (float) getX();
-        float y = (float) getY();
-        /* When dependent on X/Y-Axis and orientation, following
-           can be used as a base:
-        if (orientation == PlotOrientation.VERTICAL) {
-            j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea,
-                        domainEdge);
-            j2DY1 = (float) rangeAxis.valueToJava2D(y, dataArea,
-                        rangeEdge);
-            j2DX2 = (float) domainAxis.valueToJava2D(x, dataArea,
-                        domainEdge);
-            j2DY2 = (float) rangeAxis.valueToJava2D(y, dataArea,
-                        rangeEdge);
-            }
-        else if (orientation == PlotOrientation.HORIZONTAL) {
-            j2DY1 = (float) domainAxis.valueToJava2D(x, dataArea,
-                    domainEdge);
-            j2DX1 = (float) rangeAxis.valueToJava2D(y, dataArea,
-                    rangeEdge);
-            j2DY2 = (float) domainAxis.valueToJava2D(x, dataArea,
-                    domainEdge);
-            j2DX2 = (float) rangeAxis.valueToJava2D(y, dataArea,
-                    rangeEdge);
-        }
-
-        g2.setPaint(this.paint);
-        g2.setStroke(this.stroke);
-        */
-        if (this.stickyAxis == SimpleAxis.X_AXIS) {
-            j2DY1 = (float) RectangleEdge.coordinate(dataArea, domainEdge);
-            double rangeLow = rangeAxis.getRange().getLowerBound();
-            // Line ends at 1.5% of full distance.
-            j2DY2 = (float) rangeAxis.valueToJava2D(
-                      (1f - 0.015f) * rangeLow + 0.015f * 
-                      rangeAxis.getRange().getUpperBound(),
-                     dataArea, rangeEdge);
-            j2DX1 = (float) domainAxis.valueToJava2D(x, dataArea, domainEdge);
-            j2DX2 = j2DX1;
-        } else {
-            j2DX1 = (float) RectangleEdge.coordinate(dataArea, rangeEdge);
-            Range domainRange = domainAxis.getRange();
-            double rangeLow = domainRange.getLowerBound();
-            // Line ends at 1.5% of full distance.
-            j2DX2 = (float) domainAxis.valueToJava2D(
-                      (1f - 0.015f) * rangeLow + 0.015f * 
-                      domainRange.getUpperBound(),
-                     dataArea, domainEdge);
-            j2DY1 = (float) rangeAxis.valueToJava2D(pos, dataArea, rangeEdge);
-            j2DY2 = j2DY1;
-        }
-
-        Line2D line = new Line2D.Float(j2DX1, j2DY1, j2DX2, j2DY2);
-
-        // line is clipped to avoid JRE bug 6574155, for more info
-        // see JFreeChart bug 2221495
-        boolean visible = LineUtilities.clipLine(line, dataArea);
-        if (visible) {
-            setOutlineStroke(new BasicStroke((float) lineWidth));
-            g2.setStroke(getOutlineStroke());
-            g2.setPaint(lineColor);
-            g2.draw(line);
-        }
     }
 
 
-    /**
-     * Draw the Annotation; the text only if it does not collide with other
-     * already drawn Annotations- texts.
-     *
-     * @param g2            the graphics device.
-     * @param plot          the plot.
-     * @param dataArea      the data area.
-     * @param domainAxis    the domain axis.
-     * @param rangeAxis     the range axis.
-     * @param rendererIndex the render index.
-     * @param info          state information, escpecially collects info about
-     *                      already drawn shapes (and thus annotations), used
-     *                      for collision detection.
-     */
-    @Override
-    public void draw(
-       java.awt.Graphics2D g2,
-       XYPlot plot,
-       java.awt.geom.Rectangle2D dataArea,
-       ValueAxis domainAxis,
-       ValueAxis rangeAxis,
-       int rendererIndex,
-       PlotRenderingInfo info) {
-
-        if (info == null)
-            return;
-
-        if (domainAxis == null || rangeAxis == null
-                || domainAxis.getRange()    == null
-                || rangeAxis.getRange()     == null
-                ) {
-            logger.error("Annotation cannot be drawn (missing axis).");
-            return;
-        }
-
-        // Calculate the bounding box.
-        ChartRenderingInfo chartInfo = info.getOwner();
-
-        PlotOrientation orientation = plot.getOrientation();
-        RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
-            plot.getDomainAxisLocation(), orientation);
-        RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(
-            plot.getRangeAxisLocation(), orientation);
-        float anchorX = 0f;
-        float anchorY = 0.0f;
-        if (this.stickyAxis == SimpleAxis.X_AXIS) {
-            // Text starts at 2% of full distance.
-            float rangeLow = (float) rangeAxis.getRange().getLowerBound();
-            float y = rangeLow + 0.02f * ((float)
-                rangeAxis.getRange().getUpperBound() - rangeLow);
-            setY(y);
-
-            anchorX = (float) domainAxis.valueToJava2D(
-                getX(), dataArea, domainEdge);
-            anchorY = (float) rangeAxis.valueToJava2D(
-                getY(), dataArea, rangeEdge);
-        } else {
-            float rangeLow = (float) domainAxis.getRange().getLowerBound();
-            float x = rangeLow + 0.02f * ((float)
-                domainAxis.getRange().getUpperBound() - rangeLow);
-            setX(x);
-            anchorX = (float) domainAxis.valueToJava2D(
-                getX(), dataArea, domainEdge);
-            anchorY = (float) rangeAxis.valueToJava2D(
-                getY(), dataArea, rangeEdge);
-        }
-        if (orientation == PlotOrientation.HORIZONTAL) {
-            float tempAnchor = anchorX;
-            anchorX = anchorY;
-            anchorY = tempAnchor;
-        }
-
-        //Call to apply orientation.
-        setStickyAxis(stickyAxis);
-
-        // Always draw the small line at axis.
-        drawAxisMark(g2, dataArea, domainAxis, rangeAxis, domainEdge,
-            rangeEdge, orientation);
-
-        Shape hotspot = TextUtilities.calculateRotatedStringBounds(
-            getText(), g2, anchorX, anchorY, getTextAnchor(),
-            getRotationAngle(), getRotationAnchor());
-        Rectangle2D hotspotBox = hotspot.getBounds2D();
-        // Check for collisions with other XYAnnotations.
-        for (Iterator i = chartInfo.getEntityCollection().iterator();
-                i.hasNext(); ) {
-            Object next = i.next();
-            // Collision with other stuff than XYAnnotations are okay.
-            if (next instanceof XYAnnotationEntity) {
-                XYAnnotationEntity drawnShape = (XYAnnotationEntity) next;
-                if (drawnShape.getArea().intersects(hotspotBox)) {
-                    // Found collision, early stop.
-                    return;
-                }
-            }
-        }
-
-        // Draw the background.
-        if (showBackground) {
-            g2.setStroke(new BasicStroke ((float) 1));
-            g2.setBackground(textBackground);
-            g2.setPaint(textBackground);
-            hotspot = TextUtilities.calculateRotatedStringBounds(
-                getText(), g2, anchorX, anchorY, getTextAnchor(),
-                getRotationAngle(), getRotationAnchor());
-            g2.fill(hotspot);
-            g2.draw(hotspot);
-        }
-
-        // Draw the text.
-        g2.setPaint(textColor);
-        g2.setFont(font);
-        TextUtilities.drawRotatedString(getText(), g2, anchorX, anchorY,
-            getTextAnchor(), getRotationAngle(), getRotationAnchor());
-
-        // Add info that we have drawn this Annotation.
-        addEntity(info, hotspot, rendererIndex, getToolTipText(), getURL());
+    public float getPos() {
+        return this.pos;
     }
 
+    public SimpleAxis getStickyAxis() {
+        return this.stickyAxis;
+    }
 
-    public void applyTheme(ThemeAccess ta) {
-        lineWidth       = ta.parseLineWidth();
-        lineColor       = ta.parseLineColorField();
-        textColor       = ta.parseTextColor();
-        font            = ta.parseTextFont();
-        textOrientation = ta.parseTextOrientation();
-        textBackground  = ta.parseTextBackground();
-        showBackground  = ta.parseShowTextBackground();
+    public boolean atX() {
+        return this.getStickyAxis() == SimpleAxis.X_AXIS;
+    }
+
+    public String getText() {
+        return this.text;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeAccess.java	Mon Jan 23 07:55:17 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/themes/ThemeAccess.java	Mon Jan 23 10:44:34 2012 +0000
@@ -101,6 +101,28 @@
     more of this
     */
 
+    public LineStyle parseLineStyle() {
+        return new LineStyle(parseLineColorField(), Integer.valueOf(parseLineWidth()));
+    }
+
+    public static class LineStyle {
+        protected Color lineColor;
+        protected int   lineWidth;
+
+        public LineStyle(Color color, int width) {
+            this.lineColor = color;
+            this.lineWidth = width;
+        }
+
+        public int getWidth() {
+            return lineWidth;
+        }
+
+        public Color getColor() {
+            return lineColor;
+        }
+    }
+
     public TextStyle parseTextStyle() {
         return new TextStyle(parseTextColor(), parseTextFont(),
             parseTextBackground(), false);

http://dive4elements.wald.intevation.org