Mercurial > dive4elements > river
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 } |