# HG changeset patch # User Ingo Weinzierl # Date 1259768566 0 # Node ID 42a5269636eb91305f19a751170a7f810b5b59f3 # Parent 861d939e587cb539b27f34cdea76f0c8254b9580 Added time gap detection to time series charts. gnv-artifacts/trunk@395 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 861d939e587c -r 42a5269636eb gnv-artifacts/ChangeLog --- a/gnv-artifacts/ChangeLog Wed Dec 02 11:07:40 2009 +0000 +++ b/gnv-artifacts/ChangeLog Wed Dec 02 15:42:46 2009 +0000 @@ -1,3 +1,9 @@ +2009-12-02 Ingo Weinzierl + + * src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java: Added time gap + detection. If a time gap is detected, a null value will be inserted to + break the current line. + 2009-12-02 Ingo Weinzierl * pom.xml: Added JBoss repository for JFreeChart 1.0.13 and removed explicit diff -r 861d939e587c -r 42a5269636eb gnv-artifacts/src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java Wed Dec 02 11:07:40 2009 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java Wed Dec 02 15:42:46 2009 +0000 @@ -3,6 +3,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Collection; +import java.util.Date; import java.util.Iterator; import java.util.Locale; @@ -21,6 +22,7 @@ import org.jfree.data.time.TimeSeriesCollection; import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.timeseries.gap.TimeGap; /** @@ -32,6 +34,8 @@ private static final String DATE_FORMAT = "dd-MMM"; + private static final long NO_TIME_GAP = Long.MAX_VALUE - 1000; + private static Logger log = Logger.getLogger(TimeSeriesChart.class); @@ -96,7 +100,14 @@ String seriesName = null; TimeSeries series = null; - int idx = 0; + int idx = 0; + int startPos = 0; + int endPos = 0; + Date startDate = null; + Date endDate = null; + + Result[] results = + (Result[]) resultSet.toArray(new Result[resultSet.size()]); while (iter.hasNext()) { row = (Result) iter.next(); @@ -109,9 +120,15 @@ log.debug("prepare data/plot for next dataset"); if(series != null) { + // add gaps before adding series to chart + startDate = results[startPos].getDate("XORDINATE"); + endDate = results[endPos-1].getDate("XORDINATE"); + addGaps(results,series,startDate,endDate,startPos,endPos); addSeries(series, idx); + prepareAxis(((String)series.getKey()), idx); adjustRenderer(idx++, linesVisible, shapesVisible); + startPos = endPos + 1; } // prepare variables for next plot @@ -127,12 +144,19 @@ log.debug("next dataset is '" + seriesName + "'"); series = new TimeSeries(seriesName, Minute.class); + + // set values of start date and start position in collection for + // next parameter } addValue(row, series); + endPos++; } // add the last dataset if existing to plot and prepare its axis + startDate = results[startPos].getDate("XORDINATE"); + endDate = results[endPos-1].getDate("XORDINATE"); + addGaps(results, series, startDate, endDate, startPos, endPos); addSeries(series, idx); if (series != null) { @@ -143,7 +167,6 @@ protected void addValue(Result row, Series series) { - // TODO look for gaps between two values ((TimeSeries) series).addOrUpdate( new Minute(row.getDate("XORDINATE")), row.getDouble("YORDINATE") @@ -190,5 +213,111 @@ findValueTitle(measurements, breakPoint2) + "m"; } + + + protected void addGaps( + Result[] results, + Series series, + Date startDate, + Date endDate, + int startPos, + int endPos + ) { + int gapID = results[startPos].getInteger("GAPID"); + long maxDiff = calculateGapSize( + startDate, endDate, startPos, endPos, gapID + ); + + Date last = startDate; + for (int i = startPos+1; i < endPos; i++) { + Result res = results[i]; + Date now = res.getDate("XORDINATE"); + + if ((now.getTime() - last.getTime()) > maxDiff) { + // add gap, add 1 minute to last date and add null value + log.info( + "Gap between " + + last.toString() + " and " + now.toString() + ); + last.setTime(last.getTime() + 60000); + ((TimeSeries) series).addOrUpdate(new Minute(last), null); + } + + last = now; + } + } + + + protected long calculateGapSize( + Date start, + Date end, + int startPos, + int endPos, + int gapID + ){ + long maxGap = (end.getTime() - start.getTime()) / 20; + long interval = getTimeGapValue(start, end, startPos, endPos, gapID); + + if (maxGap < interval) + maxGap = interval + 10; + + return maxGap; + } + + + protected long getTimeGapValue( + Date dStart, + Date dEnd, + int pStart, + int pEnd, + int gapID + ){ + long gap = 0; + + if (gapID < 0 || gapID >= 99) { + + if (gapID == -1) { + // no gaps in meshes + gap = NO_TIME_GAP; + } + else if (pEnd-pStart < 60) { + gap = (3/(pEnd-pStart)) * (dEnd.getTime() - dStart.getTime()); + } + } + else{ + Iterator it = timeGaps.iterator(); + + while (it.hasNext()) { + TimeGap tempTimeGap = (TimeGap) it.next(); + + if (tempTimeGap.getKey() == gapID){ + String unit = tempTimeGap.getUnit(); + int gapValue = tempTimeGap.getValue(); + + if (unit.equals(TimeGap.TIME_UNIT_MINUTE)) { + gap = gapValue * TimeGap.MINUTE_IN_MILLIS; + } + else if (unit.equals(TimeGap.TIME_UNIT_HOUR)) { + gap = gapValue * TimeGap.HOUR_IN_MILLIS; + } + else if (unit.equals(TimeGap.TIME_UNIT_DAY)) { + gap = gapValue * TimeGap.DAY_IN_MILLIS; + } + else if (unit.equals(TimeGap.TIME_UNIT_WEEK)) { + gap = gapValue * TimeGap.WEEK_IN_MILLIS; + } + else if (unit.equals(TimeGap.TIME_UNIT_MONTH)) { + gap = gapValue * (TimeGap.DAY_IN_MILLIS *30); + } + else if (unit.equals(TimeGap.TIME_UNIT_YEAR)) { + gap = gapValue * (TimeGap.DAY_IN_MILLIS *365); + } + break; + } + } + } + + return gap; + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :