diff artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveGenerator.java @ 9252:c2a0028bfa9f

Work on S-Info flood duration curve chart
author mschaefer
date Thu, 12 Jul 2018 18:09:48 +0200
parents
children ef7b65576d4b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveGenerator.java	Thu Jul 12 18:09:48 2018 +0200
@@ -0,0 +1,258 @@
+/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
+ * Software engineering by Intevation GmbH
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+
+package org.dive4elements.river.artifacts.sinfo.flood_duration;
+
+import java.awt.Font;
+import java.awt.geom.Point2D;
+
+import org.apache.log4j.Logger;
+import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
+import org.dive4elements.artifacts.CallContext;
+import org.dive4elements.river.artifacts.model.CalculationResult;
+import org.dive4elements.river.artifacts.model.FacetTypes;
+import org.dive4elements.river.artifacts.model.WQDay;
+import org.dive4elements.river.exports.IdentifiableNumberAxis;
+import org.dive4elements.river.exports.XYChartGenerator;
+import org.dive4elements.river.jfree.Bounds;
+import org.dive4elements.river.jfree.RiverAnnotation;
+import org.dive4elements.river.jfree.StyledXYSeries;
+import org.dive4elements.river.themes.ThemeDocument;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.ValueAxis;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.data.Range;
+import org.jfree.data.xy.XYSeries;
+
+
+/**
+ * An OutGenerator that generates duration curves.
+ *
+ * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
+ */
+public class FloodDurationCurveGenerator
+extends      XYChartGenerator
+implements   FacetTypes
+{
+    public static enum YAXIS {
+        W(0),
+        Q(1);
+        public int idx;
+        private YAXIS(final int c) {
+            this.idx = c;
+        }
+    }
+
+    /** Local log. */
+    private static Logger log =
+            Logger.getLogger(FloodDurationCurveGenerator.class);
+
+    public static final String I18N_CHART_TITLE = "sinfo.chart.flood_duration.curve.section.title";
+
+    public static final String I18N_CHART_SUBTITLE = "chart.duration.curve.subtitle";
+
+    public static final String I18N_XAXIS_LABEL = "sinfo.chart.flood_duration.curve.xaxis.label";
+
+    public static final String I18N_YAXIS_LABEL_W = "chart.duration.curve.yaxis.label.w";
+
+    public static final String I18N_YAXIS_LABEL_Q = "chart.duration.curve.yaxis.label.q";
+
+    public static final String I18N_CHART_TITLE_DEFAULT = "Dauerlinie";
+
+    public static final String I18N_XAXIS_LABEL_DEFAULT = "Überflutungsdauer [d/a]";
+
+
+    public FloodDurationCurveGenerator() {
+        super();
+    }
+
+
+    /**
+     * Create Axis for given index.
+     * @return axis with according internationalized label.
+     */
+    @Override
+    protected NumberAxis createYAxis(final int index) {
+        final Font labelFont = new Font("Tahoma", Font.BOLD, 14);
+        final String label   = getYAxisLabel(index);
+
+        final NumberAxis axis = createNumberAxis(index, label);
+        if (index == YAXIS.W.idx) {
+            axis.setAutoRangeIncludesZero(false);
+        }
+        axis.setLabelFont(labelFont);
+        return axis;
+    }
+
+
+    @Override
+    protected String getDefaultChartTitle(final CallContext context) {
+        return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
+    }
+
+
+    @Override
+    protected String getDefaultChartSubtitle(final CallContext context) {
+
+        final double[] dist  = getRange();
+        return msg(I18N_CHART_SUBTITLE, "", getRiverName(), dist[0]);
+    }
+
+
+    @Override
+    protected String getDefaultXAxisLabel(final CallContext context) {
+        return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
+    }
+
+
+    @Override
+    protected String getDefaultYAxisLabel(final int index) {
+
+        String label = "default";
+        if (index == YAXIS.W.idx) {
+            label = msg(I18N_YAXIS_LABEL_W, I18N_YAXIS_LABEL_W, getRiverUnit());
+        }
+        else if (index == YAXIS.Q.idx) {
+            label = msg(I18N_YAXIS_LABEL_Q);
+        }
+        return label;
+    }
+
+
+    @Override
+    protected boolean zoomX(final XYPlot plot, final ValueAxis axis, final Bounds bounds, final Range x) {
+
+        final boolean zoomin = super.zoom(plot, axis, bounds, x);
+        if (!zoomin)
+            axis.setLowerBound(0d);
+        // axis.setUpperBound(364);
+        return zoomin;
+    }
+
+
+    /**
+     * This method overrides the method in the parent class to set the lower
+     * bounds of the Q axis to 0. This axis should never display negative
+     * values on its own.
+     */
+    @Override
+    protected boolean zoomY(final XYPlot plot, final ValueAxis axis, final Bounds bounds, final Range x) {
+
+        final boolean zoomin = super.zoom(plot, axis, bounds, x);
+        if (!zoomin && axis instanceof IdentifiableNumberAxis) {
+            final String id = ((IdentifiableNumberAxis) axis).getId();
+            if (YAXIS.Q.toString().equals(id))
+                axis.setLowerBound(0d);
+        }
+        return zoomin;
+    }
+
+
+    @Override
+    public void doOut(final ArtifactAndFacet artifactFacet, final ThemeDocument attr, final boolean visible) {
+
+        final String name = artifactFacet.getFacetName();
+
+        log.debug("FloodDurationCurveGenerator.doOut: " + name);
+
+        if (name == null || name.length() == 0) {
+            log.error("No facet given. Cannot create dataset.");
+            return;
+        }
+
+        final CallContext context = getContext();
+
+        if (name.equals(DURATION_W)) {
+            doWOut((WQDay) ((CalculationResult) artifactFacet.getData(context)).getData(), artifactFacet, attr, visible);
+        }
+        else if (name.equals(DURATION_Q)) {
+            doQOut((WQDay) ((CalculationResult) artifactFacet.getData(context)).getData(), artifactFacet, attr, visible);
+        }
+        else if (name.equals(MAINVALUES_Q) || name.equals(MAINVALUES_W)) {
+            doAnnotations((RiverAnnotation) artifactFacet.getData(context), artifactFacet, attr, visible);
+        }
+        else if (name.equals(RELATIVE_POINT)) {
+            doPointOut((Point2D) artifactFacet.getData(context), artifactFacet, attr, visible);
+        }
+        else if (FacetTypes.IS.MANUALPOINTS(name)) {
+            doPoints(artifactFacet.getData(context), artifactFacet, attr, visible, YAXIS.W.idx);
+        }
+        else {
+            log.warn("Unknown facet name: " + name);
+            return;
+        }
+    }
+
+    /**
+     * Creates the series for a duration curve's W facet.
+     *
+     * @param wqdays The WQDay store that contains the Ws.
+     * @param theme
+     */
+    protected void doWOut(final WQDay wqdays, final ArtifactAndFacet aaf, final ThemeDocument theme, final boolean visible) {
+
+        // log.debug("DurationCurveGenerator.doWOut");
+        final XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), theme);
+        final int size = wqdays.size();
+        for (int i = 0; i < size; i++) {
+            final int  day = wqdays.getDay(i);
+            final double w = wqdays.getW(i);
+            series.add(day, w);
+        }
+        addAxisSeries(series, YAXIS.W.idx, visible);
+    }
+
+    protected void doPointOut(final Point2D point, final ArtifactAndFacet aandf, final ThemeDocument theme, final boolean visible) {
+
+        // log.debug("DurationCurveGenerator.doPointOut");
+        final XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
+        series.add(point.getX(), point.getY());
+        addAxisSeries(series, YAXIS.W.idx, visible);
+    }
+
+
+    /**
+     * Creates the series for a duration curve's Q facet.
+     *
+     * @param wqdays The WQDay store that contains the Qs.
+     * @param theme
+     */
+    protected void doQOut(final WQDay wqdays, final ArtifactAndFacet aaf, final ThemeDocument theme, final boolean visible) {
+
+        // log.debug("DurationCurveGenerator.doQOut");
+        final XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), theme);
+        final int size = wqdays.size();
+        for (int i = 0; i < size; i++) {
+            final int  day = wqdays.getDay(i);
+            final double q = wqdays.getQ(i);
+            series.add(day, q);
+        }
+        addAxisSeries(series, YAXIS.Q.idx, visible);
+    }
+
+
+    @Override
+    protected YAxisWalker getYAxisWalker() {
+        return new YAxisWalker() {
+            @Override
+            public int length() {
+                return YAXIS.values().length;
+            }
+
+            @Override
+            public String getId(final int idx) {
+                final YAXIS[] yaxes = YAXIS.values();
+                return yaxes[idx].toString();
+            }
+        };
+    }
+
+    // MainValue-Annotations should be visualized by
+    // a line that goes to the curve itself.
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org