diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/RaceTimePanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/RaceTimePanel.java index 35c29d38f4d..f1639ab7c27 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/RaceTimePanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/RaceTimePanel.java @@ -18,8 +18,8 @@ public class RaceTimePanel extends TimePanel implements R private boolean autoAdjustPlayMode; private RaceTimesInfoDTO lastRaceTimesInfo; - public RaceTimePanel(Timer timer, StringMessages stringMessages, RaceTimesInfoProvider raceTimesInfoProvider) { - super(timer, stringMessages); + public RaceTimePanel(Timer timer, TimeRangeProvider timeRangeProvider, StringMessages stringMessages, RaceTimesInfoProvider raceTimesInfoProvider) { + super(timer, timeRangeProvider, stringMessages); this.raceTimesInfoProvider = raceTimesInfoProvider; selectedRace = null; autoAdjustPlayMode = true; @@ -66,7 +66,7 @@ public class RaceTimePanel extends TimePanel implements R timer.setPlayMode(PlayModes.Live); } - boolean timerAlreadyInitialized = getMin() != null && getMax() != null && timeSlider.getCurrentValue() != null; + boolean timerAlreadyInitialized = getFromTime() != null && getToTime() != null && timeSlider.getCurrentValue() != null; if (!isTimeZoomed) { updateMinMax(raceTimesInfo); if (!timerAlreadyInitialized) { @@ -83,7 +83,7 @@ public class RaceTimePanel extends TimePanel implements R } @Override - public void onTimeZoom(Date zoomStartTimepoint, Date zoomEndTimepoint) { + public void onTimeZoomChanged(Date zoomStartTimepoint, Date zoomEndTimepoint) { isTimeZoomed = true; timeSlider.setZoomed(true); timer.setAutoAdvance(false); @@ -151,7 +151,7 @@ public class RaceTimePanel extends TimePanel implements R Date max = raceMinMax.getB(); // never reduce max if it was already set - if (min != null && max != null && (getMax() == null || getMax().before(max))) { + if (min != null && max != null && (getToTime() == null || getToTime().before(max))) { setMinMax(min, max, /* fireEvent */ false); // no event because we guarantee time to be between min and max } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimePanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimePanel.java index 3c8c09282d0..05c0997a02c 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimePanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimePanel.java @@ -31,23 +31,10 @@ import com.sap.sailing.gwt.ui.shared.controls.slider.SliderBar; import com.sap.sailing.gwt.ui.shared.controls.slider.TimeSlider; public class TimePanel extends FormPanel implements Component, TimeListener, TimeZoomChangeListener, - PlayStateListener, RequiresResize { + TimeRangeChangeListener, PlayStateListener, RequiresResize { protected final Timer timer; protected boolean isTimeZoomed; - - /** - * The start time point of the time interval visualized by this time panel. May be null if not yet initialized. - * - * @see #setMinMax(Date, Date, boolean) - */ - private Date min; - - /** - * The end time point of the time interval visualized by this time panel. May be null if not yet initialized. - * - * @see #setMinMax(Date, Date, boolean) - */ - private Date max; + protected final TimeRangeProvider timeRangeProvider; private final IntegerBox playSpeedBox; private final Label timeDelayLabel; @@ -67,7 +54,7 @@ public class TimePanel extends FormPanel implements private final Image playModeImage; protected Date lastReceivedDataTimepoint; private final Button slowDownButton; - private final Button speedUpButton; + private final Button speedUpButton; /** * The live delay may be adjusted automatically if the server decides so. However, if the user explicitly sets a live delay, @@ -96,12 +83,14 @@ public class TimePanel extends FormPanel implements } } - public TimePanel(Timer timer, StringMessages stringMessages) { + public TimePanel(Timer timer, TimeRangeProvider timeRangeProvider, StringMessages stringMessages) { this.timer = timer; + this.timeRangeProvider = timeRangeProvider; this.stringMessages = stringMessages; isTimeZoomed = false; timer.addTimeListener(this); - timer.addPlayStateListener(this); + timer.addPlayStateListener(this); + timeRangeProvider.addTimeRangeChangeListener(this); userExplicitlyChangedLivePlayDelay = false; FlowPanel timePanelInnerWrapper = new FlowPanel(); timePanelInnerWrapper.setStyleName("timePanelInnerWrapper"); @@ -296,16 +285,21 @@ public class TimePanel extends FormPanel implements @Override public void timeChanged(Date time) { - if (getMin() != null && getMax() != null) { - // Handle also the case where time advances beyond slider's end. - // Handle it equally for replay and live mode for robustness reasons. This at least allows a user - // to watch on even if the time panel was off in its assumptions about race end and end of tracking. - if (time.after(getMax())) { - Date newMaxTime = new Date(time.getTime()); - if (newMaxTime.getTime() - getMax().getTime() < MINIMUM_AUTO_ADVANCE_TIME_IN_MS) { - newMaxTime.setTime(getMax().getTime() + MINIMUM_AUTO_ADVANCE_TIME_IN_MS); + if (getFromTime() != null && getToTime() != null) { + // handle the case where time advances beyond slider's end. + if (time.after(getToTime())) { + switch (timer.getPlayMode()) { + case Live: + Date newMaxTime = new Date(time.getTime()); + if (newMaxTime.getTime() - getToTime().getTime() < MINIMUM_AUTO_ADVANCE_TIME_IN_MS) { + newMaxTime.setTime(getToTime().getTime() + MINIMUM_AUTO_ADVANCE_TIME_IN_MS); + } + setMinMax(getFromTime(), newMaxTime, /* fireEvent */ false); // no event because we guarantee that time is between min/max + break; + case Replay: + timer.stop(); + break; } - setMinMax(getMin(), newMaxTime, /* fireEvent */ false); // no event because we guarantee that time is between min/max } long t = time.getTime(); timeSlider.setCurrentValue(new Double(t), false); @@ -318,12 +312,12 @@ public class TimePanel extends FormPanel implements } } - protected Date getMin() { - return min; + protected Date getFromTime() { + return timeRangeProvider.getFromTime(); } - protected Date getMax() { - return max; + protected Date getToTime() { + return timeRangeProvider.getToTime(); } /** @@ -334,20 +328,20 @@ public class TimePanel extends FormPanel implements assert min != null && max != null; boolean changed = false; - if (!max.equals(this.max)) { + if (!max.equals(timeRangeProvider.getToTime())) { changed = true; - this.max = max; timeSlider.setMaxValue(new Double(max.getTime()), fireEvent); } - if (!min.equals(this.min)) { + if (!min.equals(timeRangeProvider.getFromTime())) { changed = true; - this.min = min; timeSlider.setMinValue(new Double(min.getTime()), fireEvent); if (timeSlider.getCurrentValue() == null) { timeSlider.setCurrentValue(new Double(min.getTime()), fireEvent); } } if (changed) { + timeRangeProvider.setTimeRange(min, max, this); + int numSteps = timeSlider.getElement().getClientWidth(); if (numSteps > 0) { timeSlider.setStepSize(numSteps, fireEvent); @@ -379,6 +373,7 @@ public class TimePanel extends FormPanel implements case Paused: playPauseButton.getElement().removeClassName("playPauseButtonPause"); case Stopped: + playPauseButton.getElement().removeClassName("playPauseButtonPause"); playModeImage.setResource(playModeInactiveImg); break; } @@ -406,13 +401,17 @@ public class TimePanel extends FormPanel implements } @Override - public void onTimeZoom(Date zoomStartTimepoint, Date zoomEndTimepoint) { + public void onTimeZoomChanged(Date zoomStartTimepoint, Date zoomEndTimepoint) { } @Override public void onTimeZoomReset() { } - + + @Override + public void onTimeRangeChanged(Date fromTime, Date toTime) { + } + protected boolean isLiveModeToBeMadePossible() { return false; } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeChangeListener.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeChangeListener.java new file mode 100644 index 00000000000..491dbb43a6c --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeChangeListener.java @@ -0,0 +1,7 @@ +package com.sap.sailing.gwt.ui.client; + +import java.util.Date; + +public interface TimeRangeChangeListener { + void onTimeRangeChanged(Date fromTime, Date toTime); +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeModel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeModel.java new file mode 100644 index 00000000000..4c85bda0d67 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeModel.java @@ -0,0 +1,60 @@ +package com.sap.sailing.gwt.ui.client; + +import java.util.Arrays; +import java.util.Date; +import java.util.HashSet; +import java.util.Set; + +import com.sap.sailing.domain.common.impl.Util.Pair; + +public class TimeRangeModel implements TimeRangeProvider { + + /** + * The 'from' time of the time interval. May be null if not yet initialized. + */ + protected Date fromTime; + + /** + * The 'to' time of the time interval. May be null if not yet initialized. + */ + protected Date toTime; + + protected final Set listeners; + + public TimeRangeModel() { + listeners = new HashSet(); + } + + @Override + public void addTimeRangeChangeListener(TimeRangeChangeListener listener) { + listeners.add(listener); + } + + @Override + public void removeTimeRangeChangeListener(TimeRangeChangeListener listener) { + listeners.remove(listener); + } + + public void setTimeRange(final Date fromTime, final Date toTime, TimeRangeChangeListener... listenersNotToNotify) { + this.fromTime = fromTime != null ? new Date(fromTime.getTime()) : null; + this.toTime = toTime != null ? new Date(toTime.getTime()) : null; + + for (TimeRangeChangeListener listener : listeners) { + if (listenersNotToNotify == null || !Arrays.asList(listenersNotToNotify).contains(listener)) { + listener.onTimeRangeChanged(fromTime, toTime); + } + } + } + + public Pair getTimeRange() { + return new Pair(fromTime, toTime); + } + + public Date getFromTime() { + return fromTime; + } + + public Date getToTime() { + return toTime; + } +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeProvider.java new file mode 100644 index 00000000000..de2204030a7 --- /dev/null +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeProvider.java @@ -0,0 +1,20 @@ +package com.sap.sailing.gwt.ui.client; + +import java.util.Date; + +import com.sap.sailing.domain.common.impl.Util.Pair; + +public interface TimeRangeProvider { + + public void addTimeRangeChangeListener(TimeRangeChangeListener listener); + + public void removeTimeRangeChangeListener(TimeRangeChangeListener listener); + + public void setTimeRange(Date fromTime, Date toTime, TimeRangeChangeListener... listenersNotToNotify); + + public Date getFromTime(); + + public Date getToTime(); + + public Pair getTimeRange(); +} diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeZoomModel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeWithZoomModel.java similarity index 88% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeZoomModel.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeWithZoomModel.java index 52c608b2405..362a7fd35fa 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeZoomModel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeWithZoomModel.java @@ -7,14 +7,14 @@ import java.util.Set; import com.sap.sailing.domain.common.impl.Util.Pair; -public class TimeZoomModel implements TimeZoomProvider { +public class TimeRangeWithZoomModel extends TimeRangeModel implements TimeRangeWithZoomProvider { private Date zoomStartTimepoint; private Date zoomEndTimepoint; private boolean isTimeZoomed; private final Set listeners; - public TimeZoomModel() { + public TimeRangeWithZoomModel() { isTimeZoomed = false; listeners = new HashSet(); } @@ -35,7 +35,7 @@ public class TimeZoomModel implements TimeZoomProvider { this.isTimeZoomed = true; for (TimeZoomChangeListener listener : listeners) { if (listenersNotToNotify == null || !Arrays.asList(listenersNotToNotify).contains(listener)) { - listener.onTimeZoom(zoomStartTimepoint, zoomEndTimepoint); + listener.onTimeZoomChanged(zoomStartTimepoint, zoomEndTimepoint); } } } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeZoomProvider.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeWithZoomProvider.java similarity index 88% rename from java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeZoomProvider.java rename to java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeWithZoomProvider.java index d05ccd45ca0..0d9084ce601 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeZoomProvider.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeRangeWithZoomProvider.java @@ -4,7 +4,7 @@ import java.util.Date; import com.sap.sailing.domain.common.impl.Util.Pair; -public interface TimeZoomProvider { +public interface TimeRangeWithZoomProvider extends TimeRangeProvider { public void addTimeZoomChangeListener(TimeZoomChangeListener listener); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeZoomChangeListener.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeZoomChangeListener.java index f75679738ec..dfa80677980 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeZoomChangeListener.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/TimeZoomChangeListener.java @@ -4,7 +4,7 @@ import java.util.Date; public interface TimeZoomChangeListener { - void onTimeZoom(Date zoomStartTimepoint, Date zoomEndTimepoint); + void onTimeZoomChanged(Date zoomStartTimepoint, Date zoomEndTimepoint); void onTimeZoomReset(); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/CompareCompetitorsChartDialog.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/CompareCompetitorsChartDialog.java index 673bdfaf8cd..74829869213 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/CompareCompetitorsChartDialog.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/CompareCompetitorsChartDialog.java @@ -18,10 +18,9 @@ import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider; import com.sap.sailing.gwt.ui.client.ErrorReporter; import com.sap.sailing.gwt.ui.client.RaceSelectionModel; import com.sap.sailing.gwt.ui.client.RaceSelectionProvider; -import com.sap.sailing.gwt.ui.client.RaceTimesInfoProvider; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; -import com.sap.sailing.gwt.ui.client.TimeZoomModel; +import com.sap.sailing.gwt.ui.client.TimeRangeWithZoomModel; import com.sap.sailing.gwt.ui.client.Timer; import com.sap.sailing.gwt.ui.shared.charts.MultiChartPanel; import com.sap.sailing.gwt.ui.shared.charts.MultiChartSettings; @@ -37,8 +36,6 @@ public class CompareCompetitorsChartDialog extends DialogBoxExt { private final RaceSelectionProvider raceSelectionProvider; private final MultiChartPanel multiChartPanel; - - private final RaceTimesInfoProvider raceTimesInfoProvider; final ListBox racesListBox; @@ -54,12 +51,9 @@ public class CompareCompetitorsChartDialog extends DialogBoxExt { raceSelectionProvider = new RaceSelectionModel(); raceSelectionProvider.setAllRaces(races); - raceTimesInfoProvider = new RaceTimesInfoProvider(sailingService, errorReporter, races, 1000l); - multiChartPanel = new MultiChartPanel(sailingService, new AsyncActionsExecutor(), competitorSelectionProvider, raceSelectionProvider, - timer, new TimeZoomModel(), stringConstants, errorReporter, false, false); + timer, new TimeRangeWithZoomModel(), stringConstants, errorReporter, false, false); multiChartPanel.setSize("100%", "100%"); - raceTimesInfoProvider.addRaceTimesInfoProviderListener(multiChartPanel); VerticalPanel contentPanel = new VerticalPanel(); contentPanel.setSize("100%", "100%"); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java index ab7e64c5d18..4309238a32e 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java @@ -33,7 +33,7 @@ import com.sap.sailing.gwt.ui.client.RegattaDisplayer; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.client.TimeListener; -import com.sap.sailing.gwt.ui.client.TimeZoomModel; +import com.sap.sailing.gwt.ui.client.TimeRangeWithZoomModel; import com.sap.sailing.gwt.ui.client.Timer; import com.sap.sailing.gwt.ui.client.UserAgentDetails; import com.sap.sailing.gwt.ui.leaderboard.LeaderboardPanel; @@ -84,7 +84,7 @@ public class RaceBoardPanel extends FormPanel implements RegattaDisplayer, RaceS private final RaceSelectionProvider raceSelectionProvider; private final UserAgentDetails userAgent; private final CompetitorSelectionModel competitorSelectionModel; - private final TimeZoomModel timeZoomModel; + private final TimeRangeWithZoomModel timeRangeWithZoomModel; private final RegattaAndRaceIdentifier selectedRaceIdentifier; private LeaderboardPanel leaderboardPanel; @@ -123,7 +123,7 @@ public class RaceBoardPanel extends FormPanel implements RegattaDisplayer, RaceS setWidget(mainPanel); this.timer = timer; - timeZoomModel = new TimeZoomModel(); + timeRangeWithZoomModel = new TimeRangeWithZoomModel(); componentViewers = new ArrayList(); competitorSelectionModel = new CompetitorSelectionModel(/* hasMultiSelection */ true); @@ -138,8 +138,8 @@ public class RaceBoardPanel extends FormPanel implements RegattaDisplayer, RaceS break; } - timePanel = new RaceTimePanel(timer, stringMessages, raceTimesInfoProvider); - timeZoomModel.addTimeZoomChangeListener(timePanel); + timePanel = new RaceTimePanel(timer, timeRangeWithZoomModel, stringMessages, raceTimesInfoProvider); + timeRangeWithZoomModel.addTimeZoomChangeListener(timePanel); raceTimesInfoProvider.addRaceTimesInfoProviderListener(timePanel); raceSelectionProvider.addRaceSelectionChangeListener(timePanel); timePanel.onRaceSelectionChange(raceSelectionProvider.getSelectedRaces()); @@ -155,16 +155,14 @@ public class RaceBoardPanel extends FormPanel implements RegattaDisplayer, RaceS List> components = new ArrayList>(); competitorChart = new MultiChartPanel(sailingService, asyncActionsExecutor, competitorSelectionModel, raceSelectionProvider, - timer, timeZoomModel, stringMessages, errorReporter, true, true); + timer, timeRangeWithZoomModel, stringMessages, errorReporter, true, true); competitorChart.setVisible(false); - raceTimesInfoProvider.addRaceTimesInfoProviderListener(competitorChart); competitorChart.onRaceSelectionChange(raceSelectionProvider.getSelectedRaces()); components.add(competitorChart); - windChart = new WindChart(sailingService, raceSelectionProvider, timer, timeZoomModel, new WindChartSettings(), + windChart = new WindChart(sailingService, raceSelectionProvider, timer, timeRangeWithZoomModel, new WindChartSettings(), stringMessages, asyncActionsExecutor, errorReporter, /* compactChart */ true); windChart.setVisible(false); - raceTimesInfoProvider.addRaceTimesInfoProviderListener(windChart); windChart.onRaceSelectionChange(raceSelectionProvider.getSelectedRaces()); components.add(windChart); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/AbstractChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/AbstractChartPanel.java index 2182c8560a1..eb47797d953 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/AbstractChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/AbstractChartPanel.java @@ -47,7 +47,7 @@ import com.sap.sailing.gwt.ui.client.ErrorReporter; import com.sap.sailing.gwt.ui.client.RaceSelectionProvider; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; -import com.sap.sailing.gwt.ui.client.TimeZoomProvider; +import com.sap.sailing.gwt.ui.client.TimeRangeWithZoomProvider; import com.sap.sailing.gwt.ui.client.Timer; import com.sap.sailing.gwt.ui.client.Timer.PlayModes; import com.sap.sailing.gwt.ui.shared.CompetitorDTO; @@ -88,9 +88,9 @@ implements CompetitorSelectionChangeListener, RequiresResize { public AbstractChartPanel(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, CompetitorSelectionProvider competitorSelectionProvider, RaceSelectionProvider raceSelectionProvider, - Timer timer, TimeZoomProvider timeZoomProvider, final StringMessages stringMessages, ErrorReporter errorReporter, DetailType dataToShow, + Timer timer, TimeRangeWithZoomProvider timeRangeWithZoomProvider, final StringMessages stringMessages, ErrorReporter errorReporter, DetailType dataToShow, boolean compactChart, boolean allowTimeAdjust) { - super(sailingService, timer, timeZoomProvider, stringMessages, asyncActionsExecutor, errorReporter); + super(sailingService, timer, timeRangeWithZoomProvider, stringMessages, asyncActionsExecutor, errorReporter); this.competitorSelectionProvider = competitorSelectionProvider; this.dataToShow = dataToShow; this.compactChart = compactChart; @@ -107,8 +107,6 @@ implements CompetitorSelectionChangeListener, RequiresResize { competitorSelectionProvider.addCompetitorSelectionChangeListener(this); raceSelectionProvider.addRaceSelectionChangeListener(this); - timer.addTimeListener(this); - timeZoomProvider.addTimeZoomChangeListener(this); } @Override @@ -243,14 +241,14 @@ implements CompetitorSelectionChangeListener, RequiresResize { if (!chartData.contains(competitor)) { dataQuery.add(new Pair(new Date(0), competitor)); } else if (competitorDateOfNewestData.before(chartDataDateOfNewestData) - || competitorDateOfNewestData.before(maxTimepoint)) { + || competitorDateOfNewestData.before(timeRangeWithZoomProvider.getToTime())) { dataQuery.add(new Pair(new Date(competitorDateOfNewestData.getTime() + getStepSize()), competitor)); } } GetCompetitorsRaceDataAction getCompetitorsRaceDataAction = new GetCompetitorsRaceDataAction( - sailingService, selectedRaceIdentifier, dataQuery, maxTimepoint, getStepSize(), + sailingService, selectedRaceIdentifier, dataQuery, timeRangeWithZoomProvider.getToTime(), getStepSize(), getDataToShow(), new AsyncCallback() { @Override @@ -273,8 +271,8 @@ implements CompetitorSelectionChangeListener, RequiresResize { } } } - chart.getXAxis().setMin(minTimepoint.getTime()); - chart.getXAxis().setMax(maxTimepoint.getTime()); + chart.getXAxis().setMin(timeRangeWithZoomProvider.getFromTime().getTime()); + chart.getXAxis().setMax(timeRangeWithZoomProvider.getToTime().getTime()); drawChartData(); chart.redraw(); diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/ChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/ChartPanel.java index 8bdb5e08862..c2b988cc661 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/ChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/ChartPanel.java @@ -7,7 +7,7 @@ import com.sap.sailing.gwt.ui.client.ErrorReporter; import com.sap.sailing.gwt.ui.client.RaceSelectionProvider; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; -import com.sap.sailing.gwt.ui.client.TimeZoomProvider; +import com.sap.sailing.gwt.ui.client.TimeRangeWithZoomProvider; import com.sap.sailing.gwt.ui.client.Timer; import com.sap.sailing.gwt.ui.shared.components.Component; import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent; @@ -27,9 +27,9 @@ import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent; public class ChartPanel extends AbstractChartPanel implements Component { public ChartPanel(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, CompetitorSelectionProvider competitorSelectionProvider, - RaceSelectionProvider raceSelectionProvider, Timer timer, TimeZoomProvider timeZoomProvider, DetailType dataToShow, StringMessages stringMessages, + RaceSelectionProvider raceSelectionProvider, Timer timer, TimeRangeWithZoomProvider timeRangeWithZoomProvider, DetailType dataToShow, StringMessages stringMessages, ErrorReporter errorReporter, boolean compactChart, boolean allowTimeAdjust) { - super(sailingService, asyncActionsExecutor, competitorSelectionProvider, raceSelectionProvider, timer, timeZoomProvider, stringMessages, errorReporter, + super(sailingService, asyncActionsExecutor, competitorSelectionProvider, raceSelectionProvider, timer, timeRangeWithZoomProvider, stringMessages, errorReporter, dataToShow, compactChart, allowTimeAdjust); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/MultiChartPanel.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/MultiChartPanel.java index 7d16fdd67e2..0b8a9e5fa73 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/MultiChartPanel.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/MultiChartPanel.java @@ -7,7 +7,7 @@ import com.sap.sailing.gwt.ui.client.ErrorReporter; import com.sap.sailing.gwt.ui.client.RaceSelectionProvider; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; -import com.sap.sailing.gwt.ui.client.TimeZoomProvider; +import com.sap.sailing.gwt.ui.client.TimeRangeWithZoomProvider; import com.sap.sailing.gwt.ui.client.Timer; import com.sap.sailing.gwt.ui.shared.components.Component; import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent; @@ -27,9 +27,9 @@ import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent; public class MultiChartPanel extends AbstractChartPanel implements Component { public MultiChartPanel(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, CompetitorSelectionProvider competitorSelectionProvider, RaceSelectionProvider raceSelectionProvider, - Timer timer, TimeZoomProvider timeZoomProvider, final StringMessages stringMessages, ErrorReporter errorReporter, boolean compactChart, + Timer timer, TimeRangeWithZoomProvider timeRangeWithZoomProvider, final StringMessages stringMessages, ErrorReporter errorReporter, boolean compactChart, boolean allowTimeAdjust) { - super(sailingService, asyncActionsExecutor, competitorSelectionProvider, raceSelectionProvider, timer, timeZoomProvider, stringMessages, errorReporter, + super(sailingService, asyncActionsExecutor, competitorSelectionProvider, raceSelectionProvider, timer, timeRangeWithZoomProvider, stringMessages, errorReporter, /*show initially*/ DetailType.WINDWARD_DISTANCE_TO_OVERALL_LEADER, compactChart, allowTimeAdjust); } diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/RaceChart.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/RaceChart.java index f60a80b6050..619a0f725c7 100644 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/RaceChart.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/RaceChart.java @@ -1,7 +1,6 @@ package com.sap.sailing.gwt.ui.shared.charts; import java.util.Date; -import java.util.Map; import org.moxieapps.gwt.highcharts.client.Chart; import org.moxieapps.gwt.highcharts.client.Legend; @@ -18,33 +17,26 @@ import org.moxieapps.gwt.highcharts.client.plotOptions.SeriesPlotOptions; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.ui.SimplePanel; import com.sap.sailing.domain.common.RegattaAndRaceIdentifier; -import com.sap.sailing.domain.common.impl.Util.Pair; import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor; import com.sap.sailing.gwt.ui.client.ErrorReporter; import com.sap.sailing.gwt.ui.client.RaceSelectionChangeListener; -import com.sap.sailing.gwt.ui.client.RaceTimesCalculationUtil; -import com.sap.sailing.gwt.ui.client.RaceTimesInfoProviderListener; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; import com.sap.sailing.gwt.ui.client.TimeListener; +import com.sap.sailing.gwt.ui.client.TimeRangeChangeListener; +import com.sap.sailing.gwt.ui.client.TimeRangeWithZoomProvider; import com.sap.sailing.gwt.ui.client.TimeZoomChangeListener; -import com.sap.sailing.gwt.ui.client.TimeZoomProvider; import com.sap.sailing.gwt.ui.client.Timer; import com.sap.sailing.gwt.ui.client.Timer.PlayModes; -import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO; -public abstract class RaceChart extends SimplePanel implements RaceTimesInfoProviderListener, RaceSelectionChangeListener, - TimeListener, TimeZoomChangeListener { +public abstract class RaceChart extends SimplePanel implements RaceSelectionChangeListener, + TimeListener, TimeZoomChangeListener, TimeRangeChangeListener { protected Chart chart; protected final Timer timer; - protected final TimeZoomProvider timeZoomProvider; - - protected Date minTimepoint; - protected Date maxTimepoint; - + protected final TimeRangeWithZoomProvider timeRangeWithZoomProvider; + protected RegattaAndRaceIdentifier selectedRaceIdentifier; - protected RaceTimesInfoDTO lastRaceTimesInfo; protected final DateTimeFormat dateFormat = DateTimeFormat.getFormat("HH:mm:ss"); protected final DateTimeFormat dateFormatHoursMinutes = DateTimeFormat.getFormat("HH:mm"); @@ -62,47 +54,17 @@ public abstract class RaceChart extends SimplePanel implements RaceTimesInfoProv private boolean ignoreNextClickEvent; - public RaceChart(SailingServiceAsync sailingService, Timer timer, TimeZoomProvider timeZoomProvider, final StringMessages stringMessages, + public RaceChart(SailingServiceAsync sailingService, Timer timer, TimeRangeWithZoomProvider timeRangeWithZoomProvider, final StringMessages stringMessages, AsyncActionsExecutor asyncActionsExecutor, ErrorReporter errorReporter) { this.sailingService = sailingService; this.timer = timer; - this.timeZoomProvider = timeZoomProvider; + this.timeRangeWithZoomProvider = timeRangeWithZoomProvider; this.stringMessages = stringMessages; this.asyncActionsExecutor = asyncActionsExecutor; this.errorReporter = errorReporter; - } - - @Override - public void raceTimesInfosReceived(Map raceTimesInfos) { - this.lastRaceTimesInfo = raceTimesInfos.get(selectedRaceIdentifier); - - Pair raceMinMax = RaceTimesCalculationUtil.caluclateRaceMinMax(timer, this.lastRaceTimesInfo); - boolean updateMinMax = false; - - if(chart != null) { - if (minTimepoint == null || maxTimepoint == null) { - minTimepoint = raceMinMax.getA(); - maxTimepoint = raceMinMax.getB(); - updateMinMax = true; - } else if(minTimepoint.getTime() != raceMinMax.getA().getTime() || maxTimepoint.getTime() != raceMinMax.getB().getTime()) { - minTimepoint = raceMinMax.getA(); - maxTimepoint = raceMinMax.getB(); - updateMinMax = true; - } - } - if (updateMinMax) { - if (minTimepoint != null) { - chart.getXAxis().setMin(minTimepoint.getTime()); - } - if (maxTimepoint != null) { - chart.getXAxis().setMax(maxTimepoint.getTime()); - } - if (minTimepoint != null && maxTimepoint != null) { - chart.getXAxis().setExtremes(minTimepoint.getTime(), maxTimepoint.getTime(), false, false); - long tickInterval = (maxTimepoint.getTime() - minTimepoint.getTime()) / TICKCOUNT; - chart.getXAxis().setTickInterval(tickInterval); - } - } + timer.addTimeListener(this); + timeRangeWithZoomProvider.addTimeZoomChangeListener(this); + timeRangeWithZoomProvider.addTimeRangeChangeListener(this); } protected void showLoading(String message) { @@ -126,10 +88,10 @@ public abstract class RaceChart extends SimplePanel implements RaceTimesInfoProv if (!isZoomed) { isZoomed = true; } - timeZoomProvider.setTimeZoom(new Date(xAxisMin), new Date(xAxisMax), this); + timeRangeWithZoomProvider.setTimeZoom(new Date(xAxisMin), new Date(xAxisMax), this); } catch (Throwable t) { // in case the user clicks the "reset zoom" button chartSelectionEvent.getXAxisMinAsLong() throws in exception - timeZoomProvider.resetTimeZoom(this); + timeRangeWithZoomProvider.resetTimeZoom(this); // Trigger the redrawing... otherwise chart wouldn't reset the zoom chart.redraw(); isZoomed = false; @@ -151,19 +113,42 @@ public abstract class RaceChart extends SimplePanel implements RaceTimesInfoProv return true; } + protected void resetMinMaxInterval(Date minIntervalTimepoint, Date maxIntervalTimepoint) { + XAxis xAxis = chart.getXAxis(); + Date minTimepoint = timeRangeWithZoomProvider.getFromTime(); + Date maxTimepoint = timeRangeWithZoomProvider.getToTime(); + + if (minTimepoint != null) { + xAxis.setMin(minTimepoint.getTime()); + } + if (maxTimepoint != null) { + xAxis.setMax(maxTimepoint.getTime()); + } + if (minTimepoint != null && maxTimepoint != null) { + xAxis.setExtremes(minTimepoint.getTime(), maxTimepoint.getTime(), false, false); + long tickInterval = (maxTimepoint.getTime() - minTimepoint.getTime()) / TICKCOUNT; + xAxis.setTickInterval(tickInterval); + } + chart.redraw(); + } + protected void changeMinMaxInterval(Date minIntervalTimepoint, Date maxIntervalTimepoint) { XAxis xAxis = chart.getXAxis(); xAxis.setExtremes(minIntervalTimepoint.getTime(), maxIntervalTimepoint.getTime(), true, true); } - public void onTimeZoom(Date zoomStartTimepoint, Date zoomEndTimepoint) { + public void onTimeZoomChanged(Date zoomStartTimepoint, Date zoomEndTimepoint) { changeMinMaxInterval(zoomStartTimepoint, zoomEndTimepoint); // Probably there is a function for this in a newer version of highcharts: http://jsfiddle.net/mqz3N/1071/ // chart.showResetZoom(); } + public void onTimeRangeChanged(Date fromTime, Date toTime) { + resetMinMaxInterval(fromTime, toTime); + } + public void onTimeZoomReset() { - changeMinMaxInterval(minTimepoint, maxTimepoint); + changeMinMaxInterval(timeRangeWithZoomProvider.getFromTime(), timeRangeWithZoomProvider.getToTime()); } /** diff --git a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/WindChart.java b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/WindChart.java index 5b4bd7ac284..a4cf77feafb 100755 --- a/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/WindChart.java +++ b/java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/shared/charts/WindChart.java @@ -43,7 +43,7 @@ import com.sap.sailing.gwt.ui.client.ErrorReporter; import com.sap.sailing.gwt.ui.client.RaceSelectionProvider; import com.sap.sailing.gwt.ui.client.SailingServiceAsync; import com.sap.sailing.gwt.ui.client.StringMessages; -import com.sap.sailing.gwt.ui.client.TimeZoomProvider; +import com.sap.sailing.gwt.ui.client.TimeRangeWithZoomProvider; import com.sap.sailing.gwt.ui.client.Timer; import com.sap.sailing.gwt.ui.client.Timer.PlayModes; import com.sap.sailing.gwt.ui.client.WindSourceTypeFormatter; @@ -75,9 +75,9 @@ public class WindChart extends RaceChart implements Component * server and displayed in this chart. If no race is selected, the chart is cleared. */ public WindChart(SailingServiceAsync sailingService, RaceSelectionProvider raceSelectionProvider, Timer timer, - TimeZoomProvider timeZoomProvider, WindChartSettings settings, final StringMessages stringMessages, + TimeRangeWithZoomProvider timeRangeWithZoomProvider, WindChartSettings settings, final StringMessages stringMessages, AsyncActionsExecutor asyncActionsExecutor, ErrorReporter errorReporter, boolean compactChart) { - super(sailingService, timer, timeZoomProvider, stringMessages, asyncActionsExecutor, errorReporter); + super(sailingService, timer, timeRangeWithZoomProvider, stringMessages, asyncActionsExecutor, errorReporter); this.windSourceDirectionSeries = new HashMap(); this.windSourceSpeedSeries = new HashMap(); this.colorMap = new ColorMap(); @@ -170,8 +170,6 @@ public class WindChart extends RaceChart implements Component setSize("100%", "100%"); raceSelectionProvider.addRaceSelectionChangeListener(this); - timer.addTimeListener(this); - timeZoomProvider.addTimeZoomChangeListener(this); } @Override @@ -424,7 +422,7 @@ public class WindChart extends RaceChart implements Component timeOfEarliestRequestInMillis = null; timeOfLatestRequestInMillis = null; - loadData(minTimepoint, maxTimepoint, /* append */false); + loadData(timeRangeWithZoomProvider.getFromTime(), timeRangeWithZoomProvider.getToTime(), /* append */false); } /** @@ -504,9 +502,9 @@ public class WindChart extends RaceChart implements Component { // is date before first cache entry or is cache empty? if (timeOfEarliestRequestInMillis == null || timeOfEarliestRequestInMillis > date.getTime()) { - loadData(minTimepoint, date, /* append */ true); + loadData(timeRangeWithZoomProvider.getFromTime(), date, /* append */ true); } else if (timeOfLatestRequestInMillis < date.getTime()) { - loadData(new Date(timeOfLatestRequestInMillis), maxTimepoint, /* append */true); + loadData(new Date(timeOfLatestRequestInMillis), timeRangeWithZoomProvider.getToTime(), /* append */true); } // otherwise the cache spans across date and so we don't need to load anything break; @@ -515,7 +513,7 @@ public class WindChart extends RaceChart implements Component { // assuming play mode is replay / non-live if (timeOfLatestRequestInMillis == null) { - loadData(minTimepoint, maxTimepoint, /* append */false); // replace old series + loadData(timeRangeWithZoomProvider.getFromTime(), timeRangeWithZoomProvider.getToTime(), /* append */false); // replace old series } break; }