Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/chart/TimeSeriesChart.java @ 1119:7c4f81f74c47
merged gnv-artifacts
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:00 +0200 |
parents | f953c9a559d8 |
children |
comparison
equal
deleted
inserted
replaced
1027:fca4b5eb8d2f | 1119:7c4f81f74c47 |
---|---|
1 /* | |
2 * Copyright (c) 2010 by Intevation GmbH | |
3 * | |
4 * This program is free software under the LGPL (>=v2.1) | |
5 * Read the file LGPL.txt coming with the software for details | |
6 * or visit http://www.gnu.org/licenses/ if it does not exist. | |
7 */ | |
8 | |
9 package de.intevation.gnv.chart; | |
10 | |
11 import de.intevation.gnv.artifacts.ressource.RessourceFactory; | |
12 | |
13 import de.intevation.gnv.geobackend.base.Result; | |
14 | |
15 import de.intevation.gnv.state.describedata.KeyValueDescibeData; | |
16 | |
17 import de.intevation.gnv.timeseries.gap.TimeGap; | |
18 | |
19 import java.text.DateFormat; | |
20 import java.text.SimpleDateFormat; | |
21 | |
22 import java.util.Collection; | |
23 import java.util.Date; | |
24 import java.util.HashMap; | |
25 import java.util.Iterator; | |
26 import java.util.Locale; | |
27 import java.util.TimeZone; | |
28 | |
29 import org.apache.log4j.Logger; | |
30 | |
31 import org.jfree.chart.ChartFactory; | |
32 import org.jfree.chart.ChartTheme; | |
33 | |
34 import org.jfree.chart.axis.Axis; | |
35 import org.jfree.chart.axis.DateAxis; | |
36 import org.jfree.chart.axis.DateTickUnit; | |
37 import org.jfree.chart.axis.DateTickUnitType; | |
38 import org.jfree.chart.axis.TickUnitSource; | |
39 import org.jfree.chart.axis.TickUnits; | |
40 import org.jfree.chart.axis.ValueAxis; | |
41 | |
42 import org.jfree.chart.plot.PlotOrientation; | |
43 import org.jfree.chart.plot.XYPlot; | |
44 | |
45 import org.jfree.data.general.Series; | |
46 | |
47 import org.jfree.data.time.Minute; | |
48 import org.jfree.data.time.TimeSeries; | |
49 import org.jfree.data.time.TimeSeriesCollection; | |
50 | |
51 /** | |
52 * This class is used to create timeseries charts. The domain axis contains | |
53 * multiple date/time objects. | |
54 * | |
55 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> | |
56 */ | |
57 public class TimeSeriesChart | |
58 extends AbstractXYLineChart | |
59 { | |
60 | |
61 /** | |
62 * Constant format which can be useful to format date items. Value is | |
63 * {@value}. | |
64 */ | |
65 public static final String DEFAULT_DATE_FORMAT = "dd-MMM-yyyy"; | |
66 | |
67 /** | |
68 * Constant field used if no gap detection should be done here. This field | |
69 * is used in @see #getTimeGapValue. Value is {@value}. | |
70 */ | |
71 public static final long NO_TIME_GAP = Long.MAX_VALUE - 1000; | |
72 | |
73 /** | |
74 * Percentage used for gap detection. Its value is {@value}. | |
75 */ | |
76 public static int GAP_SIZE = 5; // in percent | |
77 | |
78 /** | |
79 * Logger used for logging with log4j. | |
80 */ | |
81 private static Logger log = Logger.getLogger(TimeSeriesChart.class); | |
82 | |
83 static { | |
84 /* The percentage defining the width of a gap should be configured in | |
85 * conf.xml instead of being configured in a system property */ | |
86 GAP_SIZE = Integer.getInteger("chart.gap.percentage", GAP_SIZE); | |
87 } | |
88 | |
89 | |
90 /** | |
91 * Constructor used to create <code>TimeSeries</code> charts. | |
92 * | |
93 * @param labels Labels used to be displayed in title, subtitle and so on. | |
94 * @param theme ChartTheme used to adjust the rendering of this chart. | |
95 * @param parameters Collection containing a bunch of parameters. | |
96 * @param measurements Collection containing a bunch of measurements. | |
97 * @param dates Collection containing a bunch of date objects. | |
98 * @param result Collection containing a bunch of <code>Result</code> | |
99 * objects which contain the actual data items to be displayed. | |
100 * @param timeGaps Collection with timegap definitions. | |
101 * @param locale Locale used to specify the format of labels, numbers, ... | |
102 * @param linesVisible Render lines between data points if true, otherwise | |
103 * not. | |
104 * @param shapesVisible Render vertices as points if true, otherwise not. | |
105 */ | |
106 public TimeSeriesChart( | |
107 ChartLabels labels, | |
108 ChartTheme theme, | |
109 Collection parameters, | |
110 Collection measurements, | |
111 Collection dates, | |
112 Collection result, | |
113 Collection timeGaps, | |
114 Locale locale, | |
115 boolean linesVisible, | |
116 boolean shapesVisible | |
117 ) { | |
118 this.labels = labels; | |
119 this.theme = theme; | |
120 this.parameters = parameters; | |
121 this.measurements = measurements; | |
122 this.dates = dates; | |
123 this.resultSet = result; | |
124 this.timeGaps = timeGaps; | |
125 this.locale = locale; | |
126 this.PLOT_ORIENTATION = PlotOrientation.VERTICAL; | |
127 this.linesVisible = linesVisible; | |
128 this.shapesVisible = shapesVisible; | |
129 this.datasets = new HashMap(); | |
130 this.ranges = new HashMap(); | |
131 } | |
132 | |
133 | |
134 /** | |
135 * see de.intevation.gnv.chart.AbstractXYLineChart#initChart() | |
136 */ | |
137 @Override | |
138 protected void initChart() { | |
139 chart = ChartFactory.createTimeSeriesChart( | |
140 labels.getTitle(), | |
141 labels.getDomainAxisLabel(), | |
142 null, | |
143 null, | |
144 true, | |
145 false, | |
146 false | |
147 ); | |
148 | |
149 XYPlot plot = (XYPlot) chart.getPlot(); | |
150 plot.setDomainAxis(0, new DateAxis( | |
151 labels.getDomainAxisLabel(), TimeZone.getDefault(), locale)); | |
152 } | |
153 | |
154 | |
155 /** | |
156 * @see de.intevation.gnv.chart.AbstractXYLineChart#initData() | |
157 */ | |
158 protected void initData() { | |
159 log.debug("init data for timeseries chart"); | |
160 | |
161 String breakPoint1 = null; | |
162 String breakPoint2 = null; | |
163 String breakPoint3 = null; | |
164 | |
165 Iterator iter = resultSet.iterator(); | |
166 Result row = null; | |
167 String seriesName = null; | |
168 String parameter = null; | |
169 TimeSeries series = null; | |
170 | |
171 int idx = 0; | |
172 int startPos = 0; | |
173 int endPos = 0; | |
174 Date startDate = null; | |
175 Date endDate = null; | |
176 | |
177 Result[] results = | |
178 (Result[]) resultSet.toArray(new Result[resultSet.size()]); | |
179 | |
180 while (iter.hasNext()) { | |
181 row = (Result) iter.next(); | |
182 | |
183 // add current data to plot and prepare for next one | |
184 if (!row.getString("GROUP1").equals(breakPoint1) || | |
185 !row.getString("GROUP2").equals(breakPoint2) || | |
186 !row.getString("GROUP3").equals(breakPoint3) | |
187 ) { | |
188 log.debug("prepare data/plot for next dataset"); | |
189 | |
190 if(series != null) { | |
191 // add gaps before adding series to chart | |
192 startDate = results[startPos].getDate("XORDINATE"); | |
193 endDate = results[endPos-1].getDate("XORDINATE"); | |
194 addGaps(results,series,startDate,endDate,startPos,endPos); | |
195 addSeries(series, parameter, idx); | |
196 | |
197 startPos = endPos + 1; | |
198 } | |
199 | |
200 // prepare variables for next plot | |
201 breakPoint1 = row.getString("GROUP1"); | |
202 breakPoint2 = row.getString("GROUP2"); | |
203 breakPoint3 = row.getString("GROUP3"); | |
204 | |
205 seriesName = createSeriesName( | |
206 breakPoint1, | |
207 breakPoint2, | |
208 breakPoint3 | |
209 ); | |
210 parameter = findParameter(seriesName); | |
211 | |
212 log.debug("next dataset is '" + seriesName + "'"); | |
213 series = new TimeSeries(seriesName, Minute.class); | |
214 } | |
215 | |
216 addValue(row, series); | |
217 storeMaxRange(ranges, row.getDouble("YORDINATE"), parameter); | |
218 endPos++; | |
219 } | |
220 | |
221 if (startPos < results.length && endPos-1 < results.length) { | |
222 // add the last dataset if existing to plot and prepare its axis | |
223 startDate = results[startPos].getDate("XORDINATE"); | |
224 endDate = results[endPos-1].getDate("XORDINATE"); | |
225 addGaps(results, series, startDate, endDate, startPos, endPos); | |
226 addSeries(series, parameter, idx); | |
227 } | |
228 | |
229 addDatasets(); | |
230 } | |
231 | |
232 | |
233 /** | |
234 * @see de.intevation.gnv.chart.AbstractXYLineChart#addValue(Result, Series) | |
235 */ | |
236 protected void addValue(Result row, Series series) { | |
237 ((TimeSeries) series).addOrUpdate( | |
238 new Minute(row.getDate("XORDINATE")), | |
239 row.getDouble("YORDINATE") | |
240 ); | |
241 } | |
242 | |
243 | |
244 /** | |
245 * @param parameter | |
246 * @see de.intevation.gnv.chart.AbstractXYLineChart#addSeries(Series, | |
247 * String, int) | |
248 */ | |
249 protected void addSeries(Series series, String parameter, int idx) { | |
250 log.debug("add series (" + parameter + ")to timeseries chart"); | |
251 | |
252 if (series == null) { | |
253 log.warn("no data to add"); | |
254 return; | |
255 } | |
256 | |
257 TimeSeriesCollection tsc = null; | |
258 | |
259 if (datasets.containsKey(parameter)) | |
260 tsc = (TimeSeriesCollection) datasets.get(parameter); | |
261 else | |
262 tsc = new TimeSeriesCollection(); | |
263 | |
264 tsc.addSeries((TimeSeries) series); | |
265 datasets.put(parameter, tsc); | |
266 } | |
267 | |
268 | |
269 /** | |
270 * Method to add processed datasets to plot. Each dataset is adjusted using | |
271 * <code>prepareAxis</code> and <code>adjustRenderer</code> methods. | |
272 */ | |
273 protected void addDatasets() { | |
274 Iterator iter = parameters.iterator(); | |
275 XYPlot plot = chart.getXYPlot(); | |
276 int idx = 0; | |
277 | |
278 TimeSeriesCollection tsc = null; | |
279 KeyValueDescibeData data = null; | |
280 String key = null; | |
281 while (iter.hasNext()) { | |
282 data = (KeyValueDescibeData) iter.next(); | |
283 key = data.getValue(); | |
284 | |
285 if (datasets.containsKey(key)) { | |
286 tsc = (TimeSeriesCollection)datasets.get(key); | |
287 plot.setDataset(idx, tsc ); | |
288 log.debug("Added " + key + " parameter to plot."); | |
289 prepareAxis(key, idx); | |
290 adjustRenderer( | |
291 idx++, | |
292 tsc.getSeriesCount(), | |
293 linesVisible, | |
294 shapesVisible | |
295 ); | |
296 } | |
297 } | |
298 } | |
299 | |
300 | |
301 /** | |
302 * @param locale | |
303 * @see de.intevation.gnv.chart.AbstractXYLineChart#localizeDomainAxis(Axis, | |
304 * Locale) | |
305 */ | |
306 protected void localizeDomainAxis(Axis axis, Locale locale) { | |
307 ((ValueAxis)axis).setStandardTickUnits(createStandardDateTickUnits( | |
308 TimeZone.getDefault(), | |
309 locale)); | |
310 } | |
311 | |
312 | |
313 /** | |
314 * @param zone | |
315 * @param locale | |
316 * @return TickUnitSource | |
317 * @see org.jfree.chart.axis.DateAxis#createStandardDateTickUnits(TimeZone, | |
318 * Locale) | |
319 */ | |
320 public static TickUnitSource createStandardDateTickUnits( | |
321 TimeZone zone, | |
322 Locale locale) | |
323 { | |
324 /* | |
325 * This method have been copied from JFreeChart's DateAxis class. | |
326 * DateFormat objects are hard coded in DateAxis and cannot be adjusted. | |
327 */ | |
328 if (zone == null) { | |
329 throw new IllegalArgumentException("Null 'zone' argument."); | |
330 } | |
331 if (locale == null) { | |
332 throw new IllegalArgumentException("Null 'locale' argument."); | |
333 } | |
334 TickUnits units = new TickUnits(); | |
335 | |
336 // date formatters | |
337 DateFormat f1 = new SimpleDateFormat("HH:mm:ss.SSS", locale); | |
338 DateFormat f2 = new SimpleDateFormat("HH:mm:ss", locale); | |
339 DateFormat f3 = new SimpleDateFormat("HH:mm", locale); | |
340 DateFormat f4 = new SimpleDateFormat("d-MMM, HH:mm", locale); | |
341 DateFormat f5 = new SimpleDateFormat("d-MMM yyyy", locale); | |
342 DateFormat f6 = new SimpleDateFormat("MMM-yyyy", locale); | |
343 DateFormat f7 = new SimpleDateFormat("yyyy", locale); | |
344 | |
345 f1.setTimeZone(zone); | |
346 f2.setTimeZone(zone); | |
347 f3.setTimeZone(zone); | |
348 f4.setTimeZone(zone); | |
349 f5.setTimeZone(zone); | |
350 f6.setTimeZone(zone); | |
351 f7.setTimeZone(zone); | |
352 | |
353 // milliseconds | |
354 units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 1, f1)); | |
355 units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 5, | |
356 DateTickUnitType.MILLISECOND, 1, f1)); | |
357 units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 10, | |
358 DateTickUnitType.MILLISECOND, 1, f1)); | |
359 units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 25, | |
360 DateTickUnitType.MILLISECOND, 5, f1)); | |
361 units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 50, | |
362 DateTickUnitType.MILLISECOND, 10, f1)); | |
363 units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 100, | |
364 DateTickUnitType.MILLISECOND, 10, f1)); | |
365 units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 250, | |
366 DateTickUnitType.MILLISECOND, 10, f1)); | |
367 units.add(new DateTickUnit(DateTickUnitType.MILLISECOND, 500, | |
368 DateTickUnitType.MILLISECOND, 50, f1)); | |
369 | |
370 // seconds | |
371 units.add(new DateTickUnit(DateTickUnitType.SECOND, 1, | |
372 DateTickUnitType.MILLISECOND, 50, f2)); | |
373 units.add(new DateTickUnit(DateTickUnitType.SECOND, 5, | |
374 DateTickUnitType.SECOND, 1, f2)); | |
375 units.add(new DateTickUnit(DateTickUnitType.SECOND, 10, | |
376 DateTickUnitType.SECOND, 1, f2)); | |
377 units.add(new DateTickUnit(DateTickUnitType.SECOND, 30, | |
378 DateTickUnitType.SECOND, 5, f2)); | |
379 | |
380 // minutes | |
381 units.add(new DateTickUnit(DateTickUnitType.MINUTE, 1, | |
382 DateTickUnitType.SECOND, 5, f3)); | |
383 units.add(new DateTickUnit(DateTickUnitType.MINUTE, 2, | |
384 DateTickUnitType.SECOND, 10, f3)); | |
385 units.add(new DateTickUnit(DateTickUnitType.MINUTE, 5, | |
386 DateTickUnitType.MINUTE, 1, f3)); | |
387 units.add(new DateTickUnit(DateTickUnitType.MINUTE, 10, | |
388 DateTickUnitType.MINUTE, 1, f3)); | |
389 units.add(new DateTickUnit(DateTickUnitType.MINUTE, 15, | |
390 DateTickUnitType.MINUTE, 5, f3)); | |
391 units.add(new DateTickUnit(DateTickUnitType.MINUTE, 20, | |
392 DateTickUnitType.MINUTE, 5, f3)); | |
393 units.add(new DateTickUnit(DateTickUnitType.MINUTE, 30, | |
394 DateTickUnitType.MINUTE, 5, f3)); | |
395 | |
396 // hours | |
397 units.add(new DateTickUnit(DateTickUnitType.HOUR, 1, | |
398 DateTickUnitType.MINUTE, 5, f3)); | |
399 units.add(new DateTickUnit(DateTickUnitType.HOUR, 2, | |
400 DateTickUnitType.MINUTE, 10, f3)); | |
401 units.add(new DateTickUnit(DateTickUnitType.HOUR, 4, | |
402 DateTickUnitType.MINUTE, 30, f3)); | |
403 units.add(new DateTickUnit(DateTickUnitType.HOUR, 6, | |
404 DateTickUnitType.HOUR, 1, f3)); | |
405 units.add(new DateTickUnit(DateTickUnitType.HOUR, 12, | |
406 DateTickUnitType.HOUR, 1, f4)); | |
407 | |
408 // days | |
409 units.add(new DateTickUnit(DateTickUnitType.DAY, 1, | |
410 DateTickUnitType.HOUR, 1, f5)); | |
411 units.add(new DateTickUnit(DateTickUnitType.DAY, 2, | |
412 DateTickUnitType.HOUR, 1, f5)); | |
413 units.add(new DateTickUnit(DateTickUnitType.DAY, 7, | |
414 DateTickUnitType.DAY, 1, f5)); | |
415 units.add(new DateTickUnit(DateTickUnitType.DAY, 15, | |
416 DateTickUnitType.DAY, 1, f5)); | |
417 | |
418 // months | |
419 units.add(new DateTickUnit(DateTickUnitType.MONTH, 1, | |
420 DateTickUnitType.DAY, 1, f6)); | |
421 units.add(new DateTickUnit(DateTickUnitType.MONTH, 2, | |
422 DateTickUnitType.DAY, 1, f6)); | |
423 units.add(new DateTickUnit(DateTickUnitType.MONTH, 3, | |
424 DateTickUnitType.MONTH, 1, f6)); | |
425 units.add(new DateTickUnit(DateTickUnitType.MONTH, 4, | |
426 DateTickUnitType.MONTH, 1, f6)); | |
427 units.add(new DateTickUnit(DateTickUnitType.MONTH, 6, | |
428 DateTickUnitType.MONTH, 1, f6)); | |
429 | |
430 // years | |
431 units.add(new DateTickUnit(DateTickUnitType.YEAR, 1, | |
432 DateTickUnitType.MONTH, 1, f7)); | |
433 units.add(new DateTickUnit(DateTickUnitType.YEAR, 2, | |
434 DateTickUnitType.MONTH, 3, f7)); | |
435 units.add(new DateTickUnit(DateTickUnitType.YEAR, 5, | |
436 DateTickUnitType.YEAR, 1, f7)); | |
437 units.add(new DateTickUnit(DateTickUnitType.YEAR, 10, | |
438 DateTickUnitType.YEAR, 1, f7)); | |
439 units.add(new DateTickUnit(DateTickUnitType.YEAR, 25, | |
440 DateTickUnitType.YEAR, 5, f7)); | |
441 units.add(new DateTickUnit(DateTickUnitType.YEAR, 50, | |
442 DateTickUnitType.YEAR, 10, f7)); | |
443 units.add(new DateTickUnit(DateTickUnitType.YEAR, 100, | |
444 DateTickUnitType.YEAR, 20, f7)); | |
445 | |
446 return units; | |
447 } | |
448 | |
449 | |
450 /** | |
451 * Method to get a message from resource bundle. | |
452 * | |
453 * @param locale Locale used to specify the resource bundle. | |
454 * @param key Key to specify the required message. | |
455 * @param def Default string if resource is not existing. | |
456 * | |
457 * @return Message | |
458 */ | |
459 protected String getMessage(Locale locale, String key, String def) { | |
460 return RessourceFactory.getInstance().getRessource(locale, key, def); | |
461 } | |
462 | |
463 | |
464 /** | |
465 * @see de.intevation.gnv.chart.AbstractXYLineChart#createSeriesName(String, | |
466 * String, String) | |
467 */ | |
468 protected String createSeriesName( | |
469 String breakPoint1, | |
470 String breakPoint2, | |
471 String breakPoint3 | |
472 ) { | |
473 log.debug("create seriesname of timeseries chart"); | |
474 return findValueTitle(parameters, breakPoint1) + | |
475 " " + | |
476 findValueTitle(measurements, breakPoint2) + | |
477 "m"; | |
478 } | |
479 | |
480 | |
481 /** | |
482 * Method to add gaps between two data points. The max valid space between | |
483 * two data points is calculated by <code>calculateGapSize</code>. | |
484 * | |
485 * @param results All data points in this dataset. | |
486 * @param series Series to be processed. | |
487 * @param startDate Date item where the scan for gaps should begin. | |
488 * @param endDate Date item where the scan should end. | |
489 * @param startPos Start position of this series in <code>results</code>. | |
490 * @param endPos End position of a series in <code>results</code> | |
491 */ | |
492 protected void addGaps( | |
493 Result[] results, | |
494 Series series, | |
495 Date startDate, | |
496 Date endDate, | |
497 int startPos, | |
498 int endPos | |
499 ) { | |
500 int gapID = results[startPos].getInteger("GAPID"); | |
501 long maxDiff = calculateGapSize( | |
502 startDate, endDate, startPos, endPos, gapID | |
503 ); | |
504 | |
505 if (log.isDebugEnabled()) { | |
506 log.debug("*****************************************************"); | |
507 log.debug("Values of gap detection."); | |
508 log.debug("Start date: " + startDate.toString()); | |
509 log.debug("End date: " + endDate.toString()); | |
510 long diff = endDate.getTime() - startDate.getTime(); | |
511 log.debug("Time difference (in ms): " + diff); | |
512 log.debug("Time difference (in h): " + (diff/(1000*60*60))); | |
513 log.debug("Configured gap size (in %): " + GAP_SIZE); | |
514 log.debug("Calculated gap size (in ms): " + maxDiff); | |
515 log.debug("Calculated gap size (in h): " + (maxDiff/(1000*60*60))); | |
516 log.debug("*****************************************************"); | |
517 } | |
518 | |
519 Date last = startDate; | |
520 for (int i = startPos+1; i < endPos; i++) { | |
521 Result res = results[i]; | |
522 Date now = res.getDate("XORDINATE"); | |
523 | |
524 if ((now.getTime() - last.getTime()) > maxDiff) { | |
525 // add gap, add 1 minute to last date and add null value | |
526 log.info( | |
527 "Gap between " + | |
528 last.toString() + " and " + now.toString() | |
529 ); | |
530 last.setTime(last.getTime() + 60000); | |
531 ((TimeSeries) series).addOrUpdate(new Minute(last), null); | |
532 } | |
533 | |
534 last = now; | |
535 } | |
536 } | |
537 | |
538 | |
539 /** | |
540 * Method to calculate the max space between two data points. | |
541 * | |
542 * @param start First date | |
543 * @param end Last date | |
544 * @param startPos Start position of the current series in the collection | |
545 * containing the bunch of series. | |
546 * @param endPos End position of the current series in the collection | |
547 * containing the bunch of series. | |
548 * @param gapID Gap id used to specify the time intervals. | |
549 * | |
550 * @return Min size of a gap. | |
551 */ | |
552 protected long calculateGapSize( | |
553 Date start, | |
554 Date end, | |
555 int startPos, | |
556 int endPos, | |
557 int gapID | |
558 ){ | |
559 long maxGap = (end.getTime() - start.getTime()) / 100 * GAP_SIZE; | |
560 long interval = getTimeGapValue(start, end, startPos, endPos, gapID); | |
561 | |
562 if (maxGap < interval) | |
563 maxGap = interval + 10; | |
564 | |
565 return maxGap; | |
566 } | |
567 | |
568 | |
569 /** | |
570 * Determine the interval size between two data points. | |
571 * | |
572 * @param dStart Start date | |
573 * @param dEnd End date | |
574 * @param pStart Index of start point in series used to specify the total | |
575 * amount of date items. | |
576 * @param pEnd Index of end point in series used to specify the total amount | |
577 * of date items. | |
578 * @param gapID Gap id used to determine gaps configured in a xml document. | |
579 * | |
580 * @return Interval size between two data points. | |
581 */ | |
582 protected long getTimeGapValue( | |
583 Date dStart, | |
584 Date dEnd, | |
585 int pStart, | |
586 int pEnd, | |
587 int gapID | |
588 ){ | |
589 long gap = 0; | |
590 | |
591 if (gapID < 0 || gapID >= 99) { | |
592 | |
593 if (gapID == -1) { | |
594 // no gaps in meshes | |
595 gap = NO_TIME_GAP; | |
596 } | |
597 else if (pEnd-pStart < 60) { | |
598 gap = (3/(pEnd-pStart)) * (dEnd.getTime() - dStart.getTime()); | |
599 } | |
600 } | |
601 else{ | |
602 Iterator it = timeGaps.iterator(); | |
603 | |
604 while (it.hasNext()) { | |
605 TimeGap tempTimeGap = (TimeGap) it.next(); | |
606 | |
607 if (tempTimeGap.getKey() == gapID){ | |
608 String unit = tempTimeGap.getUnit(); | |
609 int gapValue = tempTimeGap.getValue(); | |
610 | |
611 if (unit.equals(TimeGap.TIME_UNIT_MINUTE)) { | |
612 gap = gapValue * TimeGap.MINUTE_IN_MILLIS; | |
613 } | |
614 else if (unit.equals(TimeGap.TIME_UNIT_HOUR)) { | |
615 gap = gapValue * TimeGap.HOUR_IN_MILLIS; | |
616 } | |
617 else if (unit.equals(TimeGap.TIME_UNIT_DAY)) { | |
618 gap = gapValue * TimeGap.DAY_IN_MILLIS; | |
619 } | |
620 else if (unit.equals(TimeGap.TIME_UNIT_WEEK)) { | |
621 gap = gapValue * TimeGap.WEEK_IN_MILLIS; | |
622 } | |
623 else if (unit.equals(TimeGap.TIME_UNIT_MONTH)) { | |
624 gap = gapValue * (TimeGap.DAY_IN_MILLIS *30); | |
625 } | |
626 else if (unit.equals(TimeGap.TIME_UNIT_YEAR)) { | |
627 gap = gapValue * (TimeGap.DAY_IN_MILLIS *365); | |
628 } | |
629 break; | |
630 } | |
631 } | |
632 } | |
633 | |
634 return gap; | |
635 } | |
636 } | |
637 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 : |