ingo@2237: package de.intevation.flys.exports; ingo@2237: ingo@2237: import org.jfree.data.Range; ingo@2237: import org.jfree.data.xy.XYDataset; ingo@2587: import org.jfree.data.xy.XYSeriesCollection; ingo@2394: import org.jfree.data.time.RegularTimePeriod; ingo@2394: import org.jfree.data.time.TimeSeriesCollection; ingo@2394: import org.jfree.data.time.TimeSeries; ingo@2237: ingo@2241: import org.apache.log4j.Logger; ingo@2241: ingo@2394: import de.intevation.flys.jfree.Bounds; ingo@2394: import de.intevation.flys.jfree.DoubleBounds; ingo@2394: import de.intevation.flys.jfree.TimeBounds; ingo@2394: ingo@2237: ingo@2237: /** ingo@2237: * @author Ingo Weinzierl ingo@2237: */ ingo@2237: public class ChartHelper { ingo@2237: ingo@2241: private static final Logger logger = Logger.getLogger(ChartHelper.class); ingo@2241: ingo@2241: ingo@2237: /** ingo@2237: * This method returns the ranges of the XYDataset dataset as array ingo@2237: * with [xrange, yrange]. ingo@2237: * ingo@2237: * @param dataset The dataset which should be evaluated. ingo@2237: * ingo@2237: * @return an array with x and y ranges. ingo@2237: */ ingo@2587: public static Bounds[] getBounds(XYSeriesCollection dataset) { ingo@2241: int seriesCount = dataset != null ? dataset.getSeriesCount() : 0; ingo@2241: ingo@2241: if (seriesCount == 0) { ingo@2241: logger.warn("Dataset is empty or has no Series set."); ingo@2237: return null; ingo@2237: } ingo@2237: ingo@2241: boolean foundValue = false; ingo@2241: ingo@2237: double minX = Double.MAX_VALUE; ingo@2237: double maxX = -Double.MAX_VALUE; ingo@2237: double minY = Double.MAX_VALUE; ingo@2237: double maxY = -Double.MAX_VALUE; ingo@2237: ingo@2241: for (int i = 0, m = seriesCount; i < m; i++) { ingo@2237: for (int j = 0, n = dataset.getItemCount(i); j < n; j++) { ingo@2237: double x = dataset.getXValue(i, j); ingo@2237: double y = dataset.getYValue(i, j); ingo@2237: ingo@2241: if (Double.isNaN(x) || Double.isNaN(y)) { ingo@2241: logger.warn("Item " + j + " in Series " + i + " is broken"); ingo@2241: continue; ingo@2241: } ingo@2241: ingo@2241: foundValue = true; ingo@2241: ingo@2237: if (x < minX) { ingo@2237: minX = x; ingo@2237: } ingo@2237: ingo@2237: if (x > maxX) { ingo@2237: maxX = x; ingo@2237: } ingo@2237: ingo@2237: if (y < minY) { ingo@2237: minY = y; ingo@2237: } ingo@2237: ingo@2237: if (y > maxY) { ingo@2237: maxY = y; ingo@2237: } ingo@2237: } ingo@2237: } ingo@2237: ingo@2241: return foundValue ingo@2587: ? new Bounds[] { ingo@2587: new DoubleBounds(minX, maxX), ingo@2587: new DoubleBounds(minY, maxY) } ingo@2241: : null; ingo@2241: } ingo@2241: ingo@2241: ingo@2587: public static Bounds[] getBounds(XYDataset dataset) { ingo@2587: if (dataset instanceof XYSeriesCollection) { ingo@2587: return getBounds((XYSeriesCollection) dataset); ingo@2587: } ingo@2587: else if(dataset instanceof TimeSeriesCollection) { ingo@2587: return getBounds((TimeSeriesCollection) dataset); ingo@2587: } ingo@2587: else { ingo@2587: logger.warn("Unknown XYDataset instance: " + dataset.getClass()); ingo@2587: return null; ingo@2587: } ingo@2587: } ingo@2587: ingo@2587: ingo@2394: public static Bounds[] getBounds(TimeSeriesCollection collection) { ingo@2394: int seriesCount = collection != null ? collection.getSeriesCount() : 0; ingo@2394: ingo@2394: if (seriesCount == 0) { ingo@2394: logger.warn("TimeSeriesCollection is empty or has no Series set."); ingo@2394: return null; ingo@2394: } ingo@2394: ingo@2394: boolean foundValue = false; ingo@2394: ingo@2394: long lowerX = Long.MAX_VALUE; ingo@2394: long upperX = -Long.MAX_VALUE; ingo@2394: ingo@2394: double lowerY = Double.MAX_VALUE; ingo@2394: double upperY = -Double.MAX_VALUE; ingo@2394: ingo@2394: for (int i = 0, m = seriesCount; i < m; i++) { ingo@2394: TimeSeries series = collection.getSeries(i); ingo@2394: ingo@2394: for (int j = 0, n = collection.getItemCount(i); j < n; j++) { ingo@2394: RegularTimePeriod rtp = series.getTimePeriod(j); ingo@2394: ingo@2394: if (rtp == null) { ingo@2394: continue; ingo@2394: } ingo@2394: ingo@2394: foundValue = true; ingo@2394: ingo@2394: long start = rtp.getFirstMillisecond(); ingo@2394: long end = rtp.getLastMillisecond(); ingo@2394: ingo@2394: if (start < lowerX) { ingo@2394: lowerX = start; ingo@2394: } ingo@2394: ingo@2394: if (end > upperX) { ingo@2394: upperX = end; ingo@2394: } ingo@2394: ingo@2394: double y = series.getValue(j).doubleValue(); ingo@2394: ingo@2394: lowerY = Math.min(lowerY, y); ingo@2394: upperY = Math.max(upperY, y); ingo@2394: } ingo@2394: } ingo@2394: ingo@2394: if (foundValue) { ingo@2394: return new Bounds[] { ingo@2394: new TimeBounds(lowerX, upperX), ingo@2394: new DoubleBounds(lowerY, upperY) ingo@2394: }; ingo@2394: } ingo@2394: ingo@2394: return null; ingo@2394: } ingo@2394: ingo@2394: ingo@2241: /** ingo@2241: * Expand range by percent. ingo@2241: * ingo@2241: * @param range The range to expand. ingo@2241: * @param percent The percentage to expand. ingo@2241: * ingo@2241: * @param an expanded range. ingo@2241: */ ingo@2241: public static Range expandRange(Range range, double percent) { ingo@2241: if (range == null) { ingo@2241: return null; ingo@2241: } ingo@2241: ingo@2241: double value = range.getLowerBound(); ingo@2241: double expand = Math.abs(value / 100 * percent); ingo@2241: ingo@2241: return expand != 0 ingo@2241: ? new Range(value-expand, value+expand) ingo@2241: : new Range(-0.01 * percent, 0.01 * percent); ingo@2237: } ingo@2237: } ingo@2237: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :