changeset 561:460b8e0f0563

Parse the min/max axes ranges for the ChartInfo and modified the zoom and pan actions to match the current server implementation. flys-client/trunk@2096 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Thu, 09 Jun 2011 10:57:42 +0000
parents 5274b9317e40
children 9f16ac843dda
files flys-client/ChangeLog flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java flys-client/src/main/java/de/intevation/flys/client/server/ChartInfoServiceImpl.java flys-client/src/main/java/de/intevation/flys/client/shared/model/Axis.java flys-client/src/main/java/de/intevation/flys/client/shared/model/ChartInfo.java
diffstat 5 files changed, 257 insertions(+), 92 deletions(-) [+]
line wrap: on
line diff
--- a/flys-client/ChangeLog	Thu Jun 09 06:05:44 2011 +0000
+++ b/flys-client/ChangeLog	Thu Jun 09 10:57:42 2011 +0000
@@ -1,3 +1,20 @@
+2011-06-09  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/client/server/ChartInfoServiceImpl.java:
+	  Parse min/max values for axes and all transformation matrix elements.
+
+	* src/main/java/de/intevation/flys/client/shared/model/Axis.java: An axis
+	  has a min and max value now.
+
+	* src/main/java/de/intevation/flys/client/shared/model/ChartInfo.java:
+	  The ChartInfo object provides a Transform2D object for each y axis
+	  contained in the chart.
+
+	* src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java:
+	  Refactored the zoom and pan actions. The values used to select a
+	  concrete clip of the chart are computed based on the min/max range of an
+	  axis. The chart request uses percentual values for axes ranges now.
+
 2011-06-09  Ingo Weinzierl <ingo@intevation.de>
 
 	  flys/issue139 (WINFO: NPE bei Step-Back bei ungleichwertiger Berechnungsart)
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java	Thu Jun 09 06:05:44 2011 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ChartOutputTab.java	Thu Jun 09 10:57:42 2011 +0000
@@ -57,7 +57,7 @@
     protected ChartInfo chartInfo;
 
     /** The transformer used to transform image pixels into chart coordinates.*/
-    protected Transform2D transformer;
+    protected Transform2D[] transformer;
 
     /** The collection view.*/
     protected CollectionView view;
@@ -74,8 +74,10 @@
 
 
     /** Chart zoom options.*/
-    protected double[] xrange;
-    protected double[] yrange;
+    protected int[] xrange;
+    protected int[] yrange;
+
+    protected double[] zoom;
 
 
     /**
@@ -97,8 +99,9 @@
         left      = new Canvas();
         right     = new Canvas();
         tbarPanel = new ChartToolbar(collectionView, this);
-        xrange    = new double[2];
-        yrange    = new double[2];
+        xrange    = new int[2];
+        yrange    = new int[2];
+        zoom      = new double[4];
 
         left.setBorder("1px solid black");
         left.setWidth(THEMEPANEL_MIN_WIDTH);
@@ -139,7 +142,7 @@
      */
     public void onResized(ResizedEvent event) {
         updateChartPanel();
-        updateTransformer();
+        updateChartInfo();
     }
 
 
@@ -160,63 +163,126 @@
      * @param evt The ZoomEvent that stores the coordinates for zooming.
      */
     public void onZoom(ZoomEvent evt) {
-        if (transformer == null) {
-            return;
-        }
-        double[] lower = transformer.transform(evt.getStartX(), evt.getStartY());
-        double[] upper = transformer.transform(evt.getEndX(), evt.getEndY());
+        xrange[0] = evt.getStartX();
+        xrange[1] = evt.getEndX();
+        yrange[0] = evt.getStartY();
+        yrange[1] = evt.getEndY();
 
-        xrange[0] = lower[0];
-        xrange[1] = upper[0];
-        yrange[0] = upper[1];
-        yrange[1] = lower[1];
+        xrange[0] = xrange[0] < xrange[1] ? xrange[0] : xrange[1];
+        yrange[0] = yrange[0] < yrange[1] ? yrange[0] : yrange[1];
 
-        updateTransformer();
+        translateCoordinates();
+
+        updateChartInfo();
         updateChartPanel();
     }
 
 
+    protected double[] translateCoordinates() {
+        if (xrange == null || (xrange[0] == 0 && xrange[1] == 0)) {
+            zoom[0] = 0d;
+            zoom[1] = 1d;
+        }
+        else {
+            translateXCoordinates();
+        }
+
+        if (yrange == null || (yrange[0] == 0 && yrange[1] == 0)) {
+            zoom[2] = 0d;
+            zoom[3] = 1d;
+        }
+        else {
+            translateYCoordinates();
+        }
+
+        return zoom;
+    }
+
+
+    protected void translateXCoordinates() {
+        Axis xAxis = chartInfo.getXAxis(0);
+
+        double xmin   = xAxis.getMin();
+        double xmax   = xAxis.getMax();
+        double xRange = xmax - xmin;
+
+        Transform2D transformer = getTransformer(0);
+
+        double[] start = transformer.transform(xrange[0], yrange[0]);
+        double[] end   = transformer.transform(xrange[1], yrange[1]);
+
+        zoom[0] = (start[0] - xmin) / xRange;
+        zoom[1] = (end[0] - xmin) / xRange;
+    }
+
+
+    protected void translateYCoordinates() {
+        Axis yAxis = chartInfo.getYAxis(0);
+
+        double ymin   = yAxis.getMin();
+        double ymax   = yAxis.getMax();
+        double yRange = ymax - ymin;
+
+        Transform2D transformer = getTransformer(0);
+
+        double[] start = transformer.transform(xrange[0], yrange[0]);
+        double[] end   = transformer.transform(xrange[1], yrange[1]);
+
+        zoom[2] = (start[1] - ymin) / yRange;
+        zoom[3] = (end[1] - ymin) / yRange;
+    }
+
+
     public void onPan(PanEvent event) {
-        if (transformer == null) {
+        if (chartInfo == null) {
             return;
         }
+
         int[] start = event.getStartPos();
         int[] end   = event.getEndPos();
 
-        double[] startPos = transformer.transform(start[0], start[1]);
-        double[] endPos   = transformer.transform(end[0], end[1]);
-
-        double diffX = startPos[0] - endPos[0];
-        double diffY = startPos[1] - endPos[1];
+        Transform2D t = getTransformer();
 
-        panTo(diffX, diffY);
-    }
-
+        double[] ts = t.transform(start[0], start[1]);
+        double[] tt = t.transform(end[0], end[1]);
 
-    /**
-     * This method pans to chart with a given factor.
-     */
-    public void panTo(double diffX, double diffY) {
+        double diffX = ts[0] - tt[0];
+        double diffY = ts[1] - tt[1];
+
         Axis xAxis = chartInfo.getXAxis(0);
         Axis yAxis = chartInfo.getYAxis(0);
 
-        xrange[0] = xAxis.getFrom() + diffX;
-        xrange[1] = xAxis.getTo() + diffX;
-        yrange[0] = yAxis.getFrom() + diffY;
-        yrange[1] = yAxis.getTo() + diffY;
+        double[] x = panAxis(xAxis, diffX);
+        double[] y = panAxis(yAxis, diffY);
 
-        updateTransformer();
+        zoom[0] = x[0];
+        zoom[1] = x[1];
+        zoom[2] = y[0];
+        zoom[3] = y[1];
+
+        updateChartInfo();
         updateChartPanel();
     }
 
 
+    protected double[] panAxis(Axis axis, double diff) {
+        double min = axis.getFrom();
+        double max = axis.getTo();
+
+        min += diff;
+        max += diff;
+
+        return computeZoom(axis, min, max);
+    }
+
+
     public void resetRanges() {
-        xrange[0] = 0;
-        xrange[1] = 0;
-        yrange[0] = 0;
-        yrange[1] = 0;
+        zoom[0] = 0d;
+        zoom[1] = 1d;
+        zoom[2] = 0d;
+        zoom[3] = 1d;
 
-        updateTransformer();
+        updateChartInfo();
         updateChartPanel();
     }
 
@@ -227,27 +293,58 @@
      * @param factor The factor should be between 0-100.
      */
     public void zoomOut(int factor) {
-        if (factor < 0 || factor > 100 || xrange == null || yrange == null) {
+        if (factor < 0 || factor > 100 || chartInfo == null) {
             return;
         }
 
-        double xadd = (xrange[1] - xrange[0]) / 100 * factor;
-        double yadd = (yrange[1] - yrange[0]) / 100 * factor;
+        Axis xAxis = chartInfo.getXAxis(0);
+        Axis yAxis = chartInfo.getYAxis(0);
 
-        xrange[0] -= xadd;
-        xrange[1] += xadd;
-        yrange[0] -= yadd;
-        yrange[1] += yadd;
+        double[] x = zoomAxis(xAxis, factor);
+        double[] y = zoomAxis(yAxis, factor);
 
-        updateTransformer();
+        zoom[0] = x[0];
+        zoom[1] = x[1];
+        zoom[2] = x[0];
+        zoom[3] = y[1];
+
+        updateChartInfo();
         updateChartPanel();
     }
 
 
+    public double[] zoomAxis(Axis axis, int factor) {
+        double min  = axis.getFrom();
+        double max  = axis.getTo();
+
+        double add = (max - min) / 100 * factor;
+        add = add < 0 ? (-1) * add : add;
+
+        min -= add;
+        max += add;
+
+        return computeZoom(axis, min, max);
+    }
+
+
+    public static double[] computeZoom(Axis axis, double min, double max) {
+        double[] zoom = new double[2];
+
+        double absMin = axis.getMin();
+        double absMax = axis.getMax();
+        double diff   = absMax > absMin ? absMax - absMin : absMin - absMax;
+
+        zoom[0] = (min - absMin) / diff;
+        zoom[1] = (max - absMin) / diff;
+
+        return zoom;
+    }
+
+
     /**
      * Updates the Transform2D object using the chart info service.
      */
-    public void updateTransformer() {
+    public void updateChartInfo() {
         Config config = Config.getInstance();
         String url    = config.getServerUrl();
         String locale = config.getLocale();
@@ -304,7 +401,15 @@
 
     protected void setChartInfo(ChartInfo chartInfo) {
         this.chartInfo = chartInfo;
-        setTransformer(chartInfo.getTransformer());
+    }
+
+
+    public Transform2D getTransformer() {
+        if (chartInfo == null) {
+            return null;
+        }
+
+        return chartInfo.getTransformer(0);
     }
 
 
@@ -312,21 +417,16 @@
      * Returns the Transform2D object used to transform image coordinates into
      * chart coordinates.
      *
+     * @param pos The index of a specific transformer.
+     *
      * @return the Transform2D object.
      */
-    public Transform2D getTransformer() {
-        return transformer;
-    }
-
+    public Transform2D getTransformer(int pos) {
+        if (chartInfo == null) {
+            return null;
+        }
 
-    /**
-     * Set a new Transform2D object for the chart. This should be the case, only
-     * if the chart image size has changed.
-     *
-     * @param transformer The new Transform2D object.
-     */
-    protected void setTransformer(Transform2D transformer) {
-        this.transformer = transformer;
+        return chartInfo.getTransformer(pos);
     }
 
 
@@ -393,16 +493,15 @@
         imgUrl += "&width=" + Integer.toString(width);
         imgUrl += "&height=" + Integer.toString(height);
 
-        if (xrange != null) {
-            GWT.log("Zoom to xrange.");
-            imgUrl += "&minx=" + Double.toString(xrange[0]);
-            imgUrl += "&maxx=" + Double.toString(xrange[1]);
-        }
+        double[] zoom = getZoomValues();
 
-        if (yrange != null) {
-            GWT.log("Zoom to xrange.");
-            imgUrl += "&miny=" + Double.toString(yrange[0]);
-            imgUrl += "&maxy=" + Double.toString(yrange[1]);
+        if (zoom != null) {
+            GWT.log("Zoom to specified range.");
+
+            imgUrl += "&minx=" + Double.toString(zoom[0]);
+            imgUrl += "&maxx=" + Double.toString(zoom[1]);
+            imgUrl += "&miny=" + Double.toString(zoom[2]);
+            imgUrl += "&maxy=" + Double.toString(zoom[3]);
         }
 
         return imgUrl;
@@ -416,17 +515,21 @@
         attr.put("width", chart.getWidth().toString());
         attr.put("height", chart.getHeight().toString());
 
-        if (xrange != null) {
-            attr.put("minx", Double.toString(xrange[0]));
-            attr.put("maxx", Double.toString(xrange[1]));
-        }
+        double[] zoom = getZoomValues();
 
-        if (yrange != null) {
-            attr.put("miny", Double.toString(yrange[0]));
-            attr.put("maxy", Double.toString(yrange[1]));
+        if (zoom != null) {
+            attr.put("minx", Double.toString(zoom[0]));
+            attr.put("maxx", Double.toString(zoom[1]));
+            attr.put("miny", Double.toString(zoom[2]));
+            attr.put("maxy", Double.toString(zoom[3]));
         }
 
         return attr;
     }
+
+
+    protected double[] getZoomValues() {
+        return zoom;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/server/ChartInfoServiceImpl.java	Thu Jun 09 06:05:44 2011 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/server/ChartInfoServiceImpl.java	Thu Jun 09 10:57:42 2011 +0000
@@ -2,6 +2,8 @@
 
 import java.io.InputStream;
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 
 import javax.xml.xpath.XPathConstants;
@@ -39,7 +41,7 @@
 implements   ChartInfoService
 {
     public static final String XPATH_TRANSFORM_MATRIX =
-        "/art:chartinfo/art:transformation-matrix";
+        "/art:chartinfo/art:transformation-matrix/art:matrix";
 
     public static final String XPATH_X_AXES =
         "/art:chartinfo/art:axes/art:domain";
@@ -91,9 +93,9 @@
 
 
     protected ChartInfo parseInfoDocument(Document doc) {
-        Transform2D transformer = parseTransformationMatrix(doc);
-        Axis[]      xAxes       = parseXAxes(doc);
-        Axis[]      yAxes       = parseYAxes(doc);
+        Transform2D[] transformer = parseTransformationMatrix(doc);
+        Axis[]      xAxes         = parseXAxes(doc);
+        Axis[]      yAxes         = parseYAxes(doc);
 
         return new ChartInfo(xAxes, yAxes, transformer);
     }
@@ -150,10 +152,18 @@
             String toStr = XMLUtils.xpathString(
                 node, "@art:to", ArtifactNamespaceContext.INSTANCE);
 
+            String minStr = XMLUtils.xpathString(
+                node, "@art:min", ArtifactNamespaceContext.INSTANCE);
+
+            String maxStr = XMLUtils.xpathString(
+                node, "@art:max", ArtifactNamespaceContext.INSTANCE);
+
             try {
                 int    pos  = Integer.parseInt(posStr);
                 double from = Double.parseDouble(fromStr);
                 double to   = Double.parseDouble(toStr);
+                double min  = Double.parseDouble(minStr);
+                double max  = Double.parseDouble(maxStr);
 
                 if (pos >= result.length) {
                     // this should never happen
@@ -161,7 +171,7 @@
                     continue;
                 }
 
-                result[pos] = new Axis(pos, from, to);
+                result[pos] = new Axis(pos, from, to, min, max);
             }
             catch (NumberFormatException nfe) {
                 nfe.printStackTrace();
@@ -182,19 +192,35 @@
      * @return a Transform2D object to transfrom pixel coordinates into chart
      * coordinates.
      */
-    protected Transform2D parseTransformationMatrix(Document doc) {
+    protected Transform2D[] parseTransformationMatrix(Document doc) {
         System.out.println("ChartInfoServiceImpl.parseTransformationMatrix");
 
-        Node matrix = (Node) XMLUtils.xpath(
+        NodeList matrix = (NodeList) XMLUtils.xpath(
             doc,
             XPATH_TRANSFORM_MATRIX,
-            XPathConstants.NODE,
+            XPathConstants.NODESET,
             ArtifactNamespaceContext.INSTANCE);
 
-        if (matrix == null) {
-            return new Transform2D(1d, 1d, 0d, 0d);
+        int num = matrix != null ? matrix.getLength() : 0;
+
+        List<Transform2D> transformer = new ArrayList<Transform2D>(num);
+
+        for (int i = 0; i < num; i++) {
+            Transform2D t = createTransformer(matrix.item(i));
+
+            if (t == null) {
+                System.err.println("Broken transformation matrix at pos: " + i);
+                continue;
+            }
+
+            transformer.add(t);
         }
 
+        return (Transform2D[]) transformer.toArray(new Transform2D[num]);
+    }
+
+
+    protected Transform2D createTransformer(Node matrix) {
         String sx = XMLUtils.xpathString(
             matrix, "@art:sx", ArtifactNamespaceContext.INSTANCE);
 
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/Axis.java	Thu Jun 09 06:05:44 2011 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/Axis.java	Thu Jun 09 10:57:42 2011 +0000
@@ -13,15 +13,20 @@
     protected double from;
     protected double to;
 
+    protected double min;
+    protected double max;
+
 
     public Axis() {
     }
 
 
-    public Axis(int pos, double from, double to) {
+    public Axis(int pos, double from, double to, double min, double max) {
         this.pos  = pos;
         this.from = from;
         this.to   = to;
+        this.min  = min;
+        this.max  = max;
     }
 
 
@@ -38,5 +43,15 @@
     public double getTo() {
         return to;
     }
+
+
+    public double getMin() {
+        return min;
+    }
+
+
+    public double getMax() {
+        return max;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/shared/model/ChartInfo.java	Thu Jun 09 06:05:44 2011 +0000
+++ b/flys-client/src/main/java/de/intevation/flys/client/shared/model/ChartInfo.java	Thu Jun 09 10:57:42 2011 +0000
@@ -13,22 +13,26 @@
     protected Axis[] xAxes;
     protected Axis[] yAxes;
 
-    protected Transform2D transformer;
+    protected Transform2D[] transformer;
 
 
     public ChartInfo() {
     }
 
 
-    public ChartInfo(Axis[] xAxes, Axis[] yAxes, Transform2D transformer) {
+    public ChartInfo(Axis[] xAxes, Axis[] yAxes, Transform2D[] transformer) {
         this.xAxes       = xAxes;
         this.yAxes       = yAxes;
         this.transformer = transformer;
     }
 
 
-    public Transform2D getTransformer() {
-        return transformer;
+    public Transform2D getTransformer(int pos) {
+        if (pos >= 0 && pos < transformer.length) {
+            return transformer[pos];
+        }
+
+        return null;
     }
 
 

http://dive4elements.wald.intevation.org