teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5863: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5863: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.exports; felix@2218: teichmann@5831: import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; teichmann@5831: import org.dive4elements.river.artifacts.model.FacetTypes; teichmann@5831: import org.dive4elements.river.artifacts.model.WW; teichmann@5831: import org.dive4elements.river.artifacts.model.WW.ApplyFunctionIterator; teichmann@5831: import org.dive4elements.river.artifacts.model.WWAxisTypes; teichmann@5831: import org.dive4elements.river.jfree.FLYSAnnotation; teichmann@5831: import org.dive4elements.river.jfree.StyledXYSeries; teichmann@5831: import org.dive4elements.river.utils.Formatter; sascha@2245: christian@3409: import java.awt.geom.Point2D; christian@3409: christian@3409: import org.apache.log4j.Logger; christian@3409: import org.jfree.chart.axis.NumberAxis; christian@3409: import org.jfree.chart.axis.NumberTickUnit; christian@3409: import org.jfree.chart.axis.TickUnits; christian@3409: import org.jfree.chart.axis.ValueAxis; christian@3409: import org.jfree.data.xy.XYSeries; christian@3409: import org.w3c.dom.Document; felix@2218: felix@2218: /** felix@2218: * An OutGenerator that generates reference curves. felix@2218: */ felix@2218: public class ReferenceCurveGenerator felix@2218: extends XYChartGenerator felix@2218: implements FacetTypes felix@2218: { felix@2218: public static enum YAXIS { sascha@2407: W(0); felix@2266: felix@2218: public int idx; felix@2218: private YAXIS(int c) { felix@2218: idx = c; felix@2218: } felix@2218: } felix@2218: felix@2266: /** House logger. */ felix@2218: private static Logger logger = felix@2218: Logger.getLogger(ReferenceCurveGenerator.class); felix@2218: felix@2218: public static final String I18N_CHART_TITLE = felix@2218: "chart.reference.curve.title"; felix@2218: felix@2218: public static final String I18N_CHART_SUBTITLE = felix@2218: "chart.reference.curve.subtitle"; felix@2218: sascha@2407: public static final String I18N_X_AXIS_IN_CM = sascha@2407: "chart.reference.curve.x.axis.in.cm"; felix@2263: sascha@2407: public static final String I18N_X_AXIS_IN_M = sascha@2407: "chart.reference.curve.x.axis.in.m"; felix@2218: sascha@2407: public static final String I18N_Y_AXIS_IN_CM = sascha@2407: "chart.reference.curve.y.axis.in.cm"; felix@2218: sascha@2407: public static final String I18N_Y_AXIS_IN_M = sascha@2407: "chart.reference.curve.y.axis.in.m"; felix@2266: felix@2266: public static final String I18N_CHART_TITLE_DEFAULT = felix@2266: "Bezugslinie"; felix@2266: felix@2266: felix@2218: public ReferenceCurveGenerator() { felix@2218: } felix@2218: felix@2218: /** felix@2218: * Create Axis for given index. felix@2218: * @return axis with according internationalized label. felix@2218: */ felix@2218: @Override felix@2218: protected NumberAxis createYAxis(int index) { sascha@2407: NumberAxis axis = super.createYAxis(index); sascha@2323: axis.setAutoRangeIncludesZero(false); felix@2218: return axis; felix@2218: } felix@2218: felix@2263: felix@2218: /** Get default chart title. */ felix@2218: @Override felix@2218: protected String getDefaultChartTitle() { felix@2263: return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT); felix@2218: } felix@2218: felix@2218: @Override felix@2218: protected String getDefaultChartSubtitle() { felix@2218: Object[] args = new Object[] { felix@2218: getRiverName(), felix@2218: }; felix@2218: felix@2218: return msg(I18N_CHART_SUBTITLE, "", args); felix@2218: } felix@2218: felix@2218: felix@3567: /** True if axis is in cm (because at gauge). */ sascha@2407: protected boolean getInCm(int index) { sascha@2407: Object obj = context.getContextValue("reference.curve.axis.scale"); sascha@2407: return obj instanceof WWAxisTypes && ((WWAxisTypes)obj).getInCm(index); sascha@2407: } sascha@2407: felix@2218: felix@2218: /** Get Label for X-axis (W). */ felix@2218: @Override felix@2218: protected String getDefaultXAxisLabel() { sascha@2407: return msg(getInCm(0) ? I18N_X_AXIS_IN_CM : I18N_X_AXIS_IN_M); felix@2218: } felix@2218: felix@2218: felix@2218: /** felix@2218: * Get Label for primary and other Y Axes. felix@2218: * @param index Axis-Index (0-based). felix@2218: */ felix@2218: @Override felix@2218: protected String getDefaultYAxisLabel(int index) { sascha@2407: return msg(getInCm(1) ? I18N_Y_AXIS_IN_CM : I18N_Y_AXIS_IN_M); felix@2218: } felix@2218: sascha@2408: protected String facetName() { sascha@2408: return REFERENCE_CURVE; sascha@2408: } sascha@2408: felix@2229: felix@2229: /** felix@2229: * Called for each facet/them in the out mapped to this generator. felix@2229: * @param artifactFacet artifact and facet for this theme. felix@2229: * @param theme styling info. felix@2229: * @param visible Whether or not the theme is visible. felix@2229: */ felix@2218: @Override felix@2218: public void doOut( felix@2218: ArtifactAndFacet artifactFacet, felix@2229: Document theme, felix@2218: boolean visible felix@2218: ) { felix@2218: String name = artifactFacet.getFacetName(); felix@2218: felix@2218: logger.debug("ReferenceCurveGenerator.doOut: " + name); felix@2218: felix@2218: if (name == null || name.length() == 0) { felix@2218: logger.error("No facet given. Cannot create dataset."); felix@2218: return; felix@2218: } felix@2218: sascha@2408: if (name.equals(facetName())) { felix@2229: doReferenceOut(artifactFacet.getData(context), theme, visible); felix@2218: } felix@2299: else if (FacetTypes.IS.MANUALPOINTS(name)) { ingo@2325: doPoints( ingo@2325: artifactFacet.getData(context), ingo@2325: artifactFacet, ingo@2325: theme, ingo@2325: visible, sascha@2407: YAXIS.W.idx); felix@2299: } felix@2758: else if (name.equals(RELATIVE_POINT)) { felix@2758: doPointOut( felix@2758: (Point2D) artifactFacet.getData(context), felix@2758: artifactFacet, felix@2758: theme, felix@2758: visible); felix@2758: } felix@2769: else if (name.equals(MAINVALUES_W)) { felix@2769: doAnnotations( felix@2769: ((FLYSAnnotation) artifactFacet.getData(context)).flipStickyAxis(), felix@2769: artifactFacet, felix@2769: theme, felix@2769: visible); sascha@3076: felix@2769: } felix@2218: else { felix@2218: logger.warn("Unknown facet name: " + name); felix@2218: } felix@2218: } felix@2218: sascha@2408: protected boolean doNormalize() { sascha@2408: return false; sascha@2408: } sascha@2408: felix@2218: felix@2266: /** Register DataSeries with (maybe transformed) points. */ felix@2229: public void doReferenceOut( felix@2229: Object data, felix@2229: Document theme, felix@2229: boolean visible sascha@2245: ) { sascha@2256: WW ww = (WW)data; sascha@2256: sascha@2278: Object obj = context.getContextValue("reference.curve.axis.scale"); sascha@2278: sascha@2278: WWAxisTypes wwat = obj instanceof WWAxisTypes sascha@2278: ? (WWAxisTypes)obj sascha@2278: : new WWAxisTypes(ww); sascha@2256: sascha@2408: ApplyFunctionIterator iter = wwat.transform(ww, doNormalize()); felix@2229: sascha@2253: XYSeries series = new StyledXYSeries( sascha@2256: ww.getName(), false, theme); sascha@2245: sascha@2245: double [] values = new double[2]; sascha@2245: sascha@2245: while (iter.hasNext()) { sascha@2245: iter.next(values); sascha@2253: series.add(values[0], values[1], false); felix@2229: } felix@2229: sascha@2407: addAxisSeries(series, YAXIS.W.idx, visible); felix@2229: } felix@2229: felix@2758: // TODO resolve duplicate in DurationCurveGenerator felix@2758: protected void doPointOut( felix@2758: Point2D point, felix@2758: ArtifactAndFacet aandf, felix@2758: Document theme, felix@2758: boolean visible felix@2758: ){ felix@2758: logger.debug("ReferenceCurveGenerator.doPointOut"); felix@2758: felix@2758: XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme); felix@2758: felix@2758: series.add(point.getX(), point.getY()); felix@2758: felix@2758: addAxisSeries(series, YAXIS.W.idx, visible); felix@2758: } felix@2758: felix@3567: felix@3567: /** Set the tick units for given axis. */ felix@3567: protected void setAxisTickUnit(double tick, ValueAxis axis) { sascha@2603: TickUnits units = new TickUnits(); felix@3567: units.add(new NumberTickUnit(tick, Formatter.getWaterlevelW(context))); sascha@2603: axis.setStandardTickUnits(units); sascha@2603: axis.setAutoTickUnitSelection(true); sascha@2603: } sascha@2603: sascha@2603: @Override sascha@2603: protected void localizeDomainAxis(ValueAxis domainAxis) { sascha@2603: super.localizeDomainAxis(domainAxis); felix@3567: if (getInCm(0)) { felix@3567: setAxisTickUnit(100d, domainAxis); felix@3567: } felix@3567: else { felix@3567: setAxisTickUnit(1d, domainAxis); felix@3567: } sascha@2603: } sascha@2603: sascha@2603: sascha@2603: @Override sascha@2603: protected void localizeRangeAxis(ValueAxis rangeAxis) { sascha@2603: super.localizeRangeAxis(rangeAxis); felix@3567: setAxisTickUnit(1d, rangeAxis); sascha@2603: } felix@2229: felix@2229: /** Get Walker to iterate over all axes. */ felix@2218: @Override felix@2218: protected YAxisWalker getYAxisWalker() { felix@2218: return new YAxisWalker() { felix@2246: /** Get number of items. */ felix@2218: @Override felix@2218: public int length() { felix@2218: return YAXIS.values().length; felix@2218: } felix@2218: felix@2246: /** Get identifier for this index. */ felix@2218: @Override felix@2218: public String getId(int idx) { felix@2218: YAXIS[] yaxes = YAXIS.values(); felix@2218: return yaxes[idx].toString(); felix@2218: } felix@2218: }; felix@2218: } felix@2218: } felix@2218: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :