ingo@298: package de.intevation.gnv.chart; ingo@298: ingo@315: import java.text.DateFormat; ingo@315: import java.text.SimpleDateFormat; ingo@298: import java.util.Collection; ingo@298: import java.util.Iterator; ingo@298: import java.util.Locale; ingo@298: ingo@298: import org.apache.log4j.Logger; ingo@298: ingo@298: import org.jfree.chart.ChartTheme; ingo@312: import org.jfree.chart.ChartFactory; ingo@312: import org.jfree.chart.JFreeChart; ingo@315: import org.jfree.chart.axis.Axis; ingo@315: import org.jfree.chart.axis.DateAxis; ingo@298: import org.jfree.chart.plot.XYPlot; ingo@298: import org.jfree.chart.plot.PlotOrientation; ingo@298: import org.jfree.data.general.Series; ingo@298: import org.jfree.data.time.TimeSeries; ingo@298: import org.jfree.data.time.Minute; ingo@298: import org.jfree.data.time.TimeSeriesCollection; ingo@298: ingo@298: import de.intevation.gnv.geobackend.base.Result; ingo@298: ingo@298: ingo@298: /** ingo@298: * @author Ingo Weinzierl ingo@298: */ ingo@298: public class TimeSeriesChart ingo@298: extends AbstractXYLineChart ingo@298: { ingo@298: ingo@315: private static final String DATE_FORMAT = "dd-MMM"; ingo@315: ingo@298: private static Logger log = Logger.getLogger(TimeSeriesChart.class); ingo@298: ingo@298: ingo@298: public TimeSeriesChart( ingo@298: ChartLabels labels, ingo@298: ChartTheme theme, ingo@298: Collection parameters, ingo@298: Collection measurements, ingo@310: Collection dates, ingo@298: Collection result, ingo@310: Collection timeGaps, ingo@298: Locale locale ingo@298: ) { ingo@298: this.labels = labels; ingo@298: this.theme = theme; ingo@298: this.parameters = parameters; ingo@298: this.measurements = measurements; ingo@310: this.dates = dates; ingo@298: this.resultSet = result; ingo@310: this.timeGaps = timeGaps; ingo@298: this.locale = locale; ingo@298: this.PLOT_ORIENTATION = PlotOrientation.VERTICAL; ingo@298: } ingo@298: ingo@298: ingo@312: public JFreeChart generateChart() { ingo@312: log.debug("generate timeseries chart"); ingo@312: ingo@312: if (chart != null) ingo@312: return chart; ingo@312: ingo@312: chart = ChartFactory.createTimeSeriesChart( ingo@312: labels.getTitle(), ingo@312: labels.getDomainAxisLabel(), ingo@312: null, ingo@312: null, ingo@312: true, ingo@312: false, ingo@312: false ingo@312: ); ingo@312: ingo@312: theme.apply(chart); ingo@312: initData(); ingo@312: ingo@312: return chart; ingo@312: } ingo@312: ingo@312: ingo@298: protected void initData() { ingo@298: log.debug("init data for timeseries chart"); ingo@298: ingo@298: String breakPoint1 = null; ingo@298: String breakPoint2 = null; ingo@298: String breakPoint3 = null; ingo@298: ingo@298: Iterator iter = resultSet.iterator(); ingo@298: Result row = null; ingo@298: String seriesName = null; ingo@298: TimeSeries series = null; ingo@298: ingo@298: int idx = 0; ingo@298: ingo@298: while (iter.hasNext()) { ingo@298: row = (Result) iter.next(); ingo@298: ingo@298: // add current data to plot and prepare for next one ingo@298: if (!row.getString("GROUP1").equals(breakPoint1) || ingo@298: !row.getString("GROUP2").equals(breakPoint2) || ingo@298: !row.getString("GROUP3").equals(breakPoint3) ingo@298: ) { ingo@298: log.debug("prepare data/plot for next dataset"); ingo@298: ingo@298: if(series != null) { ingo@298: addSeries(series, idx); ingo@298: prepareAxis(((String)series.getKey()), idx++); ingo@298: } ingo@298: ingo@298: // prepare variables for next plot ingo@298: breakPoint1 = row.getString("GROUP1"); ingo@298: breakPoint2 = row.getString("GROUP2"); ingo@298: breakPoint3 = row.getString("GROUP3"); ingo@298: ingo@298: seriesName = createSeriesName( ingo@298: breakPoint1, ingo@298: breakPoint2, ingo@298: breakPoint3 ingo@298: ); ingo@298: ingo@298: log.debug("next dataset is '" + seriesName + "'"); ingo@298: series = new TimeSeries(seriesName, Minute.class); ingo@298: } ingo@298: ingo@298: addValue(row, series); ingo@298: } ingo@298: ingo@298: // add the last dataset if existing to plot and prepare its axis ingo@298: addSeries(series, idx); ingo@310: ingo@310: if (series != null) ingo@310: prepareAxis(((String)series.getKey()), idx++); ingo@298: } ingo@298: ingo@298: ingo@298: protected void addValue(Result row, Series series) { ingo@298: // TODO look for gaps between two values ingo@298: ((TimeSeries) series).addOrUpdate( ingo@298: new Minute(row.getDate("XORDINATE")), ingo@298: row.getDouble("YORDINATE") ingo@298: ); ingo@298: } ingo@298: ingo@298: ingo@298: protected void addSeries(Series series, int idx) { ingo@298: log.debug("add series to timeseries chart"); ingo@298: XYPlot plot = chart.getXYPlot(); ingo@298: ingo@298: if (series == null) { ingo@298: log.warn("no data to add"); ingo@298: return; ingo@298: } ingo@298: ingo@298: TimeSeriesCollection tsc = new TimeSeriesCollection((TimeSeries)series); ingo@298: plot.setDataset(idx, tsc); ingo@298: } ingo@298: ingo@298: ingo@315: protected void localizeDomainAxis(Axis axis, Locale locale) { ingo@315: if (locale == null) ingo@315: return; ingo@315: ingo@315: log.debug( ingo@315: "Set language of axis [" + axis.getLabel() + "] " + ingo@315: "to " + locale.toString() ingo@315: ); ingo@315: ingo@315: DateFormat format = new SimpleDateFormat(DATE_FORMAT, locale); ingo@315: ((DateAxis) axis).setDateFormatOverride(format); ingo@315: } ingo@315: ingo@315: ingo@298: protected String createSeriesName( ingo@298: String breakPoint1, ingo@298: String breakPoint2, ingo@298: String breakPoint3 ingo@298: ) { ingo@298: log.debug("create seriesname of timeseries chart"); ingo@298: return findValueTitle(parameters, breakPoint1) + ingo@298: " " + ingo@298: findValueTitle(measurements, breakPoint2) + ingo@298: "m"; ingo@298: } ingo@298: } ingo@315: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :