ingo@385: package de.intevation.flys.exports; ingo@385: ingo@420: import java.awt.Color; ingo@420: ingo@385: import org.w3c.dom.Document; ingo@385: ingo@385: import org.apache.log4j.Logger; ingo@385: ingo@385: import org.jfree.chart.JFreeChart; ingo@385: import org.jfree.chart.axis.NumberAxis; ingo@385: import org.jfree.chart.plot.XYPlot; ingo@420: import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; ingo@414: import org.jfree.chart.title.TextTitle; ingo@385: import org.jfree.data.xy.XYSeries; ingo@385: import org.jfree.data.xy.XYSeriesCollection; ingo@385: ingo@385: import de.intevation.artifacts.Artifact; ingo@385: ingo@695: import de.intevation.artifactdatabase.state.Facet; ingo@695: ingo@696: import de.intevation.flys.artifacts.FLYSArtifact; ingo@696: import de.intevation.flys.artifacts.model.FacetTypes; ingo@385: import de.intevation.flys.artifacts.model.WQDay; ingo@686: import de.intevation.flys.artifacts.resources.Resources; ingo@385: ingo@385: ingo@385: /** ingo@385: * An OutGenerator that generates duration curves. ingo@385: * ingo@385: * @author Ingo Weinzierl ingo@385: */ ingo@696: public class DurationCurveGenerator ingo@696: extends XYChartGenerator ingo@696: implements FacetTypes ingo@696: { ingo@385: private static Logger logger = ingo@385: Logger.getLogger(DurationCurveGenerator.class); ingo@385: ingo@385: /** The storage for the W series to be drawn in this chart.*/ ingo@385: protected XYSeriesCollection w; ingo@385: ingo@385: /** The storage for the Q series to be drawn in this chart.*/ ingo@385: protected XYSeriesCollection q; ingo@385: ingo@385: ingo@696: public static final String I18N_DURATION_W = ingo@696: "chart.duration.curve.curve.w"; ingo@385: ingo@696: public static final String I18N_DURATION_Q = ingo@696: "chart.duration.curve.curve.q"; ingo@385: ingo@408: public static final String I18N_CHART_TITLE = ingo@408: "chart.duration.curve.title"; ingo@408: ingo@414: public static final String I18N_CHART_SUBTITLE = ingo@414: "chart.duration.curve.subtitle"; ingo@414: ingo@408: public static final String I18N_XAXIS_LABEL = ingo@408: "chart.duration.curve.xaxis.label"; ingo@408: ingo@408: public static final String I18N_YAXIS_LABEL = ingo@408: "chart.duration.curve.yaxis.label"; ingo@408: ingo@408: public static final String I18N_CHART_TITLE_DEFAULT = ingo@408: "Dauerlinie"; ingo@408: ingo@408: public static final String I18N_XAXIS_LABEL_DEFAULT = ingo@408: "Unterschreitungsdauer [Tage]"; ingo@408: ingo@408: public static final String I18N_YAXIS_LABEL_DEFAULT = ingo@408: "W [NN + m]"; ingo@408: ingo@385: ingo@385: public DurationCurveGenerator() { ingo@385: super(); ingo@385: ingo@385: this.w = new XYSeriesCollection(); ingo@385: this.q = new XYSeriesCollection(); ingo@385: } ingo@385: ingo@385: ingo@385: protected String getChartTitle() { ingo@408: return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT); ingo@385: } ingo@385: ingo@385: ingo@414: @Override ingo@414: protected void addSubtitles(JFreeChart chart) { ingo@414: double[] dist = getRange(); ingo@414: ingo@414: Object[] args = new Object[] { ingo@414: getRiverName(), ingo@414: dist[0] ingo@414: }; ingo@414: ingo@414: String subtitle = msg(I18N_CHART_SUBTITLE, "", args); ingo@414: chart.addSubtitle(new TextTitle(subtitle)); ingo@414: } ingo@414: ingo@414: ingo@385: protected String getXAxisLabel() { ingo@408: return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT); ingo@385: } ingo@385: ingo@385: ingo@385: protected String getYAxisLabel() { ingo@408: return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT); ingo@385: } ingo@385: ingo@385: ingo@385: public void addDatasets(JFreeChart chart) { ingo@385: XYPlot plot = (XYPlot) chart.getPlot(); ingo@385: ingo@385: plot.setDataset(0, w); ingo@385: plot.setDataset(1, q); ingo@385: } ingo@385: ingo@385: ingo@420: protected void adjustPlot(XYPlot plot) { ingo@420: super.adjustPlot(plot); ingo@420: ingo@420: // TODO REMOVE THIS CODE, IF WE HAVE INTRODUCED THEMES! ingo@420: XYLineAndShapeRenderer rw = (XYLineAndShapeRenderer) ingo@420: plot.getRendererForDataset(w); ingo@420: ingo@420: XYLineAndShapeRenderer rq = null; ingo@420: try { ingo@420: rq = (XYLineAndShapeRenderer) rw.clone(); ingo@420: } ingo@420: catch (Exception e) { ingo@420: logger.error(e, e); ingo@420: } ingo@420: ingo@420: int wNum = w.getSeriesCount(); ingo@420: int qNum = q.getSeriesCount(); ingo@420: ingo@420: for (int i = 0; i < wNum; i++) { ingo@420: rw.setSeriesPaint(i, Color.BLUE); ingo@420: } ingo@420: ingo@420: for (int i = 0; i < qNum; i++) { ingo@420: rq.setSeriesPaint(i, Color.GREEN); ingo@420: } ingo@420: ingo@420: plot.setRenderer(0, rw); ingo@420: plot.setRenderer(1, rq); ingo@420: } ingo@420: ingo@420: ingo@385: protected void adjustAxes(XYPlot plot) { ingo@385: super.adjustAxes(plot); ingo@385: sascha@665: NumberAxis qAxis = new NumberAxis("Q [m\u00b3/s]"); ingo@385: ingo@686: plot.setRangeAxis(1, qAxis); ingo@686: plot.mapDatasetToRangeAxis(1, 1); ingo@385: } ingo@385: ingo@385: ingo@695: @Override ingo@695: public void doOut(Artifact artifact, Facet facet, Document attr) { ingo@696: String name = facet != null ? facet.getName() : null; ingo@385: ingo@695: logger.debug("DurationCurveGenerator.doOut: " + name); ingo@695: ingo@695: if (name == null || name.length() == 0) { ingo@385: logger.error("No facet given. Cannot create dataset."); ingo@385: return; ingo@385: } ingo@385: ingo@696: FLYSArtifact flys = (FLYSArtifact) artifact; ingo@696: Facet f = flys.getNativeFacet(facet); ingo@686: ingo@696: if (name.equals(DURATION_W)) { ingo@696: doWOut((WQDay) f.getData(artifact, context)); ingo@385: } ingo@696: else if (name.equals(DURATION_Q)) { ingo@696: doQOut((WQDay) f.getData(artifact, context)); ingo@385: } ingo@385: else { ingo@695: logger.warn("Unknown facet name: " + name); ingo@385: return; ingo@385: } ingo@385: } ingo@385: ingo@385: ingo@385: /** ingo@385: * Creates the series for a duration curve's W facet. ingo@385: * ingo@385: * @param wqdays The WQDay store that contains the Ws. ingo@686: * @param river The name of the river. ingo@385: */ ingo@696: protected void doWOut(WQDay wqdays) { ingo@385: logger.debug("DurationCurveGenerator.doWOut"); ingo@385: ingo@385: // TODO find the correct series name ingo@686: XYSeries series = new XYSeries( ingo@696: getSeriesName(getRiverName(), DURATION_W)); ingo@385: ingo@385: int size = wqdays.size(); ingo@385: for (int i = 0; i < size; i++) { ingo@385: int day = wqdays.getDay(i); ingo@385: double w = wqdays.getW(i); ingo@385: ingo@385: series.add((double) day, w); ingo@385: } ingo@385: ingo@385: this.w.addSeries(series); ingo@385: } ingo@385: ingo@385: ingo@385: /** ingo@385: * Creates the series for a duration curve's Q facet. ingo@385: * ingo@385: * @param wqdays The WQDay store that contains the Qs. ingo@686: * @param river The name of the river. ingo@385: */ ingo@696: protected void doQOut(WQDay wqdays) { ingo@385: logger.debug("DurationCurveGenerator.doQOut"); ingo@385: ingo@385: // TODO find the correct series name ingo@686: XYSeries series = new XYSeries( ingo@696: getSeriesName(getRiverName(), DURATION_Q)); ingo@385: ingo@385: int size = wqdays.size(); ingo@385: for (int i = 0; i < size; i++) { ingo@385: int day = wqdays.getDay(i); ingo@385: double q = wqdays.getQ(i); ingo@385: ingo@385: series.add((double) day, q); ingo@385: } ingo@385: ingo@385: this.q.addSeries(series); ingo@385: } ingo@385: ingo@385: ingo@686: protected String getSeriesName(String river, String type) { ingo@686: Object[] args = new Object[] { river }; ingo@686: ingo@686: if (type == null || type.length() == 0) { ingo@686: logger.warn("No duration curve type given."); ingo@686: return "n/a"; ingo@686: } ingo@696: else if (type.equals(DURATION_W)) { ingo@686: return Resources.getMsg( ingo@686: context.getMeta(), ingo@686: I18N_DURATION_W, ingo@686: "W", ingo@686: args); ingo@686: } ingo@696: else if (type.equals(DURATION_Q)) { ingo@686: return Resources.getMsg( ingo@686: context.getMeta(), ingo@686: I18N_DURATION_Q, ingo@686: "W", ingo@686: args); ingo@686: } ingo@686: ingo@686: logger.warn("Could not determine chart curve type: " + type); ingo@686: return type; ingo@686: } ingo@385: } ingo@385: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :