[PATCH 2 of 4] Moved stepping behaviour of NaviOutputChart into an exchangeable strategy
Wald Commits
scm-commit at wald.intevation.org
Tue Jul 17 19:48:35 CEST 2018
# HG changeset patch
# User gernotbelger
# Date 1531849698 -7200
# Node ID abf14917be32342903492834851988cc4780fffc
# Parent fee5fa18361c2c81fbfac4de816aabea463c8cab
Moved stepping behaviour of NaviOutputChart into an exchangeable strategy.
Allows for distinct values stepping of sinfo flood duration.
diff -r fee5fa18361c -r abf14917be32 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/CollectionView.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/CollectionView.java Tue Jul 17 19:48:09 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/CollectionView.java Tue Jul 17 19:48:18 2018 +0200
@@ -28,8 +28,6 @@
import org.dive4elements.river.client.client.event.ParameterChangeHandler;
import org.dive4elements.river.client.client.services.AddArtifactService;
import org.dive4elements.river.client.client.services.AddArtifactServiceAsync;
-import org.dive4elements.river.client.client.services.ArtifactService;
-import org.dive4elements.river.client.client.services.ArtifactServiceAsync;
import org.dive4elements.river.client.client.services.CollectionAttributeService;
import org.dive4elements.river.client.client.services.CollectionAttributeServiceAsync;
import org.dive4elements.river.client.client.services.CreateCollectionService;
@@ -62,64 +60,58 @@
* @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
*/
public class CollectionView extends Window implements CollectionChangeHandler, HasCollectionChangeHandlers, OutputModesChangeHandler, HasOutputModesChangeHandlers, ParameterChangeHandler, CloseClickHandler {
- /** The ArtifactService used to communicate with the Artifact server. */
- protected CreateCollectionServiceAsync createCollectionService = GWT.create(CreateCollectionService.class);
+
+ /** The message class that provides i18n strings. */
+ private static final FLYSConstants messages = GWT.create(FLYSConstants.class);
/** The ArtifactService used to communicate with the Artifact server. */
- protected ArtifactServiceAsync createArtifactService = GWT.create(ArtifactService.class);
+ private final CreateCollectionServiceAsync createCollectionService = GWT.create(CreateCollectionService.class);
/** The AddArtifactService used to add an artifact to a collection. */
- protected AddArtifactServiceAsync addArtifactService = GWT.create(AddArtifactService.class);
+ private final AddArtifactServiceAsync addArtifactService = GWT.create(AddArtifactService.class);
/** The DescribeCollectionService used to update the existing collection. */
- protected DescribeCollectionServiceAsync describeCollectionService = GWT.create(DescribeCollectionService.class);
+ private final DescribeCollectionServiceAsync describeCollectionService = GWT.create(DescribeCollectionService.class);
- protected CollectionAttributeServiceAsync updater = GWT.create(CollectionAttributeService.class);
+ private final CollectionAttributeServiceAsync updater = GWT.create(CollectionAttributeService.class);
/** The LoadArtifactService used to load recommendations */
- protected LoadArtifactServiceAsync loadArtifactService = GWT.create(LoadArtifactService.class);
-
- /** The message class that provides i18n strings. */
- protected FLYSConstants messages = GWT.create(FLYSConstants.class);
+ private final LoadArtifactServiceAsync loadArtifactService = GWT.create(LoadArtifactService.class);
/** The FLYS instance used to call services. */
- protected FLYS flys;
+ private final FLYS flys;
/** The ParameterList. */
- protected ParameterList parameterList;
+ private ParameterList parameterList;
/** The list of CollectionChangeHandlers. */
- protected List<CollectionChangeHandler> handlers;
+ private final List<CollectionChangeHandler> handlers;
/** The list of OutputModesChangeHandlers. */
- protected List<OutputModesChangeHandler> outHandlers;
+ private final List<OutputModesChangeHandler> outHandlers;
/** The collection to be displayed. */
- protected Collection collection;
+ private Collection collection;
/** The artifact that handles the parameterization. */
- protected Artifact artifact;
+ private Artifact artifact;
- protected TabSet tabs;
+ private final TabSet tabs;
/** The output tab. */
- protected Map<String, OutputTab> outputTabs;
+ private final Map<String, OutputTab> outputTabs;
/** The layout. */
- protected Layout layout;
+ private final Layout layout;
/** Layout to show spinning wheel of joy. */
- protected VLayout lockScreen;
+ private VLayout lockScreen;
- protected int artifactsQueue;
- protected int recommendationQueue;
- protected Stack<Recommendation> newRecommendations;
+ private final int artifactsQueue;
+ private final Stack<Recommendation> newRecommendations;
/** Values for fix analysis charts */
- protected double currentKm;
- protected double minKm;
- protected double maxKm;
- protected double steps;
+ private double currentKm;
/**
* This constructor creates a new CollectionView that is used to display the
@@ -132,15 +124,11 @@
this.handlers = new ArrayList<CollectionChangeHandler>();
this.outHandlers = new ArrayList<OutputModesChangeHandler>();
this.layout = new VLayout();
- this.parameterList = new ParameterList(flys, this, this.messages.new_project());
+ this.parameterList = new ParameterList(flys, this, CollectionView.messages.new_project());
this.artifactsQueue = 0;
- this.recommendationQueue = 0;
this.newRecommendations = new Stack<Recommendation>();
this.currentKm = -1d;
- this.minKm = -1d;
- this.maxKm = -1d;
- this.steps = -1d;
addCollectionChangeHandler(this);
addCollectionChangeHandler(this.parameterList);
@@ -169,9 +157,6 @@
this.layout = new VLayout();
this.currentKm = -1d;
- this.minKm = -1d;
- this.maxKm = -1d;
- this.steps = -1d;
if (artifact != null) {
this.parameterList = new ParameterList(flys, this,
@@ -179,9 +164,9 @@
// but... the international name is resolved client-side.... Instead also transport the description of the artifact and
// use it!
// FIXME: the same holds for a very few other international strings (e.g. names of facets used in Tabs)
- this.messages.getString(artifact.getName()), artifact);
+ CollectionView.messages.getString(artifact.getName()), artifact);
} else {
- this.parameterList = new ParameterList(flys, this, this.messages.new_project());
+ this.parameterList = new ParameterList(flys, this, CollectionView.messages.new_project());
}
this.artifactsQueue = 0;
@@ -208,7 +193,7 @@
/**
* This method handles the initial layout stuff.
*/
- protected void init() {
+ private void init() {
setWidth(1010);
setHeight(700);
@@ -229,7 +214,7 @@
this.tabs.addTab(this.parameterList);
}
- protected FLYS getFlys() {
+ private FLYS getFlys() {
return this.flys;
}
@@ -263,13 +248,13 @@
* This method calls the <code>onValueChange()</code> method of all
* registered ValueChangeHanders.
*/
- protected void fireCollectionChangeEvent(final Collection old, final Collection newCol) {
+ private void fireCollectionChangeEvent(final Collection old, final Collection newCol) {
for (final CollectionChangeHandler handler : this.handlers) {
handler.onCollectionChange(new CollectionChangeEvent(old, newCol));
}
}
- protected void fireOutputModesChangeEvent(final OutputMode[] outputs) {
+ private void fireOutputModesChangeEvent(final OutputMode[] outputs) {
if (this.collection == null) {
return;
}
@@ -290,16 +275,6 @@
}
/**
- * This method returns true, if the Collection is new and no plugins has
- * been chosen.
- *
- * @return true, if the Collection is new.
- */
- public boolean isNew() {
- return this.collection.hasItems();
- }
-
- /**
* Returns the artifact that is used for the parameterization.
*
* @return the artifact that is used for the parameterization.
@@ -321,10 +296,6 @@
public void setArtifact(final Artifact artifact) {
this.artifact = artifact;
- onArtifactChanged(artifact);
- }
-
- public void onArtifactChanged(final Artifact artifact) {
artifactChanged();
if (artifact.isInBackground()) {
@@ -346,7 +317,7 @@
setArtifact(event.getNewValue());
}
- protected void artifactChanged() {
+ private void artifactChanged() {
final Collection c = getCollection();
if (c != null) {
@@ -359,15 +330,14 @@
/**
* Loads all information of a collection.
* If 'recommendations' present, load these.
- *
+ *
* @param c
* the Collection
*/
private void loadCollection(final Collection c) {
final ArtifactDescription desc = getArtifact().getArtifactDescription();
final Recommendation[] recom = desc.getRecommendations();
- final Config config = Config.getInstance();
- final String locale = config.getLocale();
+ final String locale = Config.getInstance().getLocale();
this.describeCollectionService.describe(c.identifier(), locale, new AsyncCallback<Collection>() {
@Override
@@ -403,7 +373,7 @@
return this.collection;
}
- protected void setCollection(final Collection collection) {
+ private void setCollection(final Collection collection) {
setCollection(collection, false);
}
@@ -415,7 +385,7 @@
* @param suppress
* Whether to fire a collectionchangeevent.
*/
- protected void setCollection(final Collection collection, final boolean suppress) {
+ public void setCollection(final Collection collection, final boolean suppress) {
if (collection != null && this.collection == null) {
this.flys.getWorkspace().addView(collection.identifier(), this);
}
@@ -423,11 +393,11 @@
final Collection tmp = this.collection;
this.collection = collection;
- setTitle(collection.getDisplayName());
+ if (collection != null)
+ setTitle(collection.getDisplayName());
- if (!suppress) {
+ if (!suppress)
fireCollectionChangeEvent(tmp, this.collection);
- }
}
@Override
@@ -488,7 +458,7 @@
* @param name
* The name and title of the output.
*/
- protected void addOutputTab(final String name, final OutputMode out) {
+ private void addOutputTab(final String name, final OutputMode out) {
if (out instanceof ExportMode) {
final ExportMode export = (ExportMode) out;
@@ -509,18 +479,17 @@
GWT.log("Add new output tab for '" + name + "'");
- final String title = this.messages.getString(name);
+ final String title = CollectionView.messages.getString(name);
final OutputTab tab = out.createOutputTab(title, getCollection(), this);
- if (tab != null) {
+ if (tab != null)
this.outputTabs.put(name, tab);
- }
}
/**
* Removes all output mode tabs from tab bar.
*/
- protected void clearOutputTabs() {
+ private void clearOutputTabs() {
GWT.log("Clear OutputTabs.");
final int num = this.tabs.getNumTabs();
@@ -535,7 +504,7 @@
/**
* Update the view (refresh the list of old and current data).
*/
- protected void updateView() {
+ private void updateView() {
GWT.log("CollectionView.updateView()");
updateOutputTabs();
}
@@ -543,7 +512,7 @@
/**
* This method is used to update the tabs to show specific output modes.
*/
- protected void updateOutputTabs() {
+ private void updateOutputTabs() {
GWT.log("Update output tabs.");
if (this.outputTabs != null) {
final Set<String> keys = this.outputTabs.keySet();
@@ -569,14 +538,12 @@
}
public void addArtifactToCollection(final Artifact artifact) {
- final Config config = Config.getInstance();
- final String locale = config.getLocale();
- final Collection collection = getCollection();
+ final String locale = Config.getInstance().getLocale();
- GWT.log("CollectionView.addArtifactToCollection " + collection);
+ GWT.log("CollectionView.addArtifactToCollection " + this.collection);
- if (collection != null) {
- this.addArtifactService.add(collection, artifact, locale, new AsyncCallback<Collection>() {
+ if (this.collection != null) {
+ this.addArtifactService.add(this.collection, artifact, locale, new AsyncCallback<Collection>() {
@Override
public void onFailure(final Throwable caught) {
GWT.log("An error occured while adding artifact.");
@@ -596,7 +563,7 @@
@Override
public void onFailure(final Throwable caught) {
GWT.log("Could not create the new collection.");
- SC.warn(FLYS.getExceptionString(CollectionView.this.messages, caught));
+ SC.warn(FLYS.getExceptionString(CollectionView.messages, caught));
}
@Override
@@ -620,18 +587,16 @@
}
}
- protected void addRecommendationsToCollection() {
- final Config config = Config.getInstance();
- final String locale = config.getLocale();
- final Collection collection = getCollection();
+ private void addRecommendationsToCollection() {
+ final String locale = Config.getInstance().getLocale();
- collection.addRecommendations(this.newRecommendations);
+ this.collection.addRecommendations(this.newRecommendations);
- this.updater.update(collection, locale, new AsyncCallback<Collection>() {
+ this.updater.update(this.collection, locale, new AsyncCallback<Collection>() {
@Override
public void onFailure(final Throwable caught) {
CollectionView.this.newRecommendations.removeAllElements();
- setCollection(collection);
+ setCollection(CollectionView.this.collection);
GWT.log("An error occured while saving recommendations.");
SC.warn(FLYS.getExceptionString(CollectionView.this.messages, caught));
@@ -646,10 +611,8 @@
});
}
- protected void loadRecommendedArtifacts(final Recommendation[] recommendations) {
- final Config config = Config.getInstance();
- final String locale = config.getLocale();
- final Collection collection = getCollection();
+ private void loadRecommendedArtifacts(final Recommendation[] recommendations) {
+ final String locale = Config.getInstance().getLocale();
final Artifact masterArtifact = getArtifact();
@@ -659,7 +622,7 @@
}
for (final Recommendation recommendation : recommendations) {
- if (collection.loadedRecommendation(recommendation)) {
+ if (this.collection.loadedRecommendation(recommendation)) {
continue;
}
this.newRecommendations.push(recommendation);
@@ -672,11 +635,11 @@
}
- this.loadArtifactService.loadMany(collection, recommendations, null, locale, new AsyncCallback<Artifact[]>() {
+ this.loadArtifactService.loadMany(this.collection, recommendations, null, locale, new AsyncCallback<Artifact[]>() {
@Override
public void onFailure(final Throwable caught) {
GWT.log("Error loading recommendations: " + caught.getMessage());
- SC.warn(FLYS.getExceptionString(CollectionView.this.messages, caught));
+ SC.warn(FLYS.getExceptionString(CollectionView.messages, caught));
}
@Override
@@ -698,29 +661,4 @@
public double getCurrentKm() {
return this.currentKm;
}
-
- public void setMinKm(final double km) {
- this.minKm = km;
- }
-
- public double getMinKm() {
- return this.minKm;
- }
-
- public void setMaxKm(final double km) {
- this.maxKm = km;
- }
-
- public double getMaxKm() {
- return this.maxKm;
- }
-
- public void setSteps(final double step) {
- this.steps = step;
- }
-
- public double getSteps() {
- return this.steps;
- }
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
diff -r fee5fa18361c -r abf14917be32 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/DistinctValuesNaviChartStepper.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/DistinctValuesNaviChartStepper.java Tue Jul 17 19:48:18 2018 +0200
@@ -0,0 +1,126 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui.chart;
+
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ * Allows stepping through a list of distinct (known) values.
+ *
+ * @author Gernot Belger
+ */
+public class DistinctValuesNaviChartStepper implements INaviChartStepper {
+
+ private final TreeSet<Double> validSteps = new TreeSet<Double>();
+
+ private double currentKm;
+
+ public DistinctValuesNaviChartStepper(final Set<Double> validKms) {
+ this.validSteps.addAll(validKms);
+
+ if (this.validSteps.isEmpty())
+ this.validSteps.add(-1d);
+
+ this.currentKm = this.validSteps.first();
+ }
+
+ @Override
+ public double getCurrentKm() {
+ return this.currentKm;
+ }
+
+ @Override
+ public double stepForward() {
+ this.currentKm = calculateStepFormward();
+ return this.currentKm;
+ }
+
+ private double calculateStepFormward() {
+ // REMARK: can't use higher due to gwt bug
+ // final Double next = this.validSteps.higher(this.currentKm);
+
+ // REMAREK: add a bit, because tailSet is inclusive
+ final SortedSet<Double> tailSet = this.validSteps.tailSet(this.currentKm + 1e-6);
+ final Double next = tailSet.isEmpty() ? null : tailSet.first();
+
+ if (next != null)
+ return next;
+
+ return this.validSteps.last();
+ }
+
+ @Override
+ public double stepBackward() {
+ this.currentKm = calculateStepBackward();
+ return this.currentKm;
+ }
+
+ private double calculateStepBackward() {
+ // REMARK: can't use lower due to gwt bug
+ // final Double prev = this.validSteps.lower(this.currentKm);
+
+ final SortedSet<Double> headSet = this.validSteps.headSet(this.currentKm);
+ final Double prev = headSet.isEmpty() ? null : headSet.last();
+
+ if (prev != null)
+ return prev;
+
+ return this.validSteps.first();
+ }
+
+ @Override
+ public double setValidCurrentKm(final double currentKm) {
+ this.currentKm = calculateValidCurrentKm(currentKm);
+ return this.currentKm;
+ }
+
+ private double calculateValidCurrentKm(final double newKm) {
+
+ if (this.validSteps.contains(newKm)) {
+ /* special case, and because headSet() is not inclusive */
+ return newKm;
+ }
+
+ final SortedSet<Double> headSet = this.validSteps.headSet(newKm);
+ final SortedSet<Double> tailSet = this.validSteps.tailSet(newKm);
+
+ // REMARK: can't use floor/ceiling because of gwt bug
+ // final Double floor = this.validSteps.floor(currentKm);
+ // final Double ceiling = this.validSteps.ceiling(currentKm);
+ final Double floor = headSet.isEmpty() ? null : headSet.last();
+ final Double ceiling = tailSet.isEmpty() ? null : tailSet.first();
+
+ if (floor != null && ceiling == null)
+ return floor;
+
+ if (floor == null && ceiling != null)
+ return ceiling;
+
+ if (floor == null && ceiling == null) {
+ /* should never happen as validKms is never empty */
+ return this.currentKm;
+ }
+
+ if (floor == null || ceiling == null) {
+ /* will never happen, but makes the NullPointer access checker happy, else we get warnings in the folowing code */
+ return this.currentKm;
+ }
+
+ /* both not null; find nearest */
+ final double floorDiff = Math.abs(newKm - floor);
+ final double ceilingDiff = Math.abs(newKm - ceiling);
+ if (floorDiff < ceilingDiff)
+ return floor;
+
+ return ceiling;
+ }
+}
\ No newline at end of file
diff -r fee5fa18361c -r abf14917be32 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/INaviChartStepper.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/INaviChartStepper.java Tue Jul 17 19:48:18 2018 +0200
@@ -0,0 +1,25 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui.chart;
+
+/**
+ * Abstraction for stepping through the navi chart.
+ *
+ * @author Gernot Belger
+ */
+public interface INaviChartStepper {
+ double getCurrentKm();
+
+ double stepForward();
+
+ double stepBackward();
+
+ double setValidCurrentKm(double userInput);
+}
\ No newline at end of file
diff -r fee5fa18361c -r abf14917be32 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/MinMaxStepNaviChartStepper.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/MinMaxStepNaviChartStepper.java Tue Jul 17 19:48:18 2018 +0200
@@ -0,0 +1,80 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui.chart;
+
+/**
+ * 'Old' stepping behaviour of the navi chart, as used by WINFO and Fixierungsanalyse.
+ *
+ * @author Gernot Belger
+ */
+public class MinMaxStepNaviChartStepper implements INaviChartStepper {
+
+ private double currentKm;
+ private final double minKm;
+ private final double maxKm;
+ private final double step;
+
+ public MinMaxStepNaviChartStepper(final double minKm, final double maxKm, final double step) {
+ this.minKm = minKm;
+ this.maxKm = maxKm;
+ this.step = step;
+
+ this.currentKm = minKm;
+ }
+
+ @Override
+ public double getCurrentKm() {
+ return this.currentKm;
+ }
+
+ @Override
+ public double stepForward() {
+
+ if (this.currentKm >= this.maxKm)
+ this.currentKm = this.maxKm;
+ else {
+ // Why this math?
+ double newVal = this.currentKm * 100;
+ newVal += this.step / 10;
+ this.currentKm = (double) Math.round(newVal) / 100;
+ }
+
+ return this.currentKm;
+ }
+
+ @Override
+ public double stepBackward() {
+
+ if (this.currentKm <= this.minKm)
+ this.currentKm = this.minKm;
+ else {
+ // Why this math?
+ double newVal = this.currentKm * 100;
+ newVal -= this.step / 10;
+
+ this.currentKm = ((double) Math.round(newVal) / 100);
+ }
+
+ return this.currentKm;
+ }
+
+ @Override
+ public double setValidCurrentKm(final double userInput) {
+
+ if (userInput > this.maxKm)
+ this.currentKm = this.maxKm;
+ else if (userInput < this.minKm)
+ this.currentKm = this.minKm;
+ else
+ this.currentKm = userInput;
+
+ return this.currentKm;
+ }
+}
\ No newline at end of file
diff -r fee5fa18361c -r abf14917be32 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/NaviChartOutputTab.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/NaviChartOutputTab.java Tue Jul 17 19:48:09 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/NaviChartOutputTab.java Tue Jul 17 19:48:18 2018 +0200
@@ -11,18 +11,22 @@
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import org.dive4elements.river.client.client.Config;
import org.dive4elements.river.client.client.ui.CollectionView;
import org.dive4elements.river.client.shared.model.AbstractFixBunduArtifact;
import org.dive4elements.river.client.shared.model.Artifact;
import org.dive4elements.river.client.shared.model.Collection;
+import org.dive4elements.river.client.shared.model.CollectionItem;
import org.dive4elements.river.client.shared.model.FixFilter;
import org.dive4elements.river.client.shared.model.OutputMode;
+import org.dive4elements.river.client.shared.model.SINFOArtifact;
import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.NumberFormat;
import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.events.ClickEvent;
@@ -42,10 +46,17 @@
* @author <a href="mailto:ingo.weinzierl at intevation.de">Ingo Weinzierl</a>
*/
public class NaviChartOutputTab extends ChartOutputTab implements TabSelectedHandler {
- protected TextItem currentkm;
+ private TextItem currentkm;
+
+ private final NumberFormat kmFormat = NumberFormat.getDecimalFormat();
+
+ private INaviChartStepper stepper;
public NaviChartOutputTab(final String title, final Collection collection, final OutputMode mode, final CollectionView collectionView) {
super(title, collection, mode, collectionView);
+
+ this.stepper = new NilNaviChartStepper();
+
this.right.removeChild(this.chart);
this.right.addChild(createNaviChart());
collectionView.registerTabHandler(this);
@@ -72,121 +83,37 @@
form.setFields(this.currentkm);
form.setWidth(60);
- double fromKm;
- double toKm;
-
- if (art instanceof AbstractFixBunduArtifact) {
- final AbstractFixBunduArtifact fix = (AbstractFixBunduArtifact) art;
- final FixFilter fixFilter = fix.getFilter();
- final String s = fix.getArtifactDescription().getDataValueAsString("ld_step");
- try {
- final double ds = Double.parseDouble(s);
- this.collectionView.setSteps(ds);
- }
- catch (final NumberFormatException nfe) {
- this.collectionView.setSteps(100d);
- }
- fromKm = fixFilter.getLowerKm();
- toKm = fixFilter.getUpperKm();
- } else {
- // Probably WINFOArtifact kind of artifact.
- final String ld_step = art.getArtifactDescription().getDataValueAsString("ld_step");
- try {
- this.collectionView.setSteps(Double.valueOf(ld_step));
- }
- catch (final Exception e) {
- GWT.log("No ld_steps data or not parsable.");
- return root;
- }
-
- final double[] kmRange = art.getArtifactDescription().getKMRange();
- if (kmRange == null || kmRange.length == 2) {
- fromKm = kmRange[0];
- toKm = kmRange[1];
- } else {
- GWT.log("No KM range in description found.");
- return root;
- }
- }
-
- this.collectionView.setMinKm(fromKm);
- this.collectionView.setMaxKm(toKm);
-
- final NumberFormat nf = NumberFormat.getDecimalFormat();
+ this.stepper = createStepper(art);
// Always jump to the from km when initialized.
- try {
- final double d = Double.valueOf(fromKm);
- this.currentkm.setValue(nf.format(d));
- }
- catch (final NumberFormatException e) {
- this.currentkm.setValue(fromKm);
- }
- this.collectionView.setCurrentKm(fromKm);
+ final double currentKm = this.stepper.getCurrentKm();
+ this.collectionView.setCurrentKm(currentKm);
+ this.currentkm.setValue(this.kmFormat.format(currentKm));
lower.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent ce) {
- NaviChartOutputTab.this.tbarPanel.deselectControls();
updateChartDown();
- try {
- final double d = Double.valueOf(NaviChartOutputTab.this.collectionView.getCurrentKm());
- NaviChartOutputTab.this.currentkm.setValue(nf.format(d));
- NaviChartOutputTab.this.tbarPanel.onZoom(null);
- }
- catch (final NumberFormatException e) {
- NaviChartOutputTab.this.currentkm.setValue(NaviChartOutputTab.this.collectionView.getCurrentKm());
- }
}
});
upper.addClickHandler(new ClickHandler() {
@Override
public void onClick(final ClickEvent ce) {
- NaviChartOutputTab.this.tbarPanel.deselectControls();
updateChartUp();
- try {
- final double d = Double.valueOf(NaviChartOutputTab.this.collectionView.getCurrentKm());
- NaviChartOutputTab.this.currentkm.setValue(nf.format(d));
- NaviChartOutputTab.this.tbarPanel.onZoom(null);
- }
- catch (final NumberFormatException e) {
- NaviChartOutputTab.this.currentkm.setValue(NaviChartOutputTab.this.collectionView.getCurrentKm());
- }
}
});
this.currentkm.addKeyPressHandler(new KeyPressHandler() {
@Override
public void onKeyPress(final KeyPressEvent kpe) {
- if (!kpe.getKeyName().equals("Enter")) {
+
+ if (!kpe.getKeyName().equals("Enter"))
return;
- }
+
if (kpe.getItem().getValue() != null) {
- NaviChartOutputTab.this.tbarPanel.deselectControls();
- try {
- final String s = kpe.getItem().getValue().toString();
- double d;
- try {
- d = nf.parse(s);
- NaviChartOutputTab.this.currentkm.setValue(nf.format(d));
- }
- catch (final NumberFormatException e) {
- d = -1d;
- }
- if (d <= NaviChartOutputTab.this.collectionView.getMaxKm() && d >= NaviChartOutputTab.this.collectionView.getMinKm()) {
- NaviChartOutputTab.this.collectionView.setCurrentKm(d);
- NaviChartOutputTab.this.tbarPanel.updateLinks();
- NaviChartOutputTab.this.tbarPanel.onZoom(null);
- if (NaviChartOutputTab.this.right != null) {
- updateChartPanel();
- updateChartInfo();
- }
- }
- }
- catch (final NumberFormatException nfe) {
- // Do nothing.
- }
+ final String kmText = kpe.getItem().getValue().toString();
+ updateChartKm(kmText);
}
}
});
@@ -199,21 +126,84 @@
return root;
}
+ private INaviChartStepper createStepper(final Artifact art) {
+
+ if (art instanceof AbstractFixBunduArtifact) {
+ final AbstractFixBunduArtifact fix = (AbstractFixBunduArtifact) art;
+ final FixFilter fixFilter = fix.getFilter();
+
+ final double fromKm = fixFilter.getLowerKm();
+ final double toKm = fixFilter.getUpperKm();
+
+ final String s = fix.getArtifactDescription().getDataValueAsString("ld_step");
+ try {
+ final double ds = Double.parseDouble(s);
+ return new MinMaxStepNaviChartStepper(fromKm, toKm, ds);
+ }
+ catch (final NumberFormatException nfe) {
+ return new MinMaxStepNaviChartStepper(fromKm, toKm, 100d);
+ }
+ } else if (art instanceof SINFOArtifact) {
+ /* special case for SINFO-Flood-Duration */
+ final SINFOArtifact sinfo = (SINFOArtifact) art;
+
+ final CollectionItem item = this.collection.getItem(sinfo.getUuid());
+
+ final Set<Double> validKms = sinfo.getValidDurationChartKms(item);
+ return new DistinctValuesNaviChartStepper(validKms);
+ } else {
+ // Probably WINFOArtifact kind of artifact.
+
+ double fromKm;
+ double toKm;
+
+ final double[] kmRange = art.getArtifactDescription().getKMRange();
+ if (kmRange != null && kmRange.length == 2) {
+ fromKm = kmRange[0];
+ toKm = kmRange[1];
+ } else {
+ GWT.log("No KM range in description found.");
+ return new NilNaviChartStepper();
+ }
+
+ final String ld_step = art.getArtifactDescription().getDataValueAsString("ld_step");
+ try {
+ final Double step = Double.valueOf(ld_step);
+ return new MinMaxStepNaviChartStepper(fromKm, toKm, step);
+ }
+ catch (final Exception e) {
+ GWT.log("No ld_steps data or not parsable.", e);
+ return new MinMaxStepNaviChartStepper(fromKm, toKm, 100d);
+ }
+ }
+ }
+
+ protected void updateChartKm(final String kmText) {
+
+ NaviChartOutputTab.this.tbarPanel.deselectControls();
+
+ try {
+ final double d = this.kmFormat.parse(kmText);
+
+ final double validCurrentKm = this.stepper.setValidCurrentKm(d);
+ updateCurrentKm(validCurrentKm);
+ }
+ catch (final NumberFormatException e) {
+ SC.warn("Invalid value: " + kmText);
+ // do nothing, but an error message would be nice
+ }
+ }
+
/**
* Callback when km-up-button is clicked.
* Increases collectionViews KM and refreshes view.
*/
protected void updateChartUp() {
- final double currentKm = this.collectionView.getCurrentKm();
- if (currentKm < this.collectionView.getMaxKm()) {
- // Why this math?
- double newVal = currentKm * 100;
- newVal += (this.collectionView.getSteps() / 10);
- this.collectionView.setCurrentKm((double) Math.round(newVal) / 100);
- this.tbarPanel.updateLinks();
- updateChartPanel();
- updateChartInfo();
- }
+
+ this.tbarPanel.deselectControls();
+
+ final double nextKm = this.stepper.stepForward();
+ updateCurrentKm(nextKm);
}
/**
@@ -221,16 +211,24 @@
* Decreases collectionViews KM and refreshes view.
*/
protected void updateChartDown() {
- final double currentKm = this.collectionView.getCurrentKm();
- if (currentKm > this.collectionView.getMinKm()) {
- // Why this math?
- double newVal = currentKm * 100;
- newVal -= (this.collectionView.getSteps() / 10);
- this.collectionView.setCurrentKm((double) Math.round(newVal) / 100);
- this.tbarPanel.updateLinks();
- updateChartPanel();
- updateChartInfo();
- }
+
+ this.tbarPanel.deselectControls();
+
+ final double prevKm = this.stepper.stepBackward();
+ updateCurrentKm(prevKm);
+ }
+
+ private void updateCurrentKm(final double currentKm) {
+
+ this.collectionView.setCurrentKm(currentKm);
+
+ this.tbarPanel.updateLinks();
+
+ updateChartPanel();
+ updateChartInfo();
+
+ this.currentkm.setValue(this.kmFormat.format(currentKm));
+ this.tbarPanel.onZoom(null);
}
@@ -289,14 +287,17 @@
}
}
- if (this.collectionView.getArtifact() instanceof AbstractFixBunduArtifact) {
- if (this.collectionView.getCurrentKm() == -1) {
+ if (this.collectionView.getCurrentKm() == -1) {
+ // REMARK: this happens, because we get called from the constructor of our super class
+
+ if (this.collectionView.getArtifact() instanceof AbstractFixBunduArtifact) {
final AbstractFixBunduArtifact fix = (AbstractFixBunduArtifact) this.collectionView.getArtifact();
this.collectionView.setCurrentKm(fix.getFilter().getLowerKm());
}
- } else if (this.collectionView.getCurrentKm() == -1) {
- this.collectionView.setCurrentKm(this.collectionView.getArtifact().getArtifactDescription().getKMRange()[0]);
+ else
+ this.collectionView.setCurrentKm(this.collectionView.getArtifact().getArtifactDescription().getKMRange()[0]);
}
+
if (this.collectionView.getCurrentKm() != -1) {
imgUrl += "¤tKm=" + this.collectionView.getCurrentKm();
}
@@ -307,9 +308,11 @@
@Override
public void onTabSelected(final TabSelectedEvent tse) {
if (this.equals(tse.getTab())) {
- updateChartPanel();
- updateChartInfo();
- this.currentkm.setValue(this.collectionView.getCurrentKm());
+
+ final double currentKm = this.collectionView.getCurrentKm();
+
+ final double validCurrentKm = this.stepper.setValidCurrentKm(currentKm);
+ updateCurrentKm(validCurrentKm);
}
}
@@ -335,5 +338,4 @@
}
return url;
}
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+}
\ No newline at end of file
diff -r fee5fa18361c -r abf14917be32 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/NilNaviChartStepper.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/NilNaviChartStepper.java Tue Jul 17 19:48:18 2018 +0200
@@ -0,0 +1,38 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.client.client.ui.chart;
+
+/**
+ * Nil implementation that always return 0 as current station.
+ *
+ * @author Gernot Belger
+ */
+public class NilNaviChartStepper implements INaviChartStepper {
+
+ @Override
+ public double getCurrentKm() {
+ return 0;
+ }
+
+ @Override
+ public double stepForward() {
+ return 0;
+ }
+
+ @Override
+ public double stepBackward() {
+ return 0;
+ }
+
+ @Override
+ public double setValidCurrentKm(final double userInput) {
+ return 0;
+ }
+}
\ No newline at end of file
diff -r fee5fa18361c -r abf14917be32 gwt-client/src/main/java/org/dive4elements/river/client/shared/model/ChartMode.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/ChartMode.java Tue Jul 17 19:48:09 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/ChartMode.java Tue Jul 17 19:48:18 2018 +0200
@@ -49,7 +49,8 @@
this.getName().equals("extreme_wq_curve") ||
this.getName().equals("fix_deltawt_curve") ||
this.getName().equals("fix_derivate_curve") ||
- this.getName().equals("fix_vollmer_wq_curve")){
+ this.getName().equals("fix_vollmer_wq_curve") ||
+ this.getName().equals("sinfo_floodduration_curve")){
return new NaviChartOutputTab(t, c, this, p);
}
return new ChartOutputTab(t, c, this, p);
diff -r fee5fa18361c -r abf14917be32 gwt-client/src/main/java/org/dive4elements/river/client/shared/model/SINFOArtifact.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/SINFOArtifact.java Tue Jul 17 19:48:09 2018 +0200
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/shared/model/SINFOArtifact.java Tue Jul 17 19:48:18 2018 +0200
@@ -8,8 +8,10 @@
package org.dive4elements.river.client.shared.model;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
-
+import java.util.Set;
/**
* The SINFO implementation of an Artifact.
@@ -18,29 +20,43 @@
*/
public class SINFOArtifact extends DefaultArtifact {
- /** The name of this artifact: 'sinfo'.*/
+ /** The name of this artifact: 'sinfo'. */
private static final String NAME = "sinfo";
/** Necessary for serialization */
public SINFOArtifact() {
}
-// public SINFOArtifact(String uuid, String hash) {
-// super(uuid, hash);
-// }
-
- public SINFOArtifact(
- String uuid,
- String hash,
- boolean inBackground,
- List<CalculationMessage> messages
- ) {
+ public SINFOArtifact(final String uuid, final String hash, final boolean inBackground, final List<CalculationMessage> messages) {
super(uuid, hash, inBackground, messages);
}
-
+ @Override
public String getName() {
return NAME;
}
-}
-// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
+
+ public Set<Double> getValidDurationChartKms(final CollectionItem item) {
+
+ final String validKmsText = item.getData().get("validStations");
+ if (validKmsText == null || validKmsText.trim().isEmpty())
+ return Collections.emptySet();
+
+ final String[] split = validKmsText.split(",");
+
+ final Set<Double> validKms = new HashSet<Double>(split.length);
+
+ for (final String stationText : split) {
+
+ try {
+ final double station = Double.parseDouble(stationText);
+ validKms.add(station);
+ }
+ catch (final NumberFormatException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return validKms;
+ }
+}
\ No newline at end of file
More information about the Dive4Elements-commits
mailing list