changeset 8341:130160b8d245

Introduce annotations, which know to which axis they belong.
author Tom Gottfried <tom@intevation.de>
date Tue, 30 Sep 2014 11:50:43 +0200
parents 8679875f2c09
children d786b6a852c1
files artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java artifacts/src/main/java/org/dive4elements/river/exports/process/MiscDischargeProcessor.java artifacts/src/main/java/org/dive4elements/river/jfree/AnnotationHelper.java artifacts/src/main/java/org/dive4elements/river/jfree/StickyAxisAnnotation.java
diffstat 5 files changed, 107 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java	Tue Sep 30 10:57:58 2014 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ChartGenerator2.java	Tue Sep 30 11:50:43 2014 +0200
@@ -129,6 +129,9 @@
     /** Map of datasets ("index"). */
     protected SortedMap<Integer, AxisDataset> datasets;
 
+    /** Map of annotations to add at specific Y-axis. */
+    protected SortedMap<Integer, RiverAnnotation> yAnnotations;
+
     /** List of annotations to insert in plot. */
     protected List<RiverAnnotation> annotations = new ArrayList<RiverAnnotation>();
 
@@ -141,6 +144,7 @@
      */
     public ChartGenerator2() {
         datasets = new TreeMap<Integer, AxisDataset>();
+        yAnnotations = new TreeMap<Integer, RiverAnnotation>();
     }
 
     /**
@@ -150,6 +154,10 @@
         annotations.add(annotation);
     }
 
+    public void addYAnnotation(RiverAnnotation annotation, int axisIndex) {
+        yAnnotations.put(axisIndex, annotation);
+    }
+
     /**
      * This method needs to be implemented by concrete subclasses to create new
      * instances of JFreeChart.
--- a/artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java	Tue Sep 30 10:57:58 2014 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/DiagramGenerator.java	Tue Sep 30 11:50:43 2014 +0200
@@ -18,6 +18,7 @@
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.ArrayList;
 import java.util.Map;
 import java.util.Set;
 
@@ -39,6 +40,7 @@
 
 import org.dive4elements.river.exports.process.Processor;
 
+import org.dive4elements.river.jfree.RiverAnnotation;
 import org.dive4elements.river.jfree.AnnotationHelper;
 import org.dive4elements.river.jfree.AxisDataset;
 import org.dive4elements.river.jfree.Bounds;
@@ -226,6 +228,8 @@
         // These have to go after the autozoom.
         AnnotationHelper.addAnnotationsToRenderer(annotations, plot,
                 getChartSettings(), datasets);
+        AnnotationHelper.addYAnnotationsToRenderer(yAnnotations, plot,
+                getChartSettings(), datasets);
 
         // Add a logo (maybe).
         addLogo(plot);
@@ -564,6 +568,14 @@
     }
 
 
+    public void addYAnnotation(
+        RiverAnnotation annotation,
+        String axisName
+    ) {
+        addYAnnotation(annotation, diagramAttributes.getAxisIndex(axisName));
+    }
+
+
     /**
      * Effect: extend range of x axis to include given limits.
      *
--- a/artifacts/src/main/java/org/dive4elements/river/exports/process/MiscDischargeProcessor.java	Tue Sep 30 10:57:58 2014 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/process/MiscDischargeProcessor.java	Tue Sep 30 11:50:43 2014 +0200
@@ -74,9 +74,14 @@
                 generator, (WQKms) data, bundle, theme, visible);
             return;
         }
+        if (MAINVALUES_W.equals(bundle.getFacetName())) {
+            doYRiverAnnotationOut(
+                generator, (RiverAnnotation)data, theme, visible);
+            return;
+            }
         else if (data instanceof RiverAnnotation) {
             doRiverAnnotationOut(
-                generator, (RiverAnnotation)data, bundle, theme, visible);
+                generator, (RiverAnnotation)data, theme, visible);
             return;
         }
         else if (data instanceof double[][]) {
@@ -330,9 +335,19 @@
         log.warn("No WQ found for km " + getKm());
     }
 
+    protected void doYRiverAnnotationOut(DiagramGenerator generator,
+        RiverAnnotation annotations,
+        ThemeDocument theme,
+        boolean visible
+    ) {
+        if (visible) {
+            annotations.setTheme(theme);
+            generator.addYAnnotation(annotations, axisName);
+        }
+    }
+
     protected void doRiverAnnotationOut(DiagramGenerator generator,
         RiverAnnotation annotations,
-        ArtifactAndFacet bundle,
         ThemeDocument theme,
         boolean visible
     ) {
--- a/artifacts/src/main/java/org/dive4elements/river/jfree/AnnotationHelper.java	Tue Sep 30 10:57:58 2014 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/jfree/AnnotationHelper.java	Tue Sep 30 11:50:43 2014 +0200
@@ -10,7 +10,10 @@
 import org.dive4elements.river.themes.ThemeDocument;
 
 import java.util.List;
+import java.util.ArrayList;
 import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
 
 import java.awt.BasicStroke;
 import java.awt.Color;
@@ -22,6 +25,7 @@
 import org.jfree.chart.LegendItemCollection;
 import org.jfree.chart.annotations.XYTextAnnotation;
 import org.jfree.chart.annotations.XYLineAnnotation;
+import org.jfree.chart.renderer.xy.XYItemRenderer;
 
 import org.dive4elements.river.themes.LineStyle;
 import org.dive4elements.river.themes.TextStyle;
@@ -41,16 +45,48 @@
     public static final int    DEFAULT_FONT_SIZE       = 12;
     public static final String DEFAULT_FONT_NAME       = "Tahoma";
 
+
+    public static void addYAnnotationsToRenderer(
+        SortedMap<Integer, RiverAnnotation> yAnnotations,
+        XYPlot plot,
+        ChartSettings settings,
+        Map<Integer, AxisDataset> datasets
+    ) {
+        List<RiverAnnotation> annotations = new ArrayList<RiverAnnotation>();
+
+        for (Map.Entry<Integer, RiverAnnotation> entry:
+                 yAnnotations.entrySet()) {
+            int axis = entry.getKey();
+            AxisDataset dataset = datasets.get(new Integer(axis));
+
+            if (dataset == null || dataset.getRange() == null) {
+                log.warn("No dataset available and active for axis " + axis);
+            }
+            else {
+                RiverAnnotation ya = entry.getValue();
+                for (StickyAxisAnnotation sta: ya.getAxisTextAnnotations()) {
+                    sta.setAxisSymbol(axis);
+                }
+                annotations.add(ya);
+            }
+        }
+
+        addAnnotationsToRenderer(annotations, plot, settings, datasets);
+    }
+
     /**
      * Add annotations (Sticky, Text and hyk zones) to a plot.
      * @param annotations Annotations to add
-     * @param plot Plot to add annotations to.
+     * @param plot XYPlot to add annotations to.
      * @param settings ChartSettings object for settings.
+     * @param datasets Map of axis index and datasets
      */
-    public static void addAnnotationsToRenderer(List<RiverAnnotation> annotations,
-            XYPlot plot, ChartSettings settings, Map<Integer, AxisDataset> datasets) {
-        log.debug("addAnnotationsToRenderer");
-
+    public static void addAnnotationsToRenderer(
+        List<RiverAnnotation> annotations,
+        XYPlot plot,
+        ChartSettings settings,
+        Map<Integer, AxisDataset> datasets
+    ) {
         if (annotations == null || annotations.isEmpty()) {
             log.debug("addAnnotationsToRenderer: no annotations.");
             return;
@@ -69,7 +105,7 @@
             TextStyle textStyle = null;
             LineStyle lineStyle = null;
 
-            // Get Themeing information and add legend item.
+            // Get Theming information and add legend item.
             if (theme != null) {
                 textStyle = theme.parseComplexTextStyle();
                 lineStyle = theme.parseComplexLineStyle();
@@ -150,7 +186,14 @@
         XYLineAnnotation lineAnnotation = null;
         XYTextAnnotation textAnnotation = null;
 
-        int rendererIndex = 0;
+        int axisIndex = annotation.getAxisSymbol();
+        XYItemRenderer renderer = null;
+        if (dataset.getDatasets().length > 0) {
+            renderer = plot.getRendererForDataset(dataset.getDatasets()[0]);
+        }
+        else {
+            renderer = plot.getRenderer();
+        }
 
         if (annotation.atX()) {
             textAnnotation = new CollisionFreeXYTextAnnotation(
@@ -163,31 +206,25 @@
             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).
-            if (dataset == null) {
-                log.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) {
+            if (axisIndex != 0 && plot.getRangeAxis(axisIndex) != null) {
                 // 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());
+                    annotation.getText(),
+                    area.ofRight(TEXT_OFF),
+                    annotation.getPos()
+                );
                 textAnnotation.setRotationAnchor(TextAnchor.CENTER_RIGHT);
                 textAnnotation.setTextAnchor(TextAnchor.CENTER_RIGHT);
                 lineAnnotation = createRightStickAnnotation(
-                    area2, annotation.getPos(), lineStyle);
+                    area, annotation.getPos(), lineStyle);
+
+                // hit-lines for duration curve
+                ChartArea area2 = new ChartArea(
+                    plot.getDomainAxis(), plot.getRangeAxis(axisIndex));
                 if (!Float.isNaN(annotation.getHitPoint()) && theme != null) {
                     // New line annotation to hit curve.
                     if (theme.parseShowVerticalLine()) {
@@ -196,7 +233,7 @@
                                 StickyAxisAnnotation.SimpleAxis.X_AXIS,
                                 annotation.getHitPoint(), annotation.getPos(),// annotation.getHitPoint(),
                                 area2, lineStyle);
-                        plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation,
+                        renderer.addAnnotation(hitLineAnnotation,
                             org.jfree.ui.Layer.BACKGROUND);
                     }
                     if (theme.parseShowHorizontalLine()) {
@@ -205,7 +242,7 @@
                                 StickyAxisAnnotation.SimpleAxis.Y_AXIS2,
                                 annotation.getPos(), annotation.getHitPoint(),
                                 area2, lineStyle);
-                        plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation,
+                        renderer.addAnnotation(lineBackAnnotation,
                             org.jfree.ui.Layer.BACKGROUND);
                     }
                 }
@@ -224,7 +261,7 @@
                                 StickyAxisAnnotation.SimpleAxis.Y_AXIS,
                                 annotation.getPos(), annotation.getHitPoint(),
                                 area, lineStyle);
-                        plot.getRenderer(rendererIndex).addAnnotation(hitLineAnnotation,
+                        renderer.addAnnotation(hitLineAnnotation,
                             org.jfree.ui.Layer.BACKGROUND);
                     }
                     if (theme.parseShowVerticalLine()) {
@@ -233,7 +270,7 @@
                                 StickyAxisAnnotation.SimpleAxis.X_AXIS,
                                 annotation.getHitPoint(), annotation.getPos(),
                                 area, lineStyle);
-                        plot.getRenderer(rendererIndex).addAnnotation(lineBackAnnotation,
+                        renderer.addAnnotation(lineBackAnnotation,
                             org.jfree.ui.Layer.BACKGROUND);
                     }
                 }
@@ -246,10 +283,8 @@
         }
 
         // 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);
+        renderer.addAnnotation(textAnnotation, org.jfree.ui.Layer.FOREGROUND);
+        renderer.addAnnotation(lineAnnotation, org.jfree.ui.Layer.FOREGROUND);
     }
 
    /**
@@ -288,8 +323,8 @@
         // Style the line.
         if (lineStyle != null) {
             return new XYLineAnnotation(
+                area.atRight(), pos,
                 area.ofRight(ANNOTATIONS_AXIS_OFFSET), pos,
-                area.atRight(), pos,
                 new BasicStroke(lineStyle.getWidth()), lineStyle.getColor());
         }
         else {
--- a/artifacts/src/main/java/org/dive4elements/river/jfree/StickyAxisAnnotation.java	Tue Sep 30 10:57:58 2014 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/jfree/StickyAxisAnnotation.java	Tue Sep 30 11:50:43 2014 +0200
@@ -124,6 +124,9 @@
         return this.axisSymbol;
     }
 
+    public void setAxisSymbol(int axis) {
+        this.axisSymbol = axis;
+    }
 
     /** Set where to hit a curve (if any). */
     public void setHitPoint(float pos) {

http://dive4elements.wald.intevation.org