raimund@3131: package de.intevation.flys.exports.fixings;
raimund@3131:
christian@3988: import de.intevation.artifactdatabase.state.ArtifactAndFacet;
christian@3988: import de.intevation.artifacts.CallContext;
christian@3988: import de.intevation.flys.artifacts.FLYSArtifact;
christian@3988: import de.intevation.flys.artifacts.access.FixAnalysisAccess;
christian@3988: import de.intevation.flys.artifacts.model.DateRange;
christian@3988: import de.intevation.flys.artifacts.model.FacetTypes;
christian@3988: import de.intevation.flys.artifacts.model.QWDDateRange;
christian@3988: import de.intevation.flys.artifacts.model.fixings.QWD;
christian@3988: import de.intevation.flys.artifacts.resources.Resources;
christian@3988: import de.intevation.flys.exports.TimeseriesChartGenerator;
christian@3988: import de.intevation.flys.jfree.CollisionFreeXYTextAnnotation;
christian@3988: import de.intevation.flys.jfree.FLYSAnnotation;
christian@3988: import de.intevation.flys.jfree.StyledDomainMarker;
christian@3988: import de.intevation.flys.jfree.StyledTimeSeries;
christian@3988: import de.intevation.flys.jfree.StyledValueMarker;
christian@3988: import de.intevation.flys.utils.ThemeUtil;
christian@3988:
christian@3746: import java.io.OutputStream;
christian@3908: import java.text.NumberFormat;
christian@3746: import java.util.ArrayList;
christian@3746: import java.util.HashMap;
christian@3746: import java.util.List;
christian@3908: import java.util.Locale;
christian@3746: import java.util.Map;
christian@3746:
christian@3746: import org.apache.log4j.Logger;
christian@3746: import org.jfree.chart.annotations.XYTextAnnotation;
christian@3746: import org.jfree.data.time.Day;
christian@3746: import org.jfree.data.time.RegularTimePeriod;
christian@3746: import org.jfree.data.time.TimeSeries;
christian@3746: import org.jfree.data.time.TimeSeriesCollection;
christian@3746: import org.w3c.dom.Document;
christian@3746:
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: {
felix@3467: /** Private logger. */
raimund@3131: private static Logger logger =
christian@3746: Logger.getLogger(FixDeltaWtGenerator.class);
raimund@3131:
raimund@3131: public static final String I18N_CHART_TITLE =
christian@3746: "chart.fix.deltawt.title";
raimund@3131:
raimund@3131: public static final String I18N_CHART_SUBTITLE =
christian@3746: "chart.fix.deltawt.subtitle";
raimund@3131:
raimund@3131: public static final String I18N_XAXIS_LABEL =
christian@3746: "chart.fix.deltawt.xaxis.label";
raimund@3131:
raimund@3131: public static final String I18N_YAXIS_LABEL =
christian@3746: "chart.fix.deltawt.yaxis.label";
raimund@3131:
raimund@3131: public static final String I18N_YAXIS_SECOND_LABEL =
christian@3746: "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
christian@3406: protected String getChartTitle() {
christian@3406: return Resources.format(
christian@3406: context.getMeta(),
christian@3406: I18N_CHART_TITLE,
christian@3406: "",
sascha@3727: FixChartGenerator
christian@3746: .getCurrentKmFromRequest(request).doubleValue());
christian@3406: }
christian@3406:
christian@3406:
christian@3406: @Override
raimund@3131: protected String getDefaultChartSubtitle() {
sascha@3408: FixAnalysisAccess access = new FixAnalysisAccess(artifact);
christian@3409: DateRange dateRange = access.getDateRange();
christian@3409: DateRange refRange = access.getReferencePeriod();
christian@3279: return Resources.format(
sascha@3280: context.getMeta(),
sascha@3280: I18N_CHART_SUBTITLE,
sascha@3280: "",
christian@3279: access.getRiver(),
christian@3409: dateRange.getFrom(),
christian@3409: dateRange.getTo(),
christian@3409: refRange.getFrom(),
christian@3409: refRange.getTo());
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(
christian@3746: ArtifactAndFacet artifactFacet,
christian@3746: Document theme,
christian@3746: boolean visible
christian@3746: ) {
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(
christian@3746: (FLYSArtifact) artifactFacet.getArtifact(),
christian@3746: artifactFacet.getData(context),
christian@3746: artifactFacet.getFacetDescription(),
christian@3746: theme,
christian@3746: visible);
raimund@3131: }
raimund@3131: else if (name.equals(FIX_REFERENCE_EVENTS_DWT)) {
raimund@3131: doReferenceEventsOut(
christian@3746: (FLYSArtifact) artifactFacet.getArtifact(),
christian@3746: artifactFacet.getData(context),
christian@3746: artifactFacet.getFacetDescription(),
christian@3746: theme,
christian@3746: visible);
raimund@3131: }
raimund@3131: else if (name.equals(FIX_ANALYSIS_EVENTS_DWT)) {
raimund@3131: doAnalysisEventsOut(
christian@3746: (FLYSArtifact) artifactFacet.getArtifact(),
christian@3746: artifactFacet.getData(context),
christian@3746: artifactFacet.getFacetDescription(),
christian@3746: theme,
christian@3746: visible);
raimund@3131: }
raimund@3131: else if (name.equals(FIX_DEVIATION_DWT)) {
raimund@3131: doDeviationOut(
christian@3746: (FLYSArtifact) artifactFacet.getArtifact(),
christian@3746: artifactFacet.getData(context),
christian@3746: artifactFacet.getFacetDescription(),
christian@3746: theme,
christian@3746: visible);
raimund@3131: }
raimund@3131: else if (name.equals(FIX_ANALYSIS_PERIODS_DWT)) {
raimund@3131: doAnalysisPeriodsOut(
christian@3746: (FLYSArtifact) artifactFacet.getArtifact(),
christian@3746: artifactFacet.getData(context),
christian@3746: artifactFacet.getFacetDescription(),
christian@3746: theme,
christian@3746: visible);
raimund@3131: }
christian@3907: else if (name.equals(FIX_REFERENCE_PERIOD_DWT)) {
christian@3907: doReferencePeriodsOut(
christian@3907: (FLYSArtifact) artifactFacet.getArtifact(),
christian@3907: artifactFacet.getData(context),
christian@3907: artifactFacet.getFacetDescription(),
christian@3907: theme,
christian@3907: visible);
christian@3907: }
christian@3770: else if (FacetTypes.IS.MANUALPOINTS(name)) {
christian@3770: doPoints (artifactFacet.getData(context),
christian@3770: artifactFacet,
christian@3770: theme, visible, YAXIS.dW.idx);
christian@3770: }
raimund@3131: else {
christian@3746: logger.warn("doOut(): unknown facet name: " + name);
christian@3746: return;
raimund@3131: }
raimund@3131: }
raimund@3131:
raimund@3131:
christian@3907: protected void doReferencePeriodsOut(
christian@3907: FLYSArtifact artifact,
christian@3907: Object data,
christian@3907: String desc,
christian@3907: Document theme,
christian@3907: boolean visible)
christian@3907: {
christian@3907: logger.debug("doReferencePeriodsOut()");
christian@3907:
christian@3988: if (visible) {
christian@3988: FixAnalysisAccess access = new FixAnalysisAccess(artifact);
christian@3988: DateRange refRange = access.getReferencePeriod();
christian@3907:
christian@3988: RegularTimePeriod start = new Day(refRange.getFrom());
christian@3988: RegularTimePeriod end = new Day(refRange.getTo());
christian@3988: StyledDomainMarker marker = new StyledDomainMarker(
christian@3988: start.getMiddleMillisecond(),
christian@3988: end.getMiddleMillisecond(),
christian@3988: theme);
christian@3988: domainMarker.add(marker);
christian@3988: }
christian@3907: }
christian@3907:
christian@3907:
raimund@3131: protected void doSectorAverageOut(
christian@3746: FLYSArtifact artifact,
christian@3746: Object data,
christian@3746: String desc,
christian@3746: Document theme,
christian@3746: boolean visible)
raimund@3131: {
raimund@3131: logger.debug("doSectorAverageOut(): description = " + desc);
raimund@3131:
felix@3467: QWDDateRange qwd = (QWDDateRange) data;
raimund@3131: TimeSeriesCollection tsc = new TimeSeriesCollection();
raimund@3131: TimeSeries series = new StyledTimeSeries(desc, theme);
raimund@3131:
felix@3467: if (qwd == null || qwd.qwd == null || qwd.dateRange == null) {
raimund@3131: return;
raimund@3131: }
felix@3467: RegularTimePeriod rtp = new Day(qwd.qwd.getDate());
felix@3467: double value = qwd.qwd.getDeltaW();
raimund@3611:
felix@3467: // Draw a line spanning the analysis time.
raimund@3131: series.add(rtp, value);
felix@3467: rtp = new Day(qwd.dateRange.getFrom());
raimund@3611: series.addOrUpdate(rtp, value);
felix@3467: rtp = new Day(qwd.dateRange.getTo());
raimund@3611: series.addOrUpdate(rtp, value);
felix@3467:
raimund@3131: tsc.addSeries(series);
raimund@3131:
raimund@3131: addAxisDataset(tsc, 0, visible);
christian@3746:
christian@3746: if (visible && ThemeUtil.parseShowLineLabel(theme)) {
christian@3746: List textAnnos = new ArrayList();
christian@3746: XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
christian@3746: "\u0394 W(t) [cm] " + (float)Math.round(qwd.qwd.getDeltaW() * 10000) / 10000,
christian@3746: tsc.getXValue(0, 0),
christian@3746: qwd.qwd.getDeltaW());
christian@3746: textAnnos.add(anno);
christian@3746:
christian@3746: FLYSAnnotation flysAnno = new FLYSAnnotation(null, null, null, theme);
christian@3746: flysAnno.setTextAnnotations(textAnnos);
christian@3746: addAnnotations(flysAnno);
christian@3746: }
raimund@3131: }
raimund@3131:
raimund@3131:
raimund@3131: protected void doAnalysisEventsOut(
christian@3746: FLYSArtifact artifact,
christian@3746: Object data,
christian@3746: String desc,
christian@3746: Document theme,
christian@3746: boolean visible
christian@3746: ) {
raimund@3131: logger.debug("doAnalysisEventsOut: desc = " + desc);
raimund@3131:
raimund@3610: QWD qwd = (QWD) data;
raimund@3610: doQWDEventsOut(qwd, desc, theme, visible);
christian@3438: }
christian@3438:
christian@3438:
raimund@3610: protected void doQWDEventsOut(QWD qwd, String desc, Document theme, boolean visible)
christian@3438: {
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@3610: if (qwd == null) {
raimund@3610: logger.debug("doQWDEventsOut: qwd == null");
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@3610: RegularTimePeriod rtp = new Day(qwd.getDate());
raimund@3610: double value = qwd.getDeltaW();
raimund@3610: boolean interpolate = qwd.getInterpolated();
raimund@3610: if (interpolate) {
raimund@3610: if(interpol.addOrUpdate(rtp, value) == null) {
raimund@3610: annoIdxMap.put(
raimund@3610: 0,
raimund@3610: new int[]{1, idxInterpol});
raimund@3610: idxInterpol++;
raimund@3134: }
raimund@3131: }
raimund@3610: else {
raimund@3610: if(series.addOrUpdate(rtp, value) == null) {
raimund@3610: annoIdxMap.put(
raimund@3610: 0,
raimund@3610: new int[]{0, idxRegular});
raimund@3610: idxRegular++;
raimund@3610: }
raimund@3610: }
raimund@3610:
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:
raimund@3610: doQWDTextAnnotations(annoIdxMap, tsc, qwd, theme, visible);
raimund@3131: }
raimund@3131:
raimund@3131:
christian@3438: /**
christian@3438: * @param annoIdxMap map of index in qwds to series/data item indices in tsc.
christian@3438: */
christian@3438: protected void doQWDTextAnnotations(Map annoIdxMap,
raimund@3610: TimeSeriesCollection tsc, QWD qwd, Document theme,
christian@3438: boolean visible) {
christian@3438: logger.debug("doQWDTextAnnotation()");
christian@3438:
christian@3438: if (!visible || !ThemeUtil.parseShowPointLabel(theme)) {
christian@3438: logger.debug("doQWDTextAnnotation: annotation not visible");
christian@3438: return;
christian@3438: }
christian@3438:
christian@3908: Locale locale = Resources.getLocale(context.getMeta());
christian@3908: NumberFormat nf = NumberFormat.getInstance(locale);
christian@3908:
christian@3438: List textAnnos = new ArrayList();
christian@3438:
teichmann@4050: for (int[] idxs: annoIdxMap.values()) {
teichmann@4050:
christian@3438: double x = tsc.getXValue(idxs[0], idxs[1]);
christian@3908:
christian@3438: XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(
christian@3908: nf.format(qwd.getQ()) + " m\u00B3/s",
christian@3746: x,
christian@3746: qwd.getDeltaW());
christian@3438: textAnnos.add(anno);
christian@3438: }
christian@3438:
christian@3438: FLYSAnnotation flysAnno = new FLYSAnnotation(null, null, null, theme);
christian@3438: flysAnno.setTextAnnotations(textAnnos);
christian@3438: addAnnotations(flysAnno);
christian@3438: }
christian@3438:
christian@3438:
christian@3438: protected void doReferenceEventsOut(
christian@3746: FLYSArtifact artifact,
christian@3746: Object data,
christian@3746: String desc,
christian@3746: Document theme,
christian@3746: boolean visible
christian@3746: ) {
christian@3438: logger.debug("doReferenceEventsOut: desc = " + desc);
christian@3438:
raimund@3610: QWD qwd = (QWD) data;
raimund@3610: doQWDEventsOut(qwd, desc, theme, visible);
christian@3438: }
christian@3438:
christian@3438:
raimund@3131: protected void doDeviationOut(
christian@3746: FLYSArtifact artifact,
christian@3746: Object data,
christian@3746: String desc,
christian@3746: Document theme,
christian@3746: boolean visible
christian@3746: ) {
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(
christian@3746: FLYSArtifact artifact,
christian@3746: Object data,
christian@3746: String desc,
christian@3746: Document theme,
christian@3907: boolean visible)
christian@3907: {
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@3611: RegularTimePeriod start = new Day(ranges[i].getFrom());
raimund@3611: RegularTimePeriod end = new Day(ranges[i].getTo());
christian@3254: StyledDomainMarker marker =
christian@3746: new StyledDomainMarker(start.getMiddleMillisecond(),
christian@3746: 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:
sascha@3727: Double currentKm = FixChartGenerator.getCurrentKmFromRequest(request);
sascha@3404:
sascha@3404: if (logger.isDebugEnabled()) {
sascha@3404: logger.debug("currentKm = " + currentKm);
sascha@3404: }
sascha@3404:
sascha@3404: context.putContextValue("currentKm", currentKm);
raimund@3131:
christian@3254: StyledValueMarker marker = new StyledValueMarker(0, request);
raimund@3131: valueMarker.add(marker);
raimund@3131: }
raimund@3131: }
raimund@3131: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :