comparison artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flood_duration/FloodDurationCurveGenerator.java @ 9252:c2a0028bfa9f

Work on S-Info flood duration curve chart
author mschaefer
date Thu, 12 Jul 2018 18:09:48 +0200
parents
children ef7b65576d4b
comparison
equal deleted inserted replaced
9251:4082b8429353 9252:c2a0028bfa9f
1 /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
2 * Software engineering by Intevation GmbH
3 *
4 * This file is Free Software under the GNU AGPL (>=v3)
5 * and comes with ABSOLUTELY NO WARRANTY! Check out the
6 * documentation coming with Dive4Elements River for details.
7 */
8
9 package org.dive4elements.river.artifacts.sinfo.flood_duration;
10
11 import java.awt.Font;
12 import java.awt.geom.Point2D;
13
14 import org.apache.log4j.Logger;
15 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
16 import org.dive4elements.artifacts.CallContext;
17 import org.dive4elements.river.artifacts.model.CalculationResult;
18 import org.dive4elements.river.artifacts.model.FacetTypes;
19 import org.dive4elements.river.artifacts.model.WQDay;
20 import org.dive4elements.river.exports.IdentifiableNumberAxis;
21 import org.dive4elements.river.exports.XYChartGenerator;
22 import org.dive4elements.river.jfree.Bounds;
23 import org.dive4elements.river.jfree.RiverAnnotation;
24 import org.dive4elements.river.jfree.StyledXYSeries;
25 import org.dive4elements.river.themes.ThemeDocument;
26 import org.jfree.chart.axis.NumberAxis;
27 import org.jfree.chart.axis.ValueAxis;
28 import org.jfree.chart.plot.XYPlot;
29 import org.jfree.data.Range;
30 import org.jfree.data.xy.XYSeries;
31
32
33 /**
34 * An OutGenerator that generates duration curves.
35 *
36 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
37 */
38 public class FloodDurationCurveGenerator
39 extends XYChartGenerator
40 implements FacetTypes
41 {
42 public static enum YAXIS {
43 W(0),
44 Q(1);
45 public int idx;
46 private YAXIS(final int c) {
47 this.idx = c;
48 }
49 }
50
51 /** Local log. */
52 private static Logger log =
53 Logger.getLogger(FloodDurationCurveGenerator.class);
54
55 public static final String I18N_CHART_TITLE = "sinfo.chart.flood_duration.curve.section.title";
56
57 public static final String I18N_CHART_SUBTITLE = "chart.duration.curve.subtitle";
58
59 public static final String I18N_XAXIS_LABEL = "sinfo.chart.flood_duration.curve.xaxis.label";
60
61 public static final String I18N_YAXIS_LABEL_W = "chart.duration.curve.yaxis.label.w";
62
63 public static final String I18N_YAXIS_LABEL_Q = "chart.duration.curve.yaxis.label.q";
64
65 public static final String I18N_CHART_TITLE_DEFAULT = "Dauerlinie";
66
67 public static final String I18N_XAXIS_LABEL_DEFAULT = "Überflutungsdauer [d/a]";
68
69
70 public FloodDurationCurveGenerator() {
71 super();
72 }
73
74
75 /**
76 * Create Axis for given index.
77 * @return axis with according internationalized label.
78 */
79 @Override
80 protected NumberAxis createYAxis(final int index) {
81 final Font labelFont = new Font("Tahoma", Font.BOLD, 14);
82 final String label = getYAxisLabel(index);
83
84 final NumberAxis axis = createNumberAxis(index, label);
85 if (index == YAXIS.W.idx) {
86 axis.setAutoRangeIncludesZero(false);
87 }
88 axis.setLabelFont(labelFont);
89 return axis;
90 }
91
92
93 @Override
94 protected String getDefaultChartTitle(final CallContext context) {
95 return msg(I18N_CHART_TITLE, I18N_CHART_TITLE_DEFAULT);
96 }
97
98
99 @Override
100 protected String getDefaultChartSubtitle(final CallContext context) {
101
102 final double[] dist = getRange();
103 return msg(I18N_CHART_SUBTITLE, "", getRiverName(), dist[0]);
104 }
105
106
107 @Override
108 protected String getDefaultXAxisLabel(final CallContext context) {
109 return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
110 }
111
112
113 @Override
114 protected String getDefaultYAxisLabel(final int index) {
115
116 String label = "default";
117 if (index == YAXIS.W.idx) {
118 label = msg(I18N_YAXIS_LABEL_W, I18N_YAXIS_LABEL_W, getRiverUnit());
119 }
120 else if (index == YAXIS.Q.idx) {
121 label = msg(I18N_YAXIS_LABEL_Q);
122 }
123 return label;
124 }
125
126
127 @Override
128 protected boolean zoomX(final XYPlot plot, final ValueAxis axis, final Bounds bounds, final Range x) {
129
130 final boolean zoomin = super.zoom(plot, axis, bounds, x);
131 if (!zoomin)
132 axis.setLowerBound(0d);
133 // axis.setUpperBound(364);
134 return zoomin;
135 }
136
137
138 /**
139 * This method overrides the method in the parent class to set the lower
140 * bounds of the Q axis to 0. This axis should never display negative
141 * values on its own.
142 */
143 @Override
144 protected boolean zoomY(final XYPlot plot, final ValueAxis axis, final Bounds bounds, final Range x) {
145
146 final boolean zoomin = super.zoom(plot, axis, bounds, x);
147 if (!zoomin && axis instanceof IdentifiableNumberAxis) {
148 final String id = ((IdentifiableNumberAxis) axis).getId();
149 if (YAXIS.Q.toString().equals(id))
150 axis.setLowerBound(0d);
151 }
152 return zoomin;
153 }
154
155
156 @Override
157 public void doOut(final ArtifactAndFacet artifactFacet, final ThemeDocument attr, final boolean visible) {
158
159 final String name = artifactFacet.getFacetName();
160
161 log.debug("FloodDurationCurveGenerator.doOut: " + name);
162
163 if (name == null || name.length() == 0) {
164 log.error("No facet given. Cannot create dataset.");
165 return;
166 }
167
168 final CallContext context = getContext();
169
170 if (name.equals(DURATION_W)) {
171 doWOut((WQDay) ((CalculationResult) artifactFacet.getData(context)).getData(), artifactFacet, attr, visible);
172 }
173 else if (name.equals(DURATION_Q)) {
174 doQOut((WQDay) ((CalculationResult) artifactFacet.getData(context)).getData(), artifactFacet, attr, visible);
175 }
176 else if (name.equals(MAINVALUES_Q) || name.equals(MAINVALUES_W)) {
177 doAnnotations((RiverAnnotation) artifactFacet.getData(context), artifactFacet, attr, visible);
178 }
179 else if (name.equals(RELATIVE_POINT)) {
180 doPointOut((Point2D) artifactFacet.getData(context), artifactFacet, attr, visible);
181 }
182 else if (FacetTypes.IS.MANUALPOINTS(name)) {
183 doPoints(artifactFacet.getData(context), artifactFacet, attr, visible, YAXIS.W.idx);
184 }
185 else {
186 log.warn("Unknown facet name: " + name);
187 return;
188 }
189 }
190
191 /**
192 * Creates the series for a duration curve's W facet.
193 *
194 * @param wqdays The WQDay store that contains the Ws.
195 * @param theme
196 */
197 protected void doWOut(final WQDay wqdays, final ArtifactAndFacet aaf, final ThemeDocument theme, final boolean visible) {
198
199 // log.debug("DurationCurveGenerator.doWOut");
200 final XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), theme);
201 final int size = wqdays.size();
202 for (int i = 0; i < size; i++) {
203 final int day = wqdays.getDay(i);
204 final double w = wqdays.getW(i);
205 series.add(day, w);
206 }
207 addAxisSeries(series, YAXIS.W.idx, visible);
208 }
209
210 protected void doPointOut(final Point2D point, final ArtifactAndFacet aandf, final ThemeDocument theme, final boolean visible) {
211
212 // log.debug("DurationCurveGenerator.doPointOut");
213 final XYSeries series = new StyledXYSeries(aandf.getFacetDescription(), theme);
214 series.add(point.getX(), point.getY());
215 addAxisSeries(series, YAXIS.W.idx, visible);
216 }
217
218
219 /**
220 * Creates the series for a duration curve's Q facet.
221 *
222 * @param wqdays The WQDay store that contains the Qs.
223 * @param theme
224 */
225 protected void doQOut(final WQDay wqdays, final ArtifactAndFacet aaf, final ThemeDocument theme, final boolean visible) {
226
227 // log.debug("DurationCurveGenerator.doQOut");
228 final XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), theme);
229 final int size = wqdays.size();
230 for (int i = 0; i < size; i++) {
231 final int day = wqdays.getDay(i);
232 final double q = wqdays.getQ(i);
233 series.add(day, q);
234 }
235 addAxisSeries(series, YAXIS.Q.idx, visible);
236 }
237
238
239 @Override
240 protected YAxisWalker getYAxisWalker() {
241 return new YAxisWalker() {
242 @Override
243 public int length() {
244 return YAXIS.values().length;
245 }
246
247 @Override
248 public String getId(final int idx) {
249 final YAXIS[] yaxes = YAXIS.values();
250 return yaxes[idx].toString();
251 }
252 };
253 }
254
255 // MainValue-Annotations should be visualized by
256 // a line that goes to the curve itself.
257 }
258 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org