# HG changeset patch # User Ingo Weinzierl # Date 1328872707 0 # Node ID 5948857036872a3677b3a4d63a9b9d2b79b2f8ef # Parent d999062c20e6b9532a0aca3c812668aa41974268 Picked changes r4015:4026 from trunk. flys-artifacts/tags/2.6@4028 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r d999062c20e6 -r 594885703687 flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/ChangeLog Fri Feb 10 11:18:27 2012 +0000 @@ -1,3 +1,78 @@ +2012-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/exports/InfoGeneratorHelper.java: Write + correct min and max values for date axes into the info document. + + * src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java: + Enabled zooming for timeseries charts. + +2012-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/jfree/Bounds.java, + src/main/java/de/intevation/flys/jfree/TimeBounds.java, + src/main/java/de/intevation/flys/jfree/DoubleBounds.java: Added a method + applyBounds(ValueAxis, int) that might be used to adapt the range of the + axis to the bounds adding a space to the left and right. + +2012-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/exports/ChartGenerator.java: Defined + new abstract methods for setting and getting Bounds. Modified and + renamed getValueAxisRange(). This method is now called + getValueAxisRangeFromRequest() and returns no longer a Range object but + a String array that consists of the raw string values speicified in the + request document. + + * src/main/java/de/intevation/flys/exports/XYChartGenerator.java: + Implemented the missing method getDomainAxisRange(). This method returns + a Range object based on the String array returned from + getValueAxisRangeFromRequest(). + +2012-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/jfree/TimeBounds.java: Added new + methods getLowerAsDate() and getUpperAsDate(). The toString() method + will now return a string that contains a human readable date string. + + * src/main/java/de/intevation/flys/jfree/DoubleBounds.java: Made 'lower' + always be smaller than 'upper' in the default constructor. + +2012-02-10 Sascha L. Teichmann + + * src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java: + Give more precise message when an error occurs in W~W relation. + + * src/main/resources/messages.properties, + src/main/resources/messages_de_DE.properties, + src/main/resources/messages_en.properties, + src/main/resources/messages_de.properties: + Improved error messages. + +2012-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/exports/ChartGenerator.java: Modified + and renamend getDomainAxisRange(). This method is now called + getDomainAxisRangeFromRequest() and returns no longer a Range object but + a String array that consists of the raw string values specified in the + request document. + + * src/main/java/de/intevation/flys/exports/XYChartGenerator.java: + Implemented the missing method getDomainAxisRange(). This method returns + a Range object based on the String array returned from + getDomainAxisRangeFromRequest(). + +2012-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/exports/ChartHelper.java: Added a + helper function to determine the min and max bounds (x and y) for + TimeSeriesCollections. + +2012-02-10 Ingo Weinzierl + + * src/main/java/de/intevation/flys/jfree/TimeBounds.java, + src/main/java/de/intevation/flys/jfree/DoubleBounds.java: Removed + useless imports. + 2012-02-10 Felix Wolfsteller * src/main/java/de/intevation/flys/artifacts/model/WW.java: diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java Fri Feb 10 11:18:27 2012 +0000 @@ -903,11 +903,28 @@ return relateWs(km1, km2, RELATE_WS_SAMPLES, errors); } + private static class ErrorHandler { + + boolean hasErrors; + Calculation errors; + + ErrorHandler(Calculation errors) { + this.errors = errors; + } + + void error(double km, String key, Object ... args) { + if (errors != null && !hasErrors) { + hasErrors = true; + errors.addProblem(km, key, args); + } + } + } // class ErrorHandler + + /* TODO: Add optimized methods of relateWs to relate one * start km to many end kms. The index generation/spline stuff for * the start km is always the same. */ - public double [][] relateWs( double km1, double km2, @@ -951,31 +968,51 @@ TDoubleArrayList qs1 = new TDoubleArrayList(numSamples); TDoubleArrayList qs2 = new TDoubleArrayList(numSamples); - boolean hadErrors = false; + ErrorHandler err = new ErrorHandler(errors); int i = 0; for (double p = 0d; p <= N-1; p += stepWidth, ++i) { + + double q1; try { - double q1 = iQ1.value(p); - double w1 = qW1.value(q1); - double q2 = iQ2.value(p); - double w2 = qW2.value(q2); - ws1.add(w1); - ws2.add(w2); - qs1.add(q1); - qs2.add(q2); + q1 = iQ1.value(p); } catch (ArgumentOutsideDomainException aode) { - if (!hadErrors) { - // XXX: I'm not sure if this really can happen - // and if we should report this more than once. - hadErrors = true; - if (errors != null) { - errors.addProblem("relating.w.w.failed"); - log.warn("W~W failed", aode); - } - } + err.error(km1, "w.w.qkm1.failed", p); + continue; } + + double w1; + try { + w1 = qW1.value(q1); + } + catch (ArgumentOutsideDomainException aode) { + err.error(km1, "w.w.wkm1.failed", p); + continue; + } + + double q2; + try { + q2 = iQ2.value(p); + } + catch (ArgumentOutsideDomainException aode) { + err.error(km2, "w.w.qkm2.failed", p); + continue; + } + + double w2; + try { + w2 = qW2.value(q2); + } + catch (ArgumentOutsideDomainException aode) { + err.error(km2, "w.w.wkm2.failed", p); + continue; + } + + ws1.add(w1); + ws2.add(w2); + qs1.add(q1); + qs2.add(q2); } return new double [][] { diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartGenerator.java Fri Feb 10 11:18:27 2012 +0000 @@ -49,6 +49,7 @@ import de.intevation.flys.artifacts.FLYSArtifact; import de.intevation.flys.artifacts.resources.Resources; +import de.intevation.flys.jfree.Bounds; import de.intevation.flys.jfree.EnhancedLineAndShapeRenderer; import de.intevation.flys.jfree.StableXYDifferenceRenderer; import de.intevation.flys.jfree.StyledAreaSeriesCollection; @@ -248,6 +249,14 @@ */ public abstract Range[] getRangesForAxis(int index); + public abstract Bounds getXBounds(int axis); + + protected abstract void setXBounds(int axis, Bounds bounds); + + public abstract Bounds getYBounds(int axis); + + protected abstract void setYBounds(int axis, Bounds bounds); + /** * This method should be used by concrete subclasses to add subtitle to @@ -1003,9 +1012,11 @@ /** - * Get Range of Domain ("X"-) Axis from request. + * Returns the X-Axis range as String array from request document. + * + * @return a String array with [lower, upper]. */ - protected Range getDomainAxisRange() { + protected String[] getDomainAxisRangeFromRequest() { Element xrange = (Element)XMLUtils.xpath( request, XPATH_CHART_X_RANGE, @@ -1021,34 +1032,11 @@ String lower = xrange.getAttributeNS(uri, "from"); String upper = xrange.getAttributeNS(uri, "to"); - if (lower.length() > 0 && upper.length() > 0) { - try { - double from = Double.parseDouble(lower); - double to = Double.parseDouble(upper); - - if (from == 0 && to == 0) { - logger.debug("No range specified. Lower and upper X == 0"); - return null; - } - - if (from > to) { - double tmp = to; - to = from; - from = tmp; - } - - return new Range(from, to); - } - catch (NumberFormatException nfe) { - logger.warn("Wrong values for domain axis range."); - } - } - - return null; + return new String[] { lower, upper }; } - protected Range getValueAxisRange() { + protected String[] getValueAxisRangeFromRequest() { Element yrange = (Element)XMLUtils.xpath( request, XPATH_CHART_Y_RANGE, @@ -1062,30 +1050,10 @@ String uri = ArtifactNamespaceContext.NAMESPACE_URI; - String lower = yrange.getAttributeNS(uri, "from"); String upper = yrange.getAttributeNS(uri, "to"); - if (lower.length() > 0 && upper.length() > 0) { - try { - double from = Double.parseDouble(lower); - double to = Double.parseDouble(upper); - - if (from == 0 && to == 0) { - logger.debug("No range specified. Lower and upper Y == 0"); - return null; - } - - return from > to - ? new Range(to, from) - : new Range(from, to); - } - catch (NumberFormatException nfe) { - logger.warn("Wrong values for value axis range."); - } - } - - return null; + return new String[] { lower, upper }; } diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/java/de/intevation/flys/exports/ChartHelper.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartHelper.java Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartHelper.java Fri Feb 10 11:18:27 2012 +0000 @@ -2,9 +2,16 @@ import org.jfree.data.Range; import org.jfree.data.xy.XYDataset; +import org.jfree.data.time.RegularTimePeriod; +import org.jfree.data.time.TimeSeriesCollection; +import org.jfree.data.time.TimeSeries; import org.apache.log4j.Logger; +import de.intevation.flys.jfree.Bounds; +import de.intevation.flys.jfree.DoubleBounds; +import de.intevation.flys.jfree.TimeBounds; + /** * @author Ingo Weinzierl @@ -73,6 +80,63 @@ } + public static Bounds[] getBounds(TimeSeriesCollection collection) { + int seriesCount = collection != null ? collection.getSeriesCount() : 0; + + if (seriesCount == 0) { + logger.warn("TimeSeriesCollection is empty or has no Series set."); + return null; + } + + boolean foundValue = false; + + long lowerX = Long.MAX_VALUE; + long upperX = -Long.MAX_VALUE; + + double lowerY = Double.MAX_VALUE; + double upperY = -Double.MAX_VALUE; + + for (int i = 0, m = seriesCount; i < m; i++) { + TimeSeries series = collection.getSeries(i); + + for (int j = 0, n = collection.getItemCount(i); j < n; j++) { + RegularTimePeriod rtp = series.getTimePeriod(j); + + if (rtp == null) { + continue; + } + + foundValue = true; + + long start = rtp.getFirstMillisecond(); + long end = rtp.getLastMillisecond(); + + if (start < lowerX) { + lowerX = start; + } + + if (end > upperX) { + upperX = end; + } + + double y = series.getValue(j).doubleValue(); + + lowerY = Math.min(lowerY, y); + upperY = Math.max(upperY, y); + } + } + + if (foundValue) { + return new Bounds[] { + new TimeBounds(lowerX, upperX), + new DoubleBounds(lowerY, upperY) + }; + } + + return null; + } + + /** * Expand range by percent. * diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/java/de/intevation/flys/exports/InfoGeneratorHelper.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/InfoGeneratorHelper.java Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/InfoGeneratorHelper.java Fri Feb 10 11:18:27 2012 +0000 @@ -24,6 +24,8 @@ import de.intevation.artifacts.common.utils.XMLUtils; import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator; +import de.intevation.flys.jfree.Bounds; + /** * This class helps generating chart info documents. @@ -204,13 +206,20 @@ Date from = axis.getMinimumDate(); Date to = axis.getMaximumDate(); + Bounds bounds = null; + if (type.equals("range")) { + bounds = generator.getYBounds(pos); + } + else { + bounds = generator.getXBounds(pos); + } + cr.addAttr(e, "axistype", "date", true); cr.addAttr(e, "from", String.valueOf(from.getTime()), true); cr.addAttr(e, "to", String.valueOf(to.getTime()), true); - // TODO Get correct min/max - cr.addAttr(e, "min", String.valueOf(from.getTime()), true); - cr.addAttr(e, "max", String.valueOf(to.getTime()), true); + cr.addAttr(e, "min", bounds.getLower().toString(), true); + cr.addAttr(e, "max", bounds.getUpper().toString(), true); return e; } diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/TimeseriesChartGenerator.java Fri Feb 10 11:18:27 2012 +0000 @@ -11,6 +11,7 @@ import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; +import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.plot.XYPlot; import org.jfree.data.Range; @@ -18,6 +19,10 @@ import org.jfree.data.general.Series; import org.jfree.data.xy.XYDataset; +import de.intevation.flys.jfree.Bounds; +import de.intevation.flys.jfree.DoubleBounds; +import de.intevation.flys.jfree.TimeBounds; + /** * @author Ingo Weinzierl @@ -106,8 +111,9 @@ protected void mergeRanges(TimeSeriesCollection dataset) { logger.debug("Range after merging: " + range); - Range[] xyRanges = ChartHelper.getRanges(dataset); - range = Range.combine(range, xyRanges[1]); + Bounds[] xyRanges = ChartHelper.getBounds(dataset); + + // TODO COMBINE BOUNDS! logger.debug("Range after merging: " + range); } @@ -120,9 +126,12 @@ Logger.getLogger(TimeseriesChartGenerator.class); - protected Map xRanges; + public static final int AXIS_SPACE = 5; - protected Map yRanges; + + protected Map xRanges; + + protected Map yRanges; @@ -132,8 +141,8 @@ public TimeseriesChartGenerator() { super(); - xRanges = new HashMap(); - yRanges = new HashMap(); + xRanges = new HashMap(); + yRanges = new HashMap(); } @@ -161,6 +170,8 @@ addSubtitles(chart); addDatasets(plot); + adaptZoom(plot); + return chart; } @@ -171,15 +182,31 @@ } - @Override - protected void setXRange(int axis, Range range) { - xRanges.put(Integer.valueOf(axis), range); + // TODO DECLARE IN UPPER CLASS AND ADD OVERRIDE ANNOTATION + protected Bounds getXRange(int axis) { + return xRanges.get(Integer.valueOf(axis)); } @Override + // TODO setXRange should always await a Bounds instance! + // TODO SHOULD BE REMOVED WHEN DEFINED IN UPPER CLASS + protected void setXRange(int axis, Range range) { + // do nothing here, we will use setXRange(int, Bounds) now + } + + + @Override + // TODO setYRange should always await a Bounds instance! protected void setYRange(int axis, Range range) { - yRanges.put(Integer.valueOf(axis), range); + if (range == null) { + logger.warn("Range is null!"); + return; + } + + setYBounds(Integer.valueOf(axis), new DoubleBounds( + range.getLowerBound(), + range.getUpperBound())); } @@ -195,6 +222,37 @@ } + // TODO THIS SHOULD BE DONE IN AN UPPER CLASS! + @Override + public void addAxisDataset(XYDataset dataset, int idx, boolean visible) { + if (dataset == null || idx < 0) { + return; + } + + AxisDataset axisDataset = getAxisDataset(idx); + + Bounds[] bounds = ChartHelper.getBounds((TimeSeriesCollection)dataset); + + if (bounds == null) { + logger.warn("Skip XYDataset for Axis (invalid ranges): " + idx); + return; + } + + if (visible) { + if (logger.isDebugEnabled()) { + logger.debug("Add new AxisDataset at index: " + idx); + logger.debug("X extent: " + bounds[0]); + logger.debug("Y extent: " + bounds[1]); + } + + axisDataset.addDataset(dataset); + } + + combineXRanges(bounds[0], 0); + combineYRanges(bounds[1], idx); + } + + /** * Effect: extend range of x axis to include given limits. * @param range the given ("minimal") range. @@ -202,40 +260,237 @@ */ @Override protected void combineXRanges(Range range, int index) { - if (range != null) { - Range old = xRanges.get(index); + throw new RuntimeException( + "TimeseriesChartGenerator.combineXRanges is not implemented!"); + } + + + protected void combineXRanges(Bounds bounds, int index) { + if (bounds != null) { + Bounds old = getXRange(index); if (old != null) { - range = Range.combine(old, range); + bounds = bounds.combine(old); } - xRanges.put(index, range); + setXBounds(index, bounds); } } + protected void combineYRanges(Bounds bounds, int index) { + if (bounds != null) { + Bounds old = getYBounds(index); + + if (old != null) { + bounds = bounds.combine(old); + } + + setYBounds(index, bounds); + } + } + + + // TODO REPLACE THIS METHOD WITH getBoundsForAxis(index) + @Override + public Range[] getRangesForAxis(int index) { + // TODO + Bounds[] bounds = getBoundsForAxis(index); + + return new Range[] { + new Range( + bounds[0].getLower().doubleValue(), + bounds[0].getUpper().doubleValue()), + new Range( + bounds[1].getLower().doubleValue(), + bounds[1].getUpper().doubleValue()) + }; + } + + @Override - public Range[] getRangesForAxis(int index) { - logger.debug("Return ranges for axis at: " + index); + public Bounds getXBounds(int axis) { + return xRanges.get(axis); + } - Range rx = xRanges.get(Integer.valueOf(0)); - Range ry = yRanges.get(Integer.valueOf(index)); + + @Override + protected void setXBounds(int axis, Bounds bounds) { + xRanges.put(axis, bounds); + } + + + @Override + public Bounds getYBounds(int axis) { + return yRanges.get(axis); + } + + + @Override + protected void setYBounds(int axis, Bounds bounds) { + yRanges.put(axis, bounds); + } + + + public Bounds[] getBoundsForAxis(int index) { + logger.debug("Return x and y bounds for axis at: " + index); + + Bounds rx = getXBounds(Integer.valueOf(index)); + Bounds ry = getYBounds(Integer.valueOf(index)); if (rx == null) { logger.warn("Range for x axis not set." + " Using default values: 0 - 1."); - rx = new Range(0, 1); - } - if (ry == null) { - logger.warn("Range for y" + index + - " axis not set. Using default values: 0 - 1."); - ry = new Range(0, 1); + rx = new TimeBounds(0l, 1l); } - logger.debug("X Range is: " + rx); - logger.debug("Y Range is: " + ry); + if (ry == null) { + logger.warn("Range for y axis not set." + + " Using default values: 0 - 1."); + ry = new DoubleBounds(0l, 1l); + } - return new Range[] {rx, ry}; + logger.debug("X Bounds at index " + index + " is: " + rx); + logger.debug("Y Bounds at index " + index + " is: " + ry); + + return new Bounds[] {rx, ry}; + } + + + public Bounds getDomainAxisRange() { + String[] ranges = getDomainAxisRangeFromRequest(); + + if (ranges == null || ranges.length < 2) { + logger.debug("No zoom range for domain axis specified."); + return null; + } + + if (ranges[0] == null || ranges[1] == null) { + logger.warn("Invalid ranges for domain axis specified!"); + return null; + } + + try { + double lower = Double.parseDouble(ranges[0]); + double upper = Double.parseDouble(ranges[1]); + + return new DoubleBounds(lower, upper); + } + catch (NumberFormatException nfe) { + logger.warn("Invalid ranges for domain axis specified: " + nfe); + } + + return null; + } + + + public Bounds getValueAxisRange() { + String[] ranges = getValueAxisRangeFromRequest(); + + if (ranges == null || ranges.length < 2) { + logger.debug("No zoom range for domain axis specified."); + return null; + } + + if (ranges[0] == null || ranges[1] == null) { + logger.warn("Invalid ranges for domain axis specified!"); + return null; + } + + try { + double lower = Double.parseDouble(ranges[0]); + double upper = Double.parseDouble(ranges[1]); + + return new DoubleBounds(lower, upper); + } + catch (NumberFormatException nfe) { + logger.warn("Invalid ranges for domain axis specified: " + nfe); + } + + return null; + } + + + protected void adaptZoom(XYPlot plot) { + logger.debug("Adapt zoom of Timeseries chart."); + + zoomX(plot, plot.getDomainAxis(), getXRange(0), getDomainAxisRange()); + + Bounds valueAxisBounds = getValueAxisRange(); + + for (int j = 0, n = plot.getRangeAxisCount(); j < n; j++) { + zoomY( + plot, + plot.getRangeAxis(j), + getYBounds(j), + valueAxisBounds); + } + } + + + protected void zoomX( + XYPlot plot, + ValueAxis axis, + Bounds total, + Bounds user + ) { + if (logger.isDebugEnabled()) { + logger.debug("== Zoom X axis =="); + logger.debug(" Total axis range : " + total); + logger.debug(" User defined range: " + user); + } + + if (user != null) { + long min = total.getLower().longValue(); + long max = total.getUpper().longValue(); + long diff = max > min ? max - min : min - max; + + long newMin = (long) Math.round(min + user.getLower().doubleValue() * diff); + long newMax = (long) Math.round(min + user.getUpper().doubleValue() * diff); + + TimeBounds newBounds = new TimeBounds(newMin, newMax); + + logger.debug(" Zoom axis to: " + newBounds); + + newBounds.applyBounds(axis, AXIS_SPACE); + } + else { + logger.debug("No user specified zoom values found!"); + total.applyBounds(axis, AXIS_SPACE); + } + } + + + protected void zoomY( + XYPlot plot, + ValueAxis axis, + Bounds total, + Bounds user + ) { + if (logger.isDebugEnabled()) { + logger.debug("== Zoom Y axis =="); + logger.debug(" Total axis range : " + total); + logger.debug(" User defined range: " + user); + } + + if (user != null) { + double min = total.getLower().doubleValue(); + double max = total.getUpper().doubleValue(); + double diff = max > min ? max - min : min - max; + + double newMin = min + user.getLower().doubleValue() * diff; + double newMax = min + user.getUpper().doubleValue() * diff; + + DoubleBounds newBounds = new DoubleBounds(newMin, newMax); + + logger.debug(" Zoom axis to: " + newBounds); + + newBounds.applyBounds(axis, AXIS_SPACE); + } + else { + logger.debug("No user specified zoom values found!"); + total.applyBounds(axis, AXIS_SPACE); + } } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java Fri Feb 10 11:18:27 2012 +0000 @@ -39,6 +39,7 @@ import de.intevation.artifactdatabase.state.ArtifactAndFacet; import de.intevation.artifactdatabase.state.Facet; +import de.intevation.flys.jfree.Bounds; import de.intevation.flys.jfree.FLYSAnnotation; import de.intevation.flys.jfree.StickyAxisAnnotation; import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation; @@ -465,6 +466,72 @@ } + protected Range getDomainAxisRange() { + String[] ranges = getDomainAxisRangeFromRequest(); + + if (ranges == null || ranges.length < 2) { + logger.debug("No zoom range for domain axis specified."); + return null; + } + + if (ranges[0].length() > 0 && ranges[1].length() > 0) { + try { + double from = Double.parseDouble(ranges[0]); + double to = Double.parseDouble(ranges[1]); + + if (from == 0 && to == 0) { + logger.debug("No range specified. Lower and upper X == 0"); + return null; + } + + if (from > to) { + double tmp = to; + to = from; + from = tmp; + } + + return new Range(from, to); + } + catch (NumberFormatException nfe) { + logger.warn("Wrong values for domain axis range."); + } + } + + return null; + } + + + protected Range getValueAxisRange() { + String[] ranges = getValueAxisRangeFromRequest(); + + if (ranges == null || ranges.length < 2) { + logger.debug("No range specified. Lower and upper Y == 0"); + return null; + } + + if (ranges[0].length() > 0 && ranges[1].length() > 0) { + try { + double from = Double.parseDouble(ranges[0]); + double to = Double.parseDouble(ranges[1]); + + if (from == 0 && to == 0) { + logger.debug("No range specified. Lower and upper Y == 0"); + return null; + } + + return from > to + ? new Range(to, from) + : new Range(from, to); + } + catch (NumberFormatException nfe) { + logger.warn("Wrong values for value axis range."); + } + } + + return null; + } + + protected boolean zoomX(XYPlot plot, ValueAxis axis, Range range, Range x) { return zoom(plot, axis, range, x); } @@ -541,6 +608,38 @@ } + @Override + public Bounds getXBounds(int axis) { + // TODO IMPLEMENT ME + throw new RuntimeException( + "XYChartGenerator.getXBounds(int) not implemented"); + } + + + @Override + protected void setXBounds(int axis, Bounds bounds) { + // TODO IMPLEMENT ME + throw new RuntimeException( + "XYChartGenerator.setXBounds(int,Bounds) not implemented"); + } + + + @Override + public Bounds getYBounds(int axis) { + // TODO IMPLEMENT ME + throw new RuntimeException( + "XYChartGenerator.getYBounds(int) not implemented"); + } + + + @Override + protected void setYBounds(int axis, Bounds bounds) { + // TODO IMPLEMENT ME + throw new RuntimeException( + "XYChartGenerator.setYBounds(int,Bounds) not implemented"); + } + + /** Get color for hyk zones by their type (which is the name). */ public Paint colorForHYKZone(String zoneName) { if (zoneName.startsWith("R")) { diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/java/de/intevation/flys/jfree/Bounds.java --- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/Bounds.java Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/Bounds.java Fri Feb 10 11:18:27 2012 +0000 @@ -16,6 +16,8 @@ void applyBounds(ValueAxis axis); + void applyBounds(ValueAxis axis, int percent); + Bounds combine(Bounds bounds); } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/java/de/intevation/flys/jfree/DoubleBounds.java --- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/DoubleBounds.java Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/DoubleBounds.java Fri Feb 10 11:18:27 2012 +0000 @@ -15,9 +15,13 @@ protected double upper; + /** + * Default constructor. A DoubleBounds has always set lower < + * upper! + */ public DoubleBounds(double lower, double upper) { - this.lower = lower; - this.upper = upper; + this.lower = Math.min(lower, upper); + this.upper = Math.max(lower, upper); } @@ -40,6 +44,13 @@ @Override + public void applyBounds(ValueAxis axis, int percent) { + double space = (upper - lower) / 100 * percent; + axis.setRange(new Range(lower-space, upper+space)); + } + + + @Override public Bounds combine(Bounds bounds) { if (bounds == null) { return this; diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/java/de/intevation/flys/jfree/TimeBounds.java --- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/TimeBounds.java Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/TimeBounds.java Fri Feb 10 11:18:27 2012 +0000 @@ -2,8 +2,6 @@ import java.util.Date; -import org.apache.log4j.Logger; - import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.ValueAxis; @@ -29,12 +27,22 @@ } + public Date getLowerAsDate() { + return new Date(lower); + } + + @Override public Number getUpper() { return Long.valueOf(upper); } + public Date getUpperAsDate() { + return new Date(upper); + } + + @Override public void applyBounds(ValueAxis axis) { DateAxis dateAxis = (DateAxis) axis; @@ -45,6 +53,17 @@ @Override + public void applyBounds(ValueAxis axis, int percent) { + DateAxis dateAxis = (DateAxis) axis; + + long space = (upper - lower) / 100 * percent; + + dateAxis.setMinimumDate(new Date(lower-space)); + dateAxis.setMaximumDate(new Date(upper+space)); + } + + + @Override public Bounds combine(Bounds bounds) { if (bounds == null) { return this; @@ -63,7 +82,7 @@ @Override public String toString() { - return "TimeBounds=[" + lower + " ; " + upper + "]"; + return "TimeBounds=["+ getLowerAsDate() + " ; " + getUpperAsDate() +"]"; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/resources/messages.properties --- a/flys-artifacts/src/main/resources/messages.properties Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/resources/messages.properties Fri Feb 10 11:18:27 2012 +0000 @@ -178,7 +178,12 @@ km.not.found = Cannot find km. cannot.create.wq.relation = Cannot create W/Q relation. cannot.create.index.q.relation = Cannot create index/Q relation. -relating.w.w.failed = Relating W with W failed. + +w.w.qkm1.failed = Calculating Q for WST index {0,number,#.##} failed. +w.w.wkm1.failed = Calculating W for WST index {0,number,#.##} failed. +w.w.qkm2.failed = Calculating Q for WST index {0,number,#.##} failed. +w.w.wkm2.failed = Calculating W for WST index {0,number,#.##} failed. + cannot.find.hist.q.for.w = Cannot find Q for W = {0,number,#.##} in timerange {1, date} - {2, date} cannot.find.hist.q.tables = Cannot find Discharge Tables for given timerange. cannot.find.hist.q.reftable = Cannot find reference Discharge Table for specified Gauge. diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/resources/messages_de.properties --- a/flys-artifacts/src/main/resources/messages_de.properties Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/resources/messages_de.properties Fri Feb 10 11:18:27 2012 +0000 @@ -178,7 +178,12 @@ km.not.found = Passender Kilometer konnte nicht gefunden werden. cannot.create.wq.relation = W/Q-Beziehung konnte nicht ermittelt werden. cannot.create.index.q.relation = Spaltenindex/Q-Beziehung konnte nicht erstellt werden. -relating.w.w.failed = W-zu-W-Zuordnung fehlgeschlagen. + +w.w.qkm1.failed = Berechnung von Q f\u00fcr WST-Index {0,number,#.##} fehlgeschlagen. +w.w.wkm1.failed = Berechnung von W f\u00fcr WST-Index {0,number,#.##} fehlgeschlagen. +w.w.qkm2.failed = Berechnung von Q f\u00fcr WST-Index {0,number,#.##} fehlgeschlagen. +w.w.wkm2.failed = Berechnung von W f\u00fcr WST-Index {0,number,#.##} fehlgeschlagen. + cannot.find.hist.q.for.w = Konnte zu W = {0,number,#.##} im Zeitraum ({1,date} - {2,date}) kein Abfluss ermitteln. cannot.find.hist.q.tables = Konnte f\u00fcr den angegebenen Zeitraum keine Abflusstafeln finden. cannot.find.hist.q.reftable = Konnte f\u00fcr den gew\u00e4hlten Pegel keine Bezugs-Abflusstafel ermitteln. diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/resources/messages_de_DE.properties --- a/flys-artifacts/src/main/resources/messages_de_DE.properties Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/resources/messages_de_DE.properties Fri Feb 10 11:18:27 2012 +0000 @@ -178,7 +178,12 @@ km.not.found = Passender Kilometer konnte nicht gefunden werden. cannot.create.wq.relation = W/Q-Beziehung konnte nicht ermittelt werden. cannot.create.index.q.relation = Spaltenindex/Q-Beziehung konnte nicht erstellt werden. -relating.w.w.failed = W-zu-W-Zuordnung fehlgeschlagen. + +w.w.qkm1.failed = Berechnung von Q f\u00fcr WST-Index {0,number,#.##} fehlgeschlagen. +w.w.wkm1.failed = Berechnung von W f\u00fcr WST-Index {0,number,#.##} fehlgeschlagen. +w.w.qkm2.failed = Berechnung von Q f\u00fcr WST-Index {0,number,#.##} fehlgeschlagen. +w.w.wkm2.failed = Berechnung von W f\u00fcr WST-Index {0,number,#.##} fehlgeschlagen. + cannot.find.hist.q.for.w = Konnte zu W = {0,number,#.##} im Zeitraum ({1,date} - {2,date}) kein Abfluss ermitteln. cannot.find.hist.q.tables = Konnte f\u00fcr den angegebenen Zeitraum keine Abflusstafeln finden. cannot.find.hist.q.reftable = Konnte f\u00fcr den gew\u00e4hlten Pegel keine Bezugs-Abflusstafel ermitteln. diff -r d999062c20e6 -r 594885703687 flys-artifacts/src/main/resources/messages_en.properties --- a/flys-artifacts/src/main/resources/messages_en.properties Fri Feb 10 08:28:17 2012 +0000 +++ b/flys-artifacts/src/main/resources/messages_en.properties Fri Feb 10 11:18:27 2012 +0000 @@ -174,7 +174,12 @@ km.not.found = Cannot find km. cannot.create.wq.relation = Cannot create W/Q relation. cannot.create.index.q.relation = Cannot create index/Q relation. -relating.w.w.failed = Relating W with W failed. + +w.w.qkm1.failed = Calculating Q for WST index {0,number,#.##} failed. +w.w.wkm1.failed = Calculating W for WST index {0,number,#.##} failed. +w.w.qkm2.failed = Calculating Q for WST index {0,number,#.##} failed. +w.w.wkm2.failed = Calculating W for WST index {0,number,#.##} failed. + cannot.find.hist.q.for.w = Cannot find Q for W = {0,number,#.##} in timerange {1, date} - {2, date} cannot.find.hist.q.tables = Cannot find Discharge Tables for given timerange. cannot.find.hist.q.reftable = Cannot find reference Discharge Table for specified Gauge.