ingo@359: package de.intevation.flys.exports; ingo@359: ingo@420: import java.awt.Color; ingo@420: ingo@359: import org.apache.log4j.Logger; ingo@359: ingo@375: import org.jfree.chart.JFreeChart; ingo@375: import org.jfree.chart.axis.NumberAxis; ingo@422: import org.jfree.chart.axis.ValueAxis; ingo@375: import org.jfree.chart.plot.XYPlot; ingo@420: import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; ingo@414: import org.jfree.chart.title.TextTitle; ingo@369: import org.jfree.data.xy.XYSeries; ingo@369: import org.jfree.data.xy.XYSeriesCollection; ingo@364: ingo@359: import org.w3c.dom.Document; ingo@359: ingo@359: import de.intevation.artifacts.Artifact; ingo@359: ingo@695: import de.intevation.artifactdatabase.state.Facet; ingo@695: ingo@422: import de.intevation.flys.model.River; ingo@422: ingo@422: import de.intevation.flys.artifacts.FLYSArtifact; sascha@706: ingo@696: import de.intevation.flys.artifacts.model.FacetTypes; ingo@364: import de.intevation.flys.artifacts.model.WQKms; ingo@364: ingo@359: ingo@359: /** ingo@359: * An OutGenerator that generates discharge curves. ingo@359: * ingo@359: * @author Ingo Weinzierl ingo@359: */ ingo@696: public class LongitudinalSectionGenerator ingo@696: extends XYChartGenerator ingo@696: implements FacetTypes ingo@696: { ingo@359: /** The logger that is used in this generator.*/ ingo@359: private static Logger logger = ingo@359: Logger.getLogger(LongitudinalSectionGenerator.class); ingo@359: ingo@408: public static final String I18N_CHART_TITLE = ingo@408: "chart.longitudinal.section.title"; ingo@408: ingo@414: public static final String I18N_CHART_SUBTITLE = ingo@414: "chart.longitudinal.section.subtitle"; ingo@414: ingo@408: public static final String I18N_XAXIS_LABEL = ingo@408: "chart.longitudinal.section.xaxis.label"; ingo@408: ingo@408: public static final String I18N_YAXIS_LABEL = ingo@408: "chart.longitudinal.section.yaxis.label"; ingo@408: ingo@408: public static final String I18N_2YAXIS_LABEL = ingo@408: "chart.longitudinal.section.yaxis.second.label"; ingo@408: sascha@664: public static final String I18N_CHART_TITLE_DEFAULT = "W-L\u00e4ngsschnitt"; ingo@408: public static final String I18N_XAXIS_LABEL_DEFAULT = "km"; ingo@408: public static final String I18N_YAXIS_LABEL_DEFAULT = "W [NN + m]"; sascha@664: public static final String I18N_2YAXIS_LABEL_DEFAULT = "Q [m\u00b3/s]"; ingo@369: ingo@375: /** The storage for the W series to be drawn in this chart.*/ ingo@375: protected XYSeriesCollection w; ingo@375: ingo@375: /** The storage for the Q series to be drawn in this chart.*/ ingo@375: protected XYSeriesCollection q; ingo@364: ingo@364: ingo@359: public LongitudinalSectionGenerator() { ingo@359: super(); ingo@364: ingo@375: this.w = new XYSeriesCollection(); ingo@375: this.q = new XYSeriesCollection(); ingo@369: } ingo@369: ingo@369: ingo@369: protected String getChartTitle() { ingo@408: return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT); ingo@369: } ingo@369: ingo@369: 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: dist[1] 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@369: protected String getXAxisLabel() { ingo@408: return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT); ingo@369: } ingo@369: ingo@369: ingo@369: protected String getYAxisLabel() { ingo@408: return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT); ingo@369: } ingo@369: ingo@369: sascha@719: @Override ingo@375: protected void addDatasets(JFreeChart chart) { ingo@375: XYPlot plot = (XYPlot) chart.getPlot(); ingo@375: ingo@375: plot.setDataset(0, w); ingo@375: plot.setDataset(1, q); ingo@375: } ingo@375: ingo@375: 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@375: protected void adjustAxes(XYPlot plot) { ingo@375: super.adjustAxes(plot); ingo@375: ingo@408: NumberAxis qAxis = new NumberAxis( ingo@408: msg(I18N_2YAXIS_LABEL, I18N_2YAXIS_LABEL_DEFAULT)); ingo@375: ingo@666: plot.setRangeAxis(1, qAxis); ingo@666: plot.mapDatasetToRangeAxis(1, 1); ingo@422: ingo@422: invertXAxis(plot.getDomainAxis()); ingo@422: } ingo@422: ingo@422: ingo@422: /** ingo@422: * This method inverts the x-axis based on the kilometer information of the ingo@422: * selected river. If the head of the river is at kilometer 0, the axis is ingo@422: * not inverted, otherwise it is. ingo@422: * ingo@422: * @param xaxis The domain axis. ingo@422: */ ingo@422: protected void invertXAxis(ValueAxis xaxis) { ingo@422: FLYSArtifact artifact = (FLYSArtifact) master; ingo@422: River river = artifact.getRiver(); ingo@422: ingo@422: boolean up = river.getKmUp(); ingo@422: ingo@422: if (up) { ingo@422: logger.info("Invert X-Axis."); ingo@422: xaxis.setInverted(true); ingo@422: } ingo@359: } ingo@359: ingo@359: ingo@695: public void doOut(Artifact artifact, Facet facet, Document attr) { ingo@695: String name = facet.getName(); ingo@359: ingo@695: logger.debug("LongitudinalSectionGenerator.doOut: " + name); ingo@695: ingo@695: if (name == null) { ingo@369: logger.error("No facet name for doOut(). No output generated!"); ingo@369: return; ingo@369: } ingo@369: ingo@696: FLYSArtifact flys = (FLYSArtifact) artifact; ingo@696: Facet f = flys.getNativeFacet(facet); ingo@696: ingo@696: if (f == null) { ingo@696: return; ingo@369: } ingo@696: ingo@696: if (name.equals(LONGITUDINAL_W)) { ingo@696: doWOut((WQKms) f.getData(artifact, context)); ingo@696: } ingo@696: else if (name.equals(LONGITUDINAL_Q)) { ingo@696: doQOut((WQKms) f.getData(artifact, context)); ingo@369: } ingo@369: else { ingo@695: logger.warn("Unknown facet name: " + name); ingo@369: return; ingo@369: } ingo@369: } ingo@369: ingo@369: ingo@369: /** ingo@369: * Process the output for W facets in a longitudinal section curve. ingo@369: * ingo@369: * @param wqkms An array of WQKms values. ingo@369: */ ingo@696: protected void doWOut(WQKms wqkms) { ingo@369: logger.debug("LongitudinalSectionGenerator.doWOut"); ingo@359: ingo@696: XYSeries series = new XYSeries(getSeriesName(wqkms, "W")); ingo@369: sascha@719: int size = wqkms.size(); ingo@696: ingo@696: if (logger.isDebugEnabled()) { ingo@696: if (wqkms.size() > 0) { ingo@696: logger.debug("Generate series: " + series.getKey()); ingo@696: logger.debug("Start km: " + wqkms.getKms(0)); ingo@696: logger.debug("End km: " + wqkms.getKms(size-1)); ingo@696: logger.debug("Values : " + size); ingo@369: } ingo@696: } ingo@369: ingo@696: for (int i = 0; i < size; i++) { sascha@719: series.add(wqkms.getKms(i), wqkms.getW(i)); ingo@369: } ingo@696: ingo@696: w.addSeries(series); ingo@369: } ingo@369: ingo@369: ingo@369: /** ingo@369: * Process the output for Q facets in a longitudinal section curve. ingo@369: * ingo@369: * @param wqkms An array of WQKms values. ingo@369: */ ingo@696: protected void doQOut(WQKms wqkms) { ingo@369: logger.debug("LongitudinalSectionGenerator.doQOut"); ingo@369: ingo@696: XYSeries series = new XYSeries(getSeriesName(wqkms, "Q")); ingo@369: sascha@719: int size = wqkms.size(); ingo@369: ingo@696: if (logger.isDebugEnabled()) { ingo@696: if (wqkms.size() > 0) { ingo@696: logger.debug("Generate series: " + series.getKey()); ingo@696: logger.debug("Start km: " + wqkms.getKms(0)); ingo@696: logger.debug("End km: " + wqkms.getKms(size-1)); ingo@696: logger.debug("Values : " + size); ingo@696: } ingo@696: } ingo@369: ingo@696: for (int i = 0; i < size; i++) { sascha@719: series.add(wqkms.getKms(i), wqkms.getQ(i)); ingo@369: } ingo@696: ingo@696: q.addSeries(series); ingo@369: } ingo@369: ingo@369: ingo@448: protected String getSeriesName(WQKms wqkms, String mode) { ingo@448: String name = wqkms.getName(); ingo@448: String prefix = name != null && name.indexOf(mode) >= 0 ? null : mode; ingo@448: ingo@448: return prefix != null && prefix.length() > 0 ingo@448: ? prefix + "(" + name +")" ingo@448: : name; ingo@359: } ingo@359: } ingo@359: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :