ingo@385: package de.intevation.flys.exports; ingo@385: felix@1933: import java.awt.Font; felix@1933: 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@733: import org.jfree.chart.axis.ValueAxis; ingo@385: import org.jfree.chart.plot.XYPlot; ingo@414: import org.jfree.chart.title.TextTitle; ingo@733: import org.jfree.data.Range; ingo@385: import org.jfree.data.xy.XYSeries; ingo@385: ingo@385: import de.intevation.artifacts.Artifact; ingo@385: ingo@695: import de.intevation.artifactdatabase.state.Facet; felix@1944: import de.intevation.artifactdatabase.state.ArtifactAndFacet; 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: felix@1850: import de.intevation.flys.jfree.FLYSAnnotation; felix@1850: 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: { felix@1933: public static enum YAXIS { felix@1933: W(0), felix@1933: Q(1); felix@1933: protected int idx; felix@1933: private YAXIS(int c) { felix@1933: idx = c; felix@1933: } felix@1933: } felix@1933: ingo@385: private static Logger logger = ingo@385: Logger.getLogger(DurationCurveGenerator.class); 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: ingo@385: felix@1933: /** felix@1933: * Create Axis for given index. felix@1933: * @return axis with according internationalized label. felix@1933: */ felix@1933: @Override felix@1933: protected NumberAxis createYAxis(int index) { felix@1933: Font labelFont = new Font("Tahoma", Font.BOLD, 14); felix@1933: String label = "default"; felix@1933: if (index == YAXIS.W.idx) { felix@1933: label = getYAxisLabel(); felix@1933: } felix@1933: else if (index == YAXIS.Q.idx) { felix@1933: // TODO i18n for this label felix@1933: label = "Q [m\u00b3/s]"; felix@1933: //label = msg(get2YAxisLabelKey(), get2YAxisDefaultLabel()); felix@1933: } felix@1933: NumberAxis axis = new NumberAxis(label); felix@1933: axis.setLabelFont(labelFont); felix@1933: return axis; felix@1933: } felix@1933: 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@733: @Override ingo@733: protected boolean zoomX(XYPlot plot, ValueAxis axis, Range range, Range x) { ingo@733: boolean zoomin = super.zoom(plot, axis, range, x); ingo@733: ingo@733: if (!zoomin) { ingo@733: axis.setLowerBound(0d); ingo@733: } ingo@733: ingo@1713: axis.setUpperBound(364); ingo@1713: ingo@733: return zoomin; ingo@733: } ingo@733: ingo@733: ingo@695: @Override ingo@1684: public void doOut( felix@1944: ArtifactAndFacet artifactFacet, felix@1944: Document attr, felix@1944: boolean visible ingo@1684: ) { felix@1944: String name = artifactFacet.getFacetName(); 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: if (name.equals(DURATION_W)) { felix@1944: doWOut((WQDay) artifactFacet.getData(context), attr, visible); ingo@385: } ingo@696: else if (name.equals(DURATION_Q)) { felix@1944: doQOut((WQDay) artifactFacet.getData(context), attr, visible); ingo@385: } felix@1850: else if (name.equals(COMPUTED_DISCHARGE_MAINVALUES_Q) felix@1850: || name.equals(MAINVALUES_Q) felix@1850: || name.equals(COMPUTED_DISCHARGE_MAINVALUES_W) felix@1850: || name.equals(MAINVALUES_W) felix@1850: ) { felix@1850: doAnnotations( felix@1944: (FLYSAnnotation) artifactFacet.getData(context), felix@1944: artifactFacet.getFacet(), attr, visible); felix@1850: } 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@924: * @param theme ingo@385: */ ingo@1684: protected void doWOut(WQDay wqdays, Document theme, boolean visible) { ingo@385: logger.debug("DurationCurveGenerator.doWOut"); ingo@385: ingo@385: // TODO find the correct series name ingo@924: XYSeries series = new StyledXYSeries( ingo@924: getSeriesName(getRiverName(), DURATION_W), theme); 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: felix@1933: addAxisSeries(series, YAXIS.W.idx, visible); 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@924: * @param theme ingo@385: */ ingo@1684: protected void doQOut(WQDay wqdays, Document theme, boolean visible) { ingo@385: logger.debug("DurationCurveGenerator.doQOut"); ingo@385: ingo@385: // TODO find the correct series name ingo@924: XYSeries series = new StyledXYSeries( ingo@924: getSeriesName(getRiverName(), DURATION_Q), theme); 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: felix@1933: addAxisSeries(series, YAXIS.Q.idx, visible); 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: } felix@1931: felix@1931: // MainValue-Annotations should be visualized by a line that goes to the curve itself. ingo@385: } ingo@385: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :