[PATCH] (issue1579) Fix axes syncronisation at Gauges

Wald Commits scm-commit at wald.intevation.org
Fri Dec 13 19:03:04 CET 2013


# HG changeset patch
# User Andre Heinecke <aheinecke at intevation.de>
# Date 1386957780 -3600
# Node ID fa4fbd66e75206d9151537312aeab06d1e103012
# Parent  4bbd222e6b7f715d733578ea84f6bd450f9d061d
(issue1579) Fix axes syncronisation at Gauges

    The SyncNumberAxis was completely broken. It only synced
    in one direction and even that did not work correctly when
    data was added to the axis (and the syncAxis rescaled but
    forgot the old axis) then there were lots of ways to bypass
    that scaling. And i also think the trans calculation was wrong.

    It has been replaced by a "mostly" simple method to just keep
    the W in M and W in CM+Datum axes in sync. I say "Mostly" because
    it had to deal with the Bounds interface.

diff -r 4bbd222e6b7f -r fa4fbd66e752 artifacts/src/main/java/org/dive4elements/river/exports/ComputedDischargeCurveGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/ComputedDischargeCurveGenerator.java	Fri Dec 13 17:44:57 2013 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/ComputedDischargeCurveGenerator.java	Fri Dec 13 19:03:00 2013 +0100
@@ -61,8 +61,6 @@
     public static final String I18N_CHART_TITLE_DEFAULT = "Abflusskurve";
     public static final String I18N_YAXIS_LABEL_DEFAULT = "W [NN + m]";
 
-    protected NumberAxis firstYAxis;
-
     /** Trivial Constructor. */
     public ComputedDischargeCurveGenerator () {
         super();
@@ -100,40 +98,6 @@
         return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT, new Object[] { unit });
     }
 
-
-    /**
-     * Create Y (range) axis for given index, here with a special axis
-     * that depends on other axis (does translation and scaling for
-     * special case at gauge in cm).
-     * @return A NumberAxis, possibly scaled.
-     */
-    @Override
-    protected NumberAxis createYAxis(int index) {
-        if (index == 0) {
-            firstYAxis = super.createYAxis(0);
-            return firstYAxis;
-        }
-        YAxisWalker walker = getYAxisWalker();
-
-        Font labelFont = new Font(
-            DEFAULT_FONT_NAME,
-            Font.BOLD,
-            getYAxisFontSize(index));
-
-        SyncNumberAxis axis = new SyncNumberAxis(
-            walker.getId(index),
-            getYAxisLabel(index),
-            firstYAxis);
-
-        axis.setAutoRangeIncludesZero(false);
-        axis.setLabelFont(labelFont);
-        axis.setTickLabelFont(labelFont);
-        axis.setShift((double)-getCurrentGaugeDatum());
-
-        return axis;
-    }
-
-
     /**
      * Process data, build up plot.
      */
diff -r 4bbd222e6b7f -r fa4fbd66e752 artifacts/src/main/java/org/dive4elements/river/exports/DischargeCurveGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/DischargeCurveGenerator.java	Fri Dec 13 17:44:57 2013 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/DischargeCurveGenerator.java	Fri Dec 13 19:03:00 2013 +0100
@@ -18,6 +18,7 @@
 import org.dive4elements.river.exports.process.DischargeProcessor;
 import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation;
 import org.dive4elements.river.jfree.Bounds;
+import org.dive4elements.river.jfree.DoubleBounds;
 import org.dive4elements.river.jfree.RiverAnnotation;
 import org.dive4elements.river.jfree.StickyAxisAnnotation;
 import org.dive4elements.river.jfree.StyledXYSeries;
@@ -109,9 +110,51 @@
         if (getCurrentGaugeDatum() != 0d) {
             // Show the W[*m] axis even if there is no data.
             plot.setRangeAxis(1, createYAxis(YAXIS.W.idx));
+            syncWAxisRanges();
         }
     }
 
+    protected void syncWAxisRanges() {
+        // Syncronizes the ranges of both W Axes to make sure
+        // that the Data matches for both axes.
+        Bounds boundsInMGauge = getYBounds(YAXIS.W.idx);
+        Bounds boundsInCM = getYBounds(YAXIS.WCm.idx);
+
+        // XXX Q-Symetry: I am assuming here that there can only
+        // be a fixed Range for WinM as this is currently the only
+        // thing that is configureable.
+        Range fixedWinMRange = getRangeForAxisFromSettings(
+                getYAxisWalker().getId(YAXIS.W.idx));
+
+        // The combination of Range and Bounds is crazy..
+        if (fixedWinMRange != null) {
+            boundsInMGauge = new DoubleBounds(fixedWinMRange.getLowerBound(),
+                    fixedWinMRange.getUpperBound());
+        }
+
+        logger.debug("Syncing Axis Bounds. Bounds W: " + boundsInMGauge.toString() +
+                " Bounds Wcm: " + boundsInCM.toString());
+
+        double datum = getCurrentGaugeDatum();
+
+        // Convert boundsInMGauge to Datum+cm
+        double convertedLower = ((Double)boundsInMGauge.getLower() - datum) * 100;
+        double convertedUpper = ((Double)boundsInMGauge.getUpper() - datum) * 100;
+        Bounds convertedBounds = new DoubleBounds(convertedLower, convertedUpper);
+
+        // Now combine both Ranges
+        boundsInCM = boundsInCM.combine(convertedBounds);
+
+        // Recalculate absolute bounds
+        boundsInMGauge = new DoubleBounds((Double)boundsInCM.getLower() / 100d + datum,
+                                          (Double)boundsInCM.getUpper() / 100d + datum);
+
+        // Set the new combined bounds
+        setYBounds(YAXIS.W.idx, boundsInMGauge);
+        setYBounds(YAXIS.WCm.idx, boundsInCM);
+        logger.debug("Synced Bounds W: " + boundsInMGauge.toString() +
+                " Bounds Wcm: " + boundsInCM.toString());
+    }
 
     public DischargeCurveGenerator() {
         super();
diff -r 4bbd222e6b7f -r fa4fbd66e752 artifacts/src/main/java/org/dive4elements/river/exports/SyncNumberAxis.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/SyncNumberAxis.java	Fri Dec 13 17:44:57 2013 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/* 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.exports;
-
-import org.jfree.chart.axis.NumberAxis;
-import org.jfree.chart.event.AxisChangeEvent;
-import org.jfree.chart.event.AxisChangeListener;
-import org.jfree.data.Range;
-
-import org.apache.log4j.Logger;
-
-/**
- * Axis which is to be registered with other axis and tries
- * to clone its range. The cloned range is transformed.
- * Keeps in sync via AxisChangedEvents.
- */
-public class SyncNumberAxis extends IdentifiableNumberAxis
-        implements AxisChangeListener
-{
-    /** The logger used in this generator. */
-    private static Logger logger =
-        Logger.getLogger(SyncNumberAxis.class);
-
-    /** The other axis to clone range from. */
-    protected NumberAxis proxyAxis;
-
-    /** Value to translate range by. */
-    protected double shift;
-
-
-    public SyncNumberAxis(String key, String label, NumberAxis n) {
-        super(key, label);
-        this.proxyAxis = n;
-    }
-
-
-    /** Range of other axis changed, adjust own range. */
-    @Override
-    public void axisChanged(AxisChangeEvent event) {
-        logger.debug("SyncNumberAxis: axischange event");
-        this.setRange(
-            transRange(((NumberAxis)event.getAxis()).getRange()));
-    }
-
-    /** Set value by which to translate the range. */
-    public void setShift(double shift) {
-        this.shift = shift;
-    }
-
-
-    /** Set other axis to relate to, register listener. */
-    public void setProxyAxis(NumberAxis ax) {
-        proxyAxis = ax;
-        proxyAxis.addChangeListener(this);
-    }
-
-    /** Translate range by shift, scale by 100. */
-    protected Range transRange(Range r) {
-        return new Range(100d*(r.getLowerBound()+shift),
-            100d*(r.getUpperBound()+shift));
-    }
-
-    /** Set Range. */
-    @Override
-    public void setRange(Range r) {
-        super.setRange(r);
-        logger.debug("SyncAxis: setRange");
-    }
-
-
-    /*
-    @Override
-    public Range getRange() {
-        Range r = new Range(100d*(proxyAxis.getRange().getLowerBound()+shift),
-            100d*(proxyAxis.getRange().getUpperBound()+shift));
-        return r;
-    }
-
-    @Override
-    public void setLowerBound(double max) {
-    }
-
-    @Override
-    public void setLowerMargin(double margin) {
-    }
-
-    @Override
-    public void setUpperBound(double max) {
-    }
-
-    @Override
-    public void setUpperMargin(double margin) {
-    }
-
-    @Override
-    public void setRange(double a, double b) {
-    }
-
-    @Override
-    public void setRange(Range range, boolean turnOffAutoRange, boolean notify){
-    }
-
-    @Override
-    public void setRangeAboutValue(double value, double length) {}
-
-    @Override
-    public void setRangeWithMargins(double lower, double upper) {}
-
-    @Override
-    public void setRangeWithMargins(Range range) {}
-
-    @Override
-    public void pan(double percent) {}
-
-    @Override
-    public void resizeRange(double p){}
-
-    @Override
-    public void resizeRange(double p, double a){}
-
-    @Override
-    public void resizeRange2(double p, double a){}
-
-    */
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 4bbd222e6b7f -r fa4fbd66e752 artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java
--- a/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java	Fri Dec 13 17:44:57 2013 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/fixings/FixWQCurveGenerator.java	Fri Dec 13 19:03:00 2013 +0100
@@ -47,7 +47,6 @@
 import org.dive4elements.river.artifacts.resources.Resources;
 import org.dive4elements.river.exports.ChartGenerator;
 import org.dive4elements.river.exports.DischargeCurveGenerator;
-import org.dive4elements.river.exports.SyncNumberAxis;
 import org.dive4elements.river.exports.StyledSeriesBuilder;
 import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation;
 import org.dive4elements.river.jfree.RiverAnnotation;
@@ -60,6 +59,11 @@
 import org.dive4elements.river.utils.RiverUtils;
 import org.dive4elements.river.java2d.ShapeUtils;
 
+import org.dive4elements.river.jfree.Bounds;
+import org.dive4elements.river.jfree.DoubleBounds;
+
+import org.jfree.data.Range;
+
 /**
  * Generator for WQ fixing charts.
  * @author <a href="mailto:christian.lins at intevation.de">Christian Lins</a>
@@ -111,49 +115,6 @@
     /** Needed to access data to create subtitle. */
     protected D4EArtifact artifact;
 
-    // TODO dupe of ComputedDischargeCurveGenerator
-    protected SyncNumberAxis secondYAxis;
-    // TODO dupe of ComputedDischargeCurveGenerator
-    protected NumberAxis firstYAxis;
-
-
-    /**
-     * Create Y (range) axis for given index, here with a special axis
-     * that depends on other axis (does translation and scaling for
-     * special case at gauge in cm).
-     */
-    // TODO dupe of ComputedDischargeCurveGenerator
-    @Override
-    protected NumberAxis createYAxis(int index) {
-        logger.debug("createYAxis: " + index);
-        if (index == 1) {
-            firstYAxis = super.createYAxis(1);
-            if (secondYAxis != null) {
-                secondYAxis.setProxyAxis(firstYAxis);
-            }
-            return firstYAxis;
-        }
-        YAxisWalker walker = getYAxisWalker();
-
-        Font labelFont = new Font(
-            DEFAULT_FONT_NAME,
-            Font.BOLD,
-            getYAxisFontSize(index));
-
-        SyncNumberAxis axis = new SyncNumberAxis(
-            walker.getId(index),
-            getYAxisLabel(index),
-            firstYAxis);
-
-        axis.setAutoRangeIncludesZero(false);
-        axis.setLabelFont(labelFont);
-        axis.setTickLabelFont(labelFont);
-        axis.setShift((double)-getCurrentGaugeDatum());
-
-        secondYAxis = axis;
-        return axis;
-    }
-
     /** Returns value != 0 if the current km is not at a gauge. */
     public double getCurrentGaugeDatum() {
         Object ckm = context.getContextValue(CURRENT_KM);
@@ -172,9 +133,55 @@
         if (getCurrentGaugeDatum() != 0d) {
             // Show the W[*m] axis even if there is no data.
             plot.setRangeAxis(1, createYAxis(YAXIS.W.idx));
+            syncWAxisRanges();
         }
     }
 
+    // XXX This is a copy of DischargeCurveGenerator syncWAxisRanges
+    // even without fancy Q Symetry this class should inherit
+    // from there..
+    protected void syncWAxisRanges() {
+        // Syncronizes the ranges of both W Axes to make sure
+        // that the Data matches for both axes.
+        Bounds boundsInMGauge = getYBounds(YAXIS.W.idx);
+        Bounds boundsInCM = getYBounds(YAXIS.WCm.idx);
+
+        // XXX Q-Symetry: I am assuming here that there can only
+        // be a fixed Range for WinM as this is currently the only
+        // thing that is configureable.
+        Range fixedWinMRange = getRangeForAxisFromSettings(
+                getYAxisWalker().getId(YAXIS.W.idx));
+
+        // The combination of Range and Bounds is crazy..
+        if (fixedWinMRange != null) {
+            boundsInMGauge = new DoubleBounds(fixedWinMRange.getLowerBound(),
+                    fixedWinMRange.getUpperBound());
+        }
+
+        logger.debug("Syncing Axis Bounds. Bounds W: " + boundsInMGauge.toString() +
+                " Bounds Wcm: " + boundsInCM.toString());
+
+        double datum = getCurrentGaugeDatum();
+
+        // Convert boundsInMGauge to Datum+cm
+        double convertedLower = ((Double)boundsInMGauge.getLower() - datum) * 100;
+        double convertedUpper = ((Double)boundsInMGauge.getUpper() - datum) * 100;
+        Bounds convertedBounds = new DoubleBounds(convertedLower, convertedUpper);
+
+        // Now combine both Ranges
+        boundsInCM = boundsInCM.combine(convertedBounds);
+
+        // Recalculate absolute bounds
+        boundsInMGauge = new DoubleBounds((Double)boundsInCM.getLower() / 100d + datum,
+                                          (Double)boundsInCM.getUpper() / 100d + datum);
+
+        // Set the new combined bounds
+        setYBounds(YAXIS.W.idx, boundsInMGauge);
+        setYBounds(YAXIS.WCm.idx, boundsInCM);
+        logger.debug("Synced Bounds W: " + boundsInMGauge.toString() +
+                " Bounds Wcm: " + boundsInCM.toString());
+    }
+
     @Override
     public void doOut(ArtifactAndFacet aaf, ThemeDocument doc, boolean visible) {
         logger.debug("doOut: " + aaf.getFacetName());


More information about the Dive4elements-commits mailing list