Mercurial > dive4elements > river
view gwt-client/src/main/java/org/dive4elements/river/client/client/ui/chart/DistinctValuesNaviChartStepper.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 | |
children |
line wrap: on
line source
/** 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; } }