changeset 1679:69929c471646

Improved the creation/rendering of annotations (km favorites, mainvalues). flys-artifacts/trunk@2896 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 05 Oct 2011 14:23:53 +0000
parents 03fbf1b30e72
children f4da2009eb8b
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/AnnotationFacet.java 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/LongitudinalSectionGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java flys-artifacts/src/main/java/de/intevation/flys/jfree/FLYSAnnotation.java
diffstat 8 files changed, 190 insertions(+), 189 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Wed Oct 05 13:16:44 2011 +0000
+++ b/flys-artifacts/ChangeLog	Wed Oct 05 14:23:53 2011 +0000
@@ -1,3 +1,30 @@
+2011-10-05  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/jfree/FLYSAnnotation.java: Stores a
+	  list of XYTextAnnotations instead of FLYS specific Annotations. This
+	  makes this class suitable for other annotation types as well.
+
+	* src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java,
+	  src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java:
+	  Both facets' getData() will now return an instance of FLYSAnnotation.
+
+	* src/main/java/de/intevation/flys/artifacts/model/AnnotationFacet.java:
+	  Create XYTextAnnotations used to instantiate an object of
+	  FLYSAnnotation.
+
+	* src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java,
+	  src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java:
+	  Removed the code to add annotations to the plot. This task is general
+	  enough to move this code to parent class.
+
+	* src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
+	  Instances of this class are now able to store - besides first and second
+	  axes datasets - a list of annotations. This annotations are added to the
+	  plot after the datasets have been added. To support LegendItems for
+	  those annotions, it was necessary to create a the LegendItemCollection
+	  by ourself. This work is done while applying the themes for each series
+	  in the chart.
+
 2011-10-05	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	Removed code duplication of guessWaterIncreasing()
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/AnnotationFacet.java	Wed Oct 05 13:16:44 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/AnnotationFacet.java	Wed Oct 05 14:23:53 2011 +0000
@@ -1,14 +1,18 @@
 package de.intevation.flys.artifacts.model;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.log4j.Logger;
 
+import org.jfree.chart.annotations.XYTextAnnotation;
+
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
 
 import de.intevation.flys.artifacts.AnnotationArtifact;
 import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StickyAxisAnnotation;
 
 import de.intevation.flys.model.Annotation;
 
@@ -53,9 +57,18 @@
     @Override
     public Object getData(Artifact artifact, CallContext context) {
         AnnotationArtifact annotationArtifact = (AnnotationArtifact) artifact;
-        List<Annotation> annotations = annotationArtifact.getAnnotations();
 
-        return new FLYSAnnotation(description, annotations);
+        List<Annotation>       as = annotationArtifact.getAnnotations();
+        List<XYTextAnnotation> xy = new ArrayList<XYTextAnnotation>();
+
+        for (Annotation a: as) {
+            xy.add(new StickyAxisAnnotation(
+                a.getPosition().getValue(),
+                (float) a.getRange().getA().doubleValue(),
+                StickyAxisAnnotation.SimpleAxis.X_AXIS));
+        }
+
+        return new FLYSAnnotation(description, xy);
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java	Wed Oct 05 13:16:44 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesQFacet.java	Wed Oct 05 14:23:53 2011 +0000
@@ -1,10 +1,19 @@
 package de.intevation.flys.artifacts.model;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jfree.chart.annotations.XYTextAnnotation;
+
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
+
 import de.intevation.artifactdatabase.state.DefaultFacet;
+
+import de.intevation.flys.artifacts.MainValuesArtifact;
 import de.intevation.flys.artifacts.model.FacetTypes;
-import de.intevation.flys.artifacts.MainValuesArtifact;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StickyAxisAnnotation;
 
 /**
  * Facet to show Main Q Values.
@@ -32,7 +41,19 @@
     @Override
     public Object getData(Artifact artifact, CallContext context) {
         MainValuesArtifact mvArtifact = (MainValuesArtifact) artifact;
-        return mvArtifact.getMainValuesQ();
+
+        List<NamedDouble>      qs = mvArtifact.getMainValuesQ();
+        List<XYTextAnnotation> xy = new ArrayList<XYTextAnnotation>();
+
+        for (NamedDouble q: qs) {
+            xy.add(new StickyAxisAnnotation(
+                q.getName(),
+                (float) q.getValue(),
+                StickyAxisAnnotation.SimpleAxis.X_AXIS));
+
+        }
+
+        return new FLYSAnnotation(description, xy);
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java	Wed Oct 05 13:16:44 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MainValuesWFacet.java	Wed Oct 05 14:23:53 2011 +0000
@@ -1,10 +1,19 @@
 package de.intevation.flys.artifacts.model;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jfree.chart.annotations.XYTextAnnotation;
+
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
+
 import de.intevation.artifactdatabase.state.DefaultFacet;
+
+import de.intevation.flys.artifacts.MainValuesArtifact;
 import de.intevation.flys.artifacts.model.FacetTypes;
-import de.intevation.flys.artifacts.MainValuesArtifact;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.jfree.StickyAxisAnnotation;
 
 /**
  * Facet to show Main W Values.
@@ -32,7 +41,19 @@
     @Override
     public Object getData(Artifact artifact, CallContext context) {
         MainValuesArtifact mvArtifact = (MainValuesArtifact) artifact;
-        return mvArtifact.getMainValuesW();
+
+        List<NamedDouble>      ws = mvArtifact.getMainValuesW();
+        List<XYTextAnnotation> xy = new ArrayList<XYTextAnnotation>();
+
+        for (NamedDouble w: ws) {
+            xy.add(new StickyAxisAnnotation(
+                w.getName(),
+                (float) w.getValue(),
+                StickyAxisAnnotation.SimpleAxis.Y_AXIS));
+
+        }
+
+        return new FLYSAnnotation(description, xy);
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java	Wed Oct 05 13:16:44 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java	Wed Oct 05 14:23:53 2011 +0000
@@ -1,31 +1,22 @@
 package de.intevation.flys.exports;
+
 import org.apache.log4j.Logger;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.w3c.dom.Document;
 
-import java.awt.Color;
 import org.jfree.chart.JFreeChart;
-import org.jfree.chart.annotations.XYAnnotation;
 import org.jfree.chart.title.TextTitle;
-import org.jfree.chart.plot.XYPlot;
 import org.jfree.data.xy.XYSeries;
-import org.jfree.data.xy.XYSeriesCollection;
 
 import de.intevation.artifacts.Artifact;
 
 import de.intevation.artifactdatabase.state.Facet;
 
 import de.intevation.flys.artifacts.FLYSArtifact;
-import de.intevation.flys.artifacts.model.NamedDouble;
 import de.intevation.flys.artifacts.model.FacetTypes;
 import de.intevation.flys.artifacts.model.WQKms;
 
-import de.intevation.flys.jfree.StickyAxisAnnotation;
-
-import de.intevation.flys.utils.ThemeUtil;
+import de.intevation.flys.jfree.FLYSAnnotation;
 
 
 /**
@@ -56,17 +47,10 @@
     public static final String I18N_MAINVALUES_Q_LABEL = "Q (Haupt- und Extremwerte)";
     public static final String I18N_MAINVALUES_W_LABEL = "W (Haupt- und Extremwerte)";
 
-    /** List of Annotations (specifically, Main Values). */
-    protected List<XYAnnotation> annotations;
-
-    /** Pseudo-Dataseries to have a legend for annotations. */
-    protected XYSeriesCollection pseudoAnnotationData = null;
-
 
     /** Trivial Constructor. */
     public ComputedDischargeCurveGenerator () {
         super();
-        annotations = new ArrayList<XYAnnotation>();
     }
 
 
@@ -131,78 +115,22 @@
      */
     protected void doMainValueWAnnotations(Object o, Document theme) {
         logger.debug("ComputedDischargeCurveGenerator set W MainValues.");
-        if (pseudoAnnotationData == null) {
-            pseudoAnnotationData = new XYSeriesCollection();
-        }
-
-        Color color = ThemeUtil.parseLineColorField(theme);
-        if (color == null) {
-            color = Color.black;
-        }
 
-        List<NamedDouble> mainValuesW = (List<NamedDouble>) o;
-        for (NamedDouble mv: mainValuesW) {
-            float pos = (float) mv.getValue();
-            String text = mv.getName();
-            StickyAxisAnnotation ta = new StickyAxisAnnotation(text, pos,
-                    StickyAxisAnnotation.SimpleAxis.Y_AXIS);
-            ta.setPaint(color);
-            this.annotations.add(ta);
-        }
-        String label = msg(I18N_MAINVALUES_W_LABEL, I18N_MAINVALUES_W_LABEL, null);
-        pseudoAnnotationData.addSeries(new StyledXYSeries(label, theme));
+        FLYSAnnotation fa = (FLYSAnnotation) o;
+        fa.setTheme(theme);
+        addAnnotations(fa);
     }
 
-    
+
     /**
      * Store Q MainValues as annotations for later plotting.
      */
     protected void doMainValueQAnnotations(Object o, Document theme) {
         logger.debug("ComputedDischargeCurveGenerator set Q MainValues.");
 
-        Color color = ThemeUtil.parseLineColorField(theme);
-        if (color == null) {
-            color = Color.black;
-        }
-
-        if (pseudoAnnotationData == null) {
-            pseudoAnnotationData = new XYSeriesCollection();
-        }
-
-        List<NamedDouble> mainValuesQ = (List<NamedDouble>) o;
-        for (NamedDouble mv: mainValuesQ) {
-            float pos = (float) mv.getValue();
-            String text = mv.getName();
-            StickyAxisAnnotation ta = new StickyAxisAnnotation(text, pos);
-            ta.setPaint(color);
-            this.annotations.add(ta);
-        }
-        String label = msg(I18N_MAINVALUES_Q_LABEL, I18N_MAINVALUES_Q_LABEL, null);
-        pseudoAnnotationData.addSeries(new StyledXYSeries(label, theme));
-    }
-
-
-    /** Generate Chart with annotations. */
-    @Override
-    public JFreeChart generateChart() {
-        JFreeChart c = super.generateChart();
-        XYPlot p = (XYPlot) c.getPlot();
-        redoAnnotations(p);
-        return c;
-    }
-
-
-    /**
-     * Recalculate some annotation positions and add them to plot.
-     * Annotations represent MainValues.
-     * @param plot      Plot to add annotations to.
-     */
-    protected void redoAnnotations(XYPlot plot) {
-        plot.clearAnnotations();
-
-        for (XYAnnotation a: annotations) {
-            plot.addAnnotation(a, false);
-        }
+        FLYSAnnotation fa = (FLYSAnnotation) o;
+        fa.setTheme(theme);
+        addAnnotations(fa);
     }
 
 
@@ -227,20 +155,6 @@
 
 
     /**
-     * Add datasets to plot.
-     * @param plot plot to add datasets to.
-     * @todo merge with LongitudinalSectionGenerator/superclass.
-     */
-    @Override
-    protected void addDatasets(XYPlot plot) {
-        super.addDatasets(plot);
-        if (pseudoAnnotationData != null) {
-            plot.setDataset(2, pseudoAnnotationData);
-        }
-    }
-
-
-    /**
      * Get the series name to display in legend.
      */
     protected String getSeriesName(WQKms wqkms) {
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java	Wed Oct 05 13:16:44 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java	Wed Oct 05 14:23:53 2011 +0000
@@ -1,20 +1,14 @@
 package de.intevation.flys.exports;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import org.apache.log4j.Logger;
 
 import org.jfree.chart.JFreeChart;
-import org.jfree.chart.LegendItem;
-import org.jfree.chart.LegendItemCollection;
 import org.jfree.chart.axis.NumberAxis;
 import org.jfree.chart.axis.ValueAxis;
 import org.jfree.chart.plot.XYPlot;
 import org.jfree.chart.title.TextTitle;
 import org.jfree.data.Range;
 import org.jfree.data.xy.XYSeries;
-import org.jfree.ui.TextAnchor;
 
 import org.w3c.dom.Document;
 
@@ -28,8 +22,6 @@
 import de.intevation.flys.artifacts.model.WQKms;
 
 import de.intevation.flys.jfree.FLYSAnnotation;
-import de.intevation.flys.jfree.StickyAxisAnnotation;
-import de.intevation.flys.model.Annotation;
 import de.intevation.flys.utils.FLYSUtils;
 
 
@@ -72,13 +64,9 @@
 
     protected boolean inverted;
 
-    /** List of annotations to insert in plot. */
-    protected List<FLYSAnnotation> annotations;
-
 
     public LongitudinalSectionGenerator() {
         super();
-        annotations = new ArrayList<FLYSAnnotation>();
     }
 
 
@@ -108,16 +96,6 @@
         chart.addSubtitle(new TextTitle(subtitle));
     }
 
-    @Override
-    public JFreeChart generateChart() {
-        JFreeChart c = super.generateChart();
-        XYPlot p = (XYPlot) c.getPlot();
-
-        redoAnnotations(p, p.getDomainAxis());
-
-        return c;
-    }
-
 
     protected String getXAxisLabel() {
         FLYSArtifact flys = (FLYSArtifact) master;
@@ -154,67 +132,6 @@
 
 
     /**
-     * Remove all annotations from plot and re-insert them at an approximately
-     * okay position. The followed approach is naive but side-effect free.
-     *
-     * @param plot the plot.
-     * @param axis the value axis.
-     */
-    protected void redoAnnotations(XYPlot plot, ValueAxis axis) {
-        plot.clearAnnotations();
-        // TODO Position calculation could/should be done in
-        // the StickyAxisAnnotation-Implementation itself.
-
-        int idx = 0;
-        ValueAxis yAxis = plot.getRangeAxis(idx);
-
-        if (yAxis == null) {
-            if (plot.getRangeAxisCount() >= 2) {
-                yAxis = plot.getRangeAxis(++idx);
-            }
-        }
-
-        if (yAxis == null) {
-            // XXX There is no y-axis that might be used to add annotations. If
-            // we absolutely want to display annotations, we need to create a
-            // virtual dataset for an axis.
-            return;
-        }
-
-        float posY = 140.f;
-        posY = (float) yAxis.getRange().getLowerBound();
-        // Add some (2%) space between Text and axis.
-        posY += 0.02f * (yAxis.getRange().getUpperBound()
-                - yAxis.getRange().getLowerBound());
-
-        LegendItemCollection lic = plot.getLegendItems();
-
-        // Add all annotations.
-        for (FLYSAnnotation fa: annotations) {
-            lic.add(new LegendItem(fa.getLabel()));
-
-            for (Annotation a: fa.getAnnotations()) {
-                float posX = (float) a.getRange().getA().doubleValue();
-                String text = a.getPosition().getValue();
-
-                StickyAxisAnnotation ta = new StickyAxisAnnotation(
-                    text,
-                    posX,
-                    posY);
-
-                double rotation = 270.0f * (Math.PI / 180.0f);
-                ta.setRotationAngle(rotation);
-                ta.setRotationAnchor(TextAnchor.CENTER_LEFT);
-                ta.setTextAnchor(TextAnchor.CENTER_LEFT);
-                plot.getRenderer(idx).addAnnotation(ta);
-            }
-        }
-
-        plot.setFixedLegendItems(lic);
-    }
-
-
-    /**
      * Create a range that includes 0 (for the Q axis).
      * @param range range with which to look up upper bound.
      * @return range with 0 included.
@@ -299,7 +216,7 @@
 
         // Add all annotations in list o to our annotation pool.
         FLYSAnnotation fa = (FLYSAnnotation) o;
-        annotations.add(fa);
+        addAnnotations(fa);
     }
 
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Wed Oct 05 13:16:44 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Wed Oct 05 14:23:53 2011 +0000
@@ -8,14 +8,23 @@
 
 import java.text.NumberFormat;
 
+import java.util.ArrayList;
+import java.util.List;
+
+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.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.XYDataset;
@@ -25,6 +34,8 @@
 import org.jfree.ui.RectangleInsets;
 
 import de.intevation.flys.exports.ChartExportHelper;
+import de.intevation.flys.jfree.FLYSAnnotation;
+import de.intevation.flys.utils.ThemeUtil;
 
 
 /**
@@ -44,6 +55,10 @@
     /** SeriesCollection used for the second axis. */
     protected XYSeriesCollection second;
 
+    /** List of annotations to insert in plot. */
+    protected List<FLYSAnnotation> annotations;
+
+
     public static final Color DEFAULT_GRID_COLOR      = Color.GRAY;
     public static final float DEFAULT_GRID_LINE_WIDTH = 0.3f;
 
@@ -106,6 +121,7 @@
         XYPlot plot = (XYPlot) chart.getPlot();
 
         addDatasets(plot);
+        addAnnotations(plot);
         addSubtitles(chart);
         adjustPlot(plot);
         adjustAxes(plot);
@@ -155,6 +171,15 @@
     }
 
 
+    public void addAnnotations(FLYSAnnotation annotation) {
+        if (annotations == null) {
+            annotations = new ArrayList<FLYSAnnotation>();
+        }
+
+        annotations.add(annotation);
+    }
+
+
     private void removeEmptyRangeAxes(XYPlot plot) {
         if (first == null) {
             plot.setRangeAxis(0, null);
@@ -292,6 +317,46 @@
     }
 
 
+    protected void addAnnotations(XYPlot plot) {
+        plot.clearAnnotations();
+
+        if (annotations == null) {
+            logger.debug("No Annotations given.");
+            return;
+        }
+
+        LegendItemCollection lic = new LegendItemCollection();
+
+        int idx = 0;
+        if (plot.getRangeAxis(idx) == null && plot.getRangeAxisCount() >= 2) {
+            idx = 1;
+        }
+
+        XYItemRenderer renderer = plot.getRenderer(idx);
+
+        for (FLYSAnnotation fa: annotations) {
+            Document theme = fa.getTheme();
+
+            Color color = theme != null
+                ? ThemeUtil.parseLineColorField(theme)
+                : null;
+
+            if (color == null) {
+                color = Color.black;
+            }
+
+            lic.add(new LegendItem(fa.getLabel(), color));
+
+            for (XYTextAnnotation ta: fa.getAnnotations()) {
+                ta.setPaint(color);
+                renderer.addAnnotation(ta);
+            }
+
+            plot.setFixedLegendItems(lic);
+        }
+    }
+
+
     /**
      * Adjusts the axes of a plot.
      *
@@ -406,6 +471,9 @@
 
 
     protected void applyThemes(XYPlot plot, XYSeriesCollection dataset, int i) {
+        LegendItemCollection lic  = new LegendItemCollection();
+        LegendItemCollection anno = plot.getFixedLegendItems();
+
         XYLineAndShapeRenderer r = getRenderer(plot, i);
 
         for (int s = 0, num = dataset.getSeriesCount(); s < num; s++) {
@@ -414,8 +482,16 @@
             if (series instanceof StyledXYSeries) {
                 ((StyledXYSeries) series).applyTheme(r, s);
             }
+
+            lic.add(r.getLegendItem(i, s));
         }
 
+        if (anno != null) {
+            lic.addAll(anno);
+        }
+
+        plot.setFixedLegendItems(lic);
+
         plot.setRenderer(i, r);
     }
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/FLYSAnnotation.java	Wed Oct 05 13:16:44 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/FLYSAnnotation.java	Wed Oct 05 14:23:53 2011 +0000
@@ -2,17 +2,21 @@
 
 import java.util.List;
 
-import de.intevation.flys.model.Annotation;
+import org.w3c.dom.Document;
+
+import org.jfree.chart.annotations.XYTextAnnotation;
 
 
 public class FLYSAnnotation {
 
-    protected List<Annotation> annotations;
+    protected List<XYTextAnnotation> annotations;
+
+    protected Document theme;
 
     protected String label;
 
 
-    public FLYSAnnotation(String label, List<Annotation> annotations) {
+    public FLYSAnnotation(String label, List<XYTextAnnotation> annotations) {
         this.label       = label;
         this.annotations = annotations;
     }
@@ -21,8 +25,16 @@
         return label;
     }
 
-    public List<Annotation> getAnnotations() {
+    public List<XYTextAnnotation> getAnnotations() {
         return annotations;
     }
+
+    public void setTheme(Document theme) {
+        this.theme = theme;
+    }
+
+    public Document getTheme() {
+        return theme;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org