raimund@3131: package de.intevation.flys.exports.fixings;
raimund@3131:
sascha@3139: import de.intevation.artifactdatabase.state.ArtifactAndFacet;
sascha@3139: import de.intevation.artifacts.ArtifactNamespaceContext;
sascha@3139: import de.intevation.artifacts.CallContext;
sascha@3139: import de.intevation.artifacts.common.utils.XMLUtils;
sascha@3139: import de.intevation.flys.artifacts.FLYSArtifact;
christian@3279: import de.intevation.flys.artifacts.access.FixationArtifactAccess;
sascha@3210: import de.intevation.flys.artifacts.model.DateRange;
sascha@3139: import de.intevation.flys.artifacts.model.FacetTypes;
sascha@3139: import de.intevation.flys.artifacts.model.fixings.QWD;
christian@3279: import de.intevation.flys.artifacts.resources.Resources;
sascha@3139: import de.intevation.flys.exports.TimeseriesChartGenerator;
christian@3212: import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
christian@3212: import de.intevation.flys.jfree.FLYSAnnotation;
christian@3254: import de.intevation.flys.jfree.StyledDomainMarker;
sascha@3139: import de.intevation.flys.jfree.StyledTimeSeries;
christian@3254: import de.intevation.flys.jfree.StyledValueMarker;
felix@3238: import de.intevation.flys.utils.ThemeUtil;
sascha@3139:
sascha@3139: import java.io.OutputStream;
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: import org.jfree.chart.JFreeChart;
christian@3212: import org.jfree.chart.annotations.XYTextAnnotation;
raimund@3131: import org.jfree.chart.title.TextTitle;
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;
sascha@3139: import org.w3c.dom.Document;
sascha@3139: import org.w3c.dom.Element;
raimund@3131:
christian@3251:
raimund@3131: /**
christian@3251: * Generator for Delta W(t) charts.
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: }
sascha@3280:
sascha@3280:
christian@3279: private FLYSArtifact artifact = null;
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() {
christian@3279: FixationArtifactAccess access = new FixationArtifactAccess(artifact);
christian@3279: DateRange range = access.getDateRange();
christian@3279: return Resources.format(
sascha@3280: context.getMeta(),
sascha@3280: I18N_CHART_SUBTITLE,
sascha@3280: "",
christian@3279: access.getRiver(),
christian@3279: range.getFrom(),
christian@3279: range.getTo());
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:
christian@3251: @Override
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());
sascha@3280:
christian@3279: this.artifact = (FLYSArtifact)artifactFacet.getArtifact();
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());
felix@3234: 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");
felix@3234: Map annoIdxMap = new HashMap();
felix@3234: annoIdxMap.put (0, new int[]{0,0});
felix@3234: doQWDTextAnnotations(annoIdxMap, tsc, new QWD[]{qwd}, theme, visible);
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:
felix@3237: int idxInterpol = 0;
felix@3237: int idxRegular = 0;
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);
felix@3234: annoIdxMap.put(
felix@3234: i,
felix@3237: new int[]{1, idxInterpol++});
raimund@3134: }
raimund@3134: else {
felix@3234: series.add(rtp, value);
christian@3212: annoIdxMap.put(
christian@3212: i,
felix@3237: new int[]{0, idxRegular++});
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@3242: if (visible) {
christian@3242: doQWDTextAnnotations(annoIdxMap, tsc, qwds, theme, visible);
christian@3242: }
christian@3212: }
christian@3212:
christian@3212:
felix@3234: /**
felix@3234: * @param annoIdxMap map of index in qwds to series/dataitem indices in tsc.
felix@3234: */
christian@3212: protected void doQWDTextAnnotations(Map annoIdxMap,
felix@3234: TimeSeriesCollection tsc, QWD[] qwds, Document theme,
felix@3234: boolean visible) {
christian@3242: logger.debug("doQWDTextAnnotation()");
christian@3242:
christian@3286: if (!visible || !ThemeUtil.parseShowPointLabel(theme)) {
christian@3242: logger.debug("doQWDTextAnnotation: annotation not visible");
felix@3238: return;
christian@3242: }
christian@3242:
christian@3212: List textAnnos = new ArrayList();
christian@3212: Set> entries = annoIdxMap.entrySet();
christian@3242:
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]);
felix@3234: XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
felix@3234: qwd.getQ() + " m\u00B3/s",
felix@3234: x,
felix@3234: qwd.getDeltaW());
felix@3234: textAnnos.add(anno);
christian@3212: logger.debug("annotation: " + x + "/" + qwd.getDeltaW());
christian@3212: }
christian@3212:
christian@3286: FLYSAnnotation flysAnno = new FLYSAnnotation(null, null, null, theme);
christian@3286: flysAnno.setTextAnnotations(textAnnos);
christian@3286: addAnnotations(flysAnno);
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:
felix@3237: int idxInterpol = 0;
felix@3237: int idxRegular = 0;
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) {
christian@3251: if(interpol.addOrUpdate(rtp, value) == null) {
christian@3251: annoIdxMap.put(
christian@3251: i,
christian@3251: new int[]{1, idxInterpol});
christian@3251: idxInterpol++;
christian@3251: }
raimund@3134: }
raimund@3134: else {
christian@3251: if(series.addOrUpdate(rtp, value) == null) {
christian@3251: annoIdxMap.put(
christian@3251: i,
christian@3251: new int[]{0, idxRegular});
christian@3251: idxRegular++;
christian@3251: }
raimund@3134: }
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:
felix@3234: 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;
christian@3254: StyledDomainMarker lower = new StyledDomainMarker((value[0] * -1), 0, theme);
christian@3254: StyledDomainMarker upper = new StyledDomainMarker(0, value[0], theme);
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());
christian@3254: StyledDomainMarker marker =
christian@3254: new StyledDomainMarker(start.getMiddleMillisecond(),
christian@3254: end.getMiddleMillisecond(), theme);
christian@3254: marker.useSecondColor(i % 2 == 0);
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:
christian@3254: StyledValueMarker marker = new StyledValueMarker(0, request);
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 :