changeset 3242:1dca41dba135

Move annotation code to base class ChartGenerator flys-artifacts/trunk@4874 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Christian Lins <christian.lins@intevation.de>
date Wed, 04 Jul 2012 22:28:44 +0000
parents da3e58694cae
children 46208d806da0
files flys-artifacts/ChangeLog flys-artifacts/doc/conf/default-themes.xml flys-artifacts/doc/conf/themes.xml flys-artifacts/doc/conf/virtual-themes.xml flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java flys-artifacts/src/main/java/de/intevation/flys/exports/ChartArea.java flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/ChartInfoGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java flys-artifacts/src/main/java/de/intevation/flys/utils/ThemeUtil.java
diffstat 12 files changed, 577 insertions(+), 735 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Wed Jul 04 06:54:39 2012 +0000
+++ b/flys-artifacts/ChangeLog	Wed Jul 04 22:28:44 2012 +0000
@@ -1,3 +1,14 @@
+2012-07-05	Christian Lins <christian.lins@intevation.de>
+
+	* doc/*-themes.xml:
+          Add textorientation field.
+
+	* src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/XYChartGenerator.java,
+	  src/main/java/de/intevation/flys/exports/ChartArea.java:
+	  Move annotation related code to base class ChartGenerator.
+
 2012-07-04	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
 
 	* src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java:
--- a/flys-artifacts/doc/conf/default-themes.xml	Wed Jul 04 06:54:39 2012 +0000
+++ b/flys-artifacts/doc/conf/default-themes.xml	Wed Jul 04 22:28:44 2012 +0000
@@ -1306,6 +1306,7 @@
                 default="3" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
                 default="0, 255, 0" />
+            <field name="textorientation" type="boolean" default="true" display="Text horizontal"/>
         </fields>
     </theme>
 
@@ -1441,4 +1442,4 @@
         </fields>
     </theme>
 
-</themegroup>
\ No newline at end of file
+</themegroup>
--- a/flys-artifacts/doc/conf/themes.xml	Wed Jul 04 06:54:39 2012 +0000
+++ b/flys-artifacts/doc/conf/themes.xml	Wed Jul 04 22:28:44 2012 +0000
@@ -167,6 +167,7 @@
         <mapping from="fix_sector_average_dwt_2" to="FixingDeltaWtAverage2"/>
         <mapping from="fix_sector_average_dwt_3" to="FixingDeltaWtAverage3"/>
         <mapping from="fix_analysis_events_dwt" to="FixingDeltaWtAnalysis"/>
+        <mapping from="fix_analysis_periods_dwt" to="FixingDeltaWtAnalysisPeriods"/>
         <mapping from="fix_reference_events_dwt" to="FixingDeltaWtReference"/>
         <mapping from="fix_sector_average_ls_deviation_0" to="FixingSectorDeviationLS0"/>
         <mapping from="fix_sector_average_ls_deviation_1" to="FixingSectorDeviationLS1"/>
@@ -177,6 +178,7 @@
         <mapping from="fix_sector_average_ls_2" to="FixingLSAverage2"/>
         <mapping from="fix_sector_average_ls_3" to="FixingLSAverage3"/>
         <mapping from="fix_deviation_ls" to="FixLSDeviation"/>
+        <mapping from="fix_deviation_dwt" to="FixDeltaWtDeviation"/>
         <mapping from="fix_analysis_events_ls" to="FixLSAnalysis"/>
         <mapping from="fix_reference_events_ls" to="FixLSReference"/>
     </mappings>
--- a/flys-artifacts/doc/conf/virtual-themes.xml	Wed Jul 04 06:54:39 2012 +0000
+++ b/flys-artifacts/doc/conf/virtual-themes.xml	Wed Jul 04 22:28:44 2012 +0000
@@ -76,6 +76,8 @@
                 default="5" />
             <field name="pointcolor" type="Color" display="Punktfarbe"
                 default="Color.BLACK" />
+            <field name="textorientation" type="boolean" display="Text horizontal"
+                default="true"/>
         </fields>
     </theme>
 
@@ -293,4 +295,4 @@
         </fields>
     </theme>
 
-</themegroup>
\ No newline at end of file
+</themegroup>
--- a/flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java	Wed Jul 04 06:54:39 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java	Wed Jul 04 22:28:44 2012 +0000
@@ -731,7 +731,7 @@
         CallContext context)
     throws    ArtifactDatabaseException
     {
-        log.debug("FLYSArtifactCollection.getFacetThemeFromAttribute");
+        log.debug("FLYSArtifactCollection.getFacetThemeFromAttribute(facet=" + facet + ", index=" + index);
 
         ArtifactDatabase db = context.getDatabase();
         CallMeta       meta = context.getMeta();
@@ -767,13 +767,13 @@
 
         Node theme = (Node) XMLUtils.xpath(
             tmp,
-            "art:themes/theme[@facet='" + facet +
+            "art:themes/theme[@facet='" + facet + 
             "' and @index='" + String.valueOf(index) + "']",
             XPathConstants.NODE,
             ArtifactNamespaceContext.INSTANCE);
 
         if (theme == null) {
-            log.warn("Could not find the theme in attribute of: " + uuid);
+            log.warn("Could not find the theme in attribute of: " + facet + " " + uuid);
 
             Theme t = getThemeForFacet(
                 uuid, facet, pattern, index, outName, context);
@@ -786,6 +786,9 @@
             addThemeToAttribute(uuid, attr, t, context);
             theme = t.toXML().getFirstChild();
         }
+        /*else {
+            log.debug("getFacetThemeFromAttribute: " + XMLUtils.toString(theme));
+        }*/
 
         Document doc = XMLUtils.newDocument();
         doc.appendChild(doc.importNode(theme, true));
@@ -847,7 +850,7 @@
         try {
             setCollectionItemAttribute(uuid, attr, context);
 
-            log.debug("Successfully added theme to item attribute.");
+            //log.debug("addThemeToAttribute: Successfully added theme to item attribute: " + XMLUtils.toString(attr));
         }
         catch (ArtifactDatabaseException e) {
             // do nothing
@@ -884,9 +887,10 @@
         }
 
         Document attr = XMLUtils.newDocument();
-
         addThemeToAttribute(uuid, attr, t, context);
 
+        log.debug("initItemAttribute for facet " + facet + ": " + XMLUtils.toString(attr));
+        
         return attr;
     }
 
@@ -949,7 +953,7 @@
         try {
             FLYSArtifact artifact = (FLYSArtifact) db.getRawArtifact(uuid);
             log.debug("Got raw artifact");
-            flysContext.put(flysContext.ARTIFACT_KEY, artifact);
+            flysContext.put(FLYSContext.ARTIFACT_KEY, artifact);
         }
         catch (ArtifactDatabaseException dbe) {
             log.error("Exception caught when trying to get art.", dbe);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartArea.java	Wed Jul 04 22:28:44 2012 +0000
@@ -0,0 +1,108 @@
+package de.intevation.flys.exports;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Paint;
+import java.awt.Stroke;
+
+import java.text.NumberFormat;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.w3c.dom.Document;
+
+import org.apache.log4j.Logger;
+
+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;
+import org.jfree.chart.annotations.XYTextAnnotation;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.ValueAxis;
+import org.jfree.chart.plot.Marker;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+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;
+
+import org.jfree.ui.TextAnchor;
+
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifactdatabase.state.Facet;
+
+import de.intevation.flys.jfree.Bounds;
+import de.intevation.flys.jfree.DoubleBounds;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StickyAxisAnnotation;
+import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
+import de.intevation.flys.jfree.StyledAreaSeriesCollection;
+import de.intevation.flys.jfree.StyledXYSeries;
+
+import de.intevation.flys.themes.ThemeAccess;
+import de.intevation.flys.utils.ThemeUtil;
+
+import de.intevation.flys.artifacts.model.HYKFactory;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+
+    /** Two Ranges that span a rectangular area. */
+    public class ChartArea {
+        protected Range xRange;
+        protected Range yRange;
+
+        public ChartArea(Range rangeX, Range rangeY) {
+            this.xRange = rangeX;
+            this.yRange = rangeY;
+        }
+
+        public ChartArea(ValueAxis axisX, ValueAxis axisY) {
+            this.xRange = axisX.getRange();
+            this.yRange = axisY.getRange();
+        }
+
+        public double ofLeft(double percent) {
+            return xRange.getLowerBound()
+                + xRange.getLength() * percent;
+        }
+
+        public double ofRight(double percent) {
+            return xRange.getUpperBound()
+                - 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 atRight() {
+            return xRange.getUpperBound();
+        }
+
+        public double atLeft() {
+            return xRange.getLowerBound();
+        }
+
+        public double above(double percent, double base) {
+            return base + yRange.getLength() * percent;
+        }
+    }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java	Wed Jul 04 06:54:39 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java	Wed Jul 04 22:28:44 2012 +0000
@@ -29,6 +29,9 @@
 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;
+import org.jfree.chart.annotations.XYTextAnnotation;
 import org.jfree.chart.axis.NumberAxis;
 import org.jfree.chart.plot.XYPlot;
 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
@@ -36,31 +39,42 @@
 import org.jfree.data.general.Series;
 import org.jfree.data.xy.XYDataset;
 import org.jfree.ui.RectangleInsets;
+import org.jfree.ui.TextAnchor;
 
 import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.ArtifactNamespaceContext;
 import de.intevation.artifacts.CallContext;
 import de.intevation.artifacts.CallMeta;
 import de.intevation.artifacts.PreferredLocale;
 
-import de.intevation.artifacts.ArtifactNamespaceContext;
 import de.intevation.artifacts.common.utils.XMLUtils;
 
 import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.artifactdatabase.state.Facet;
 import de.intevation.artifactdatabase.state.Settings;
 
 import de.intevation.flys.model.River;
 
 import de.intevation.flys.artifacts.FLYSArtifact;
+
 import de.intevation.flys.artifacts.resources.Resources;
+
+import de.intevation.flys.artifacts.model.HYKFactory;
+
 import de.intevation.flys.jfree.Bounds;
+import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
 import de.intevation.flys.jfree.DoubleBounds;
 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.StyledAreaSeriesCollection;
 import de.intevation.flys.jfree.Style;
 import de.intevation.flys.jfree.StyledSeries;
+
 import de.intevation.flys.themes.ThemeAccess;
+import de.intevation.flys.utils.ThemeUtil;
+
 import de.intevation.flys.utils.FLYSUtils;
 
 
@@ -82,6 +96,7 @@
     public static final int    DEFAULT_FONT_SIZE       = 12;
     public static final String DEFAULT_FONT_NAME       = "Tahoma";
 
+    protected static float ANNOTATIONS_AXIS_OFFSET = 0.02f;
 
     public static final String XPATH_CHART_SIZE =
         "/art:action/art:attributes/art:size";
@@ -170,7 +185,343 @@
 
         annotations.add(annotation);
     }
+    
+    /**
+     * Add a text and a line annotation.
+     * @param area convenience to determine positions in plot.
+     * @param theme (optional) theme document
+     */
+    protected void addStickyAnnotation(
+        StickyAxisAnnotation annotation,
+        XYPlot plot,
+        ChartArea area,
+        ThemeAccess.LineStyle lineStyle,
+        ThemeAccess.TextStyle textStyle,
+        Document theme
+    ) {
+        // OPTIMIZE pre-calculate area-related values
+        final float TEXT_OFF = 0.03f;
 
+        XYLineAnnotation lineAnnotation = null;
+        XYTextAnnotation textAnnotation = null;
+
+        int rendererIndex = 0;
+
+        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);
+            lineAnnotation = createGroundStickAnnotation(
+                area, annotation.getPos(), lineStyle);
+            textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT);
+            textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT);
+        }
+        else {
+            // Do the more complicated case where we stick to the Y-Axis.
+            // There is one nasty case (duration curves, where annotations
+            // might stick to the second y-axis).
+            // FIXME: Remove dependency to XYChartGenerator here
+            AxisDataset dataset = (XYChartGenerator.XYAxisDataset) getAxisDataset(
+                new Integer(annotation.getAxisSymbol()));
+            if (dataset == null) {
+                logger.warn("Annotation should stick to unfindable y-axis: "
+                    + annotation.getAxisSymbol());
+                rendererIndex = 0;
+            }
+            else {
+                rendererIndex = dataset.getPlotAxisIndex();
+            }
+
+            // Stick to the "right" (opposed to left) Y-Axis.
+            if (rendererIndex != 0) {
+                // OPTIMIZE: Pass a different area to this function,
+                //           do the adding to renderer outside (let this
+                //           function return the annotations).
+                //           Note that this path is travelled rarely.
+                ChartArea area2 = new ChartArea(plot.getDomainAxis(), plot.getRangeAxis(rendererIndex));
+                textAnnotation = new CollisionFreeXYTextAnnotation(
+                    annotation.getText(), area2.ofRight(TEXT_OFF), annotation.getPos());
+                textAnnotation.setRotationAnchor(TextAnchor.CENTER_RIGHT);
+                textAnnotation.setTextAnchor(TextAnchor.CENTER_RIGHT);
+                lineAnnotation = createRightStickAnnotation(
+                    area2, annotation.getPos(), lineStyle);
+                if (!Float.isNaN(annotation.getHitPoint()) && theme != null) {
+                    // New line annotation to hit curve.
+                    if (ThemeUtil.parseShowVerticalLine(theme)) {
+                        XYLineAnnotation hitLineAnnotation =
+                            createStickyLineAnnotation(
+                                StickyAxisAnnotation.SimpleAxis.X_AXIS,
+                                annotation.getHitPoint(), annotation.getPos(),// annotation.getHitPoint(),
+                                area2, lineStyle);
+                        plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation,
+                            org.jfree.ui.Layer.BACKGROUND);
+                    }
+                    if (ThemeUtil.parseShowHorizontalLine(theme)) {
+                        XYLineAnnotation lineBackAnnotation =
+                            createStickyLineAnnotation(
+                                StickyAxisAnnotation.SimpleAxis.Y_AXIS2,
+                                annotation.getPos(), annotation.getHitPoint(),
+                                area2, lineStyle);
+                        plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation,
+                            org.jfree.ui.Layer.BACKGROUND);
+                    }
+                }
+            }
+            else { // Stick to the left y-axis.
+                textAnnotation = new CollisionFreeXYTextAnnotation(
+                    annotation.getText(), area.ofLeft(TEXT_OFF), annotation.getPos());
+                textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT);
+                textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT);
+                lineAnnotation = createLeftStickAnnotation(area, annotation.getPos(), lineStyle);
+                if (!Float.isNaN(annotation.getHitPoint()) && theme != null) {
+                    // New line annotation to hit curve.
+                    if (ThemeUtil.parseShowHorizontalLine(theme)) {
+                        XYLineAnnotation hitLineAnnotation =
+                            createStickyLineAnnotation(
+                                StickyAxisAnnotation.SimpleAxis.Y_AXIS,
+                                annotation.getPos(), annotation.getHitPoint(),
+                                area, lineStyle);
+                        plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation,
+                            org.jfree.ui.Layer.BACKGROUND);
+                    }
+                    if (ThemeUtil.parseShowVerticalLine(theme)) {
+                        XYLineAnnotation lineBackAnnotation =
+                            createStickyLineAnnotation(
+                                StickyAxisAnnotation.SimpleAxis.X_AXIS,
+                                annotation.getHitPoint(), annotation.getPos(),
+                                area, lineStyle);
+                        plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation,
+                            org.jfree.ui.Layer.BACKGROUND);
+                    }
+                }
+            }
+        }
+
+        // Style the text.
+        if (textStyle != null) {
+            textStyle.apply(textAnnotation);
+        }
+
+        // Add the Annotations to renderer.
+        plot.getRenderer(rendererIndex).addAnnotation(textAnnotation,
+            org.jfree.ui.Layer.FOREGROUND);
+        plot.getRenderer(rendererIndex).addAnnotation(lineAnnotation,
+            org.jfree.ui.Layer.FOREGROUND);
+    }
+
+   /**
+     * Create annotation that sticks to "ground" (X) axis.
+     * @param area helper to calculate coordinates
+     * @param pos one-dimensional position (distance from axis)
+     * @param lineStyle the line style to use for the line.
+     */
+    protected static XYLineAnnotation createGroundStickAnnotation(
+        ChartArea area, float pos, ThemeAccess.LineStyle lineStyle
+    ) {
+        // Style the line.
+        if (lineStyle != null) {
+            return new XYLineAnnotation(
+                pos, area.atGround(),
+                pos, area.ofGround(ANNOTATIONS_AXIS_OFFSET),
+                new BasicStroke(lineStyle.getWidth()),lineStyle.getColor());
+        }
+        else {
+            return new XYLineAnnotation(
+                pos, area.atGround(),
+                pos, area.ofGround(ANNOTATIONS_AXIS_OFFSET));
+        }
+    }
+
+
+    /**
+     * Create annotation that sticks to the second Y axis ("right").
+     * @param area helper to calculate coordinates
+     * @param pos one-dimensional position (distance from axis)
+     * @param lineStyle the line style to use for the line.
+     */
+    protected static XYLineAnnotation createRightStickAnnotation(
+        ChartArea area, float pos, ThemeAccess.LineStyle lineStyle
+    ) {
+        // Style the line.
+        if (lineStyle != null) {
+            return new XYLineAnnotation(
+                area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos,
+                area.atRight(), pos,
+                new BasicStroke(lineStyle.getWidth()), lineStyle.getColor());
+        }
+        else {
+            return new XYLineAnnotation(
+                area.atRight(), pos,
+                area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos);
+        }
+    }
+
+
+    /**
+     * Create annotation that sticks to the first Y axis ("left").
+     * @param area helper to calculate coordinates
+     * @param pos one-dimensional position (distance from axis)
+     * @param lineStyle the line style to use for the line.
+     */
+    protected static XYLineAnnotation createLeftStickAnnotation(
+        ChartArea area, float pos, ThemeAccess.LineStyle lineStyle
+    ) {
+        // Style the line.
+        if (lineStyle != null) {
+            return new XYLineAnnotation(
+                area.atLeft(), pos,
+                area.ofLeft(ANNOTATIONS_AXIS_OFFSET), pos,
+                new BasicStroke(lineStyle.getWidth()), lineStyle.getColor());
+        }
+        else {
+            return new XYLineAnnotation(
+                area.atLeft(), pos,
+                area.ofLeft(ANNOTATIONS_AXIS_OFFSET), pos);
+        }
+    }
+
+
+    /**
+     * Create a line from a axis to a given point.
+     * @param axis   The "simple" axis.
+     * @param fromD1 from-location in first dimension.
+     * @param toD2   to-location in second dimension.
+     * @param area   helper to calculate offsets.
+     * @param lineStyle optional line style.
+     */
+    protected static XYLineAnnotation createStickyLineAnnotation(
+        StickyAxisAnnotation.SimpleAxis axis, float fromD1, float toD2,
+        ChartArea area, ThemeAccess.LineStyle lineStyle
+    ) {
+        double anchorX1 = 0d, anchorX2 = 0d, anchorY1 = 0d, anchorY2 = 0d;
+        switch(axis) {
+            case X_AXIS:
+                anchorX1 = fromD1;
+                anchorX2 = fromD1;
+                anchorY1 = area.atGround();
+                anchorY2 = toD2;
+                break;
+            case Y_AXIS:
+                anchorX1 = area.atLeft();
+                anchorX2 = toD2;
+                anchorY1 = fromD1;
+                anchorY2 = fromD1;
+                break;
+            case Y_AXIS2:
+                anchorX1 = area.atRight();
+                anchorX2 = toD2;
+                anchorY1 = fromD1;
+                anchorY2 = fromD1;
+                break;
+        }
+        // Style the line.
+        if (lineStyle != null) {
+            return new XYLineAnnotation(
+                anchorX1, anchorY1,
+                anchorX2, anchorY2,
+                new BasicStroke(lineStyle.getWidth()), lineStyle.getColor());
+        }
+        else {
+            return new XYLineAnnotation(
+                anchorX1, anchorY1,
+                anchorX2, anchorY2);
+        }
+    }
+
+    /**
+     * Add the annotations (Sticky, Text and hyk zones) stored
+     * in the annotations field.
+     */
+    protected void addAnnotationsToRenderer(XYPlot plot) {
+        logger.debug("addAnnotationsToRenderer");
+
+        if (annotations == null || annotations.size() == 0) {
+            logger.debug("addAnnotationsToRenderer: no annotations.");
+            return;
+        }
+
+        // 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);
+
+        // OPTMIMIZE: Pre-calculate positions
+        ChartArea area = new ChartArea(
+            plot.getDomainAxis(0).getRange(),
+            plot.getRangeAxis().getRange());
+
+        // Walk over all Annotation sets.
+        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();
+                if (fa.getLabel() != null) {
+                    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);
+                }
+            }
+
+            // The 'Sticky' Annotations (at axis, with line and text).
+            for (StickyAxisAnnotation sta: fa.getAxisTextAnnotations()) {
+                addStickyAnnotation(
+                    sta, plot, area, lineStyle, textStyle, theme);
+            }
+
+            // Other Text Annotations (e.g. labels of (manual) points).
+            for (XYTextAnnotation ta: fa.getTextAnnotations()) {
+                // Style the text.
+                if (textStyle != null) {
+                    textStyle.apply(ta);
+                }
+                ta.setY(area.above(0.05d, ta.getY()));
+                plot.getRenderer().addAnnotation(ta, org.jfree.ui.Layer.FOREGROUND);
+            }
+
+            // 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(), 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()) / 1.0d,
+                    area.ofGround(0.015f));
+                if (textStyle != null) {
+                    textStyle.apply(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);
+            }
+        }
+    }
+    
 
     /**
      * This method needs to be implemented by concrete subclasses to create new
@@ -275,9 +626,70 @@
     protected void addSubtitles(JFreeChart chart) {
         // do nothing
     }
+    
+    
+    /** Get color for hyk zones by their type (which is the name). */
+    protected Paint colorForHYKZone(String zoneName) {
+        if (zoneName.startsWith("R")) {
+            // Brownish.
+            return new Color(153, 60, 0);
+        }
+        else if (zoneName.startsWith("V")) {
+            // Greenish.
+            return new Color(0, 255, 0);
+        }
+        else if (zoneName.startsWith("B")) {
+            // Grayish.
+            return new Color(128, 128, 128);
+        }
+        else if (zoneName.startsWith("H")) {
+            // Blueish.
+            return new Color(0, 0, 255);
+        }
+        else {
+            // Default.
+            logger.debug("Unknown zone type found.");
+            return new Color(255, 0, 0);
+        }
+    }
 
 
     /**
+     * Register annotations like MainValues for later plotting
+     *
+     * @param annotations list of annotations (data of facet).
+     * @param aandf   Artifact and the facet.
+     * @param theme   Theme document for given annotations.
+     * @param visible The visibility of the annotations.
+     */
+    protected void doAnnotations(
+        FLYSAnnotation annotations,
+        ArtifactAndFacet aandf,
+        Document theme,
+        boolean visible
+    ){
+        // Running into trouble here.
+        logger.debug("doAnnotations");
+
+        // Add all annotations to our annotation pool.
+        annotations.setTheme(theme);
+        if (aandf != null) {
+            Facet facet = aandf.getFacet();
+            annotations.setLabel(aandf.getFacetDescription());
+        }
+        else {
+            logger.debug(
+                "Art/Facet for Annotations is null. " +
+                "This should never happen!");
+        }
+
+        if (visible) {
+            addAnnotations(annotations);
+        }
+    }
+    
+
+    /**
      * Generate chart.
      */
     @Override
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartInfoGenerator.java	Wed Jul 04 06:54:39 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartInfoGenerator.java	Wed Jul 04 22:28:44 2012 +0000
@@ -32,7 +32,7 @@
  * An OutGenerator that generates meta information for charts. A concrete
  * ChartInfoGenerator need to instantiate a concrete ChartGenerator and dispatch
  * the methods to that instance. The only thing this ChartInfoGenerator needs
- * to, is to overrite the generate() method which doesn't write the chart image
+ * to, is to overwrite the generate() method which doesn't write the chart image
  * to the OutputStream but a Document that contains some meta information of the
  * created chart.
  *
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java	Wed Jul 04 06:54:39 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java	Wed Jul 04 22:28:44 2012 +0000
@@ -1,25 +1,8 @@
 package de.intevation.flys.exports;
 
-import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-import de.intevation.artifactdatabase.state.Facet;
-
-import de.intevation.flys.jfree.Bounds;
-import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
-import de.intevation.flys.jfree.DoubleBounds;
-import de.intevation.flys.jfree.FLYSAnnotation;
-import de.intevation.flys.jfree.StyledTimeSeries;
-import de.intevation.flys.jfree.TimeBounds;
-
-import de.intevation.flys.themes.ThemeAccess;
-
-import de.intevation.flys.artifacts.model.HYKFactory;
-
-import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Font;
 import java.awt.Paint;
-import java.awt.Stroke;
-
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
@@ -27,37 +10,31 @@
 import java.util.Map;
 
 import org.apache.log4j.Logger;
-
 import org.jfree.chart.ChartFactory;
 import org.jfree.chart.JFreeChart;
-import org.jfree.chart.LegendItemCollection;
-
-import org.jfree.chart.annotations.XYBoxAnnotation;
 import org.jfree.chart.annotations.XYTextAnnotation;
-
 import org.jfree.chart.axis.ValueAxis;
-
 import org.jfree.chart.plot.Marker;
 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.time.Day;
 import org.jfree.data.time.TimeSeries;
 import org.jfree.data.time.TimeSeriesCollection;
-
 import org.jfree.data.xy.XYDataset;
-
 import org.jfree.ui.Layer;
-
 import org.json.JSONArray;
 import org.json.JSONException;
+import org.w3c.dom.Document;
 
-import org.w3c.dom.Document;
+import de.intevation.artifactdatabase.state.ArtifactAndFacet;
+import de.intevation.flys.jfree.Bounds;
+import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
+import de.intevation.flys.jfree.DoubleBounds;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StyledTimeSeries;
+import de.intevation.flys.jfree.TimeBounds;
 
 /**
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
@@ -183,10 +160,6 @@
 
     } // end of TimeseriesAxisDataset class
 
-
-    /** List of annotations to insert in plot. */
-    protected List<FLYSAnnotation> annotations;
-
     protected List<Marker> domainMarker;
 
     protected List<Marker> valueMarker;
@@ -593,213 +566,7 @@
         addAxisDataset(tsc, axisIndex, visible);
     }
 
-    /**
-     * Register annotations like MainValues for later plotting
-     *
-     * @param o     list of annotations (data of facet).
-     * @param facet The facet. This facet does NOT support any data objects. Use
-     * FLYSArtifact.getNativeFacet() instead to retrieve a Facet which supports
-     * data.
-     * @param theme   Theme document for given annotations.
-     * @param visible The visibility of the annotations.
-     */
-    protected void doAnnotations(
-        FLYSAnnotation annotations,
-        ArtifactAndFacet aandf,
-        Document theme,
-        boolean visible
-    ){
-        // Running into trouble here.
-        logger.debug("doAnnotations");
-
-        // Add all annotations to our annotation pool.
-        annotations.setTheme(theme);
-        if (aandf != null) {
-            Facet facet = aandf.getFacet();
-            annotations.setLabel(aandf.getFacetDescription());
-        }
-        else {
-            logger.debug(
-                "Art/Facet for Annotations is null. " +
-                "This should never happen!");
-        }
-
-        addAnnotations(annotations, visible);
-    }
-
-
-
-    /**
-     * Adds annotations to list (if visible is true).
-     */
-    public void addAnnotations(FLYSAnnotation annotation, boolean visible) {
-        if (!visible) {
-            return;
-        }
-
-        if (annotations == null) {
-            annotations = new ArrayList<FLYSAnnotation>();
-        }
-
-        annotations.add(annotation);
-    }
-
-
-    /** Add annotations (Sticky, Text and hyk zones). */
-   /* public void addAnnotationsToRenderer(XYPlot plot) {
-        logger.debug("addAnnotationsToRenderer");
-
-        if (annotations == null) {
-            logger.debug("addAnnotationsToRenderer: no annotations.");
-            return;
-        }
-
-        // 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);
-
-        // OPTMIMIZE: Pre-calculate positions
-        Area area = new Area(
-            plot.getDomainAxis(0).getRange(),
-            plot.getRangeAxis().getRange());
-
-        // Walk over all Annotation sets.
-        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();
-                if (fa.getLabel() != null) {
-                    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);
-                }
-            }
-
-            // Other Text Annotations (e.g. labels of manual points).
-            for (XYTextAnnotation ta: fa.getTextAnnotations()) {
-                // Style the text.
-                if (textStyle != null) {
-                    textStyle.apply(ta);
-                }
-                ta.setY(area.above(0.05d, ta.getY()));
-                plot.getRenderer().addAnnotation(ta, org.jfree.ui.Layer.FOREGROUND);
-            }
-        }
-    }*/
-
-        /**
-     * Add the annotations (Sticky, Text and hyk zones) stored
-     * in the annotations field.
-     */
-    public void addAnnotationsToRenderer(XYPlot plot) {
-        logger.debug("addAnnotationsToRenderer");
-
-        if (annotations == null) {
-            logger.debug("addAnnotationsToRenderer: no annotations.");
-            return;
-        }
-
-        // 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);
-
-        // OPTMIMIZE: Pre-calculate positions
-        Area area = new Area(
-            plot.getDomainAxis(0).getRange(),
-            plot.getRangeAxis().getRange());
-
-        // Walk over all Annotation sets.
-        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();
-                if (fa.getLabel() != null) {
-                    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);
-                }
-            }
-
-            // The 'Sticky' Annotations (at axis, with line and text).
-    /*        for (StickyAxisAnnotation sta: fa.getAxisTextAnnotations()) {
-                addStickyAnnotation(
-                    sta, plot, area, lineStyle, textStyle, theme);
-            }*/
-
-            // Other Text Annotations (e.g. labels of manual points).
-            for (XYTextAnnotation ta: fa.getTextAnnotations()) {
-                // Style the text.
-                if (textStyle != null) {
-                    textStyle.apply(ta);
-                }
-                ta.setY(area.above(0.05d, ta.getY()));
-                plot.getRenderer().addAnnotation(ta, org.jfree.ui.Layer.FOREGROUND);
-            }
-
-            // 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(), 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()) / 1.0d,
-                    area.ofGround(0.015f));
-                if (textStyle != null) {
-                    textStyle.apply(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);
-            }
-        }
-    }
-
-        /** Get color for hyk zones by their type (which is the name). */
+    /** Get color for hyk zones by their type (which is the name). */
     public Paint colorForHYKZone(String zoneName) {
         if (zoneName.startsWith("R")) {
             // Brownish.
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Wed Jul 04 06:54:39 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Wed Jul 04 22:28:44 2012 +0000
@@ -1,28 +1,17 @@
 package de.intevation.flys.exports;
 
-import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Font;
-import java.awt.Paint;
-import java.awt.Stroke;
-
 import java.text.NumberFormat;
-
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.w3c.dom.Document;
-
 import org.apache.log4j.Logger;
-
 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;
 import org.jfree.chart.annotations.XYTextAnnotation;
 import org.jfree.chart.axis.NumberAxis;
 import org.jfree.chart.axis.ValueAxis;
@@ -31,31 +20,21 @@
 import org.jfree.chart.plot.XYPlot;
 import org.jfree.data.Range;
 import org.jfree.data.general.Series;
+import org.jfree.data.xy.XYDataset;
 import org.jfree.data.xy.XYSeries;
 import org.jfree.data.xy.XYSeriesCollection;
-import org.jfree.data.xy.XYDataset;
-
-import org.jfree.ui.TextAnchor;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.w3c.dom.Document;
 
 import de.intevation.artifactdatabase.state.ArtifactAndFacet;
-import de.intevation.artifactdatabase.state.Facet;
-
 import de.intevation.flys.jfree.Bounds;
+import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
 import de.intevation.flys.jfree.DoubleBounds;
 import de.intevation.flys.jfree.FLYSAnnotation;
-import de.intevation.flys.jfree.StickyAxisAnnotation;
-import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
 import de.intevation.flys.jfree.StyledAreaSeriesCollection;
 import de.intevation.flys.jfree.StyledXYSeries;
 
-import de.intevation.flys.themes.ThemeAccess;
-import de.intevation.flys.utils.ThemeUtil;
-
-import de.intevation.flys.artifacts.model.HYKFactory;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-
 
 /**
  * An abstract base class for creating XY charts.
@@ -74,8 +53,7 @@
  */
 public abstract class XYChartGenerator extends ChartGenerator {
 
-    // TODO Consider storing the renderer here.
-    private class XYAxisDataset implements AxisDataset {
+    public class XYAxisDataset implements AxisDataset {
         /** Symbolic integer, but also coding the priority (0 goes first). */
         protected int axisSymbol;
         /** List of assigned datasets (in order). */
@@ -181,8 +159,6 @@
     /** Enumerator over existing axes. */
     protected abstract YAxisWalker getYAxisWalker();
 
-    protected static float ANNOTATIONS_AXIS_OFFSET = 0.02f;
-
     public static final int AXIS_SPACE = 5;
 
     /** The logger that is used in this generator. */
@@ -718,370 +694,6 @@
     }
 
 
-    /** Get color for hyk zones by their type (which is the name). */
-    public Paint colorForHYKZone(String zoneName) {
-        if (zoneName.startsWith("R")) {
-            // Brownish.
-            return new Color(153, 60, 0);
-        }
-        else if (zoneName.startsWith("V")) {
-            // Greenish.
-            return new Color(0, 255, 0);
-        }
-        else if (zoneName.startsWith("B")) {
-            // Grayish.
-            return new Color(128, 128, 128);
-        }
-        else if (zoneName.startsWith("H")) {
-            // Blueish.
-            return new Color(0, 0, 255);
-        }
-        else {
-            // Default.
-            logger.debug("Unknown zone type found.");
-            return new Color(255, 0, 0);
-        }
-    }
-
-
-    /**
-     * Create annotation that sticks to "ground" (X) axis.
-     * @param area helper to calculate coordinates
-     * @param pos one-dimensional position (distance from axis)
-     * @param lineStyle the line style to use for the line.
-     */
-    protected static XYLineAnnotation createGroundStickAnnotation(
-        Area area, float pos, ThemeAccess.LineStyle lineStyle
-    ) {
-        // Style the line.
-        if (lineStyle != null) {
-            return new XYLineAnnotation(
-                pos, area.atGround(),
-                pos, area.ofGround(ANNOTATIONS_AXIS_OFFSET),
-                new BasicStroke(lineStyle.getWidth()),lineStyle.getColor());
-        }
-        else {
-            return new XYLineAnnotation(
-                pos, area.atGround(),
-                pos, area.ofGround(ANNOTATIONS_AXIS_OFFSET));
-        }
-    }
-
-
-    /**
-     * Create annotation that sticks to the second Y axis ("right").
-     * @param area helper to calculate coordinates
-     * @param pos one-dimensional position (distance from axis)
-     * @param lineStyle the line style to use for the line.
-     */
-    protected static XYLineAnnotation createRightStickAnnotation(
-        Area area, float pos, ThemeAccess.LineStyle lineStyle
-    ) {
-        // Style the line.
-        if (lineStyle != null) {
-            return new XYLineAnnotation(
-                area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos,
-                area.atRight(), pos,
-                new BasicStroke(lineStyle.getWidth()), lineStyle.getColor());
-        }
-        else {
-            return new XYLineAnnotation(
-                area.atRight(), pos,
-                area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos);
-        }
-    }
-
-
-    /**
-     * Create annotation that sticks to the first Y axis ("left").
-     * @param area helper to calculate coordinates
-     * @param pos one-dimensional position (distance from axis)
-     * @param lineStyle the line style to use for the line.
-     */
-    protected static XYLineAnnotation createLeftStickAnnotation(
-        Area area, float pos, ThemeAccess.LineStyle lineStyle
-    ) {
-        // Style the line.
-        if (lineStyle != null) {
-            return new XYLineAnnotation(
-                area.atLeft(), pos,
-                area.ofLeft(ANNOTATIONS_AXIS_OFFSET), pos,
-                new BasicStroke(lineStyle.getWidth()), lineStyle.getColor());
-        }
-        else {
-            return new XYLineAnnotation(
-                area.atLeft(), pos,
-                area.ofLeft(ANNOTATIONS_AXIS_OFFSET), pos);
-        }
-    }
-
-
-    /**
-     * Create a line from a axis to a given point.
-     * @param axis   The "simple" axis.
-     * @param fromD1 from-location in first dimension.
-     * @param toD2   to-location in second dimension.
-     * @param area   helper to calculate offsets.
-     * @param lineStyle optional line style.
-     */
-    protected static XYLineAnnotation createStickyLineAnnotation(
-        StickyAxisAnnotation.SimpleAxis axis, float fromD1, float toD2,
-        Area area, ThemeAccess.LineStyle lineStyle
-    ) {
-        double anchorX1 = 0d, anchorX2 = 0d, anchorY1 = 0d, anchorY2 = 0d;
-        switch(axis) {
-            case X_AXIS:
-                anchorX1 = fromD1;
-                anchorX2 = fromD1;
-                anchorY1 = area.atGround();
-                anchorY2 = toD2;
-                break;
-            case Y_AXIS:
-                anchorX1 = area.atLeft();
-                anchorX2 = toD2;
-                anchorY1 = fromD1;
-                anchorY2 = fromD1;
-                break;
-            case Y_AXIS2:
-                anchorX1 = area.atRight();
-                anchorX2 = toD2;
-                anchorY1 = fromD1;
-                anchorY2 = fromD1;
-                break;
-        }
-        // Style the line.
-        if (lineStyle != null) {
-            return new XYLineAnnotation(
-                anchorX1, anchorY1,
-                anchorX2, anchorY2,
-                new BasicStroke(lineStyle.getWidth()), lineStyle.getColor());
-        }
-        else {
-            return new XYLineAnnotation(
-                anchorX1, anchorY1,
-                anchorX2, anchorY2);
-        }
-    }
-
-
-    /**
-     * Add a text and a line annotation.
-     * @param area convenience to determine positions in plot.
-     * @param theme (optional) theme document
-     */
-    public void addStickyAnnotation(
-        StickyAxisAnnotation annotation,
-        XYPlot plot,
-        Area area,
-        ThemeAccess.LineStyle lineStyle,
-        ThemeAccess.TextStyle textStyle,
-        Document theme
-    ) {
-        // OPTIMIZE pre-calculate area-related values
-        final float TEXT_OFF = 0.03f;
-
-        XYLineAnnotation lineAnnotation = null;
-        XYTextAnnotation textAnnotation = null;
-
-        int rendererIndex = 0;
-
-        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);
-            lineAnnotation = createGroundStickAnnotation(
-                area, annotation.getPos(), lineStyle);
-            textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT);
-            textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT);
-        }
-        else {
-            // Do the more complicated case where we stick to the Y-Axis.
-            // There is one nasty case (duration curves, where annotations
-            // might stick to the second y-axis).
-            XYAxisDataset dataset = (XYAxisDataset) getAxisDataset(
-                new Integer(annotation.getAxisSymbol()));
-            if (dataset == null) {
-                logger.warn("Annotation should stick to unfindable y-axis: "
-                    + annotation.getAxisSymbol());
-                rendererIndex = 0;
-            }
-            else {
-                rendererIndex = dataset.getPlotAxisIndex();
-            }
-
-            // Stick to the "right" (opposed to left) Y-Axis.
-            if (rendererIndex != 0) {
-                // OPTIMIZE: Pass a different area to this function,
-                //           do the adding to renderer outside (let this
-                //           function return the annotations).
-                //           Note that this path is travelled rarely.
-                Area area2 = new Area(plot.getDomainAxis(), plot.getRangeAxis(rendererIndex));
-                textAnnotation = new CollisionFreeXYTextAnnotation(
-                    annotation.getText(), area2.ofRight(TEXT_OFF), annotation.getPos());
-                textAnnotation.setRotationAnchor(TextAnchor.CENTER_RIGHT);
-                textAnnotation.setTextAnchor(TextAnchor.CENTER_RIGHT);
-                lineAnnotation = createRightStickAnnotation(
-                    area2, annotation.getPos(), lineStyle);
-                if (!Float.isNaN(annotation.getHitPoint()) && theme != null) {
-                    // New line annotation to hit curve.
-                    if (ThemeUtil.parseShowVerticalLine(theme)) {
-                        XYLineAnnotation hitLineAnnotation =
-                            createStickyLineAnnotation(
-                                StickyAxisAnnotation.SimpleAxis.X_AXIS,
-                                annotation.getHitPoint(), annotation.getPos(),// annotation.getHitPoint(),
-                                area2, lineStyle);
-                        plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation,
-                            org.jfree.ui.Layer.BACKGROUND);
-                    }
-                    if (ThemeUtil.parseShowHorizontalLine(theme)) {
-                        XYLineAnnotation lineBackAnnotation =
-                            createStickyLineAnnotation(
-                                StickyAxisAnnotation.SimpleAxis.Y_AXIS2,
-                                annotation.getPos(), annotation.getHitPoint(),
-                                area2, lineStyle);
-                        plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation,
-                            org.jfree.ui.Layer.BACKGROUND);
-                    }
-                }
-            }
-            else { // Stick to the left y-axis.
-                textAnnotation = new CollisionFreeXYTextAnnotation(
-                    annotation.getText(), area.ofLeft(TEXT_OFF), annotation.getPos());
-                textAnnotation.setRotationAnchor(TextAnchor.CENTER_LEFT);
-                textAnnotation.setTextAnchor(TextAnchor.CENTER_LEFT);
-                lineAnnotation = createLeftStickAnnotation(area, annotation.getPos(), lineStyle);
-                if (!Float.isNaN(annotation.getHitPoint()) && theme != null) {
-                    // New line annotation to hit curve.
-                    if (ThemeUtil.parseShowHorizontalLine(theme)) {
-                        XYLineAnnotation hitLineAnnotation =
-                            createStickyLineAnnotation(
-                                StickyAxisAnnotation.SimpleAxis.Y_AXIS,
-                                annotation.getPos(), annotation.getHitPoint(),
-                                area, lineStyle);
-                        plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation,
-                            org.jfree.ui.Layer.BACKGROUND);
-                    }
-                    if (ThemeUtil.parseShowVerticalLine(theme)) {
-                        XYLineAnnotation lineBackAnnotation =
-                            createStickyLineAnnotation(
-                                StickyAxisAnnotation.SimpleAxis.X_AXIS,
-                                annotation.getHitPoint(), annotation.getPos(),
-                                area, lineStyle);
-                        plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation,
-                            org.jfree.ui.Layer.BACKGROUND);
-                    }
-                }
-            }
-        }
-
-        // Style the text.
-        if (textStyle != null) {
-            textStyle.apply(textAnnotation);
-        }
-
-        // Add the Annotations to renderer.
-        plot.getRenderer(rendererIndex).addAnnotation(textAnnotation,
-            org.jfree.ui.Layer.FOREGROUND);
-        plot.getRenderer(rendererIndex).addAnnotation(lineAnnotation,
-            org.jfree.ui.Layer.FOREGROUND);
-    }
-
-
-    /**
-     * Add the annotations (Sticky, Text and hyk zones) stored
-     * in the annotations field.
-     */
-    public void addAnnotationsToRenderer(XYPlot plot) {
-        logger.debug("addAnnotationsToRenderer");
-
-        if (annotations == null) {
-            logger.debug("addAnnotationsToRenderer: no annotations.");
-            return;
-        }
-
-        // 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);
-
-        // OPTMIMIZE: Pre-calculate positions
-        Area area = new Area(
-            plot.getDomainAxis(0).getRange(),
-            plot.getRangeAxis().getRange());
-
-        // Walk over all Annotation sets.
-        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();
-                if (fa.getLabel() != null) {
-                    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);
-                }
-            }
-
-            // The 'Sticky' Annotations (at axis, with line and text).
-            for (StickyAxisAnnotation sta: fa.getAxisTextAnnotations()) {
-                addStickyAnnotation(
-                    sta, plot, area, lineStyle, textStyle, theme);
-            }
-
-            // Other Text Annotations (e.g. labels of manual points).
-            for (XYTextAnnotation ta: fa.getTextAnnotations()) {
-                // Style the text.
-                if (textStyle != null) {
-                    textStyle.apply(ta);
-                }
-                ta.setY(area.above(0.05d, ta.getY()));
-                plot.getRenderer().addAnnotation(ta, org.jfree.ui.Layer.FOREGROUND);
-            }
-
-            // 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(), 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()) / 1.0d,
-                    area.ofGround(0.015f));
-                if (textStyle != null) {
-                    textStyle.apply(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);
-            }
-        }
-    }
-
-
     /**
      * Adjusts the axes of a plot. This method sets the <i>labelFont</i> of the
      * X axis.
@@ -1163,41 +775,6 @@
 
 
     /**
-     * Register annotations like MainValues for later plotting
-     *
-     * @param annotations list of annotations (data of facet).
-     * @param aandf   Artifact and the facet.
-     * @param theme   Theme document for given annotations.
-     * @param visible The visibility of the annotations.
-     */
-    protected void doAnnotations(
-        FLYSAnnotation annotations,
-        ArtifactAndFacet aandf,
-        Document theme,
-        boolean visible
-    ){
-        // Running into trouble here.
-        logger.debug("doAnnotations");
-
-        // Add all annotations to our annotation pool.
-        annotations.setTheme(theme);
-        if (aandf != null) {
-            Facet facet = aandf.getFacet();
-            annotations.setLabel(aandf.getFacetDescription());
-        }
-        else {
-            logger.debug(
-                "Art/Facet for Annotations is null. " +
-                "This should never happen!");
-        }
-
-        if (visible) {
-            addAnnotations(annotations);
-        }
-    }
-
-
-    /**
      * Do Points out.
      */
     protected void doPoints(
@@ -1278,56 +855,5 @@
         return hash;
     }
 
-
-    /** 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 Area(ValueAxis axisX, ValueAxis axisY) {
-            this.xRange = axisX.getRange();
-            this.yRange = axisY.getRange();
-        }
-
-        public double ofLeft(double percent) {
-            return xRange.getLowerBound()
-                + xRange.getLength() * percent;
-        }
-
-        public double ofRight(double percent) {
-            return xRange.getUpperBound()
-                - 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 atRight() {
-            return xRange.getUpperBound();
-        }
-
-        public double atLeft() {
-            return xRange.getLowerBound();
-        }
-
-        public double above(double percent, double base) {
-            return base + yRange.getLength() * percent;
-        }
-    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java	Wed Jul 04 06:54:39 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/fixings/FixDeltaWtGenerator.java	Wed Jul 04 22:28:44 2012 +0000
@@ -302,7 +302,9 @@
         addAttribute(desc + "interpol", "interpolate");
         addAttribute(desc, "outline");
 
-        doQWDTextAnnotations(annoIdxMap, tsc, qwds, theme, visible);
+        if (visible) {
+            doQWDTextAnnotations(annoIdxMap, tsc, qwds, theme, visible);
+        }
     }
 
 
@@ -312,10 +314,16 @@
     protected void doQWDTextAnnotations(Map<Integer, int[]> annoIdxMap,
             TimeSeriesCollection tsc, QWD[] qwds, Document theme,
             boolean visible) {
-        if (!ThemeUtil.parseShowLineLabel(theme))
+        logger.debug("doQWDTextAnnotation()");
+
+        if (!ThemeUtil.parseShowLineLabel(theme)) {
+            logger.debug("doQWDTextAnnotation: annotation not visible");
             return;
+        }
+
         List<XYTextAnnotation> textAnnos = new ArrayList<XYTextAnnotation>();
         Set<Map.Entry<Integer, int[]>> entries = annoIdxMap.entrySet();
+
         for(Map.Entry<Integer, int[]> entry : entries) {
             QWD qwd = qwds[entry.getKey()];
             int[] idxs = entry.getValue();
@@ -332,7 +340,7 @@
 
         FLYSAnnotation flysAnno = new FLYSAnnotation(null, null, null, theme);
         flysAnno.setTextAnnotations(textAnnos);
-        addAnnotations(flysAnno, visible);
+        addAnnotations(flysAnno);
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/utils/ThemeUtil.java	Wed Jul 04 06:54:39 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/utils/ThemeUtil.java	Wed Jul 04 22:28:44 2012 +0000
@@ -422,6 +422,7 @@
      */
     public static String parseTextOrientation(Document theme) {
         String o = XMLUtils.xpathString(theme, XPATH_TEXT_ORIENTATION, null);
+        //logger.debug("parseTextOrientation: " + o + " xml: " + XMLUtils.toString(theme));
         if ("true".equals(o)) {
             return "horizontal";
         }

http://dive4elements.wald.intevation.org