aheinecke@7240: /* Copyright (C) 2013 by Bundesanstalt für Gewässerkunde aheinecke@7240: * Software engineering by Intevation GmbH aheinecke@7240: * aheinecke@7240: * This file is Free Software under the GNU AGPL (>=v3) aheinecke@7240: * and comes with ABSOLUTELY NO WARRANTY! Check out the aheinecke@7240: * documentation coming with Dive4Elements River for details. aheinecke@7240: */ aheinecke@7240: aheinecke@7240: package org.dive4elements.river.exports.process; aheinecke@7240: rrenkert@7990: import java.util.Map; andre@8540: import java.util.List; andre@8540: import java.util.ArrayList; andre@8540: import java.text.DateFormat; rrenkert@7990: aheinecke@7240: import org.apache.log4j.Logger; aheinecke@7240: aheinecke@7240: import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; aheinecke@7240: import org.dive4elements.artifacts.CallContext; andre@8540: import org.dive4elements.river.artifacts.resources.Resources; aheinecke@7240: import org.dive4elements.river.exports.DiagramGenerator; aheinecke@7240: import org.dive4elements.river.jfree.StyledXYSeries; andre@8540: import org.dive4elements.river.jfree.RiverAnnotation; aheinecke@7240: import org.dive4elements.river.themes.ThemeDocument; aheinecke@7240: import org.dive4elements.river.artifacts.model.FacetTypes; andre@8540: import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation; andre@8540: import org.jfree.chart.annotations.XYTextAnnotation; aheinecke@7240: aheinecke@7240: import org.dive4elements.river.jfree.JFreeUtil; aheinecke@7240: aheinecke@7240: import org.dive4elements.river.artifacts.model.sq.SQ; aheinecke@7240: import org.dive4elements.river.artifacts.model.sq.SQFunction; aheinecke@7240: aheinecke@7240: public class SQRelationProcessor extends DefaultProcessor { aheinecke@7240: aheinecke@7240: public static final String I18N_AXIS_LABEL = aheinecke@7240: "chart.sq_relation.yaxis.label"; aheinecke@7240: public static final String I18N_AXIS_LABEL_DEFAULT = aheinecke@7240: ""; aheinecke@7240: teichmann@8202: private final static Logger log = aheinecke@7240: Logger.getLogger(SQRelationProcessor.class); aheinecke@7240: aheinecke@7240: @Override aheinecke@7240: public void doOut( aheinecke@7240: DiagramGenerator generator, aheinecke@7240: ArtifactAndFacet bundle, aheinecke@7240: ThemeDocument theme, aheinecke@7240: boolean visible) { aheinecke@7240: CallContext context = generator.getCallContext(); aheinecke@7240: String facetName = bundle.getFacetName(); rrenkert@7990: StyledXYSeries series; aheinecke@7240: Object data = bundle.getData(context); aheinecke@7240: String desc = bundle.getFacetDescription(); rrenkert@7990: Map metaData = rrenkert@7990: bundle.getFacet().getMetaData(bundle.getArtifact(), context); aheinecke@7240: if (data == null) { aheinecke@7240: // Check has been here before so we keep it but aheinecke@7240: // this should never happen. teichmann@8202: log.error("Data is null for facet: " + facetName); aheinecke@7240: return; aheinecke@7240: } aheinecke@7240: aheinecke@7240: if (FacetTypes.IS.SQ_CURVE(facetName)) { aheinecke@7240: SQFunction func = (SQFunction) data; aheinecke@7240: aheinecke@7240: series = JFreeUtil.sampleFunction2DPositive( aheinecke@7240: func.getFunction(), aheinecke@7240: theme, aheinecke@7240: desc, aheinecke@7240: 500, aheinecke@7240: Math.max(func.getMinQ(), 0.01), aheinecke@7240: Math.max(func.getMaxQ(), 0.02)); aheinecke@7240: aheinecke@7240: } else if (FacetTypes.IS.SQ_MEASUREMENT(facetName) || aheinecke@7240: FacetTypes.IS.SQ_OUTLIER(facetName)) { aheinecke@7240: aheinecke@7240: SQ[] sqs = (SQ[]) data; aheinecke@7240: series = new StyledXYSeries(desc, theme); andre@8540: List xy = new ArrayList(); andre@8540: tom@8856: DateFormat dateFormat = DateFormat.getDateInstance( tom@8856: DateFormat.SHORT, andre@8540: Resources.getLocale(context.getMeta())); aheinecke@7240: aheinecke@7240: for (SQ sq: sqs) { aheinecke@7240: double q = sq.getQ(); aheinecke@7240: double s = sq.getS(); aheinecke@7240: if (s > 0d && q > 0d) { aheinecke@7240: series.add(q, s, false); andre@8540: // Annotate with measurement date andre@8540: if (sq.getDate() != null) { tom@8856: xy.add(new CollisionFreeXYTextAnnotation( tom@8856: dateFormat.format(sq.getDate()), q, s)); andre@8540: } aheinecke@7240: } aheinecke@7240: } andre@8540: andre@8540: if (visible && theme.parseShowPointLabel()) { andre@8540: tom@8856: RiverAnnotation annotation = new RiverAnnotation( tom@8856: "Messdatum", null, null, theme); andre@8540: annotation.setTextAnnotations(xy); andre@8540: generator.addAnnotations(annotation); andre@8540: } aheinecke@7240: } else { teichmann@8202: log.error("Could not handle: " + facetName); aheinecke@7240: return; aheinecke@7240: } rrenkert@7990: series.putMetaData(metaData, bundle.getArtifact(), context); aheinecke@7240: teichmann@8202: if (log.isDebugEnabled()) { teichmann@8202: log.debug("Series '" + desc + "' has " aheinecke@7240: + series.getItemCount() + " items."); aheinecke@7240: teichmann@8202: log.debug(" -> min x = " + series.getMinX()); teichmann@8202: log.debug(" -> max x = " + series.getMaxX()); teichmann@8202: log.debug(" -> min y = " + series.getMinY()); teichmann@8202: log.debug(" -> max y = " + series.getMaxY()); aheinecke@7240: } aheinecke@7240: aheinecke@7240: generator.addAxisSeries(series, axisName, visible); aheinecke@7240: } aheinecke@7240: aheinecke@7240: @Override aheinecke@7240: public boolean canHandle(String facettype) { aheinecke@7240: return FacetTypes.IS.SQ_CURVE(facettype) || aheinecke@7240: FacetTypes.IS.SQ_MEASUREMENT(facettype) || aheinecke@7240: FacetTypes.IS.SQ_OUTLIER(facettype); aheinecke@7240: } aheinecke@7240: aheinecke@7240: @Override aheinecke@7240: public String getAxisLabel(DiagramGenerator generator) { aheinecke@7240: return generator.msg( aheinecke@7240: I18N_AXIS_LABEL, aheinecke@7240: I18N_AXIS_LABEL_DEFAULT); aheinecke@7240: } aheinecke@7240: }