comparison gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/NaviChartOutputTab.java @ 9263:abf14917be32

Moved stepping behaviour of NaviOutputChart into an exchangeable strategy. Allows for distinct values stepping of sinfo flood duration.
author gernotbelger
date Tue, 17 Jul 2018 19:48:18 +0200
parents 850ce16034e9
children 05405292a7ca
comparison
equal deleted inserted replaced
9262:fee5fa18361c 9263:abf14917be32
9 package org.dive4elements.river.client.client.ui.chart; 9 package org.dive4elements.river.client.client.ui.chart;
10 10
11 import java.util.Date; 11 import java.util.Date;
12 import java.util.HashMap; 12 import java.util.HashMap;
13 import java.util.Map; 13 import java.util.Map;
14 import java.util.Set;
14 15
15 import org.dive4elements.river.client.client.Config; 16 import org.dive4elements.river.client.client.Config;
16 import org.dive4elements.river.client.client.ui.CollectionView; 17 import org.dive4elements.river.client.client.ui.CollectionView;
17 import org.dive4elements.river.client.shared.model.AbstractFixBunduArtifact; 18 import org.dive4elements.river.client.shared.model.AbstractFixBunduArtifact;
18 import org.dive4elements.river.client.shared.model.Artifact; 19 import org.dive4elements.river.client.shared.model.Artifact;
19 import org.dive4elements.river.client.shared.model.Collection; 20 import org.dive4elements.river.client.shared.model.Collection;
21 import org.dive4elements.river.client.shared.model.CollectionItem;
20 import org.dive4elements.river.client.shared.model.FixFilter; 22 import org.dive4elements.river.client.shared.model.FixFilter;
21 import org.dive4elements.river.client.shared.model.OutputMode; 23 import org.dive4elements.river.client.shared.model.OutputMode;
24 import org.dive4elements.river.client.shared.model.SINFOArtifact;
22 25
23 import com.google.gwt.core.client.GWT; 26 import com.google.gwt.core.client.GWT;
24 import com.google.gwt.i18n.client.NumberFormat; 27 import com.google.gwt.i18n.client.NumberFormat;
25 import com.smartgwt.client.types.Alignment; 28 import com.smartgwt.client.types.Alignment;
29 import com.smartgwt.client.util.SC;
26 import com.smartgwt.client.widgets.Button; 30 import com.smartgwt.client.widgets.Button;
27 import com.smartgwt.client.widgets.Canvas; 31 import com.smartgwt.client.widgets.Canvas;
28 import com.smartgwt.client.widgets.events.ClickEvent; 32 import com.smartgwt.client.widgets.events.ClickEvent;
29 import com.smartgwt.client.widgets.events.ClickHandler; 33 import com.smartgwt.client.widgets.events.ClickHandler;
30 import com.smartgwt.client.widgets.form.DynamicForm; 34 import com.smartgwt.client.widgets.form.DynamicForm;
40 * Tab representing and showing one Chart-output with a "navi" thing. 44 * Tab representing and showing one Chart-output with a "navi" thing.
41 * 45 *
42 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> 46 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
43 */ 47 */
44 public class NaviChartOutputTab extends ChartOutputTab implements TabSelectedHandler { 48 public class NaviChartOutputTab extends ChartOutputTab implements TabSelectedHandler {
45 protected TextItem currentkm; 49 private TextItem currentkm;
50
51 private final NumberFormat kmFormat = NumberFormat.getDecimalFormat();
52
53 private INaviChartStepper stepper;
46 54
47 public NaviChartOutputTab(final String title, final Collection collection, final OutputMode mode, final CollectionView collectionView) { 55 public NaviChartOutputTab(final String title, final Collection collection, final OutputMode mode, final CollectionView collectionView) {
48 super(title, collection, mode, collectionView); 56 super(title, collection, mode, collectionView);
57
58 this.stepper = new NilNaviChartStepper();
59
49 this.right.removeChild(this.chart); 60 this.right.removeChild(this.chart);
50 this.right.addChild(createNaviChart()); 61 this.right.addChild(createNaviChart());
51 collectionView.registerTabHandler(this); 62 collectionView.registerTabHandler(this);
52 } 63 }
53 64
70 this.currentkm.setShowTitle(false); 81 this.currentkm.setShowTitle(false);
71 82
72 form.setFields(this.currentkm); 83 form.setFields(this.currentkm);
73 form.setWidth(60); 84 form.setWidth(60);
74 85
75 double fromKm; 86 this.stepper = createStepper(art);
76 double toKm; 87
88 // Always jump to the from km when initialized.
89 final double currentKm = this.stepper.getCurrentKm();
90 this.collectionView.setCurrentKm(currentKm);
91 this.currentkm.setValue(this.kmFormat.format(currentKm));
92
93 lower.addClickHandler(new ClickHandler() {
94 @Override
95 public void onClick(final ClickEvent ce) {
96 updateChartDown();
97 }
98 });
99
100 upper.addClickHandler(new ClickHandler() {
101 @Override
102 public void onClick(final ClickEvent ce) {
103 updateChartUp();
104 }
105 });
106
107 this.currentkm.addKeyPressHandler(new KeyPressHandler() {
108 @Override
109 public void onKeyPress(final KeyPressEvent kpe) {
110
111 if (!kpe.getKeyName().equals("Enter"))
112 return;
113
114 if (kpe.getItem().getValue() != null) {
115 final String kmText = kpe.getItem().getValue().toString();
116 updateChartKm(kmText);
117 }
118 }
119 });
120 layout.addMember(lower);
121 layout.addMember(form);
122 layout.addMember(upper);
123
124 root.addMember(this.chart);
125 root.addMember(layout);
126 return root;
127 }
128
129 private INaviChartStepper createStepper(final Artifact art) {
77 130
78 if (art instanceof AbstractFixBunduArtifact) { 131 if (art instanceof AbstractFixBunduArtifact) {
79 final AbstractFixBunduArtifact fix = (AbstractFixBunduArtifact) art; 132 final AbstractFixBunduArtifact fix = (AbstractFixBunduArtifact) art;
80 final FixFilter fixFilter = fix.getFilter(); 133 final FixFilter fixFilter = fix.getFilter();
134
135 final double fromKm = fixFilter.getLowerKm();
136 final double toKm = fixFilter.getUpperKm();
137
81 final String s = fix.getArtifactDescription().getDataValueAsString("ld_step"); 138 final String s = fix.getArtifactDescription().getDataValueAsString("ld_step");
82 try { 139 try {
83 final double ds = Double.parseDouble(s); 140 final double ds = Double.parseDouble(s);
84 this.collectionView.setSteps(ds); 141 return new MinMaxStepNaviChartStepper(fromKm, toKm, ds);
85 } 142 }
86 catch (final NumberFormatException nfe) { 143 catch (final NumberFormatException nfe) {
87 this.collectionView.setSteps(100d); 144 return new MinMaxStepNaviChartStepper(fromKm, toKm, 100d);
88 } 145 }
89 fromKm = fixFilter.getLowerKm(); 146 } else if (art instanceof SINFOArtifact) {
90 toKm = fixFilter.getUpperKm(); 147 /* special case for SINFO-Flood-Duration */
148 final SINFOArtifact sinfo = (SINFOArtifact) art;
149
150 final CollectionItem item = this.collection.getItem(sinfo.getUuid());
151
152 final Set<Double> validKms = sinfo.getValidDurationChartKms(item);
153 return new DistinctValuesNaviChartStepper(validKms);
91 } else { 154 } else {
92 // Probably WINFOArtifact kind of artifact. 155 // Probably WINFOArtifact kind of artifact.
93 final String ld_step = art.getArtifactDescription().getDataValueAsString("ld_step"); 156
94 try { 157 double fromKm;
95 this.collectionView.setSteps(Double.valueOf(ld_step)); 158 double toKm;
96 }
97 catch (final Exception e) {
98 GWT.log("No ld_steps data or not parsable.");
99 return root;
100 }
101 159
102 final double[] kmRange = art.getArtifactDescription().getKMRange(); 160 final double[] kmRange = art.getArtifactDescription().getKMRange();
103 if (kmRange == null || kmRange.length == 2) { 161 if (kmRange != null && kmRange.length == 2) {
104 fromKm = kmRange[0]; 162 fromKm = kmRange[0];
105 toKm = kmRange[1]; 163 toKm = kmRange[1];
106 } else { 164 } else {
107 GWT.log("No KM range in description found."); 165 GWT.log("No KM range in description found.");
108 return root; 166 return new NilNaviChartStepper();
109 } 167 }
110 } 168
111 169 final String ld_step = art.getArtifactDescription().getDataValueAsString("ld_step");
112 this.collectionView.setMinKm(fromKm); 170 try {
113 this.collectionView.setMaxKm(toKm); 171 final Double step = Double.valueOf(ld_step);
114 172 return new MinMaxStepNaviChartStepper(fromKm, toKm, step);
115 final NumberFormat nf = NumberFormat.getDecimalFormat(); 173 }
116 174 catch (final Exception e) {
117 // Always jump to the from km when initialized. 175 GWT.log("No ld_steps data or not parsable.", e);
176 return new MinMaxStepNaviChartStepper(fromKm, toKm, 100d);
177 }
178 }
179 }
180
181 protected void updateChartKm(final String kmText) {
182
183 NaviChartOutputTab.this.tbarPanel.deselectControls();
184
118 try { 185 try {
119 final double d = Double.valueOf(fromKm); 186 final double d = this.kmFormat.parse(kmText);
120 this.currentkm.setValue(nf.format(d)); 187
188 final double validCurrentKm = this.stepper.setValidCurrentKm(d);
189 updateCurrentKm(validCurrentKm);
121 } 190 }
122 catch (final NumberFormatException e) { 191 catch (final NumberFormatException e) {
123 this.currentkm.setValue(fromKm); 192 SC.warn("Invalid value: " + kmText);
124 } 193 // do nothing, but an error message would be nice
125 this.collectionView.setCurrentKm(fromKm); 194 }
126
127 lower.addClickHandler(new ClickHandler() {
128 @Override
129 public void onClick(final ClickEvent ce) {
130 NaviChartOutputTab.this.tbarPanel.deselectControls();
131 updateChartDown();
132 try {
133 final double d = Double.valueOf(NaviChartOutputTab.this.collectionView.getCurrentKm());
134 NaviChartOutputTab.this.currentkm.setValue(nf.format(d));
135 NaviChartOutputTab.this.tbarPanel.onZoom(null);
136 }
137 catch (final NumberFormatException e) {
138 NaviChartOutputTab.this.currentkm.setValue(NaviChartOutputTab.this.collectionView.getCurrentKm());
139 }
140 }
141 });
142
143 upper.addClickHandler(new ClickHandler() {
144 @Override
145 public void onClick(final ClickEvent ce) {
146 NaviChartOutputTab.this.tbarPanel.deselectControls();
147 updateChartUp();
148 try {
149 final double d = Double.valueOf(NaviChartOutputTab.this.collectionView.getCurrentKm());
150 NaviChartOutputTab.this.currentkm.setValue(nf.format(d));
151 NaviChartOutputTab.this.tbarPanel.onZoom(null);
152 }
153 catch (final NumberFormatException e) {
154 NaviChartOutputTab.this.currentkm.setValue(NaviChartOutputTab.this.collectionView.getCurrentKm());
155 }
156 }
157 });
158
159 this.currentkm.addKeyPressHandler(new KeyPressHandler() {
160 @Override
161 public void onKeyPress(final KeyPressEvent kpe) {
162 if (!kpe.getKeyName().equals("Enter")) {
163 return;
164 }
165 if (kpe.getItem().getValue() != null) {
166 NaviChartOutputTab.this.tbarPanel.deselectControls();
167 try {
168 final String s = kpe.getItem().getValue().toString();
169 double d;
170 try {
171 d = nf.parse(s);
172 NaviChartOutputTab.this.currentkm.setValue(nf.format(d));
173 }
174 catch (final NumberFormatException e) {
175 d = -1d;
176 }
177 if (d <= NaviChartOutputTab.this.collectionView.getMaxKm() && d >= NaviChartOutputTab.this.collectionView.getMinKm()) {
178 NaviChartOutputTab.this.collectionView.setCurrentKm(d);
179 NaviChartOutputTab.this.tbarPanel.updateLinks();
180 NaviChartOutputTab.this.tbarPanel.onZoom(null);
181 if (NaviChartOutputTab.this.right != null) {
182 updateChartPanel();
183 updateChartInfo();
184 }
185 }
186 }
187 catch (final NumberFormatException nfe) {
188 // Do nothing.
189 }
190 }
191 }
192 });
193 layout.addMember(lower);
194 layout.addMember(form);
195 layout.addMember(upper);
196
197 root.addMember(this.chart);
198 root.addMember(layout);
199 return root;
200 } 195 }
201 196
202 /** 197 /**
203 * Callback when km-up-button is clicked. 198 * Callback when km-up-button is clicked.
204 * Increases collectionViews KM and refreshes view. 199 * Increases collectionViews KM and refreshes view.
205 */ 200 */
206 protected void updateChartUp() { 201 protected void updateChartUp() {
207 final double currentKm = this.collectionView.getCurrentKm(); 202
208 if (currentKm < this.collectionView.getMaxKm()) { 203 this.tbarPanel.deselectControls();
209 // Why this math? 204
210 double newVal = currentKm * 100; 205 final double nextKm = this.stepper.stepForward();
211 newVal += (this.collectionView.getSteps() / 10); 206 updateCurrentKm(nextKm);
212 this.collectionView.setCurrentKm((double) Math.round(newVal) / 100);
213 this.tbarPanel.updateLinks();
214 updateChartPanel();
215 updateChartInfo();
216 }
217 } 207 }
218 208
219 /** 209 /**
220 * Callback when km-down-button is clicked. 210 * Callback when km-down-button is clicked.
221 * Decreases collectionViews KM and refreshes view. 211 * Decreases collectionViews KM and refreshes view.
222 */ 212 */
223 protected void updateChartDown() { 213 protected void updateChartDown() {
224 final double currentKm = this.collectionView.getCurrentKm(); 214
225 if (currentKm > this.collectionView.getMinKm()) { 215 this.tbarPanel.deselectControls();
226 // Why this math? 216
227 double newVal = currentKm * 100; 217 final double prevKm = this.stepper.stepBackward();
228 newVal -= (this.collectionView.getSteps() / 10); 218 updateCurrentKm(prevKm);
229 this.collectionView.setCurrentKm((double) Math.round(newVal) / 100); 219 }
230 this.tbarPanel.updateLinks(); 220
231 updateChartPanel(); 221 private void updateCurrentKm(final double currentKm) {
232 updateChartInfo(); 222
233 } 223 this.collectionView.setCurrentKm(currentKm);
224
225 this.tbarPanel.updateLinks();
226
227 updateChartPanel();
228 updateChartInfo();
229
230 this.currentkm.setValue(this.kmFormat.format(currentKm));
231 this.tbarPanel.onZoom(null);
234 232
235 } 233 }
236 234
237 /** 235 /**
238 * Returns the existing chart panel. 236 * Returns the existing chart panel.
287 imgUrl += "&miny=" + zoom[2]; 285 imgUrl += "&miny=" + zoom[2];
288 imgUrl += "&maxy=" + zoom[3]; 286 imgUrl += "&maxy=" + zoom[3];
289 } 287 }
290 } 288 }
291 289
292 if (this.collectionView.getArtifact() instanceof AbstractFixBunduArtifact) { 290 if (this.collectionView.getCurrentKm() == -1) {
293 if (this.collectionView.getCurrentKm() == -1) { 291 // REMARK: this happens, because we get called from the constructor of our super class
292
293 if (this.collectionView.getArtifact() instanceof AbstractFixBunduArtifact) {
294 final AbstractFixBunduArtifact fix = (AbstractFixBunduArtifact) this.collectionView.getArtifact(); 294 final AbstractFixBunduArtifact fix = (AbstractFixBunduArtifact) this.collectionView.getArtifact();
295 this.collectionView.setCurrentKm(fix.getFilter().getLowerKm()); 295 this.collectionView.setCurrentKm(fix.getFilter().getLowerKm());
296 } 296 }
297 } else if (this.collectionView.getCurrentKm() == -1) { 297 else
298 this.collectionView.setCurrentKm(this.collectionView.getArtifact().getArtifactDescription().getKMRange()[0]); 298 this.collectionView.setCurrentKm(this.collectionView.getArtifact().getArtifactDescription().getKMRange()[0]);
299 } 299 }
300
300 if (this.collectionView.getCurrentKm() != -1) { 301 if (this.collectionView.getCurrentKm() != -1) {
301 imgUrl += "&currentKm=" + this.collectionView.getCurrentKm(); 302 imgUrl += "&currentKm=" + this.collectionView.getCurrentKm();
302 } 303 }
303 304
304 return imgUrl; 305 return imgUrl;
305 } 306 }
306 307
307 @Override 308 @Override
308 public void onTabSelected(final TabSelectedEvent tse) { 309 public void onTabSelected(final TabSelectedEvent tse) {
309 if (this.equals(tse.getTab())) { 310 if (this.equals(tse.getTab())) {
310 updateChartPanel(); 311
311 updateChartInfo(); 312 final double currentKm = this.collectionView.getCurrentKm();
312 this.currentkm.setValue(this.collectionView.getCurrentKm()); 313
314 final double validCurrentKm = this.stepper.setValidCurrentKm(currentKm);
315 updateCurrentKm(validCurrentKm);
313 } 316 }
314 } 317 }
315 318
316 @Override 319 @Override
317 public Map<String, String> getChartAttributes() { 320 public Map<String, String> getChartAttributes() {
334 url += "&currentKm=" + this.collectionView.getCurrentKm(); 337 url += "&currentKm=" + this.collectionView.getCurrentKm();
335 } 338 }
336 return url; 339 return url;
337 } 340 }
338 } 341 }
339 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org