mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-28 00:16:46 +00:00
Merge branch 'master' into tv-mode
Conflicts: java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/leaderboard/LeaderboardEntryPoint.java java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/raceboard/RaceBoardPanel.java
This commit is contained in:
+3
-1
@@ -79,7 +79,9 @@ public class MongoObjectFactoryImpl implements MongoObjectFactory {
|
||||
}
|
||||
|
||||
public DBCollection getWindTrackCollection() {
|
||||
return database.getCollection(CollectionNames.WIND_TRACKS.name());
|
||||
DBCollection result = database.getCollection(CollectionNames.WIND_TRACKS.name());
|
||||
result.ensureIndex(new BasicDBObject(FieldNames.EVENT_NAME.name(), null));
|
||||
return result;
|
||||
}
|
||||
|
||||
public DBObject storeWindTrackEntry(Event event, RaceDefinition race, WindSource windSource, Wind wind) {
|
||||
|
||||
+1
-1
@@ -109,7 +109,7 @@ public abstract class OnlineTracTracBasedTest extends AbstractTracTracLiveTest {
|
||||
}
|
||||
}
|
||||
for (Receiver receiver : receivers) {
|
||||
receiver.stopAfterNotReceivingEventsForSomeTime(/* timeoutInMilliseconds */ 5000l);
|
||||
receiver.stopAfterNotReceivingEventsForSomeTime(/* timeoutInMilliseconds */ 60000l);
|
||||
}
|
||||
for (Receiver receiver : receivers) {
|
||||
receiver.join();
|
||||
|
||||
+14
@@ -2,11 +2,13 @@ package com.sap.sailing.domain.tracking.impl;
|
||||
|
||||
import java.util.NavigableSet;
|
||||
|
||||
import com.sap.sailing.domain.base.impl.MillisecondsTimePoint;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.TimePoint;
|
||||
import com.sap.sailing.domain.tracking.TrackedRace;
|
||||
import com.sap.sailing.domain.tracking.Wind;
|
||||
import com.sap.sailing.domain.tracking.WindTrack;
|
||||
import com.sap.sailing.domain.tracking.impl.WindTrackImpl.DummyWind;
|
||||
|
||||
/**
|
||||
* Delivers what {@link TrackedRace#getWind(Position, TimePoint)} delivers, as a navigable set.
|
||||
@@ -35,4 +37,16 @@ public class CombinedWindAsNavigableSet extends VirtualWindFixesAsNavigableSet {
|
||||
return new CombinedWindAsNavigableSet(track, trackedRace, from, to, getResolutionInMilliseconds());
|
||||
}
|
||||
|
||||
/**
|
||||
* Time point up to and including which the GPS fixes are considered in the race's tracks. Returns the value of
|
||||
* {@link #to} unless it is <code>null</code>. In this case, the time point of the
|
||||
* {@link TrackedRace#getAssumedEnd() assumed end of race},
|
||||
* {@link #ceilingToResolution(Wind) ceiled to the resolution of this set} will be returned instead. If no valid
|
||||
* time of a newest event can be obtained from the race, <code>MillisecondsTimePoint(1)</code> is returned instead.
|
||||
*/
|
||||
protected TimePoint getTo() {
|
||||
return getToInternal() == null ? getTrackedRace().getAssumedEnd() == null ? new MillisecondsTimePoint(1)
|
||||
: ceilingToResolution(new DummyWind(getTrackedRace().getAssumedEnd())) : getToInternal();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+43
-43
@@ -853,52 +853,52 @@ public abstract class TrackedRaceImpl implements TrackedRace, CourseListener {
|
||||
LegType legType;
|
||||
try {
|
||||
legType = trackedLeg.getLegType(timePoint);
|
||||
if (legType != LegType.REACHING) {
|
||||
GPSFixTrack<Competitor, GPSFixMoving> track = getTrack(competitor);
|
||||
if (!track.hasDirectionChange(timePoint, getManeuverDegreeAngleThreshold())) {
|
||||
SpeedWithBearingWithConfidence<TimePoint> estimatedSpeedWithConfidence = track
|
||||
.getEstimatedSpeed(timePoint, weigher);
|
||||
if (estimatedSpeedWithConfidence != null
|
||||
&& estimatedSpeedWithConfidence.getObject() != null
|
||||
&&
|
||||
// Mark passings may be missing or far off. This can lead to boats apparently going
|
||||
// "backwards" regarding the leg's direction; ignore those
|
||||
isNavigatingForward(estimatedSpeedWithConfidence.getObject().getBearing(), trackedLeg,
|
||||
timePoint)) {
|
||||
// additionally to generally excluding maneuvers, reduce confidence around mark passings:
|
||||
NavigableSet<MarkPassing> markPassings = getMarkPassings(competitor);
|
||||
double markPassingProximityConfidenceReduction = 1.0;
|
||||
synchronized (markPassings) {
|
||||
NavigableSet<MarkPassing> prevMarkPassing = markPassings.headSet(
|
||||
dummyMarkPassingForNow, /* inclusive */true);
|
||||
NavigableSet<MarkPassing> nextMarkPassing = markPassings.tailSet(
|
||||
dummyMarkPassingForNow, /* inclusive */true);
|
||||
if (prevMarkPassing != null && !prevMarkPassing.isEmpty()) {
|
||||
markPassingProximityConfidenceReduction *= Math.max(0.0,
|
||||
1.0 - weigherForMarkPassingProximity.getConfidence(prevMarkPassing.last()
|
||||
.getTimePoint(), timePoint));
|
||||
}
|
||||
if (nextMarkPassing != null && !nextMarkPassing.isEmpty()) {
|
||||
markPassingProximityConfidenceReduction *= Math.max(0.0,
|
||||
1.0 - weigherForMarkPassingProximity.getConfidence(nextMarkPassing.first()
|
||||
.getTimePoint(), timePoint));
|
||||
}
|
||||
}
|
||||
BearingWithConfidence<TimePoint> bearing = new BearingWithConfidenceImpl<TimePoint>(
|
||||
estimatedSpeedWithConfidence.getObject() == null ? null
|
||||
: estimatedSpeedWithConfidence.getObject().getBearing(),
|
||||
markPassingProximityConfidenceReduction
|
||||
* estimatedSpeedWithConfidence.getConfidence(),
|
||||
estimatedSpeedWithConfidence.getRelativeTo());
|
||||
BearingWithConfidenceCluster<TimePoint> bearingClusterForLegType = bearings.get(legType);
|
||||
bearingClusterForLegType.add(bearing);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (NoWindException e) {
|
||||
logger.warning("Unable to determine leg type for race " + getRace().getName()
|
||||
+ " while trying to estimate wind");
|
||||
return null;
|
||||
}
|
||||
if (legType != LegType.REACHING) {
|
||||
GPSFixTrack<Competitor, GPSFixMoving> track = getTrack(competitor);
|
||||
if (!track.hasDirectionChange(timePoint, getManeuverDegreeAngleThreshold())) {
|
||||
SpeedWithBearingWithConfidence<TimePoint> estimatedSpeedWithConfidence = track
|
||||
.getEstimatedSpeed(timePoint, weigher);
|
||||
if (estimatedSpeedWithConfidence != null
|
||||
&& estimatedSpeedWithConfidence.getObject() != null
|
||||
&&
|
||||
// Mark passings may be missing or far off. This can lead to boats apparently going
|
||||
// "backwards" regarding the leg's direction; ignore those
|
||||
isNavigatingForward(estimatedSpeedWithConfidence.getObject().getBearing(), trackedLeg,
|
||||
timePoint)) {
|
||||
// additionally to generally excluding maneuvers, reduce confidence around mark passings:
|
||||
NavigableSet<MarkPassing> markPassings = getMarkPassings(competitor);
|
||||
double markPassingProximityConfidenceReduction = 1.0;
|
||||
synchronized (markPassings) {
|
||||
NavigableSet<MarkPassing> prevMarkPassing = markPassings.headSet(
|
||||
dummyMarkPassingForNow, /* inclusive */true);
|
||||
NavigableSet<MarkPassing> nextMarkPassing = markPassings.tailSet(
|
||||
dummyMarkPassingForNow, /* inclusive */true);
|
||||
if (prevMarkPassing != null && !prevMarkPassing.isEmpty()) {
|
||||
markPassingProximityConfidenceReduction *= Math.max(0.0,
|
||||
1.0 - weigherForMarkPassingProximity.getConfidence(prevMarkPassing.last()
|
||||
.getTimePoint(), timePoint));
|
||||
}
|
||||
if (nextMarkPassing != null && !nextMarkPassing.isEmpty()) {
|
||||
markPassingProximityConfidenceReduction *= Math.max(0.0,
|
||||
1.0 - weigherForMarkPassingProximity.getConfidence(nextMarkPassing.first()
|
||||
.getTimePoint(), timePoint));
|
||||
}
|
||||
}
|
||||
BearingWithConfidence<TimePoint> bearing = new BearingWithConfidenceImpl<TimePoint>(
|
||||
estimatedSpeedWithConfidence.getObject() == null ? null
|
||||
: estimatedSpeedWithConfidence.getObject().getBearing(),
|
||||
markPassingProximityConfidenceReduction
|
||||
* estimatedSpeedWithConfidence.getConfidence(),
|
||||
estimatedSpeedWithConfidence.getRelativeTo());
|
||||
BearingWithConfidenceCluster<TimePoint> bearingClusterForLegType = bearings.get(legType);
|
||||
bearingClusterForLegType.add(bearing);
|
||||
}
|
||||
}
|
||||
bearings = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+17
-13
@@ -74,7 +74,7 @@ public abstract class VirtualWindFixesAsNavigableSet extends AbstractUnmodifiabl
|
||||
|
||||
protected TimePoint lowerToResolution(Wind w) {
|
||||
TimePoint result;
|
||||
final TimePoint timePointOfLastEvent = trackedRace.getTimePointOfLastEvent();
|
||||
final TimePoint timePointOfLastEvent = getTrackedRace().getTimePointOfLastEvent();
|
||||
if (timePointOfLastEvent == null) {
|
||||
// nothing received yet; "lowering" to end of time
|
||||
result = new MillisecondsTimePoint((Long.MAX_VALUE - 1) / getResolutionInMilliseconds()
|
||||
@@ -90,7 +90,7 @@ public abstract class VirtualWindFixesAsNavigableSet extends AbstractUnmodifiabl
|
||||
|
||||
protected TimePoint floorToResolution(Wind w) {
|
||||
TimePoint result;
|
||||
final TimePoint timePointOfLastEvent = trackedRace.getTimePointOfLastEvent();
|
||||
final TimePoint timePointOfLastEvent = getTrackedRace().getTimePointOfLastEvent();
|
||||
if (timePointOfLastEvent == null) {
|
||||
// nothing received yet; "lowering" to end of time
|
||||
result = new MillisecondsTimePoint((Long.MAX_VALUE - 1) / getResolutionInMilliseconds()
|
||||
@@ -106,7 +106,7 @@ public abstract class VirtualWindFixesAsNavigableSet extends AbstractUnmodifiabl
|
||||
|
||||
protected TimePoint ceilingToResolution(Wind w) {
|
||||
TimePoint result;
|
||||
final TimePoint startOfTracking = trackedRace.getStartOfTracking();
|
||||
final TimePoint startOfTracking = getTrackedRace().getStartOfTracking();
|
||||
if (startOfTracking == null) {
|
||||
// no start of tracking yet; "ceiling" to beginning of time
|
||||
result = new MillisecondsTimePoint(0);
|
||||
@@ -121,7 +121,7 @@ public abstract class VirtualWindFixesAsNavigableSet extends AbstractUnmodifiabl
|
||||
|
||||
protected TimePoint higherToResolution(Wind w) {
|
||||
TimePoint result;
|
||||
final TimePoint startOfTracking = trackedRace.getStartOfTracking();
|
||||
final TimePoint startOfTracking = getTrackedRace().getStartOfTracking();
|
||||
if (startOfTracking == null) {
|
||||
// no start of tracking yet; "ceiling" to beginning of time
|
||||
result = new MillisecondsTimePoint(0);
|
||||
@@ -141,9 +141,9 @@ public abstract class VirtualWindFixesAsNavigableSet extends AbstractUnmodifiabl
|
||||
* will be returned instead. If no valid start time can be obtained from the race, <code>Long.MAX_VALUE</code> is
|
||||
* returned instead.
|
||||
*/
|
||||
private TimePoint getFrom() {
|
||||
return from == null ? trackedRace.getStart() == null ? new MillisecondsTimePoint(Long.MAX_VALUE)
|
||||
: floorToResolution(new DummyWind(trackedRace.getStart())) : from;
|
||||
protected TimePoint getFrom() {
|
||||
return from == null ? getTrackedRace().getStart() == null ? new MillisecondsTimePoint(Long.MAX_VALUE)
|
||||
: floorToResolution(new DummyWind(getTrackedRace().getStart())) : from;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,9 +153,9 @@ public abstract class VirtualWindFixesAsNavigableSet extends AbstractUnmodifiabl
|
||||
* {@link #ceilingToResolution(Wind) ceiled to the resolution of this set} will be returned instead. If no valid
|
||||
* time of a newest event can be obtained from the race, <code>MillisecondsTimePoint(1)</code> is returned instead.
|
||||
*/
|
||||
private TimePoint getTo() {
|
||||
return to == null ? trackedRace.getTimePointOfNewestEvent() == null ? new MillisecondsTimePoint(1)
|
||||
: ceilingToResolution(new DummyWind(trackedRace.getTimePointOfNewestEvent())) : to;
|
||||
protected TimePoint getTo() {
|
||||
return getToInternal() == null ? getTrackedRace().getTimePointOfNewestEvent() == null ? new MillisecondsTimePoint(1)
|
||||
: ceilingToResolution(new DummyWind(getTrackedRace().getTimePointOfNewestEvent())) : getToInternal();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -242,7 +242,7 @@ public abstract class VirtualWindFixesAsNavigableSet extends AbstractUnmodifiabl
|
||||
|
||||
@Override
|
||||
public NavigableSet<Wind> subSet(Wind fromElement, boolean fromInclusive, Wind toElement, boolean toInclusive) {
|
||||
return createSubset(track, trackedRace, fromInclusive ? ceilingToResolution(fromElement)
|
||||
return createSubset(track, getTrackedRace(), fromInclusive ? ceilingToResolution(fromElement)
|
||||
: higherToResolution(fromElement), toInclusive ? floorToResolution(toElement)
|
||||
: lowerToResolution(toElement));
|
||||
}
|
||||
@@ -254,13 +254,13 @@ public abstract class VirtualWindFixesAsNavigableSet extends AbstractUnmodifiabl
|
||||
|
||||
@Override
|
||||
public NavigableSet<Wind> headSet(Wind toElement, boolean inclusive) {
|
||||
return createSubset(track, trackedRace, /* from */ null,
|
||||
return createSubset(track, getTrackedRace(), /* from */ null,
|
||||
inclusive ? ceilingToResolution(toElement) : lowerToResolution(toElement));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableSet<Wind> tailSet(Wind fromElement, boolean inclusive) {
|
||||
return createSubset(track, trackedRace, inclusive ? floorToResolution(fromElement)
|
||||
return createSubset(track, getTrackedRace(), inclusive ? floorToResolution(fromElement)
|
||||
: higherToResolution(fromElement),
|
||||
/* to */ null);
|
||||
}
|
||||
@@ -335,5 +335,9 @@ public abstract class VirtualWindFixesAsNavigableSet extends AbstractUnmodifiabl
|
||||
T[] tResult = (T[]) result;
|
||||
return tResult;
|
||||
}
|
||||
|
||||
protected TimePoint getToInternal() {
|
||||
return to;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-5
@@ -17,11 +17,9 @@ public class LeaderboardPanelMock extends LeaderboardPanel {
|
||||
public LeaderboardPanelMock(SailingServiceAsync sailingService,
|
||||
String leaderboardName, ErrorReporter errorReporter,
|
||||
StringMessages stringConstants) {
|
||||
super(sailingService, LeaderboardSettingsFactory.getInstance()
|
||||
.createNewDefaultSettings(
|
||||
/* autoExpandFirstRace */false), new CompetitorSelectionModel(/* hasMultiSelection */true),
|
||||
leaderboardName, null, errorReporter, stringConstants, null);
|
||||
// TODO Auto-generated constructor stub
|
||||
super(sailingService, LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(
|
||||
/* racesToShow */null, /* namesOfRacesToShow */ null, /* autoExpandFirstRace */false), new CompetitorSelectionModel(
|
||||
/* hasMultiSelection */true), leaderboardName, null, errorReporter, stringConstants, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public class AdminConsoleEntryPoint extends AbstractEntryPoint implements EventR
|
||||
raceMapPanel.setSize("90%", "90%");
|
||||
tabPanel.add(raceMapPanel, stringMessages.map(), /* asHTML */ false);
|
||||
LeaderboardSettings defaultLeaderboardSettings = LeaderboardSettingsFactory.getInstance()
|
||||
.createNewDefaultSettings(/* autoExpandFirstRace */false);
|
||||
.createNewDefaultSettings(/* racesToShow */ null, /* namesOfRacesToShow */ null, /* autoExpandFirstRace */false);
|
||||
final LeaderboardPanel defaultLeaderboardPanel = new LeaderboardPanel(sailingService,
|
||||
defaultLeaderboardSettings,
|
||||
/* preSelectedRace */null, new CompetitorSelectionModel(/* hasMultiSelection */true),
|
||||
|
||||
+104
-34
@@ -41,12 +41,15 @@ import com.google.gwt.maps.client.overlay.Polyline;
|
||||
import com.google.gwt.maps.client.overlay.PolylineOptions;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.RequiresResize;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.Tack;
|
||||
import com.sap.sailing.domain.common.WindSource;
|
||||
import com.sap.sailing.domain.common.WindSourceType;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.gwt.ui.adminconsole.RaceMapZoomSettings.ZoomTypes;
|
||||
@@ -69,12 +72,14 @@ import com.sap.sailing.gwt.ui.shared.MarkDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.PositionDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.QuickRankDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.SpeedWithBearingDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.WindTrackInfoDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.components.Component;
|
||||
import com.sap.sailing.gwt.ui.shared.components.SettingsDialogComponent;
|
||||
|
||||
public class RaceMap extends SimplePanel implements TimeListener, CompetitorSelectionChangeListener, RaceSelectionChangeListener,
|
||||
Component<RaceMapSettings>, RequiresDataInitialization {
|
||||
Component<RaceMapSettings>, RequiresDataInitialization, RequiresResize {
|
||||
protected MapWidget map;
|
||||
|
||||
private final SailingServiceAsync sailingService;
|
||||
@@ -111,6 +116,10 @@ public class RaceMap extends SimplePanel implements TimeListener, CompetitorSele
|
||||
|
||||
private final Map<MarkDTO, Marker> buoyMarkers;
|
||||
|
||||
private Marker combinedWindMarker;
|
||||
|
||||
private int combinedWindMarkerPosX;
|
||||
private int combinedWindMarkerPosY;
|
||||
/**
|
||||
* markers displayed in response to
|
||||
* {@link SailingServiceAsync#getDouglasPoints(String, String, Map, Map, double, AsyncCallback)}
|
||||
@@ -197,6 +206,8 @@ public class RaceMap extends SimplePanel implements TimeListener, CompetitorSele
|
||||
fixes = new HashMap<CompetitorDTO, List<GPSFixDTO>>();
|
||||
this.competitorSelection = competitorSelection;
|
||||
competitorSelection.addCompetitorSelectionChangeListener(this);
|
||||
combinedWindMarkerPosX = 30;
|
||||
combinedWindMarkerPosY = 30;
|
||||
settings = new RaceMapSettings();
|
||||
lastTimeChangeBeforeInitialization = null;
|
||||
dataInitialized = false;
|
||||
@@ -296,8 +307,6 @@ public class RaceMap extends SimplePanel implements TimeListener, CompetitorSele
|
||||
final ParallelExecutionCallback<Map<CompetitorDTO, List<GPSFixDTO>>> getBoatsCallback = new ParallelExecutionCallback<Map<CompetitorDTO, List<GPSFixDTO>>>();
|
||||
final ParallelExecutionCallback<List<MarkDTO>> getMarksCallback = new ParallelExecutionCallback<List<MarkDTO>>();
|
||||
final ParallelExecutionCallback<List<QuickRankDTO>> getQuickRanksCallback = new ParallelExecutionCallback<List<QuickRankDTO>>();
|
||||
// final ParallelExecutionCallback<WindInfoForRaceDTO> getWindCallback = new ParallelExecutionCallback<WindInfoForRaceDTO>();
|
||||
// new ParallelExecutionHolder(getBoatsCallback, getMarksCallback, getQuickRanksCallback, getWindCallback) {
|
||||
new ParallelExecutionHolder(getBoatsCallback, getMarksCallback, getQuickRanksCallback) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
@@ -339,7 +348,6 @@ public class RaceMap extends SimplePanel implements TimeListener, CompetitorSele
|
||||
mapZoomedOrPannedSinceLastRaceSelectionChange = false;
|
||||
}
|
||||
}
|
||||
// showWindOnMap(getWindCallback.getData());
|
||||
} else {
|
||||
lastTimeChangeBeforeInitialization = date;
|
||||
}
|
||||
@@ -353,7 +361,23 @@ public class RaceMap extends SimplePanel implements TimeListener, CompetitorSele
|
||||
sailingService.getBoatPositions(race, fromAndToAndOverlap.getA(), fromAndToAndOverlap.getB(), true, getBoatsCallback);
|
||||
sailingService.getMarkPositions(race, date, getMarksCallback);
|
||||
sailingService.getQuickRanks(race, date, getQuickRanksCallback);
|
||||
// sailingService.getWindInfo(race, date, 0, 0, 0, null, getWindCallback);
|
||||
|
||||
// draw the wind into the map, get the combined wind
|
||||
List<String> windSourceTypeNames = new ArrayList<String>();
|
||||
windSourceTypeNames.add(WindSourceType.COMBINED.name());
|
||||
windSourceTypeNames.add(WindSourceType.EXPEDITION.name());
|
||||
sailingService.getWindInfo(race, date, 1000L, 1, 0.0, 0.0, null,
|
||||
new AsyncCallback<WindInfoForRaceDTO>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
errorReporter.reportError("Error obtaining wind: " + caught.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(WindInfoForRaceDTO windInfoForRaceDTO) {
|
||||
showWindOnMap(windInfoForRaceDTO);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -450,22 +474,57 @@ public class RaceMap extends SimplePanel implements TimeListener, CompetitorSele
|
||||
}
|
||||
|
||||
protected void showWindOnMap(WindInfoForRaceDTO windInfo) {
|
||||
// DON'T DELETE... THIS WILL BE IMPLEMENTED SOON
|
||||
// System.out.println("Windsources: " + windInfo.windTrackInfoByWindSource.size());
|
||||
// for(WindSource windSource: windInfo.windTrackInfoByWindSource.keySet()) {
|
||||
// switch (windSource) {
|
||||
// case COURSE_BASED:
|
||||
// case EXPEDITION:
|
||||
// case TRACK_BASED_ESTIMATION:
|
||||
// case WEB:
|
||||
// WindTrackInfoDTO windTrackInfoDTO = windInfo.windTrackInfoByWindSource.get(windSource);
|
||||
// for(WindDTO windDTO: windTrackInfoDTO.windFixes) {
|
||||
// Long timepoint = windDTO.timepoint;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
for(WindSource windSource: windInfo.windTrackInfoByWindSource.keySet()) {
|
||||
WindTrackInfoDTO windTrackInfoDTO = windInfo.windTrackInfoByWindSource.get(windSource);
|
||||
switch (windSource.getType()) {
|
||||
case COMBINED:
|
||||
{
|
||||
if(windTrackInfoDTO.windFixes.size() > 0) {
|
||||
WindDTO windDTO = windTrackInfoDTO.windFixes.get(0);
|
||||
// double speedInKnots = windDTO.dampenedTrueWindSpeedInKnots;
|
||||
double windFromDeg = windDTO.dampenedTrueWindFromDeg;
|
||||
|
||||
if(combinedWindMarker == null)
|
||||
createCombinedWindMarker();
|
||||
|
||||
if(map != null && combinedWindMarker != null) {
|
||||
LatLng windMarkerPositionLatLng = map.convertDivPixelToLatLng(Point.newInstance(combinedWindMarkerPosX, combinedWindMarkerPosY));
|
||||
combinedWindMarker.setLatLng(windMarkerPositionLatLng);
|
||||
|
||||
ImageTransformer transformer = imageResources.getCombinedWindIconTransformer();
|
||||
String transformedImageURL = transformer.getTransformedImageURL(windFromDeg, 1.0);
|
||||
combinedWindMarker.setImage(transformedImageURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EXPEDITION:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected Marker createCombinedWindMarker() {
|
||||
if(map != null && combinedWindMarker == null) {
|
||||
LatLng windMarkerPositionLatLng = map.convertDivPixelToLatLng(Point.newInstance(combinedWindMarkerPosX, combinedWindMarkerPosY));
|
||||
Icon icon = Icon.newInstance();
|
||||
icon.setImageURL(null);
|
||||
icon.setShadowURL(null);
|
||||
MarkerOptions options = MarkerOptions.newInstance(icon);
|
||||
combinedWindMarker = new Marker(windMarkerPositionLatLng, options);
|
||||
combinedWindMarker.addMarkerClickHandler(new MarkerClickHandler() {
|
||||
@Override
|
||||
public void onClick(MarkerClickEvent event) {
|
||||
}
|
||||
});
|
||||
|
||||
map.addOverlay(combinedWindMarker);
|
||||
}
|
||||
return combinedWindMarker;
|
||||
}
|
||||
|
||||
protected void showMarksOnMap(List<MarkDTO> result) {
|
||||
if (map != null) {
|
||||
Set<MarkDTO> toRemove = new HashSet<MarkDTO>(buoyMarkers.keySet());
|
||||
@@ -925,6 +984,9 @@ public class RaceMap extends SimplePanel implements TimeListener, CompetitorSele
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The last shown GPS fix for the given competitor
|
||||
*/
|
||||
protected GPSFixDTO getBoatFix(CompetitorDTO competitorDTO) {
|
||||
return fixes.get(competitorDTO).get(lastShownFix.get(competitorDTO));
|
||||
}
|
||||
@@ -1138,21 +1200,23 @@ public class RaceMap extends SimplePanel implements TimeListener, CompetitorSele
|
||||
competitors = isZoomOnlyToSelectedCompetitors() ? selectedCompetitors : forMap.getCompetitorsToShow();
|
||||
}
|
||||
for (CompetitorDTO competitor : competitors) {
|
||||
List<GPSFixDTO> competitorFixes = forMap.fixes.get(competitor);
|
||||
Integer lastShownFixForCompetitor = forMap.lastShownFix.get(competitor);
|
||||
GPSFixDTO competitorFix = competitorFixes != null && lastShownFixForCompetitor != null ? competitorFixes.get(lastShownFixForCompetitor) : null;
|
||||
PositionDTO competitorPosition = competitorFix != null ? competitorFix.position : null;
|
||||
LatLng competitorLatLng = competitorPosition != null ? LatLng.newInstance(competitorPosition.latDeg,
|
||||
competitorPosition.lngDeg) : null;
|
||||
LatLngBounds bounds = competitorLatLng != null ? LatLngBounds.newInstance(competitorLatLng,
|
||||
competitorLatLng) : null;
|
||||
if (bounds != null) {
|
||||
if (newBounds == null) {
|
||||
newBounds = bounds;
|
||||
} else {
|
||||
newBounds.extend(bounds.getNorthEast());
|
||||
newBounds.extend(bounds.getSouthWest());
|
||||
try {
|
||||
GPSFixDTO competitorFix = forMap.getBoatFix(competitor);
|
||||
PositionDTO competitorPosition = competitorFix != null ? competitorFix.position : null;
|
||||
LatLng competitorLatLng = competitorPosition != null ? LatLng.newInstance(competitorPosition.latDeg,
|
||||
competitorPosition.lngDeg) : null;
|
||||
LatLngBounds bounds = competitorLatLng != null ? LatLngBounds.newInstance(competitorLatLng,
|
||||
competitorLatLng) : null;
|
||||
if (bounds != null) {
|
||||
if (newBounds == null) {
|
||||
newBounds = bounds;
|
||||
} else {
|
||||
newBounds.extend(bounds.getNorthEast());
|
||||
newBounds.extend(bounds.getSouthWest());
|
||||
}
|
||||
}
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
//Catch this in case the competitor has no GPS fixes at the current time (e.g. in race 'Finale 2' of STG)
|
||||
}
|
||||
}
|
||||
return newBounds;
|
||||
@@ -1214,4 +1278,10 @@ public class RaceMap extends SimplePanel implements TimeListener, CompetitorSele
|
||||
public boolean isDataInitialized() {
|
||||
return dataInitialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResize() {
|
||||
map.checkResize();
|
||||
zoomMapToNewBounds(getSettings().getZoomSettings().getNewBounds(RaceMap.this));
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -57,6 +57,11 @@ public class RaceMapResources {
|
||||
*/
|
||||
protected ImageTransformer boatIconHighlightedStarboardTransformer;
|
||||
|
||||
/**
|
||||
* An arrow showing the combined wind depending on the wind direction
|
||||
*/
|
||||
protected ImageTransformer combinedWindIconTransformer;
|
||||
|
||||
protected Icon buoyIcon;
|
||||
|
||||
protected Map<Pair<ManeuverType, Tack>, Icon> maneuverIconsForTypeAndTargetTack;
|
||||
@@ -76,6 +81,7 @@ public class RaceMapResources {
|
||||
boatIconHighlightedPortTransformer = new ImageTransformer(resources.highlightedBoatIcon_Port());
|
||||
boatIconStarboardTransformer = new ImageTransformer(resources.lowlightedBoatIcon_Starboard());
|
||||
boatIconHighlightedStarboardTransformer = new ImageTransformer(resources.highlightedBoatIcon_Starboard());
|
||||
combinedWindIconTransformer = new ImageTransformer(resources.windDirectionIcon());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,6 +180,10 @@ public class RaceMapResources {
|
||||
}
|
||||
}
|
||||
|
||||
public ImageTransformer getCombinedWindIconTransformer() {
|
||||
return combinedWindIconTransformer;
|
||||
}
|
||||
|
||||
public String getBoatImageURL(GPSFixDTO boatFix, boolean highlighted) {
|
||||
return getBoatImageURL(getBoatImageTransformer(boatFix, highlighted), boatFix);
|
||||
}
|
||||
|
||||
+22
-1
@@ -20,6 +20,8 @@ import org.moxieapps.gwt.highcharts.client.ToolTipData;
|
||||
import org.moxieapps.gwt.highcharts.client.ToolTipFormatter;
|
||||
import org.moxieapps.gwt.highcharts.client.events.ChartClickEvent;
|
||||
import org.moxieapps.gwt.highcharts.client.events.ChartClickEventHandler;
|
||||
import org.moxieapps.gwt.highcharts.client.events.ChartSelectionEvent;
|
||||
import org.moxieapps.gwt.highcharts.client.events.ChartSelectionEventHandler;
|
||||
import org.moxieapps.gwt.highcharts.client.plotOptions.LinePlotOptions;
|
||||
import org.moxieapps.gwt.highcharts.client.plotOptions.Marker;
|
||||
|
||||
@@ -61,6 +63,7 @@ public class WindChart extends SimplePanel implements Component<WindChartSetting
|
||||
private final ErrorReporter errorReporter;
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final Chart chart;
|
||||
private boolean ignoreClickOnce;
|
||||
private final Timer timer;
|
||||
private final DateTimeFormat dateFormat = DateTimeFormat.getFormat("HH:mm:ss");
|
||||
|
||||
@@ -114,10 +117,28 @@ public class WindChart extends SimplePanel implements Component<WindChartSetting
|
||||
chart.setClickEventHandler(new ChartClickEventHandler() {
|
||||
@Override
|
||||
public boolean onClick(ChartClickEvent chartClickEvent) {
|
||||
WindChart.this.timer.setTime(chartClickEvent.getXAxisValueAsLong());
|
||||
if (ignoreClickOnce) {
|
||||
ignoreClickOnce = false;
|
||||
} else {
|
||||
WindChart.this.timer.setTime(chartClickEvent.getXAxisValueAsLong());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
chart.setSelectionEventHandler(new ChartSelectionEventHandler() {
|
||||
@Override
|
||||
public boolean onSelection(ChartSelectionEvent chartSelectionEvent) {
|
||||
try {
|
||||
chartSelectionEvent.getXAxisMaxAsLong();
|
||||
chartSelectionEvent.getXAxisMinAsLong();
|
||||
ignoreClickOnce = true;
|
||||
return true;
|
||||
} catch (Throwable t) {
|
||||
chart.redraw();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
chart.getXAxis().setType(Axis.Type.DATE_TIME).setMaxZoom(10000) // ten seconds
|
||||
.setAxisTitleText(stringMessages.time());
|
||||
chart.getYAxis(0).setAxisTitleText(stringMessages.fromDeg()).setStartOnTick(false).setShowFirstLabel(false);
|
||||
|
||||
+1
-1
@@ -59,7 +59,7 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
|
||||
mainPanel.add(tvViewPanel);
|
||||
} else {
|
||||
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService,
|
||||
LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(/* autoExpandFirstRace */ false),
|
||||
LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, /* autoExpandFirstRace */ false),
|
||||
/* preSelectedRace */ null, new CompetitorSelectionModel(/* hasMultiSelection */ true),
|
||||
new Timer(PlayModes.Replay, /* delayBetweenAutoAdvancesInMilliseconds */3000l),
|
||||
leaderboardName, leaderboardGroupName,
|
||||
|
||||
+185
-92
@@ -147,11 +147,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
|
||||
private final Timer timer;
|
||||
|
||||
/**
|
||||
* The delay with which the timer shall work. Before the timer is resumed, the delay is set to this value.
|
||||
*/
|
||||
private long delayInMilliseconds;
|
||||
|
||||
private boolean autoExpandFirstRace;
|
||||
|
||||
/**
|
||||
@@ -184,6 +179,22 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
|
||||
private final BusyIndicator busyIndicator;
|
||||
|
||||
/**
|
||||
* Tells whether the leaderboard settings were explicitly changed by an external call to
|
||||
* {@link #updateSettings(LeaderboardSettings)}. If so, a {@link #playStateChanged(PlayStates, PlayModes) play state
|
||||
* change} will not automatically lead to a settings change.
|
||||
*/
|
||||
private boolean settingsUpdatedExplicitly = false;
|
||||
|
||||
/**
|
||||
* Tells if the leaderboard is currently handling a {@link #playStateChanged(PlayStates, PlayModes) play state change}.
|
||||
* If this is the case, a call to {@link #updateSettings(LeaderboardSettings)} won't set the
|
||||
* {@link #settingsUpdatedExplicitly} flag.
|
||||
*/
|
||||
private boolean currentlyHandlingPlayStateChange;
|
||||
|
||||
private PlayModes oldPlayMode;
|
||||
|
||||
private class SettingsClickHandler implements ClickHandler {
|
||||
private final StringMessages stringMessages;
|
||||
|
||||
@@ -223,6 +234,9 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
}
|
||||
|
||||
public void updateSettings(LeaderboardSettings newSettings) {
|
||||
if (!currentlyHandlingPlayStateChange) {
|
||||
settingsUpdatedExplicitly = true;
|
||||
}
|
||||
List<ExpandableSortableColumn<?>> columnsToExpandAgain = new ArrayList<ExpandableSortableColumn<?>>();
|
||||
for (int i = 0; i < getLeaderboardTable().getColumnCount(); i++) {
|
||||
Column<LeaderboardRowDTO, ?> c = getLeaderboardTable().getColumn(i);
|
||||
@@ -237,24 +251,52 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
}
|
||||
}
|
||||
}
|
||||
selectedManeuverDetails.clear();
|
||||
selectedManeuverDetails.addAll(newSettings.getManeuverDetailsToShow());
|
||||
selectedLegDetails.clear();
|
||||
selectedLegDetails.addAll(newSettings.getLegDetailsToShow());
|
||||
selectedRaceDetails.clear();
|
||||
selectedRaceDetails.addAll(newSettings.getRaceDetailsToShow());
|
||||
selectedRaceColumns.clear();
|
||||
selectedRaceColumns.addAll(newSettings.getRaceColumnsToShow());
|
||||
if (newSettings.getManeuverDetailsToShow() != null) {
|
||||
selectedManeuverDetails.clear();
|
||||
selectedManeuverDetails.addAll(newSettings.getManeuverDetailsToShow());
|
||||
}
|
||||
if (newSettings.getLegDetailsToShow() != null) {
|
||||
selectedLegDetails.clear();
|
||||
selectedLegDetails.addAll(newSettings.getLegDetailsToShow());
|
||||
}
|
||||
if (newSettings.getRaceDetailsToShow() != null) {
|
||||
selectedRaceDetails.clear();
|
||||
selectedRaceDetails.addAll(newSettings.getRaceDetailsToShow());
|
||||
}
|
||||
if (newSettings.getNamesOfRaceColumnsToShow() != null) {
|
||||
selectedRaceColumns.clear();
|
||||
for (String nameOfRaceColumnToShow : newSettings.getNamesOfRaceColumnsToShow()) {
|
||||
RaceInLeaderboardDTO raceColumnToShow = getRaceByColumnName(nameOfRaceColumnToShow);
|
||||
if (raceColumnToShow != null) {
|
||||
selectedRaceColumns.add(raceColumnToShow);
|
||||
}
|
||||
}
|
||||
} else if (newSettings.getNamesOfRacesToShow() != null) {
|
||||
selectedRaceColumns.clear();
|
||||
for (String nameOfRaceToShow : newSettings.getNamesOfRacesToShow()) {
|
||||
RaceInLeaderboardDTO raceColumnToShow = getRaceByName(nameOfRaceToShow);
|
||||
if (raceColumnToShow != null) {
|
||||
selectedRaceColumns.add(raceColumnToShow);
|
||||
}
|
||||
}
|
||||
}
|
||||
setAutoExpandFirstRace(false); // avoid expansion during updateLeaderboard(...); will expand later if it was expanded before
|
||||
// update leaderboard after settings panel column selection change
|
||||
updateLeaderboard(leaderboard);
|
||||
setAutoExpandFirstRace(newSettings.isAutoExpandFirstRace());
|
||||
|
||||
timer.setRefreshInterval(newSettings.getDelayBetweenAutoAdvancesInMilliseconds());
|
||||
setDelayInMilliseconds(newSettings.getDelayInMilliseconds());
|
||||
if (newSettings.getDelayBetweenAutoAdvancesInMilliseconds() != null) {
|
||||
timer.setRefreshInterval(newSettings.getDelayBetweenAutoAdvancesInMilliseconds());
|
||||
}
|
||||
if (newSettings.getDelayInMilliseconds() != null) {
|
||||
setDelayInMilliseconds(newSettings.getDelayInMilliseconds());
|
||||
}
|
||||
for (ExpandableSortableColumn<?> expandableSortableColumn : columnsToExpandAgain) {
|
||||
expandableSortableColumn.toggleExpansion();
|
||||
}
|
||||
if (newSettings.getNameOfRaceToSort() != null) {
|
||||
sort(getRaceColumnByRaceName(newSettings.getNameOfRaceToSort()), /* ascending */ true);
|
||||
}
|
||||
}
|
||||
|
||||
protected class CompetitorColumn extends SortableColumn<LeaderboardRowDTO, String> {
|
||||
@@ -362,7 +404,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
return race;
|
||||
}
|
||||
|
||||
public String getRaceName() {
|
||||
public String getRaceColumnName() {
|
||||
return race.getRaceColumnName();
|
||||
}
|
||||
|
||||
@@ -390,7 +432,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
*/
|
||||
@Override
|
||||
public void render(Context context, LeaderboardRowDTO object, SafeHtmlBuilder html) {
|
||||
LeaderboardEntryDTO entry = object.fieldsByRaceName.get(getRaceName());
|
||||
LeaderboardEntryDTO entry = object.fieldsByRaceName.get(getRaceColumnName());
|
||||
if (entry != null) {
|
||||
// don't show points if max points / penalty
|
||||
if (entry.reasonForMaxPoints.equals("NONE")) {
|
||||
@@ -422,18 +464,8 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
if (race.isMedalRace()) {
|
||||
return getLeaderboard().getMedalRaceComparator(race.getRaceColumnName());
|
||||
} else {
|
||||
return new Comparator<LeaderboardRowDTO>() {
|
||||
@Override
|
||||
public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) {
|
||||
boolean ascending = isSortedAscendingForThisColumn(getLeaderboardPanel().getLeaderboardTable());
|
||||
LeaderboardEntryDTO o1Entry = o1.fieldsByRaceName.get(race.getRaceColumnName());
|
||||
LeaderboardEntryDTO o2Entry = o2.fieldsByRaceName.get(race.getRaceColumnName());
|
||||
return (o1Entry == null || o1Entry.netPoints == 0) ? (o2Entry == null || o2Entry.netPoints == 0) ? 0
|
||||
: ascending ? 1 : -1
|
||||
: (o2Entry == null || o2Entry.netPoints == 0) ? ascending ? -1 : 1 : o1Entry.netPoints
|
||||
- o2Entry.netPoints;
|
||||
}
|
||||
};
|
||||
return new NetPointsComparator(isSortedAscendingForThisColumn(getLeaderboardPanel().getLeaderboardTable()),
|
||||
race.getRaceColumnName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,12 +505,12 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
|
||||
@Override
|
||||
public String getValue(LeaderboardRowDTO object) {
|
||||
return "" + object.fieldsByRaceName.get(getRaceName()).totalPoints;
|
||||
return "" + object.fieldsByRaceName.get(getRaceColumnName()).totalPoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void ensureExpansionDataIsLoaded(final Runnable callWhenExpansionDataIsLoaded) {
|
||||
if (getLeaderboard().getLegCount(getRaceName()) != -1) {
|
||||
if (getLeaderboard().getLegCount(getRaceColumnName()) != -1) {
|
||||
callWhenExpansionDataIsLoaded.run();
|
||||
} else {
|
||||
getSailingService().getLeaderboardByName(getLeaderboardName(), getLeaderboardDisplayDate(),
|
||||
@@ -546,7 +578,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
// it is important to re-use existing LegColumn objects because
|
||||
// removing the columns from the table
|
||||
// is based on column identity
|
||||
int legCount = getLeaderboard().getLegCount(getRaceName());
|
||||
int legCount = getLeaderboard().getLegCount(getRaceColumnName());
|
||||
if (legCount != -1) {
|
||||
for (int i = 0; i < legCount; i++) {
|
||||
LegColumn legColumn = getLegColumn(i);
|
||||
@@ -569,7 +601,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
if (legColumns.size() > legNumber && legColumns.get(legNumber) != null) {
|
||||
result = legColumns.get(legNumber);
|
||||
} else {
|
||||
result = new LegColumn(LeaderboardPanel.this, getRaceName(), legNumber, stringMessages,
|
||||
result = new LegColumn(LeaderboardPanel.this, getRaceColumnName(), legNumber, stringMessages,
|
||||
Collections.unmodifiableList(selectedLegDetails), LEG_COLUMN_HEADER_STYLE, LEG_COLUMN_STYLE,
|
||||
LEG_DETAIL_COLUMN_HEADER_STYLE, LEG_DETAIL_COLUMN_STYLE);
|
||||
while (legColumns.size() <= legNumber) {
|
||||
@@ -589,7 +621,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
@Override
|
||||
public Double get(LeaderboardRowDTO row) {
|
||||
Double result = null;
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceName.get(getRaceName());
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceName.get(getRaceColumnName());
|
||||
if (fieldsForRace != null && fieldsForRace.legDetails != null) {
|
||||
double distanceTraveledInMeters = 0;
|
||||
long timeInMilliseconds = 0;
|
||||
@@ -616,7 +648,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
@Override
|
||||
public Double get(LeaderboardRowDTO row) {
|
||||
Double result = null;
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceName.get(getRaceName());
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceName.get(getRaceColumnName());
|
||||
if (fieldsForRace != null && fieldsForRace.legDetails != null) {
|
||||
for (LegEntryDTO legDetail : fieldsForRace.legDetails) {
|
||||
if (legDetail != null) {
|
||||
@@ -637,7 +669,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
@Override
|
||||
public Double get(LeaderboardRowDTO row) {
|
||||
Double result = null;
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceName.get(getRaceName());
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceName.get(getRaceColumnName());
|
||||
if (fieldsForRace != null && fieldsForRace.legDetails != null && !fieldsForRace.legDetails.isEmpty()) {
|
||||
for (LegEntryDTO legDetail : fieldsForRace.legDetails) {
|
||||
if (legDetail != null) {
|
||||
@@ -668,7 +700,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
@Override
|
||||
public Double get(LeaderboardRowDTO row) {
|
||||
Double result = null;
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceName.get(getRaceName());
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceName.get(getRaceColumnName());
|
||||
if (fieldsForRace != null && fieldsForRace.legDetails != null) {
|
||||
int lastLegIndex = fieldsForRace.legDetails.size() - 1;
|
||||
LegEntryDTO lastLegDetail = fieldsForRace.legDetails.get(lastLegIndex);
|
||||
@@ -693,7 +725,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
@Override
|
||||
public Double get(LeaderboardRowDTO row) {
|
||||
Double result = null;
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceName.get(getRaceName());
|
||||
LeaderboardEntryDTO fieldsForRace = row.fieldsByRaceName.get(getRaceColumnName());
|
||||
if (fieldsForRace != null && fieldsForRace.windwardDistanceToOverallLeaderInMeters != null) {
|
||||
result = fieldsForRace.windwardDistanceToOverallLeaderInMeters;
|
||||
}
|
||||
@@ -820,7 +852,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
ErrorReporter errorReporter, final StringMessages stringMessages, final UserAgentTypes userAgentType) {
|
||||
this(sailingService, settings, preSelectedRace, competitorSelectionProvider, new Timer(PlayModes.Replay, /* delayBetweenAutoAdvancesInMilliseconds */3000l),
|
||||
leaderboardName, leaderboardGroupName, errorReporter, stringMessages, userAgentType);
|
||||
timer.setDelay(getDelayInMilliseconds()); // set time/delay before adding as listener
|
||||
}
|
||||
|
||||
public LeaderboardPanel(SailingServiceAsync sailingService, LeaderboardSettings settings, RaceIdentifier preSelectedRace,
|
||||
@@ -841,7 +872,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
selectedLegDetails.addAll(settings.getLegDetailsToShow());
|
||||
selectedManeuverDetails.addAll(settings.getManeuverDetailsToShow());
|
||||
selectedRaceDetails.addAll(settings.getRaceDetailsToShow());
|
||||
delayInMilliseconds = settings.getDelayInMilliseconds();
|
||||
setAutoExpandFirstRace(settings.isAutoExpandFirstRace());
|
||||
|
||||
this.timer = timer;
|
||||
@@ -906,7 +936,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
if (LeaderboardPanel.this.timer.getPlayState() == PlayStates.Playing) {
|
||||
LeaderboardPanel.this.timer.pause();
|
||||
} else {
|
||||
LeaderboardPanel.this.timer.setDelay(getDelayInMilliseconds());
|
||||
LeaderboardPanel.this.timer.play();
|
||||
}
|
||||
}
|
||||
@@ -949,6 +978,43 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
}
|
||||
contentPanel.add(getLeaderboardTable());
|
||||
setWidget(contentPanel);
|
||||
if (settings.getNameOfRaceToSort() != null) {
|
||||
RaceColumn<?> column = getRaceColumnByRaceName(settings.getNameOfRaceToSort());
|
||||
sort(column, settings.isSortAscending());
|
||||
}
|
||||
}
|
||||
|
||||
private RaceInLeaderboardDTO getRaceByName(String raceName) {
|
||||
if (getLeaderboard() != null) {
|
||||
for (RaceInLeaderboardDTO race : getLeaderboard().getRaceList()) {
|
||||
if (race.getRaceIdentifier() != null && raceName.equals(race.getRaceIdentifier().getRaceName())) {
|
||||
return race;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private RaceInLeaderboardDTO getRaceByColumnName(String columnName) {
|
||||
if (getLeaderboard() != null) {
|
||||
for (RaceInLeaderboardDTO race : getLeaderboard().getRaceList()) {
|
||||
if (columnName.equals(race.getRaceColumnName())) {
|
||||
return race;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private RaceColumn<?> getRaceColumnByRaceName(String raceName) {
|
||||
for (int i=0; i<getLeaderboardTable().getColumnCount(); i++) {
|
||||
Column<LeaderboardRowDTO, ?> column = getLeaderboardTable().getColumn(i);
|
||||
if (column instanceof RaceColumn<?>
|
||||
&& ((RaceColumn<?>) column).getRace().getRaceIdentifier().getRaceName().equals(raceName)) {
|
||||
return (RaceColumn<?>) column;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private SafeHtml getPlayPauseImgHtml(PlayStates playState) {
|
||||
@@ -958,16 +1024,8 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
return AbstractImagePrototype.create(playIcon).getSafeHtml();
|
||||
}
|
||||
|
||||
private long getDelayInMilliseconds() {
|
||||
return delayInMilliseconds;
|
||||
}
|
||||
|
||||
private void setDelayInMilliseconds(long delayInMilliseconds) {
|
||||
this.delayInMilliseconds = delayInMilliseconds;
|
||||
timer.setDelay(delayInMilliseconds);
|
||||
if (timer.getPlayMode() == PlayModes.Live) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAutoExpandFirstRace() {
|
||||
@@ -1081,7 +1139,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
if (column instanceof RaceColumn<?>) {
|
||||
RaceColumn<?> raceColumn = (RaceColumn<?>) column;
|
||||
if (raceColumn.isExpanded()) {
|
||||
namesOfExpandedRaces.add(raceColumn.getRaceName());
|
||||
namesOfExpandedRaces.add(raceColumn.getRaceColumnName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1092,45 +1150,60 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
* Also updates the min/max values on the columns
|
||||
*/
|
||||
protected void updateLeaderboard(LeaderboardDTO leaderboard) {
|
||||
competitorSelectionProvider.setCompetitors(leaderboard.competitors);
|
||||
selectedRaceColumns.addAll(getRaceColumnsToAddImplicitly(leaderboard));
|
||||
setLeaderboard(leaderboard);
|
||||
adjustColumnLayout(leaderboard);
|
||||
getData().getList().clear();
|
||||
if (leaderboard != null) {
|
||||
boolean firstRace = true;
|
||||
getData().getList().addAll(leaderboard.rows.values());
|
||||
for (int i = 0; i < getLeaderboardTable().getColumnCount(); i++) {
|
||||
SortableColumn<?, ?> c = (SortableColumn<?, ?>) getLeaderboardTable().getColumn(i);
|
||||
c.updateMinMax(leaderboard);
|
||||
//Toggle the first race, if the setting is set and it isn't open yet
|
||||
if (firstRace && isAutoExpandFirstRace() && c instanceof ExpandableSortableColumn<?>) {
|
||||
ExpandableSortableColumn<?> expandableSortableColumn = (ExpandableSortableColumn<?>) c;
|
||||
if (!expandableSortableColumn.isExpanded()) {
|
||||
expandableSortableColumn.toggleExpansion();
|
||||
competitorSelectionProvider.setCompetitors(leaderboard.competitors);
|
||||
selectedRaceColumns.addAll(getRaceColumnsToAddImplicitly(leaderboard));
|
||||
setLeaderboard(leaderboard);
|
||||
adjustColumnLayout(leaderboard);
|
||||
getData().getList().clear();
|
||||
if (leaderboard != null) {
|
||||
boolean firstRace = true;
|
||||
getData().getList().addAll(leaderboard.rows.values());
|
||||
for (int i = 0; i < getLeaderboardTable().getColumnCount(); i++) {
|
||||
SortableColumn<?, ?> c = (SortableColumn<?, ?>) getLeaderboardTable().getColumn(i);
|
||||
c.updateMinMax(leaderboard);
|
||||
// Toggle the first race, if the setting is set and it isn't open yet
|
||||
if (firstRace && isAutoExpandFirstRace() && c instanceof ExpandableSortableColumn<?>) {
|
||||
ExpandableSortableColumn<?> expandableSortableColumn = (ExpandableSortableColumn<?>) c;
|
||||
if (!expandableSortableColumn.isExpanded()) {
|
||||
expandableSortableColumn.toggleExpansion();
|
||||
}
|
||||
firstRace = false;
|
||||
}
|
||||
firstRace = false;
|
||||
}
|
||||
}
|
||||
Comparator<LeaderboardRowDTO> comparator = getComparatorForSelectedSorting();
|
||||
if (comparator != null) {
|
||||
Collections.sort(getData().getList(), comparator);
|
||||
} else {
|
||||
// if no sorting was selected, sort by ascending rank and mark
|
||||
// table header so
|
||||
Collections.sort(getData().getList(), getRankColumn().getComparator());
|
||||
getLeaderboardTable().getColumnSortList().push(getRankColumn());
|
||||
}
|
||||
//Reselect the selected rows
|
||||
clearSelection();
|
||||
for (LeaderboardRowDTO row : data.getList()) {
|
||||
if (competitorSelectionProvider.isSelected(row.competitor)) {
|
||||
leaderboardSelectionModel.setSelected(row, true);
|
||||
Comparator<LeaderboardRowDTO> comparator = getComparatorForSelectedSorting();
|
||||
if (comparator != null) {
|
||||
Collections.sort(getData().getList(), comparator);
|
||||
} else {
|
||||
RankColumn columnToSortFor = getRankColumn();
|
||||
// if no sorting was selected, sort by ascending rank and mark
|
||||
// table header so
|
||||
sort(columnToSortFor, true);
|
||||
}
|
||||
// Reselect the selected rows
|
||||
clearSelection();
|
||||
for (LeaderboardRowDTO row : data.getList()) {
|
||||
if (competitorSelectionProvider.isSelected(row.competitor)) {
|
||||
leaderboardSelectionModel.setSelected(row, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts the leaderboard contents in ascending order according to <code>columnToSortFor</code>'s comparator and
|
||||
* marks the table's column sort list so.
|
||||
*/
|
||||
private void sort(SortableColumn<LeaderboardRowDTO, ?> columnToSortFor, boolean ascending) {
|
||||
Collections.sort(getData().getList(), getComparator(columnToSortFor, ascending));
|
||||
ColumnSortInfo columnSortInfo = getLeaderboardTable().getColumnSortList().push(columnToSortFor);
|
||||
if (ascending != columnSortInfo.isAscending()) {
|
||||
// flip ascending bit by repeating the push:
|
||||
getLeaderboardTable().getColumnSortList().push(columnToSortFor);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearSelection() {
|
||||
for (LeaderboardRowDTO row : getData().getList()) {
|
||||
leaderboardSelectionModel.setSelected(row, false);
|
||||
@@ -1162,11 +1235,19 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
@SuppressWarnings("unchecked")
|
||||
SortableColumn<LeaderboardRowDTO, ?> castResult = (SortableColumn<LeaderboardRowDTO, ?>) columnSortInfo
|
||||
.getColumn();
|
||||
if (columnSortInfo.isAscending()) {
|
||||
result = castResult.getComparator();
|
||||
} else {
|
||||
result = Collections.reverseOrder(castResult.getComparator());
|
||||
}
|
||||
final boolean ascending = columnSortInfo.isAscending();
|
||||
result = getComparator(castResult, ascending);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private Comparator<LeaderboardRowDTO> getComparator(SortableColumn<LeaderboardRowDTO, ?> column,
|
||||
final boolean ascending) {
|
||||
Comparator<LeaderboardRowDTO> result;
|
||||
if (ascending) {
|
||||
result = column.getComparator();
|
||||
} else {
|
||||
result = Collections.reverseOrder(column.getComparator());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1219,7 +1300,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
Column<LeaderboardRowDTO, ?> c = getLeaderboardTable().getColumn(leaderboardposition);
|
||||
if (c instanceof RaceColumn) {
|
||||
RaceColumn<?> raceColumn = (RaceColumn<?>) c;
|
||||
if (raceColumn.getRaceName().equals(race.getRaceColumnName())) {
|
||||
if (raceColumn.getRaceColumnName().equals(race.getRaceColumnName())) {
|
||||
correctColumnData(raceColumn);
|
||||
return true;
|
||||
}
|
||||
@@ -1261,7 +1342,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
Column<LeaderboardRowDTO, ?> c = getLeaderboardTable().getColumn(leaderboardposition);
|
||||
if (c instanceof RaceColumn) {
|
||||
RaceColumn<?> raceColumn = (RaceColumn<?>) c;
|
||||
if (!raceColumn.getRaceName().equals(race.getRaceColumnName()) && raceColumnStartIndex == counter) {
|
||||
if (!raceColumn.getRaceColumnName().equals(race.getRaceColumnName()) && raceColumnStartIndex == counter) {
|
||||
removeColumn(raceColumn);
|
||||
} else {
|
||||
return;
|
||||
@@ -1339,7 +1420,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
for (int i = 0; i < getLeaderboardTable().getColumnCount(); i++) {
|
||||
Column<LeaderboardRowDTO, ?> c = getLeaderboardTable().getColumn(i);
|
||||
if (c instanceof RaceColumn
|
||||
&& (leaderboard == null || !selectedRaceColumnNames.contains(((RaceColumn<?>) c).getRaceName()))) {
|
||||
&& (leaderboard == null || !selectedRaceColumnNames.contains(((RaceColumn<?>) c).getRaceColumnName()))) {
|
||||
columnsToRemove.add(c);
|
||||
}
|
||||
}
|
||||
@@ -1392,7 +1473,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
for (int i = 0; i < getLeaderboardTable().getColumnCount(); i++) {
|
||||
Column<LeaderboardRowDTO, ?> c = getLeaderboardTable().getColumn(i);
|
||||
if (c instanceof RaceColumn
|
||||
&& (leaderboard == null || !leaderboard.raceListContains(((RaceColumn<?>) c).getRaceName()))) {
|
||||
&& (leaderboard == null || !leaderboard.raceListContains(((RaceColumn<?>) c).getRaceColumnName()))) {
|
||||
columnsToRemove.add(c);
|
||||
}
|
||||
}
|
||||
@@ -1519,10 +1600,22 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
|
||||
@Override
|
||||
public void playStateChanged(PlayStates playState, PlayModes playMode) {
|
||||
currentlyHandlingPlayStateChange = true;
|
||||
playPause.setHTML(getPlayPauseImgHtml(playState));
|
||||
playPause.setTitle(playState == PlayStates.Playing ? stringMessages.pauseAutomaticRefresh() : stringMessages.autoRefresh());
|
||||
if (!settingsUpdatedExplicitly && playMode != oldPlayMode) {
|
||||
// if settings weren't explicitly modified, auto-switch to live mode settings and sort for
|
||||
// any pre-selected race
|
||||
updateSettings(LeaderboardSettingsFactory.getInstance().createNewSettingsForPlayMode(
|
||||
playMode,
|
||||
/* don't touch columnToSort if no race was pre-selected */ preSelectedRace == null ? null : preSelectedRace.getRaceName(),
|
||||
/* don't change nameOfRaceColumnToShow */ null,
|
||||
/* set nameOfRaceToShow if race was pre-selected */ preSelectedRace == null ? null : preSelectedRace.getRaceName()));
|
||||
}
|
||||
currentlyHandlingPlayStateChange = false;
|
||||
oldPlayMode = playMode;
|
||||
}
|
||||
|
||||
|
||||
private void compareCompetitors() {
|
||||
List<RaceIdentifier> races = getTrackedRacesIdentifiers();
|
||||
CompareCompetitorsChartDialog chartDialog = new CompareCompetitorsChartDialog(sailingService, races,
|
||||
@@ -1556,7 +1649,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
Collections.unmodifiableList(selectedLegDetails),
|
||||
Collections.unmodifiableList(selectedRaceDetails), /* All races to select */
|
||||
leaderboard.getRaceList(), selectedRaceColumns,
|
||||
autoExpandFirstRace, timer.getRefreshInterval(), delayInMilliseconds, stringMessages);
|
||||
autoExpandFirstRace, timer.getRefreshInterval(), timer.getLivePlayDelayInMillis(), stringMessages);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+72
-11
@@ -2,28 +2,61 @@ package com.sap.sailing.gwt.ui.leaderboard;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.gwt.ui.shared.RaceInLeaderboardDTO;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
|
||||
public class LeaderboardSettings {
|
||||
private final List<RaceInLeaderboardDTO> raceColumnsToShow;
|
||||
/**
|
||||
* Only one of {@link #namesOfRaceColumnsToShow} and {@link #namesOfRacesToShow} must be non-<code>null</code>.
|
||||
*/
|
||||
private final List<String> namesOfRaceColumnsToShow;
|
||||
|
||||
/**
|
||||
* Only one of {@link #namesOfRaceColumnsToShow} and {@link #namesOfRacesToShow} must be non-<code>null</code>.
|
||||
*/
|
||||
private final List<String> namesOfRacesToShow;
|
||||
private final List<DetailType> maneuverDetailsToShow;
|
||||
private final List<DetailType> legDetailsToShow;
|
||||
private final List<DetailType> raceDetailsToShow;
|
||||
private final boolean autoExpandFirstRace;
|
||||
private final long delayBetweenAutoAdvancesInMilliseconds;
|
||||
private final long delayInMilliseconds;
|
||||
private final Long delayBetweenAutoAdvancesInMilliseconds;
|
||||
private final Long delayInMilliseconds;
|
||||
|
||||
/**
|
||||
* An optional sort column; if <code>null</code>, the leaderboard sorting won't be touched when updating the settings.
|
||||
* Otherwise, the leaderboard will be sorted by the race column (ascending if {@link #sortAscending}, descending otherwise.
|
||||
*/
|
||||
private final String nameOfRaceToSort;
|
||||
private final boolean sortAscending;
|
||||
|
||||
/**
|
||||
* @param meneuverDetailsToShow
|
||||
* @param legDetailsToShow
|
||||
* @param raceDetailsToShow
|
||||
* @param namesOfRacesToShow
|
||||
* @param autoExpandFirstRace
|
||||
* @param delayBetweenAutoAdvancesInMilliseconds
|
||||
* @param delayInMilliseconds
|
||||
* @param nameOfRaceToSort
|
||||
* @param sortAscending
|
||||
* @param raceColumnsToShow <code>null</code> means don't modify the list of races shown
|
||||
*/
|
||||
public LeaderboardSettings(List<DetailType> meneuverDetailsToShow, List<DetailType> legDetailsToShow,
|
||||
List<DetailType> raceDetailsToShow, List<RaceInLeaderboardDTO> raceColumnsToShow, boolean autoExpandFirstRace,
|
||||
long delayBetweenAutoAdvancesInMilliseconds, long delayInMilliseconds) {
|
||||
List<DetailType> raceDetailsToShow, List<String> namesOfRaceColumnsToShow,
|
||||
List<String> namesOfRacesToShow, boolean autoExpandFirstRace, Long delayBetweenAutoAdvancesInMilliseconds,
|
||||
Long delayInMilliseconds, String nameOfRaceToSort, boolean sortAscending) {
|
||||
if (namesOfRacesToShow != null && namesOfRaceColumnsToShow != null) {
|
||||
throw new IllegalArgumentException("You can identify races either only by their race or by their column names, not both");
|
||||
}
|
||||
this.legDetailsToShow = legDetailsToShow;
|
||||
this.raceDetailsToShow = raceDetailsToShow;
|
||||
this.raceColumnsToShow = raceColumnsToShow;
|
||||
this.namesOfRacesToShow = namesOfRacesToShow;
|
||||
this.namesOfRaceColumnsToShow = namesOfRaceColumnsToShow;
|
||||
this.autoExpandFirstRace = autoExpandFirstRace;
|
||||
this.delayBetweenAutoAdvancesInMilliseconds = delayBetweenAutoAdvancesInMilliseconds;
|
||||
this.delayInMilliseconds = delayInMilliseconds;
|
||||
this.maneuverDetailsToShow = meneuverDetailsToShow;
|
||||
this.nameOfRaceToSort = nameOfRaceToSort;
|
||||
this.sortAscending = sortAscending;
|
||||
}
|
||||
|
||||
public List<DetailType> getManeuverDetailsToShow() {
|
||||
@@ -38,19 +71,47 @@ public class LeaderboardSettings {
|
||||
return raceDetailsToShow;
|
||||
}
|
||||
|
||||
public List<RaceInLeaderboardDTO> getRaceColumnsToShow(){
|
||||
return raceColumnsToShow;
|
||||
/**
|
||||
* If <code>null</code>, this is to mean that the race columns should not be modified by
|
||||
* {@link LeaderboardPanel#updateSettings(LeaderboardSettings)}.
|
||||
*/
|
||||
public List<String> getNamesOfRaceColumnsToShow() {
|
||||
return namesOfRaceColumnsToShow;
|
||||
}
|
||||
|
||||
/**
|
||||
* If <code>null</code>, this is to mean that the race columns should not be modified by
|
||||
* {@link LeaderboardPanel#updateSettings(LeaderboardSettings)}.
|
||||
*/
|
||||
public List<String> getNamesOfRacesToShow() {
|
||||
return namesOfRacesToShow;
|
||||
}
|
||||
|
||||
public boolean isAutoExpandFirstRace() {
|
||||
return autoExpandFirstRace;
|
||||
}
|
||||
|
||||
public long getDelayBetweenAutoAdvancesInMilliseconds() {
|
||||
/**
|
||||
* @return if <code>null</code>, leave refresh interval alone (don't change in
|
||||
* {@link LeaderboardPanel#updateSettings(LeaderboardSettings)}
|
||||
*/
|
||||
public Long getDelayBetweenAutoAdvancesInMilliseconds() {
|
||||
return delayBetweenAutoAdvancesInMilliseconds;
|
||||
}
|
||||
|
||||
public long getDelayInMilliseconds() {
|
||||
/**
|
||||
* @return if <code>null</code>, leave delay alone (don't change in {@link LeaderboardPanel#updateSettings(LeaderboardSettings)}
|
||||
*/
|
||||
public Long getDelayInMilliseconds() {
|
||||
return delayInMilliseconds;
|
||||
}
|
||||
|
||||
public String getNameOfRaceToSort() {
|
||||
return nameOfRaceToSort;
|
||||
}
|
||||
|
||||
public boolean isSortAscending() {
|
||||
return sortAscending;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+5
-4
@@ -133,17 +133,18 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
legDetailsToShow.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
List<RaceInLeaderboardDTO> raceColumnsToShow = new ArrayList<RaceInLeaderboardDTO>();
|
||||
List<String> namesOfRaceColumnsToShow = new ArrayList<String>();
|
||||
for (Map.Entry<RaceInLeaderboardDTO, CheckBox> entry : raceColumnCheckboxes.entrySet()) {
|
||||
if(entry.getValue().getValue()){
|
||||
raceColumnsToShow.add(entry.getKey());
|
||||
namesOfRaceColumnsToShow.add(entry.getKey().getRaceColumnName());
|
||||
}
|
||||
}
|
||||
Long delayBetweenAutoAdvancesValue = delayBetweenAutoAdvancesInSecondsBox.getValue();
|
||||
Long delayInSecondsValue = delayInSecondsBox.getValue();
|
||||
return new LeaderboardSettings(maneuverDetailsToShow, legDetailsToShow, raceDetailsToShow, raceColumnsToShow, autoExpandFirstRace,
|
||||
return new LeaderboardSettings(maneuverDetailsToShow, legDetailsToShow, raceDetailsToShow,
|
||||
namesOfRaceColumnsToShow, /* nameOfRacesToShow */null, autoExpandFirstRace,
|
||||
1000l * (delayBetweenAutoAdvancesValue == null ? 0l : delayBetweenAutoAdvancesValue.longValue()),
|
||||
1000 * (delayInSecondsValue==null?0:delayInSecondsValue.longValue()));
|
||||
1000 * (delayInSecondsValue == null ? 0 : delayInSecondsValue.longValue()), null, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+49
-8
@@ -1,10 +1,11 @@
|
||||
package com.sap.sailing.gwt.ui.leaderboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
|
||||
import com.sap.sailing.gwt.ui.shared.RaceInLeaderboardDTO;
|
||||
|
||||
/*
|
||||
* A factory class creating leaderboard settings for different contexts (user role, live or replay mode, etc.
|
||||
@@ -19,8 +20,28 @@ public class LeaderboardSettingsFactory {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public LeaderboardSettings createNewSettingsForPlayMode(PlayModes playMode) {
|
||||
/**
|
||||
* @param nameOfRaceToSort
|
||||
* if <code>null</code>, don't sort any race column
|
||||
* @param nameOfRaceColumnToShow
|
||||
* if <code>null</code>, the settings returned will cause the list of race columns shown to remain
|
||||
* unchanged during {@link LeaderboardPanel#updateSettings(LeaderboardSettings)}; otherwise, the settings
|
||||
* will show the single race column identified by this argument
|
||||
* @param nameOfRaceToShow
|
||||
* alternatively to <code>nameOfRaceColumnToShow</code>, this argument may be used in case the race name is known,
|
||||
* but its column name is not. If <code>null</code>, and <code>nameOfRaceColumnToShow</code> is also <code>null</code>,
|
||||
* no change to the selected race columns will happen while updating the leaderboard settings. It is an error
|
||||
* to pass non-<code>null</code> values for both, <code>nameOfRaceColumnToShow</code> <em>and</em>
|
||||
* <code>nameOfRaceToShow</code>, and an {@link IllegalArgumentException} will be thrown in this case.
|
||||
*/
|
||||
public LeaderboardSettings createNewSettingsForPlayMode(PlayModes playMode, String nameOfRaceToSort, String nameOfRaceColumnToShow,
|
||||
String nameOfRaceToShow) {
|
||||
if (nameOfRaceColumnToShow != null && nameOfRaceToShow != null) {
|
||||
throw new IllegalArgumentException("Can identify only one race to show, either by race name or by its column name, but not both");
|
||||
}
|
||||
LeaderboardSettings settings = null;
|
||||
List<String> namesOfRaceColumnsToShow = nameOfRaceColumnToShow == null ? null : Collections.singletonList(nameOfRaceColumnToShow);
|
||||
List<String> namesOfRacesToShow = nameOfRaceToShow == null ? null : Collections.singletonList(nameOfRaceToShow);
|
||||
switch (playMode) {
|
||||
case Live:
|
||||
ArrayList<DetailType> maneuverDetails = new ArrayList<DetailType>();
|
||||
@@ -32,17 +53,35 @@ public class LeaderboardSettingsFactory {
|
||||
legDetails.add(DetailType.AVERAGE_SPEED_OVER_GROUND_IN_KNOTS);
|
||||
legDetails.add(DetailType.RANK_GAIN);
|
||||
ArrayList<DetailType> raceDetails = new ArrayList<DetailType>();
|
||||
ArrayList<RaceInLeaderboardDTO> raceColumns = new ArrayList<RaceInLeaderboardDTO>();
|
||||
settings = new LeaderboardSettings(maneuverDetails, legDetails, raceDetails, raceColumns, true, 0l, 0l);
|
||||
raceDetails.add(DetailType.RACE_DISTANCE_TO_LEADER_IN_METERS);
|
||||
raceDetails.add(DetailType.NUMBER_OF_MANEUVERS);
|
||||
settings = new LeaderboardSettings(maneuverDetails, legDetails, raceDetails, namesOfRaceColumnsToShow,
|
||||
namesOfRacesToShow,
|
||||
/* set autoExpandFirstRace to true if we look at a single race */ nameOfRaceColumnToShow != null || nameOfRaceToShow != null, /* refresh interval */ null,
|
||||
/* delay to live */ null, /* name of race to sort */ nameOfRaceToSort, /* ascending */ true);
|
||||
break;
|
||||
case Replay:
|
||||
settings = createNewDefaultSettings(true);
|
||||
settings = createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, /* autoExpandFirstRace */ nameOfRaceColumnToShow != null);
|
||||
break;
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
public LeaderboardSettings createNewDefaultSettings(boolean autoExpandFirstRace) {
|
||||
/**
|
||||
* @param namesOfRaceColumnsToShow
|
||||
* if <code>null</code>, create settings which leave the list of races to show unchanged when applied
|
||||
* using {@link LeaderboardPanel#updateSettings(LeaderboardSettings)}; otherwise, the list of names of
|
||||
* the race columns (not their races!) that will be shown, so that, e.g., an empty list causes no race
|
||||
* columns to be shown
|
||||
* @param namesOfRacesToShow
|
||||
* alternatively, races to show can also be specified by their race names; if not <code>null</code>,
|
||||
* <code>namesOfRaceColumnsToShow</code> must be <code>null
|
||||
*/
|
||||
public LeaderboardSettings createNewDefaultSettings(List<String> namesOfRaceColumnsToShow,
|
||||
List<String> namesOfRacesToShow, boolean autoExpandFirstRace) {
|
||||
if (namesOfRaceColumnsToShow != null && namesOfRacesToShow != null) {
|
||||
throw new IllegalArgumentException("Can specify race columns either by column or by race name, not both");
|
||||
}
|
||||
ArrayList<DetailType> maneuverDetails = new ArrayList<DetailType>();
|
||||
maneuverDetails.add(DetailType.TACK);
|
||||
maneuverDetails.add(DetailType.JIBE);
|
||||
@@ -53,7 +92,9 @@ public class LeaderboardSettingsFactory {
|
||||
legDetails.add(DetailType.RANK_GAIN);
|
||||
ArrayList<DetailType> raceDetails = new ArrayList<DetailType>();
|
||||
raceDetails.add(DetailType.DISPLAY_LEGS);
|
||||
ArrayList<RaceInLeaderboardDTO> raceColumns = new ArrayList<RaceInLeaderboardDTO>();
|
||||
return new LeaderboardSettings(maneuverDetails, legDetails, raceDetails, raceColumns, autoExpandFirstRace, 0l, 0l);
|
||||
return new LeaderboardSettings(maneuverDetails, legDetails, raceDetails, namesOfRaceColumnsToShow,
|
||||
namesOfRacesToShow,
|
||||
autoExpandFirstRace, /* refresh interval */ null,
|
||||
/* delay to live */ null, /* sort by column */ null, /* ascending */ true);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -170,7 +170,7 @@ public class ManeuverCountRaceColumn extends ExpandableSortableColumn<String> im
|
||||
}
|
||||
|
||||
private String getRaceName() {
|
||||
return raceNameProvider.getRaceName();
|
||||
return raceNameProvider.getRaceColumnName();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.sap.sailing.gwt.ui.leaderboard;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardEntryDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.LeaderboardRowDTO;
|
||||
|
||||
public class NetPointsComparator implements Comparator<LeaderboardRowDTO> {
|
||||
private final boolean ascending;
|
||||
private final String raceName;
|
||||
|
||||
public NetPointsComparator(boolean ascending, String raceName) {
|
||||
super();
|
||||
this.ascending = ascending;
|
||||
this.raceName = raceName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(LeaderboardRowDTO o1, LeaderboardRowDTO o2) {
|
||||
LeaderboardEntryDTO o1Entry = o1.fieldsByRaceName.get(raceName);
|
||||
LeaderboardEntryDTO o2Entry = o2.fieldsByRaceName.get(raceName);
|
||||
return (o1Entry == null || o1Entry.netPoints == 0) ? (o2Entry == null || o2Entry.netPoints == 0) ? 0
|
||||
: ascending ? 1 : -1 : (o2Entry == null || o2Entry.netPoints == 0) ? ascending ? -1 : 1
|
||||
: o1Entry.netPoints - o2Entry.netPoints;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -14,5 +14,5 @@ package com.sap.sailing.gwt.ui.leaderboard;
|
||||
*
|
||||
*/
|
||||
public interface RaceNameProvider {
|
||||
String getRaceName();
|
||||
String getRaceColumnName();
|
||||
}
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public class TVViewPanel extends SimplePanel implements RaceTimesInfoProviderLis
|
||||
}
|
||||
|
||||
private LeaderboardPanel createLeaderboardPanel(String leaderboardName) {
|
||||
LeaderboardSettings settings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(/* autoExpandFirstRace */ false);
|
||||
LeaderboardSettings settings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, /* autoExpandFirstRace */ false);
|
||||
CompetitorSelectionModel selectionModel = new CompetitorSelectionModel(/* hasMultiSelection */ true);
|
||||
Timer timer = new Timer(PlayModes.Live, /* delayBetweenAutoAdvancesInMilliseconds */3000l);
|
||||
timer.play();
|
||||
|
||||
+2
-1
@@ -253,7 +253,8 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
public EditableLeaderboardPanel(SailingServiceAsync sailingService, String leaderboardName, String leaderboardGroupName,
|
||||
ErrorReporter errorReporter, StringMessages stringConstants, UserAgentTypes userAgentType) {
|
||||
super(sailingService, LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(
|
||||
/* autoExpandFirstRace */false), new CompetitorSelectionModel(/* hasMultiSelection */true),
|
||||
/* racesToShow */ null, /* namesOfRacesToShow */ null, /* autoExpandFirstRace */false),
|
||||
new CompetitorSelectionModel(/* hasMultiSelection */true),
|
||||
leaderboardName, leaderboardGroupName, errorReporter, stringConstants, userAgentType);
|
||||
}
|
||||
|
||||
|
||||
+11
-6
@@ -131,8 +131,11 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
|
||||
componentsNavigationPanel.addStyleName("raceBoardNavigation");
|
||||
|
||||
// create the default leaderboard and select the right race
|
||||
LeaderboardSettings leaderBoardSettings = LeaderboardSettingsFactory.getInstance().createNewSettingsForPlayMode(timer.getPlayMode());
|
||||
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService, leaderBoardSettings, selectedRaceIdentifier, competitorSelectionModel,
|
||||
LeaderboardSettings leaderBoardSettings = LeaderboardSettingsFactory.getInstance()
|
||||
.createNewSettingsForPlayMode(timer.getPlayMode(), /* nameOfRaceToSort */ selectedRaceIdentifier.getRaceName(),
|
||||
/* nameOfRaceColumnToShow */ null, /* nameOfRaceToShow */ selectedRaceIdentifier.getRaceName());
|
||||
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService, leaderBoardSettings,
|
||||
selectedRaceIdentifier, competitorSelectionModel,
|
||||
timer, leaderboardName, leaderboardGroupName, errorReporter, stringMessages, userAgentType);
|
||||
RaceMap raceMap = new RaceMap(sailingService, errorReporter, timer, competitorSelectionModel, stringMessages);
|
||||
raceMap.onRaceSelectionChange(Collections.singletonList(selectedRaceIdentifier));
|
||||
@@ -202,10 +205,12 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
|
||||
boolean showCompetitorCharts = true;
|
||||
// create the default leaderboard and select the right race
|
||||
if(showLeaderboard) {
|
||||
LeaderboardSettings leaderBoardSettings = LeaderboardSettingsFactory.getInstance().createNewSettingsForPlayMode(timer.getPlayMode());
|
||||
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService, leaderBoardSettings, selectedRaceIdentifier, competitorSelectionModel,
|
||||
timer, leaderboardName, leaderboardGroupName, errorReporter, stringMessages, userAgentType);
|
||||
|
||||
LeaderboardSettings leaderBoardSettings = LeaderboardSettingsFactory.getInstance()
|
||||
.createNewSettingsForPlayMode(timer.getPlayMode(), /* nameOfRaceToSort */ selectedRaceIdentifier.getRaceName(),
|
||||
/* nameOfRaceColumnToShow */ null, /* nameOfRaceToShow */ selectedRaceIdentifier.getRaceName());
|
||||
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService, leaderBoardSettings,
|
||||
selectedRaceIdentifier, competitorSelectionModel, timer, leaderboardName, leaderboardGroupName,
|
||||
errorReporter, stringMessages, userAgentType);
|
||||
CollapsableComponentViewer<LeaderboardSettings> leaderboardViewer = new CollapsableComponentViewer<LeaderboardSettings>(
|
||||
leaderboardPanel, "100%", "100%", stringMessages, ViewerPanelTypes.SCROLL_PANEL);
|
||||
componentViewers.add(leaderboardViewer);
|
||||
|
||||
-2
@@ -34,9 +34,7 @@ public class SideBySideComponentViewer implements ComponentViewer {
|
||||
mainPanel = new LayoutPanel();
|
||||
mainPanel.setSize("100%", "100%");
|
||||
splitLayoutPanel = new SplitLayoutPanel();
|
||||
|
||||
mainPanel.add(splitLayoutPanel);
|
||||
// splitLayoutPanel.setSize(defaultWidth, defaultHeight);
|
||||
|
||||
for(Component<?> component: components) {
|
||||
if(component.isVisible())
|
||||
|
||||
+23
-9
@@ -254,6 +254,29 @@ public class LeaderboardDTO implements IsSerializable {
|
||||
}
|
||||
return competitors.indexOf(competitor) + 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines the competitor's rank in the race with name <code>raceName</code>. If a race with that name does not exist or the
|
||||
* competitor has no score for that race, <code>null</code> is returned; the 1-based rank otherwise.
|
||||
*/
|
||||
public Integer getRank(CompetitorDTO competitor, String raceName) {
|
||||
Integer result = null;
|
||||
if (rows.get(competitor) != null) {
|
||||
LeaderboardEntryDTO fields = rows.get(competitor).fieldsByRaceName.get(raceName);
|
||||
if (fields != null) {
|
||||
List<CompetitorDTO> competitorsOrderedByNetPoints = new ArrayList<CompetitorDTO>(competitors);
|
||||
Collections.sort(competitorsOrderedByNetPoints, new Comparator<CompetitorDTO>() {
|
||||
@Override
|
||||
public int compare(CompetitorDTO o1, CompetitorDTO o2) {
|
||||
return getTotalRankingComparator().compare(rows.get(o1), rows.get(o2));
|
||||
}
|
||||
});
|
||||
competitorsOrderedAccordingToTotalRank = true;
|
||||
result = competitorsOrderedByNetPoints.indexOf(competitor) + 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean raceIsTracked(String raceColumnName) {
|
||||
for (RaceInLeaderboardDTO race : races) {
|
||||
@@ -303,15 +326,6 @@ public class LeaderboardDTO implements IsSerializable {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/*
|
||||
public List<String> getRaceColumnNameList() {
|
||||
List<String> raceColumnNames = new ArrayList<String>();
|
||||
for (RaceInLeaderboardDTO raceInLeaderboardDTO : races) {
|
||||
raceColumnNames.add(raceInLeaderboardDTO.getRaceColumnName());
|
||||
}
|
||||
return raceColumnNames;
|
||||
}
|
||||
*/
|
||||
|
||||
public List<RaceInLeaderboardDTO> getRaceList() {
|
||||
return races;
|
||||
|
||||
+18
-7
@@ -55,17 +55,19 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
|
||||
private ErrorReporter errorReporter;
|
||||
private LeaderboardGroupDTO group;
|
||||
private String root;
|
||||
private String viewMode;
|
||||
|
||||
private FlowPanel mainPanel;
|
||||
private Widget welcomeWidget = null;
|
||||
|
||||
public LeaderboardGroupPanel(SailingServiceAsync sailingService, StringMessages stringConstants,
|
||||
ErrorReporter errorReporter, final String groupName, String root) {
|
||||
ErrorReporter errorReporter, final String groupName, String root, String viewMode) {
|
||||
super();
|
||||
this.sailingService = sailingService;
|
||||
this.stringConstants = stringConstants;
|
||||
this.errorReporter = errorReporter;
|
||||
this.root = root;
|
||||
this.viewMode = viewMode;
|
||||
if (this.root == null || this.root.length() == 0) {
|
||||
this.root = "leaderboardGroupPanel";
|
||||
}
|
||||
@@ -187,15 +189,21 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
|
||||
String displayName = race.getRaceColumnName();
|
||||
if (race.getRaceColumnName().equals(stringConstants.overview())) {
|
||||
String link = URLFactory.INSTANCE.encode("/gwt/Leaderboard.html?name=" + leaderboard.name
|
||||
+ "&leaderboardGroupName=" + group.name + "&root=" + root
|
||||
+ (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""));
|
||||
+ "&leaderboardGroupName=" + group.name + "&root=" + root);
|
||||
if(debugParam != null && !debugParam.isEmpty())
|
||||
link += "&gwt.codesvr=" + debugParam;
|
||||
if(viewMode != null && !viewMode.isEmpty())
|
||||
link += "&viewMode=" + viewMode;
|
||||
b.append(ANCHORTEMPLATE.anchor(link, displayName, STYLE_NAME_PREFIX + "ActiveLeaderboard"));
|
||||
} else {
|
||||
if (race.getRaceIdentifier() != null) {
|
||||
EventNameAndRaceName raceId = (EventNameAndRaceName) race.getRaceIdentifier();
|
||||
String link = URLFactory.INSTANCE.encode("/gwt/RaceBoard.html?leaderboardName=" + leaderboard.name + "&raceName=" + raceId.getRaceName()
|
||||
+ "&eventName=" + raceId.getEventName() + "&leaderboardGroupName=" + group.name + "&root=" + root
|
||||
+ (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""));
|
||||
+ "&eventName=" + raceId.getEventName() + "&leaderboardGroupName=" + group.name + "&root=" + root);
|
||||
if(debugParam != null && !debugParam.isEmpty())
|
||||
link += "&gwt.codesvr=" + debugParam;
|
||||
if(viewMode != null && !viewMode.isEmpty())
|
||||
link += "&viewMode=" + viewMode;
|
||||
b.append(ANCHORTEMPLATE.anchor(link, displayName, STYLE_NAME_PREFIX + "ActiveRace"));
|
||||
} else {
|
||||
b.append(TEXTTEMPLATE.textWithClass(race.getRaceColumnName(), STYLE_NAME_PREFIX + "InactiveRace"));
|
||||
@@ -213,8 +221,11 @@ public class LeaderboardGroupPanel extends FormPanel implements HasWelcomeWidget
|
||||
EventNameAndRaceName raceId = (EventNameAndRaceName) race.getRaceIdentifier();
|
||||
String link = URLFactory.INSTANCE.encode("/gwt/RaceBoard.html?leaderboardName=" + leaderboard.name
|
||||
+ "&raceName=" + raceId.getRaceName() + "&root=" + root + raceId.getRaceName() + "&eventName="
|
||||
+ raceId.getEventName() + "&leaderboardGroupName=" + group.name
|
||||
+ (debugParam != null && !debugParam.isEmpty() ? "&gwt.codesvr=" + debugParam : ""));
|
||||
+ raceId.getEventName() + "&leaderboardGroupName=" + group.name);
|
||||
if(debugParam != null && !debugParam.isEmpty())
|
||||
link += "&gwt.codesvr=" + debugParam;
|
||||
if(viewMode != null && !viewMode.isEmpty())
|
||||
link += "&viewMode=" + viewMode;
|
||||
b.append(ANCHORTEMPLATE.anchor(link, race.getRaceColumnName(), STYLE_NAME_PREFIX + "ActiveRace"));
|
||||
} else {
|
||||
if (!first) {
|
||||
|
||||
+2
-1
@@ -21,6 +21,7 @@ public class SpectatorEntryPoint extends AbstractEntryPoint implements EventRefr
|
||||
public void onModuleLoad() {
|
||||
super.onModuleLoad();
|
||||
String groupParamValue = Window.Location.getParameter("leaderboardGroupName");
|
||||
String viewModeParamValue = Window.Location.getParameter("viewMode");
|
||||
final String groupName;
|
||||
if (groupParamValue == null || groupParamValue.isEmpty()) {
|
||||
groupName = null;
|
||||
@@ -52,7 +53,7 @@ public class SpectatorEntryPoint extends AbstractEntryPoint implements EventRefr
|
||||
// panelToDisplay = new LeaderboardGroupOverviewPanel(sailingService, this, stringMessages);
|
||||
Window.alert("No leaderboard group name was given.");
|
||||
} else {
|
||||
panelToDisplay = new LeaderboardGroupPanel(sailingService, stringMessages, this, groupName, root);
|
||||
panelToDisplay = new LeaderboardGroupPanel(sailingService, stringMessages, this, groupName, root, viewModeParamValue);
|
||||
LeaderboardGroupPanel groupPanel = (LeaderboardGroupPanel) panelToDisplay;
|
||||
groupPanel.setWelcomeWidget(new SimpleWelcomeWidget( stringMessages.welcomeToSailingAnalytics(),
|
||||
"Understanding what happens out on the race course isn't always easy. To help solve this challenge and" +
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
<body>
|
||||
<h2>SAP Sailing Analytics Suite</h2>
|
||||
|
||||
<b>Übersicht über die SAP Sailing Analytics Suite</b>
|
||||
<b>Overview SAP Sailing Analytics Suite</b>
|
||||
<div style="height:1em;"></div>
|
||||
|
||||
<a href="/gwt/AdminConsole.html"><b>Administrator Console</b></a><br/>
|
||||
<a href="/gwt/Leaderboard.html"><b>Leaderboard</b></a><br/>
|
||||
<a href="/gwt/RaceBoard.html"><b>Race board</b></a><br/>
|
||||
<a href="/gwt/RaceBoard.html"><b>Race Board</b></a><br/>
|
||||
<a href="/gwt/Spectator.html"><b>Spectators</b></a><br/>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user