raimund@3131: package de.intevation.flys.exports.fixings; raimund@3131: sascha@3139: import de.intevation.artifactdatabase.state.ArtifactAndFacet; raimund@3131: sascha@3139: import de.intevation.artifacts.ArtifactNamespaceContext; sascha@3139: import de.intevation.artifacts.CallContext; sascha@3139: sascha@3139: import de.intevation.artifacts.common.utils.XMLUtils; sascha@3139: sascha@3139: import de.intevation.flys.artifacts.FLYSArtifact; sascha@3139: sascha@3210: import de.intevation.flys.artifacts.model.DateRange; sascha@3139: import de.intevation.flys.artifacts.model.FacetTypes; sascha@3139: sascha@3139: import de.intevation.flys.artifacts.model.fixings.QWD; sascha@3139: sascha@3139: import de.intevation.flys.exports.TimeseriesChartGenerator; sascha@3139: christian@3212: import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation; christian@3212: import de.intevation.flys.jfree.FLYSAnnotation; sascha@3139: import de.intevation.flys.jfree.StyledTimeSeries; sascha@3139: sascha@3139: import de.intevation.flys.utils.FLYSUtils; sascha@3139: sascha@3139: import java.awt.BasicStroke; raimund@3131: import java.awt.Color; raimund@3131: sascha@3139: import java.io.OutputStream; sascha@3139: christian@3212: import java.util.ArrayList; christian@3212: import java.util.HashMap; christian@3212: import java.util.List; christian@3212: import java.util.Map; christian@3212: import java.util.Set; christian@3212: sascha@3139: import javax.xml.xpath.XPathConstants; raimund@3131: raimund@3131: import org.apache.log4j.Logger; raimund@3131: raimund@3131: import org.jfree.chart.JFreeChart; sascha@3139: christian@3212: import org.jfree.chart.annotations.XYTextAnnotation; christian@3212: sascha@3139: import org.jfree.chart.plot.IntervalMarker; sascha@3139: import org.jfree.chart.plot.ValueMarker; sascha@3139: raimund@3131: import org.jfree.chart.title.TextTitle; raimund@3131: raimund@3131: import org.jfree.data.time.Day; raimund@3131: import org.jfree.data.time.Month; raimund@3131: import org.jfree.data.time.RegularTimePeriod; raimund@3131: import org.jfree.data.time.TimeSeries; raimund@3131: import org.jfree.data.time.TimeSeriesCollection; raimund@3131: sascha@3139: import org.w3c.dom.Document; sascha@3139: import org.w3c.dom.Element; raimund@3131: raimund@3131: /** raimund@3131: * @author Raimund Renkert raimund@3131: */ raimund@3131: public class FixDeltaWtGenerator raimund@3131: extends TimeseriesChartGenerator raimund@3131: implements FacetTypes raimund@3131: { raimund@3131: private static Logger logger = raimund@3131: Logger.getLogger(FixDeltaWtGenerator.class); raimund@3131: raimund@3131: public static final String XPATH_CHART_CURRENTKM = raimund@3131: "/art:action/art:attributes/art:currentKm"; raimund@3131: raimund@3131: public static final String I18N_CHART_TITLE = raimund@3131: "chart.fix.deltawt.title"; raimund@3131: raimund@3131: public static final String I18N_CHART_SUBTITLE = raimund@3131: "chart.fix.deltawt.subtitle"; raimund@3131: raimund@3131: public static final String I18N_XAXIS_LABEL = raimund@3131: "chart.fix.deltawt.xaxis.label"; raimund@3131: raimund@3131: public static final String I18N_YAXIS_LABEL = raimund@3131: "chart.fix.deltawt.yaxis.label"; raimund@3131: raimund@3131: public static final String I18N_YAXIS_SECOND_LABEL = raimund@3131: "chart.fix.deltawt.yaxis.second.label"; raimund@3131: raimund@3131: raimund@3131: public static enum YAXIS { raimund@3131: dW(0); raimund@3131: protected int idx; raimund@3131: private YAXIS(int c) { raimund@3131: idx = c; raimund@3131: } raimund@3131: } raimund@3131: raimund@3131: raimund@3131: @Override raimund@3131: protected YAxisWalker getYAxisWalker() { raimund@3131: return new YAxisWalker() { raimund@3131: @Override raimund@3131: public int length() { raimund@3131: return YAXIS.values().length; raimund@3131: } raimund@3131: raimund@3131: @Override raimund@3131: public String getId(int idx) { raimund@3131: YAXIS[] yaxes = YAXIS.values(); raimund@3131: return yaxes[idx].toString(); raimund@3131: } raimund@3131: }; raimund@3131: } raimund@3131: raimund@3131: raimund@3131: @Override raimund@3131: protected String getDefaultChartTitle() { raimund@3131: return msg(I18N_CHART_TITLE, I18N_CHART_TITLE); raimund@3131: } raimund@3131: raimund@3131: raimund@3131: @Override raimund@3131: protected String getDefaultChartSubtitle() { raimund@3131: String[] args = new String[] { raimund@3131: FLYSUtils.getReferenceGaugeName((FLYSArtifact) master) raimund@3131: }; raimund@3131: raimund@3131: return msg(I18N_CHART_SUBTITLE, "", args); raimund@3131: } raimund@3131: raimund@3131: raimund@3131: /** raimund@3131: * Empty (suppress subtitle). raimund@3131: */ raimund@3131: @Override raimund@3131: protected void addSubtitles(JFreeChart chart) { raimund@3131: String subtitle = getChartSubtitle(); raimund@3131: raimund@3131: if (subtitle != null && subtitle.length() > 0) { raimund@3131: chart.addSubtitle(new TextTitle(subtitle)); raimund@3131: } raimund@3131: } raimund@3131: raimund@3131: raimund@3131: @Override raimund@3131: protected String getDefaultXAxisLabel() { raimund@3131: return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL); raimund@3131: } raimund@3131: raimund@3131: @Override raimund@3131: protected String getDefaultYAxisLabel(int pos) { raimund@3131: if (pos == 0) { raimund@3131: return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL); raimund@3131: } raimund@3131: else if (pos == 1) { raimund@3131: return msg(I18N_YAXIS_SECOND_LABEL, I18N_YAXIS_SECOND_LABEL); raimund@3131: } raimund@3131: else { raimund@3131: return "NO TITLE FOR Y AXIS: " + pos; raimund@3131: } raimund@3131: } raimund@3131: raimund@3131: raimund@3131: public void doOut( raimund@3131: ArtifactAndFacet artifactFacet, raimund@3131: Document theme, raimund@3131: boolean visible raimund@3131: ) { raimund@3131: String name = artifactFacet.getFacetName(); raimund@3131: logger.debug("FixDeltaWtGenerator.doOut: " + name); raimund@3131: logger.debug("Theme description is: " + artifactFacet.getFacetDescription()); raimund@3131: raimund@3131: if (name.contains(FIX_SECTOR_AVERAGE_DWT)) { raimund@3131: doSectorAverageOut( raimund@3131: (FLYSArtifact) artifactFacet.getArtifact(), raimund@3131: artifactFacet.getData(context), raimund@3131: artifactFacet.getFacetDescription(), raimund@3131: theme, raimund@3131: visible); raimund@3131: } raimund@3131: else if (name.equals(FIX_REFERENCE_EVENTS_DWT)) { raimund@3131: doReferenceEventsOut( raimund@3131: (FLYSArtifact) artifactFacet.getArtifact(), raimund@3131: artifactFacet.getData(context), raimund@3131: artifactFacet.getFacetDescription(), raimund@3131: theme, raimund@3131: visible); raimund@3131: } raimund@3131: else if (name.equals(FIX_ANALYSIS_EVENTS_DWT)) { raimund@3131: doAnalysisEventsOut( raimund@3131: (FLYSArtifact) artifactFacet.getArtifact(), raimund@3131: artifactFacet.getData(context), raimund@3131: artifactFacet.getFacetDescription(), raimund@3131: theme, raimund@3131: visible); raimund@3131: } raimund@3131: else if (name.equals(FIX_DEVIATION_DWT)) { raimund@3131: doDeviationOut( raimund@3131: (FLYSArtifact) artifactFacet.getArtifact(), raimund@3131: artifactFacet.getData(context), raimund@3131: artifactFacet.getFacetDescription(), raimund@3131: theme, raimund@3131: visible); raimund@3131: } raimund@3131: else if (name.equals(FIX_ANALYSIS_PERIODS_DWT)) { raimund@3131: doAnalysisPeriodsOut( raimund@3131: (FLYSArtifact) artifactFacet.getArtifact(), raimund@3131: artifactFacet.getData(context), raimund@3131: artifactFacet.getFacetDescription(), raimund@3131: theme, raimund@3131: visible); raimund@3131: } raimund@3131: else { raimund@3131: logger.warn("doOut(): unknown facet name: " + name); raimund@3131: return; raimund@3131: } raimund@3131: } raimund@3131: raimund@3131: raimund@3131: protected void doSectorAverageOut( raimund@3131: FLYSArtifact artifact, raimund@3131: Object data, raimund@3131: String desc, raimund@3131: Document theme, raimund@3131: boolean visible) raimund@3131: { raimund@3131: logger.debug("doSectorAverageOut(): description = " + desc); raimund@3131: raimund@3131: QWD qwd = (QWD) data; raimund@3131: TimeSeriesCollection tsc = new TimeSeriesCollection(); raimund@3131: TimeSeries series = new StyledTimeSeries(desc, theme); raimund@3131: raimund@3131: if (qwd == null) { raimund@3131: return; raimund@3131: } raimund@3131: RegularTimePeriod rtp = new Day(qwd.getDate()); raimund@3131: double value = qwd.getDeltaW(); raimund@3131: series.add(rtp, value); raimund@3131: tsc.addSeries(series); raimund@3131: raimund@3131: addAxisDataset(tsc, 0, visible); raimund@3168: addAttribute(desc, "outline"); raimund@3131: } raimund@3131: raimund@3131: raimund@3131: protected void doAnalysisEventsOut( raimund@3131: FLYSArtifact artifact, raimund@3131: Object data, raimund@3131: String desc, raimund@3131: Document theme, raimund@3131: boolean visible raimund@3131: ) { raimund@3131: logger.debug("doAnalysisEventsOut: desc = " + desc); raimund@3131: raimund@3131: QWD[] qwds = (QWD[]) data; raimund@3131: TimeSeriesCollection tsc = new TimeSeriesCollection(); raimund@3134: raimund@3134: TimeSeries series = new StyledTimeSeries(desc, theme); raimund@3134: TimeSeries interpol = new StyledTimeSeries(desc + "interpol", theme); raimund@3131: raimund@3131: if (qwds == null) { christian@3212: logger.debug("doAnalysisEventsOut: qwds == null"); raimund@3131: return; raimund@3131: } christian@3212: christian@3212: if (qwds.length == 0) { christian@3212: logger.debug("doAnalysisEventsOut: qwds.length == 0"); christian@3212: return; christian@3212: } christian@3212: christian@3212: Map annoIdxMap = new HashMap(); christian@3212: raimund@3131: for (int i = 0; i < qwds.length; i++) { raimund@3131: if (qwds[i] == null) { christian@3212: logger.debug("doAnalysisEventsOut: qwds[" + i + "] == null"); raimund@3131: continue; raimund@3131: } raimund@3131: RegularTimePeriod rtp = new Day(qwds[i].getDate()); raimund@3131: double value = qwds[i].getDeltaW(); raimund@3134: boolean interpolate = qwds[i].getInterpolated(); raimund@3134: if (interpolate) { raimund@3134: interpol.add(rtp, value); raimund@3134: } raimund@3134: else { christian@3212: annoIdxMap.put( christian@3212: i, christian@3212: new int[]{series.getItemCount(), tsc.getSeriesCount()}); raimund@3134: series.add(rtp, value); raimund@3134: } raimund@3131: } raimund@3131: tsc.addSeries(series); raimund@3134: tsc.addSeries(interpol); raimund@3131: addAxisDataset(tsc, 0, visible); raimund@3134: addAttribute(desc + "interpol", "interpolate"); raimund@3168: addAttribute(desc, "outline"); christian@3212: christian@3212: doQWDTextAnnotations(annoIdxMap, tsc, qwds, theme, visible); christian@3212: } christian@3212: christian@3212: christian@3212: protected void doQWDTextAnnotations(Map annoIdxMap, christian@3212: TimeSeriesCollection tsc, QWD[] qwds, Document theme, boolean visible) { christian@3212: List textAnnos = new ArrayList(); christian@3212: Set> entries = annoIdxMap.entrySet(); christian@3212: for(Map.Entry entry : entries) { christian@3212: QWD qwd = qwds[entry.getKey()]; christian@3212: int[] idxs = entry.getValue(); christian@3212: double x = tsc.getXValue(idxs[0], idxs[1]); christian@3212: XYTextAnnotation anno = new CollisionFreeXYTextAnnotation( christian@3212: qwd.getQ() + " m\u00B3/s", christian@3212: x, christian@3212: qwd.getDeltaW()); christian@3212: textAnnos.add(anno); christian@3212: logger.debug("annotation: " + x + "/" + qwd.getDeltaW()); christian@3212: } christian@3212: christian@3212: FLYSAnnotation flysAnno = new FLYSAnnotation(null, null, null, theme); christian@3212: flysAnno.setTextAnnotations(textAnnos); christian@3212: addAnnotations(flysAnno, visible); raimund@3131: } raimund@3131: raimund@3131: raimund@3131: protected void doReferenceEventsOut( raimund@3131: FLYSArtifact artifact, raimund@3131: Object data, raimund@3131: String desc, raimund@3131: Document theme, raimund@3131: boolean visible raimund@3131: ) { raimund@3131: logger.debug("doReferenceEventsOut: desc = " + desc); raimund@3131: raimund@3131: QWD[] qwds = (QWD[]) data; raimund@3131: TimeSeriesCollection tsc = new TimeSeriesCollection(); raimund@3134: raimund@3134: TimeSeries series = new StyledTimeSeries(desc, theme); raimund@3134: TimeSeries interpol = new StyledTimeSeries(desc + "interpol", theme); raimund@3131: raimund@3131: if (qwds == null) { raimund@3131: return; raimund@3131: } christian@3212: christian@3212: Map annoIdxMap = new HashMap(); christian@3212: raimund@3131: for (int i = 0; i < qwds.length; i++) { raimund@3131: if (qwds[i] == null) { raimund@3131: continue; raimund@3131: } raimund@3131: RegularTimePeriod rtp = new Day(qwds[i].getDate()); raimund@3131: double value = qwds[i].getDeltaW(); raimund@3134: boolean interpolate = qwds[i].getInterpolated(); raimund@3134: if (interpolate) { raimund@3134: interpol.addOrUpdate(rtp, value); raimund@3134: } raimund@3134: else { christian@3212: annoIdxMap.put( christian@3212: i, christian@3212: new int[]{series.getItemCount(), tsc.getSeriesCount()}); raimund@3134: series.addOrUpdate(rtp, value); raimund@3134: } christian@3212: raimund@3131: } raimund@3131: tsc.addSeries(series); raimund@3134: tsc.addSeries(interpol); raimund@3131: raimund@3131: addAxisDataset(tsc, 0, visible); raimund@3134: addAttribute(desc + "interpol", "interpolate"); raimund@3168: addAttribute(desc, "outline"); christian@3212: christian@3212: //doQWDTextAnnotations(annoIdxMap, tsc, qwds, theme, visible); raimund@3131: } raimund@3131: raimund@3131: raimund@3131: protected void doDeviationOut( raimund@3131: FLYSArtifact artifact, raimund@3131: Object data, raimund@3131: String desc, raimund@3131: Document theme, raimund@3131: boolean visible raimund@3131: ) { raimund@3131: logger.debug("doDeviationOut: desc = " + desc); raimund@3131: raimund@3131: if (data == null || !visible) { raimund@3131: logger.debug("no standard deviation"); raimund@3131: return; raimund@3131: } raimund@3131: double[] value = (double[]) data; raimund@3131: IntervalMarker lower = new IntervalMarker((value[0] * -1), 0); raimund@3131: lower.setAlpha(0.2f); raimund@3131: lower.setPaint(Color.BLACK); raimund@3131: IntervalMarker upper = new IntervalMarker(0, value[0]); raimund@3131: upper.setAlpha(0.2f); raimund@3131: upper.setPaint(Color.BLACK); raimund@3131: raimund@3131: valueMarker.add(lower); raimund@3131: valueMarker.add(upper); raimund@3131: } raimund@3131: raimund@3131: raimund@3131: protected void doAnalysisPeriodsOut( raimund@3131: FLYSArtifact artifact, raimund@3131: Object data, raimund@3131: String desc, raimund@3131: Document theme, raimund@3131: boolean visible raimund@3131: ) { raimund@3131: logger.debug("doHistoricalDischargeDifferenceOut: desc = " + desc); raimund@3131: raimund@3131: DateRange[] ranges = (DateRange[]) data; raimund@3131: if (ranges == null || !visible) { raimund@3131: return; raimund@3131: } raimund@3131: for (int i = 0; i < ranges.length; i++) { raimund@3131: logger.debug("creating domain marker"); raimund@3131: RegularTimePeriod start = new Month(ranges[i].getFrom()); raimund@3131: RegularTimePeriod end = new Month(ranges[i].getTo()); raimund@3131: IntervalMarker marker = raimund@3131: new IntervalMarker(start.getMiddleMillisecond(), raimund@3131: end.getMiddleMillisecond()); raimund@3131: marker.setAlpha(0.3f); raimund@3131: if ((i % 2) == 0) { raimund@3131: marker.setPaint(Color.RED); raimund@3131: } raimund@3131: else { raimund@3131: marker.setPaint(Color.BLUE); raimund@3131: } raimund@3131: domainMarker.add(marker); raimund@3131: } raimund@3131: logger.debug("domainmarkers: " + domainMarker.size()); raimund@3131: } raimund@3131: raimund@3131: raimund@3131: @Override raimund@3131: public void init(Document request, OutputStream out, CallContext context) { raimund@3131: super.init(request, out, context); raimund@3131: raimund@3131: logger.debug("currentKm = " + new Double(getCurrentKmFromRequest())); raimund@3131: context.putContextValue("currentKm", new Double(getCurrentKmFromRequest())); raimund@3131: raimund@3131: ValueMarker marker = new ValueMarker(0); raimund@3131: marker.setPaint(Color.black); raimund@3131: marker.setStroke(new BasicStroke(2)); raimund@3131: valueMarker.add(marker); raimund@3131: } raimund@3131: raimund@3131: public double getCurrentKmFromRequest() { raimund@3131: Element km = (Element)XMLUtils.xpath( raimund@3131: request, raimund@3131: XPATH_CHART_CURRENTKM, raimund@3131: XPathConstants.NODE, raimund@3131: ArtifactNamespaceContext.INSTANCE); raimund@3131: raimund@3131: if (km == null) { raimund@3131: return -1d; raimund@3131: } raimund@3131: raimund@3131: String uri = ArtifactNamespaceContext.NAMESPACE_URI; raimund@3131: raimund@3131: String currentKm = km.getAttributeNS(uri, "km"); raimund@3131: try { raimund@3131: double d = Double.valueOf(currentKm).doubleValue(); raimund@3131: return d; raimund@3131: } raimund@3131: catch(NumberFormatException nfe) { raimund@3131: return -1d; raimund@3131: } raimund@3131: } raimund@3131: raimund@3131: raimund@3131: } raimund@3131: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :