comparison artifacts/src/main/java/org/dive4elements/river/exports/DischargeCurveGenerator.java @ 9312:740d65e4aa14

Q [m³/s] one message
author gernotbelger
date Thu, 26 Jul 2018 15:54:20 +0200
parents 1cc7653ca84f
children 9b8e8fc1f408
comparison
equal deleted inserted replaced
9311:7c7f73e5e01e 9312:740d65e4aa14
9 package org.dive4elements.river.exports; 9 package org.dive4elements.river.exports;
10 10
11 import java.util.ArrayList; 11 import java.util.ArrayList;
12 import java.util.List; 12 import java.util.List;
13 13
14 import org.apache.log4j.Logger;
14 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; 15 import org.dive4elements.artifactdatabase.state.ArtifactAndFacet;
16 import org.dive4elements.artifactdatabase.state.State;
17 import org.dive4elements.artifacts.CallContext;
15 import org.dive4elements.river.artifacts.D4EArtifact; 18 import org.dive4elements.river.artifacts.D4EArtifact;
19 import org.dive4elements.river.artifacts.GaugeDischargeCurveArtifact;
16 import org.dive4elements.river.artifacts.access.RiverAccess; 20 import org.dive4elements.river.artifacts.access.RiverAccess;
17 import org.dive4elements.river.artifacts.model.FacetTypes; 21 import org.dive4elements.river.artifacts.model.FacetTypes;
18 import org.dive4elements.river.artifacts.model.WQKms; 22 import org.dive4elements.river.artifacts.model.WQKms;
19 import org.dive4elements.river.exports.process.MiscDischargeProcessor; 23 import org.dive4elements.river.exports.process.MiscDischargeProcessor;
24 import org.dive4elements.river.jfree.Bounds;
20 import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation; 25 import org.dive4elements.river.jfree.CollisionFreeXYTextAnnotation;
21 import org.dive4elements.river.jfree.Bounds;
22 import org.dive4elements.river.jfree.DoubleBounds; 26 import org.dive4elements.river.jfree.DoubleBounds;
23 import org.dive4elements.river.jfree.RiverAnnotation; 27 import org.dive4elements.river.jfree.RiverAnnotation;
24 import org.dive4elements.river.jfree.StickyAxisAnnotation; 28 import org.dive4elements.river.jfree.StickyAxisAnnotation;
25 import org.dive4elements.river.jfree.StyledXYSeries; 29 import org.dive4elements.river.jfree.StyledXYSeries;
26 import org.dive4elements.river.model.Gauge; 30 import org.dive4elements.river.model.Gauge;
27 import org.dive4elements.river.model.River; 31 import org.dive4elements.river.model.River;
28 import org.dive4elements.river.themes.ThemeDocument; 32 import org.dive4elements.river.themes.ThemeDocument;
29
30 import org.dive4elements.artifactdatabase.state.State;
31 import org.dive4elements.artifacts.CallContext;
32 import org.dive4elements.river.artifacts.GaugeDischargeCurveArtifact;
33
34 import org.apache.log4j.Logger;
35 import org.jfree.chart.annotations.XYTextAnnotation; 33 import org.jfree.chart.annotations.XYTextAnnotation;
36 import org.jfree.chart.axis.ValueAxis; 34 import org.jfree.chart.axis.ValueAxis;
37 import org.jfree.chart.plot.XYPlot; 35 import org.jfree.chart.plot.XYPlot;
38 import org.jfree.data.Range; 36 import org.jfree.data.Range;
39 import org.jfree.data.xy.XYSeries; 37 import org.jfree.data.xy.XYSeries;
40 38
41
42 /** 39 /**
43 * An OutGenerator that generates discharge curves. 40 * An OutGenerator that generates discharge curves.
44 * 41 *
45 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> 42 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
46 */ 43 */
47 public class DischargeCurveGenerator 44 public class DischargeCurveGenerator extends XYChartGenerator implements FacetTypes {
48 extends XYChartGenerator
49 implements FacetTypes {
50 45
51 /** Beware, in this implementation, the W axis is also in cm! */ 46 /** Beware, in this implementation, the W axis is also in cm! */
52 public static enum YAXIS { 47 public static enum YAXIS {
53 WCm(0), 48 WCm(0), W(1);
54 W(1);
55 protected int idx; 49 protected int idx;
56 private YAXIS(int c) { 50
57 idx = c; 51 private YAXIS(final int c) {
52 this.idx = c;
58 } 53 }
59 } 54 }
60 55
61 /** The log used in this generator. */ 56 /** The log used in this generator. */
62 private static Logger log = 57 private static Logger log = Logger.getLogger(DischargeCurveGenerator.class);
63 Logger.getLogger(DischargeCurveGenerator.class); 58
64 59 public static final String I18N_CHART_TITLE = "chart.discharge.curve.title";
65 public static final String I18N_CHART_TITLE = 60
66 "chart.discharge.curve.title"; 61 public static final String I18N_CHART_SUBTITLE = "chart.discharge.curve.subtitle";
67 62
68 public static final String I18N_CHART_SUBTITLE = 63 public static final String I18N_XAXIS_LABEL = "common.export.csv.header.q";
69 "chart.discharge.curve.subtitle"; 64
70 65 public static final String I18N_YAXIS_LABEL = "chart.discharge.curve.yaxis.label";
71 public static final String I18N_XAXIS_LABEL = 66
72 "chart.discharge.curve.xaxis.label"; 67 public static final String I18N_CHART_TITLE_DEFAULT = "Abflusskurven";
73 68 public static final String I18N_XAXIS_LABEL_DEFAULT = "Q [m\u00b3/s]";
74 public static final String I18N_YAXIS_LABEL = 69 public static final String I18N_YAXIS_LABEL_DEFAULT = "W [cm]";
75 "chart.discharge.curve.yaxis.label";
76
77 public static final String I18N_CHART_TITLE_DEFAULT = "Abflusskurven";
78 public static final String I18N_XAXIS_LABEL_DEFAULT = "Q [m\u00b3/s]";
79 public static final String I18N_YAXIS_LABEL_DEFAULT = "W [cm]";
80
81 70
82 /** 71 /**
83 * Returns the PNP (Datum) of gauge, if at gauge, 0 otherwise. 72 * Returns the PNP (Datum) of gauge, if at gauge, 0 otherwise.
84 */ 73 */
85 public static double getCurrentGaugeDatum( 74 public static double getCurrentGaugeDatum(final double km, final D4EArtifact artifact, final double tolerance) {
86 double km,
87 D4EArtifact artifact,
88 double tolerance
89 ) {
90 // Look if there is a gauge at chosen km: 75 // Look if there is a gauge at chosen km:
91 // Get gauge which is defined for km 76 // Get gauge which is defined for km
92 Gauge gauge = new RiverAccess(artifact).getRiver() 77 final Gauge gauge = new RiverAccess(artifact).getRiver().determineGaugeAtStation(km);
93 .determineGaugeAtStation(km);
94 if (gauge == null) { 78 if (gauge == null) {
95 log.error("No Gauge could be found at station " + km + "!"); 79 log.error("No Gauge could be found at station " + km + "!");
96 return 0d; 80 return 0d;
97 } 81 }
98 double subtractPNP = 0d; 82 double subtractPNP = 0d;
101 subtractPNP = gauge.getDatum().doubleValue(); 85 subtractPNP = gauge.getDatum().doubleValue();
102 } 86 }
103 return subtractPNP; 87 return subtractPNP;
104 } 88 }
105 89
106
107 /** Get the current Gauge datum with default distance tolerance. */ 90 /** Get the current Gauge datum with default distance tolerance. */
108 public double getCurrentGaugeDatum() { 91 public double getCurrentGaugeDatum() {
109 return getCurrentGaugeDatum(getRange()[0], 92 return getCurrentGaugeDatum(getRange()[0], (D4EArtifact) getMaster(), 1e-4);
110 (D4EArtifact) getMaster(), 1e-4); 93 }
111 }
112
113 94
114 /** Overriden to show second axis also if no visible data present. */ 95 /** Overriden to show second axis also if no visible data present. */
115 @Override 96 @Override
116 protected void adjustAxes(XYPlot plot) { 97 protected void adjustAxes(final XYPlot plot) {
117 super.adjustAxes(plot); 98 super.adjustAxes(plot);
118 // XXX Hacking around that there were two axes shown in official Gauge 99 // XXX Hacking around that there were two axes shown in official Gauge
119 // Discharge, the one from the WINFO module. 100 // Discharge, the one from the WINFO module.
120 // This should be made unecessary in a Q Diagram refactoring with 101 // This should be made unecessary in a Q Diagram refactoring with
121 // decent inheritance. 102 // decent inheritance.
122 if (getMaster() instanceof GaugeDischargeCurveArtifact) { 103 if (getMaster() instanceof GaugeDischargeCurveArtifact) {
123 GaugeDischargeCurveArtifact myMaster = 104 final GaugeDischargeCurveArtifact myMaster = (GaugeDischargeCurveArtifact) getMaster();
124 (GaugeDischargeCurveArtifact) getMaster(); 105 final State state = myMaster.getCurrentState(getContext());
125 State state = myMaster.getCurrentState(getContext());
126 if (GaugeDischargeCurveArtifact.STATIC_STATE_NAME.equals(state.getID())) { 106 if (GaugeDischargeCurveArtifact.STATIC_STATE_NAME.equals(state.getID())) {
127 return; 107 return;
128 } 108 }
129 } 109 }
130 // End Hack 110 // End Hack
148 } 128 }
149 129
150 // XXX Q-Symetry: I am assuming here that there can only 130 // XXX Q-Symetry: I am assuming here that there can only
151 // be a fixed Range for WinM as this is currently the only 131 // be a fixed Range for WinM as this is currently the only
152 // thing that is configureable. 132 // thing that is configureable.
153 Range fixedWinMRange = getRangeForAxisFromSettings( 133 final Range fixedWinMRange = getRangeForAxisFromSettings(getYAxisWalker().getId(YAXIS.W.idx));
154 getYAxisWalker().getId(YAXIS.W.idx));
155 134
156 // The combination of Range and Bounds is crazy.. 135 // The combination of Range and Bounds is crazy..
157 if (fixedWinMRange != null) { 136 if (fixedWinMRange != null) {
158 boundsInMGauge = new DoubleBounds(fixedWinMRange.getLowerBound(), 137 boundsInMGauge = new DoubleBounds(fixedWinMRange.getLowerBound(), fixedWinMRange.getUpperBound());
159 fixedWinMRange.getUpperBound()); 138 }
160 } 139
161 140 log.debug("Syncing Axis Bounds. Bounds W: " + boundsInMGauge.toString() + " Bounds Wcm: " + boundsInCM.toString());
162 log.debug("Syncing Axis Bounds. Bounds W: " 141
163 + boundsInMGauge.toString() 142 final double datum = getCurrentGaugeDatum();
164 + " Bounds Wcm: " + boundsInCM.toString());
165
166 double datum = getCurrentGaugeDatum();
167 143
168 // Convert boundsInMGauge to Datum+cm 144 // Convert boundsInMGauge to Datum+cm
169 double convertedLower = 145 final double convertedLower = ((Double) boundsInMGauge.getLower() - datum) * 100;
170 ((Double)boundsInMGauge.getLower() - datum) * 100; 146 final double convertedUpper = ((Double) boundsInMGauge.getUpper() - datum) * 100;
171 double convertedUpper = 147 final Bounds convertedBounds = new DoubleBounds(convertedLower, convertedUpper);
172 ((Double)boundsInMGauge.getUpper() - datum) * 100;
173 Bounds convertedBounds =
174 new DoubleBounds(convertedLower, convertedUpper);
175 148
176 // Now combine both Ranges 149 // Now combine both Ranges
177 boundsInCM = boundsInCM.combine(convertedBounds); 150 boundsInCM = boundsInCM.combine(convertedBounds);
178 151
179 // Recalculate absolute bounds 152 // Recalculate absolute bounds
180 boundsInMGauge = new DoubleBounds( 153 boundsInMGauge = new DoubleBounds((Double) boundsInCM.getLower() / 100d + datum, (Double) boundsInCM.getUpper() / 100d + datum);
181 (Double)boundsInCM.getLower() / 100d + datum,
182 (Double)boundsInCM.getUpper() / 100d + datum);
183 154
184 // Set the new combined bounds 155 // Set the new combined bounds
185 setYBounds(YAXIS.W.idx, boundsInMGauge); 156 setYBounds(YAXIS.W.idx, boundsInMGauge);
186 setYBounds(YAXIS.WCm.idx, boundsInCM); 157 setYBounds(YAXIS.WCm.idx, boundsInCM);
187 log.debug("Synced Bounds W: " + boundsInMGauge.toString() + 158 log.debug("Synced Bounds W: " + boundsInMGauge.toString() + " Bounds Wcm: " + boundsInCM.toString());
188 " Bounds Wcm: " + boundsInCM.toString());
189 } 159 }
190 160
191 public DischargeCurveGenerator() { 161 public DischargeCurveGenerator() {
192 super(); 162 super();
193 } 163 }
194
195 164
196 @Override 165 @Override
197 protected YAxisWalker getYAxisWalker() { 166 protected YAxisWalker getYAxisWalker() {
198 return new YAxisWalker() { 167 return new YAxisWalker() {
199 @Override 168 @Override
200 public int length() { 169 public int length() {
201 return YAXIS.values().length; 170 return YAXIS.values().length;
202 } 171 }
203 172
204 @Override 173 @Override
205 public String getId(int idx) { 174 public String getId(final int idx) {
206 YAXIS[] yaxes = YAXIS.values(); 175 final YAXIS[] yaxes = YAXIS.values();
207 return yaxes[idx].toString(); 176 return yaxes[idx].toString();
208 } 177 }
209 }; 178 };
210 } 179 }
211
212 180
213 /** 181 /**
214 * Returns always null to suppress subtitles. 182 * Returns always null to suppress subtitles.
215 */ 183 */
216 @Override 184 @Override
217 protected String getDefaultChartTitle(final CallContext context) { 185 protected String getDefaultChartTitle(final CallContext context) {
218 return null; 186 return null;
219 } 187 }
220 188
221
222 @Override 189 @Override
223 protected String getDefaultXAxisLabel(final CallContext context) { 190 protected String getDefaultXAxisLabel(final CallContext context) {
224 return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT); 191 return msg(I18N_XAXIS_LABEL, I18N_XAXIS_LABEL_DEFAULT);
225 } 192 }
226 193
227 @Override 194 @Override
228 protected String getDefaultYAxisLabel(int pos) { 195 protected String getDefaultYAxisLabel(final int pos) {
229 return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT); 196 return msg(I18N_YAXIS_LABEL, I18N_YAXIS_LABEL_DEFAULT);
230 } 197 }
231 198
232
233 /* TODO is this one really needed? */ 199 /* TODO is this one really needed? */
234 @Override 200 @Override
235 protected boolean zoomX( 201 protected boolean zoomX(final XYPlot plot, final ValueAxis axis, final Bounds bounds, final Range x) {
236 XYPlot plot, 202 final boolean zoomin = super.zoom(plot, axis, bounds, x);
237 ValueAxis axis,
238 Bounds bounds,
239 Range x
240 ) {
241 boolean zoomin = super.zoom(plot, axis, bounds, x);
242 203
243 if (!zoomin) { 204 if (!zoomin) {
244 axis.setLowerBound(0d); 205 axis.setLowerBound(0d);
245 } 206 }
246 207
247 return zoomin; 208 return zoomin;
248 } 209 }
249 210
250 /** Translate River annotations if a gauge. */ 211 /** Translate River annotations if a gauge. */
251 public void translateRiverAnnotation(RiverAnnotation riverAnnotation) { 212 public void translateRiverAnnotation(final RiverAnnotation riverAnnotation) {
252 if (getCurrentGaugeDatum() == 0d) { 213 if (getCurrentGaugeDatum() == 0d) {
253 return; 214 return;
254 } 215 }
255 log.debug("Translate some river annotation."); 216 log.debug("Translate some river annotation.");
256 double translate = getCurrentGaugeDatum(); 217 final double translate = getCurrentGaugeDatum();
257 double factor = 100d; 218 final double factor = 100d;
258 for (StickyAxisAnnotation annotation: 219 for (final StickyAxisAnnotation annotation : riverAnnotation.getAxisTextAnnotations()) {
259 riverAnnotation.getAxisTextAnnotations()
260 ){
261 if (!annotation.atX()) { 220 if (!annotation.atX()) {
262 annotation.setPos((annotation.getPos() - translate)*factor); 221 annotation.setPos((annotation.getPos() - translate) * factor);
263 } 222 }
264 } 223 }
265 for ( 224 for (final XYTextAnnotation annotation : riverAnnotation.getTextAnnotations()) {
266 XYTextAnnotation annotation: riverAnnotation.getTextAnnotations() 225 annotation.setY((annotation.getY() - translate) * factor);
267 ) { 226 }
268 annotation.setY((annotation.getY() - translate)*factor); 227 }
269 } 228
270 } 229 @Override
271 230 public void doOut(final ArtifactAndFacet artifactFacet, final ThemeDocument theme, final boolean visible) {
272 231 final String name = artifactFacet.getFacetName();
273 @Override
274 public void doOut(
275 ArtifactAndFacet artifactFacet,
276 ThemeDocument theme,
277 boolean visible
278 ) {
279 String name = artifactFacet.getFacetName();
280 log.debug("DischargeCurveGenerator.doOut: " + name); 232 log.debug("DischargeCurveGenerator.doOut: " + name);
281 233
282 final CallContext context = getContext(); 234 final CallContext context = getContext();
283 235
284 MiscDischargeProcessor dProcessor = new MiscDischargeProcessor( 236 final MiscDischargeProcessor dProcessor = new MiscDischargeProcessor(getRange()[0]);
285 getRange()[0]);
286 if (dProcessor.canHandle(name)) { 237 if (dProcessor.canHandle(name)) {
287 // In Base DischargeCurveGenerator, always at gauge, use WCm axis. 238 // In Base DischargeCurveGenerator, always at gauge, use WCm axis.
288 dProcessor.doOut( 239 dProcessor.doOut(this, artifactFacet, theme, visible, YAXIS.WCm.idx);
289 this, artifactFacet, theme, visible, YAXIS.WCm.idx); 240 } else if (name.equals(DISCHARGE_CURVE) || name.equals(GAUGE_DISCHARGE_CURVE)) {
290 } 241 doDischargeOut((D4EArtifact) artifactFacet.getArtifact(), artifactFacet.getData(context), artifactFacet.getFacetDescription(), theme, visible);
291 else if (name.equals(DISCHARGE_CURVE) 242 } else if (FacetTypes.IS.MANUALPOINTS(name)) {
292 || name.equals(GAUGE_DISCHARGE_CURVE)) { 243 doPoints(artifactFacet.getData(context), artifactFacet, theme, visible, YAXIS.W.idx);
293 doDischargeOut( 244 } else if (STATIC_WQ.equals(name)) {
294 (D4EArtifact)artifactFacet.getArtifact(), 245 doWQOut(artifactFacet.getData(context), artifactFacet, theme, visible);
295 artifactFacet.getData(context), 246 } else {
296 artifactFacet.getFacetDescription(), 247 log.warn("DischargeCurveGenerator.doOut: Unknown facet name: " + name);
297 theme, 248 return;
298 visible); 249 }
299 } 250 }
300 else if (FacetTypes.IS.MANUALPOINTS(name)) {
301 doPoints(artifactFacet.getData(context),
302 artifactFacet,
303 theme, visible, YAXIS.W.idx);
304 }
305 else if (STATIC_WQ.equals(name)) {
306 doWQOut(artifactFacet.getData(context),
307 artifactFacet,
308 theme,
309 visible);
310 }
311 else {
312 log.warn("DischargeCurveGenerator.doOut: Unknown facet name: "
313 + name);
314 return;
315 }
316 }
317
318 251
319 /** 252 /**
320 * Add series with discharge curve to diagram. 253 * Add series with discharge curve to diagram.
321 */ 254 */
322 protected void doDischargeOut( 255 protected void doDischargeOut(final D4EArtifact artifact, final Object o, final String description, final ThemeDocument theme, final boolean visible) {
323 D4EArtifact artifact,
324 Object o,
325 String description,
326 ThemeDocument theme,
327 boolean visible)
328 {
329 log.debug("DischargeCurveGenerator.doDischargeOut"); 256 log.debug("DischargeCurveGenerator.doDischargeOut");
330 WQKms wqkms = (WQKms) o; 257 final WQKms wqkms = (WQKms) o;
331 258
332 String gaugeName = wqkms.getName(); 259 final String gaugeName = wqkms.getName();
333 260
334 River river = new RiverAccess(artifact).getRiver(); 261 final River river = new RiverAccess(artifact).getRiver();
335 262
336 if (river == null) { 263 if (river == null) {
337 log.debug("no river found"); 264 log.debug("no river found");
338 return; 265 return;
339 } 266 }
340 267
341 Gauge gauge = river.determineGaugeByName(gaugeName); 268 final Gauge gauge = river.determineGaugeByName(gaugeName);
342 269
343 if (gauge == null) { 270 if (gauge == null) {
344 log.debug("no gauge found"); 271 log.debug("no gauge found");
345 return; 272 return;
346 } 273 }
347 274
348 XYSeries series = new StyledXYSeries(description, theme); 275 final XYSeries series = new StyledXYSeries(description, theme);
349 276
350 StyledSeriesBuilder.addPointsQW(series, wqkms); 277 StyledSeriesBuilder.addPointsQW(series, wqkms);
351 278
352 addAxisSeries(series, YAXIS.W.idx, visible); 279 addAxisSeries(series, YAXIS.W.idx, visible);
353 } 280 }
354 281
355 /** 282 /**
356 * Add W/Q-Series to plot. 283 * Add W/Q-Series to plot.
357 * @param wqkms actual data 284 *
358 * @param theme theme to use. 285 * @param wqkms
359 */ 286 * actual data
360 protected void doQOut( 287 * @param theme
361 Object wqkms, 288 * theme to use.
362 ArtifactAndFacet aaf, 289 */
363 ThemeDocument theme, 290 protected void doQOut(final Object wqkms, final ArtifactAndFacet aaf, final ThemeDocument theme, final boolean visible) {
364 boolean visible
365 ) {
366 log.debug("DischargeCurveGenerator: doQOut (add W/Q data)."); 291 log.debug("DischargeCurveGenerator: doQOut (add W/Q data).");
367 XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), theme); 292 final XYSeries series = new StyledXYSeries(aaf.getFacetDescription(), theme);
368 293
369 StyledSeriesBuilder.addPointsQW(series, (WQKms) wqkms); 294 StyledSeriesBuilder.addPointsQW(series, (WQKms) wqkms);
370 295
371 addAxisSeries(series, YAXIS.W.idx, visible); 296 addAxisSeries(series, YAXIS.W.idx, visible);
372 } 297 }
373 298
374
375 /** Add a point annotation at given x and y coordinates. */ 299 /** Add a point annotation at given x and y coordinates. */
376 protected void addPointTextAnnotation( 300 protected void addPointTextAnnotation(final String title, final double x, final double y, final ThemeDocument theme) {
377 String title,
378 double x,
379 double y,
380 ThemeDocument theme
381 ) {
382 final List<XYTextAnnotation> textAnnos = new ArrayList<>(); 301 final List<XYTextAnnotation> textAnnos = new ArrayList<>();
383 XYTextAnnotation anno = new CollisionFreeXYTextAnnotation( 302 final XYTextAnnotation anno = new CollisionFreeXYTextAnnotation(title, x, y);
384 title,
385 x,
386 y);
387 textAnnos.add(anno); 303 textAnnos.add(anno);
388 RiverAnnotation flysAnno = new RiverAnnotation( 304 final RiverAnnotation flysAnno = new RiverAnnotation(null, null, null, theme);
389 null, null, null, theme);
390 flysAnno.setTextAnnotations(textAnnos); 305 flysAnno.setTextAnnotations(textAnnos);
391 addAnnotations(flysAnno); 306 addAnnotations(flysAnno);
392 } 307 }
393
394 308
395 /** 309 /**
396 * Return true if all values in data[0] are smaller than zero 310 * Return true if all values in data[0] are smaller than zero
397 * (in imported data they are set to -1 symbolically). 311 * (in imported data they are set to -1 symbolically).
398 * Return false if data is null or empty 312 * Return false if data is null or empty
399 */ 313 */
400 private static boolean hasNoDischarge(double[][] data) { 314 private static boolean hasNoDischarge(final double[][] data) {
401 if (data == null || data.length == 0) { 315 if (data == null || data.length == 0) {
402 return false; 316 return false;
403 } 317 }
404 318
405 double[] qs = data[0]; 319 final double[] qs = data[0];
406 for (double q: qs) { 320 for (final double q : qs) {
407 if (q > 0d) { 321 if (q > 0d) {
408 return false; 322 return false;
409 } 323 }
410 } 324 }
411 325
412 return true; 326 return true;
413 } 327 }
414 328
415
416 /** 329 /**
417 * Add WQ Data to plot. 330 * Add WQ Data to plot.
418 * @param wq data as double[][] 331 *
419 */ 332 * @param wq
420 protected void doWQOut( 333 * data as double[][]
421 Object wq, 334 */
422 ArtifactAndFacet aaf, 335 protected void doWQOut(final Object wq, final ArtifactAndFacet aaf, final ThemeDocument theme, final boolean visible) {
423 ThemeDocument theme,
424 boolean visible
425 ) {
426 log.debug("DischargeCurveGenerator: doWQOut"); 336 log.debug("DischargeCurveGenerator: doWQOut");
427 double [][] data = (double [][]) wq; 337 final double[][] data = (double[][]) wq;
428 String title = aaf.getFacetDescription(); 338 final String title = aaf.getFacetDescription();
429 339
430 double translate = getCurrentGaugeDatum(); 340 final double translate = getCurrentGaugeDatum();
431 341
432 // If no Q values (i.e. all -1) found, add annotations. 342 // If no Q values (i.e. all -1) found, add annotations.
433 if (hasNoDischarge(data)) { 343 if (hasNoDischarge(data)) {
434 final List<StickyAxisAnnotation> xy = new ArrayList<>(); 344 final List<StickyAxisAnnotation> xy = new ArrayList<>();
435 345
436 for (double y: data[1]) { 346 for (double y : data[1]) {
437 if (translate != 0d) { 347 if (translate != 0d) {
438 y = (y-translate)*100d; 348 y = (y - translate) * 100d;
439 } 349 }
440 350
441 xy.add(new StickyAxisAnnotation( 351 xy.add(new StickyAxisAnnotation(title, (float) y, StickyAxisAnnotation.SimpleAxis.Y_AXIS));
442 title, 352 }
443 (float) y, 353
444 StickyAxisAnnotation.SimpleAxis.Y_AXIS)); 354 doAnnotations(new RiverAnnotation(title, xy), aaf, theme, visible);
445 }
446
447 doAnnotations(
448 new RiverAnnotation(title, xy),
449 aaf, theme, visible);
450 return; 355 return;
451 } 356 }
452 357
453 // Otherwise add points. 358 // Otherwise add points.
454 XYSeries series = new StyledXYSeries(title, theme); 359 final XYSeries series = new StyledXYSeries(title, theme);
455 360
456 if (translate != 0d) { 361 if (translate != 0d) {
457 StyledSeriesBuilder.addPointsQW(series, data, -translate, 100d); 362 StyledSeriesBuilder.addPointsQW(series, data, -translate, 100d);
458 addAxisSeries(series, YAXIS.W.idx, visible); 363 addAxisSeries(series, YAXIS.W.idx, visible);
459 } 364 } else {
460 else {
461 StyledSeriesBuilder.addPoints(series, data, true); 365 StyledSeriesBuilder.addPoints(series, data, true);
462 addAxisSeries(series, YAXIS.W.idx, visible); 366 addAxisSeries(series, YAXIS.W.idx, visible);
463 } 367 }
464 368
465 if (visible && theme.parseShowPointLabel() 369 if (visible && theme.parseShowPointLabel() && data != null && data.length != 0) {
466 && data != null && data.length != 0) { 370
467 371 final double[] xs = data[0];
468 double[] xs = data[0]; 372 final double[] ys = data[1];
469 double[] ys = data[1];
470 for (int i = 0; i < xs.length; i++) { 373 for (int i = 0; i < xs.length; i++) {
471 double x = xs[i]; 374 final double x = xs[i];
472 double y = ys[i]; 375 double y = ys[i];
473 376
474 if (translate != 0d) { 377 if (translate != 0d) {
475 y = (y-translate)*100d; 378 y = (y - translate) * 100d;
476 } 379 }
477 380
478 addPointTextAnnotation(title, x, y, theme); 381 addPointTextAnnotation(title, x, y, theme);
479 } 382 }
480 } 383 }

http://dive4elements.wald.intevation.org