mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-04 03:13:49 +00:00
added specific leaderboard views for MetaLeaderboards and normal leaderboards
This commit is contained in:
1 parent
c2fdb1fd6a
commit
2ab3af1405
45 files changed
+1679
-619
No files matched your search
+2
-1
@@ -31,7 +31,8 @@ public enum DetailType implements Serializable {
|
||||
TOTAL_TIME_SAILED_REACHING_IN_SECONDS(1, ASCENDING),
|
||||
MAXIMUM_SPEED_OVER_GROUND_IN_KNOTS(1, DESCENDING),
|
||||
TOTAL_DISTANCE_TRAVELED(0, ASCENDING), TOTAL_AVERAGE_SPEED_OVER_GROUND(2, DESCENDING),
|
||||
TOTAL_TIME_SAILED_IN_SECONDS(1, ASCENDING), RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING);
|
||||
TOTAL_TIME_SAILED_IN_SECONDS(1, ASCENDING), RACE_CURRENT_SPEED_OVER_GROUND_IN_KNOTS(2, DESCENDING),
|
||||
RACE_TOTAL_POINTS(2, ASCENDING), REGATTA_TOTAL_POINTS(2, ASCENDING);
|
||||
|
||||
private int precision;
|
||||
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.sap.sailing.domain.common;
|
||||
|
||||
public enum LeaderboardType {
|
||||
RegattaLeaderboard(false, true), RegattaMetaLeaderboard(true, true),
|
||||
FlexibleLeaderboard(false, false), FlexibleMetaLeaderboard(true, false);
|
||||
|
||||
boolean isRegattaLeaderboard;
|
||||
boolean isMetaLeaderboard;
|
||||
|
||||
LeaderboardType(boolean isMetaLeaderboard, boolean isRegattaLeaderboard) {
|
||||
this.isMetaLeaderboard = isMetaLeaderboard;
|
||||
this.isRegattaLeaderboard = isRegattaLeaderboard;
|
||||
}
|
||||
|
||||
public boolean isMetaLeaderboard() {
|
||||
return isMetaLeaderboard;
|
||||
}
|
||||
|
||||
public boolean isRegattaLeaderboard() {
|
||||
return isRegattaLeaderboard;
|
||||
}
|
||||
|
||||
public boolean isFlexibleLeaderboard() {
|
||||
return !isRegattaLeaderboard;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String result = "";
|
||||
if(isMetaLeaderboard) {
|
||||
result += "Meta, ";
|
||||
}
|
||||
result += isRegattaLeaderboard ? "Regatta" : "Flexible";
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -18,8 +18,7 @@ public class LeaderboardPanelMock extends LeaderboardPanel {
|
||||
String leaderboardName, ErrorReporter errorReporter,
|
||||
StringMessages stringConstants) {
|
||||
super(sailingService, null, LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(
|
||||
/* racesToShow */null, /* namesOfRacesToShow */ null, null, /* autoExpandFirstRace */ false,
|
||||
/* showMetaLeaderboardsOnSamePage */ false), new CompetitorSelectionModel(
|
||||
/* racesToShow */null, /* namesOfRacesToShow */ null, null, /* autoExpandFirstRace */ false), new CompetitorSelectionModel(
|
||||
/* hasMultiSelection */true), leaderboardName, errorReporter, stringConstants, null, /* showRaceDetails */ true);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
.gwt-SplitLayoutPanel-HDragger {
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.gwt-ToggleButton {
|
||||
background: url(images/btn-cta-orangeleft.png) center top repeat-x;
|
||||
padding: 8px;
|
||||
margin: 0 11px 0 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.gwt-ToggleButton-down {
|
||||
background: url(images/btn-cta-orangeleft.png) center -30px repeat-x;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.gwt-SplitLayoutPanel-HDragger {
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
.gwt-SplitLayoutPanel-HDragger {
|
||||
background: #cbcaca url(images/thumb_vertical.png) center center no-repeat;
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.gwt-SplitLayoutPanel-VDragger {
|
||||
background: #cbcaca url(images/thumb_horz.png) center center no-repeat;
|
||||
cursor: row-resize;
|
||||
}
|
||||
|
||||
.gwt-ToggleButton-up-hovering, .gwt-ToggleButton-down-hovering {
|
||||
background: url(images/btn-cta-orangeleft-down.png) center top repeat-x;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.gwt-MenuBarPopup .menuPopupTopLeft {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.gwt-MenuBarPopup .menuPopupTopCenter {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.gwt-MenuBarPopup .menuPopupTopCenter {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.gwt-MenuBarPopup .menuPopupTopRight {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.gwt-MenuBarPopup .menuPopupMiddleLeft {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.gwt-MenuBarPopup .menuPopupMiddleRight {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.gwt-MenuBarPopup .menuPopupMiddleRight {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.gwt-MenuBarPopup .menuPopupBottomCenter {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.gwt-MenuBarPopup .menuPopupBottomRight {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.gwt-MenuBarPopup .menuPopupBottomLeft {
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
.gwt-MenuBar-vertical .gwt-MenuItem {
|
||||
padding: 10px;
|
||||
padding-bottom: 5px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.gwt-MenuBar .gwt-MenuItem-selected {
|
||||
background: none repeat scroll 0 0 #efaa00;
|
||||
}
|
||||
|
||||
.gwt-DialogBox {
|
||||
-webkit-box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
|
||||
-moz-box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
|
||||
box-shadow: 7px 7px 5px rgba(50, 50, 50, 0.75);
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.gwt-DialogBox .Caption {
|
||||
font-size: 14px;
|
||||
padding: 14px 10px;
|
||||
background: url(images/dialogBox-bg.png) 0 0 repeat-x;
|
||||
-webkit-border-top-left-radius: 5px;
|
||||
-webkit-border-top-right-radius: 5px;
|
||||
-moz-border-radius-topleft: 5px;
|
||||
-moz-border-radius-topright: 5px;
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
font-family: UbuntuBold, Verdana, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.gwt-DialogBox .dialogContent {
|
||||
background: #ffffff;
|
||||
padding: 10px;
|
||||
border: 10px solid #a6a6a6;
|
||||
-webkit-border-bottom-right-radius: 5px;
|
||||
-webkit-border-bottom-left-radius: 5px;
|
||||
-moz-border-radius-bottomright: 5px;
|
||||
-moz-border-radius-bottomleft: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
}
|
||||
|
||||
.gwt-Button, .gwt-Button:visited {
|
||||
font-family: UbuntuBold, Verdana, Arial, sans-serif;
|
||||
border: none;
|
||||
|
||||
background: url(images/btn-cta-orangeleft.png) center top repeat-x;
|
||||
display: inline-block;
|
||||
padding: 2px 10px 4px;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
|
||||
cursor: pointer;
|
||||
height: 24px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.gwt-Button:active {
|
||||
top: 1px;
|
||||
position: relative;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.gwt-Button:hover {
|
||||
background: url(images/btn-cta-orangeleft.png) center -30px repeat-x;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.gwt-Button[disabled] {
|
||||
cursor: default;
|
||||
color: #888;
|
||||
background: #F1F1F1;
|
||||
border: 1px solid #919090;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.gwt-Button[disabled]:hover {
|
||||
cursor: default;
|
||||
color: #888;
|
||||
background: #F1F1F1;
|
||||
}
|
||||
|
||||
.gwt-Button[disabled]:active {
|
||||
cursor: default;
|
||||
color: #888;
|
||||
background: #F1F1F1;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.gwt-ButtonLarge
|
||||
.gwt-ButtonMedium
|
||||
.gwt-ButtonSmall
|
||||
|
||||
.gwt-DialogBox .boxPanel {
|
||||
padding: 0 0 10px 0;
|
||||
}
|
||||
|
||||
.gwt-DialogBox .boxPanel:after {
|
||||
display: inline-block;
|
||||
content: " ";
|
||||
display: block;
|
||||
height: 0;
|
||||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.gwt-DialogBox .settingsDialogLabel {
|
||||
float: left;
|
||||
padding: 3px 6px 0 0;
|
||||
}
|
||||
|
||||
.gwt-DialogBox .settingsDialogValue {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.gwt-DialogBox .additionalWidgets {
|
||||
padding: 5px 0 0 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.gwt-DialogBox .gwt-Label {
|
||||
line-height: 1.4;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
@import url(fontface.css);
|
||||
@import url(CommonControls.css);
|
||||
@import url(ViewerToolbar.css);
|
||||
|
||||
/** Add css rules here for your application. */
|
||||
/*
|
||||
@@ -47,10 +48,6 @@ h1 {
|
||||
table {
|
||||
border-collapse: separate; }
|
||||
|
||||
.leaderboardMargin {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.leaderboardContent {
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
.viewerToolbar {
|
||||
font-family: 'UbuntuLight', Arial, Verdana, sans-serif;
|
||||
height: 30px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.viewerToolbar-toolbaritem {
|
||||
color: #dddcdc;
|
||||
text-transform: uppercase;
|
||||
font-weight: 500;
|
||||
margin: 0 12px 0 0;
|
||||
padding: 0 0 5px 0;
|
||||
}
|
||||
|
||||
.viewerToolbar-toolbaritem:hover {
|
||||
border-bottom: 4px solid #f0ab00;
|
||||
color: #dddcdc;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.viewerToolbar-toolbaritem:active {
|
||||
border-bottom: 4px solid #f0ab00;
|
||||
color: #dddcdc;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.viewerToolbar-settingsButtonPanel {
|
||||
float: right;
|
||||
margin: 9px 12px 0 0;
|
||||
}
|
||||
|
||||
.viewerToolbar-settingsButton {
|
||||
background: url(images/settings_white.png), url(images/btn-cta-orangeleft.png);
|
||||
background-position: center, center 0;
|
||||
background-repeat: no-repeat, repeat-x;
|
||||
width: 27px;
|
||||
height: 23px;
|
||||
margin: 0 12px 0 1px;
|
||||
-webkit-border-radius: 0px 3px 3px 0px;
|
||||
border-radius: 0px 3px 3px 0px;
|
||||
}
|
||||
|
||||
.viewerToolbar-settingsButton[disabled] {
|
||||
background: url(images/settings_white.png) #ababab;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.viewerToolbar-settingsButton:hover {
|
||||
background-image: url(images/settings_white.png), url(images/btn-cta-orangeleft.png);
|
||||
background-position: center, center -30px;
|
||||
background-repeat: no-repeat, repeat-x;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.viewerToolbar-settingsButton[disabled]:hover {
|
||||
background: url(images/settings_white.png) #ababab;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
cursor: normal;}
|
||||
|
||||
.viewerToolbar-innerElement {
|
||||
background: url("images/btn-cta-orangeleft.png") repeat-x scroll center 0 transparent;
|
||||
border-bottom-left-radius: 3px;
|
||||
border-top-left-radius: 3px;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
font-family: UbuntuBold,Verdana,Arial,sans-serif;
|
||||
font-size: 14px;
|
||||
margin: 0 0 0 0;
|
||||
padding: 2px 7px 2px 3px;
|
||||
height: 18px;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
-moz-border-radius: 5px 0 0 5px;
|
||||
-webkit-border-radius: 5px 0 0 5px;
|
||||
border-radius: 5px 0 0 5px;
|
||||
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.viewerToolbar-innerElement:active {
|
||||
top: 1px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.viewerToolbar-innerElement:hover {
|
||||
background: url("images/btn-cta-orangeleft.png") repeat-x scroll center -30px transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.viewerToolbar-innerElement label {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.viewerToolbar-standaloneElement {
|
||||
background: url("images/btn-cta-orangeleft.png") repeat-x scroll center 0 transparent;
|
||||
color: #FFFFFF;
|
||||
cursor: pointer;
|
||||
font-family: UbuntuBold,Verdana,Arial,sans-serif;
|
||||
font-size: 14px;
|
||||
margin: 0 0 0 0;
|
||||
padding: 2px 7px 2px 3px;
|
||||
height: 23px;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
-moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
||||
text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.25);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
|
||||
border-radius: 5px 5px 5px 5px;
|
||||
-moz-border-radius: 5px 0 0 5px;
|
||||
-webkit-border-radius: 5px 5px 5px 5px;
|
||||
}
|
||||
|
||||
.viewerToolbar-standaloneElement:active {
|
||||
top: 1px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.viewerToolbar-standaloneElement:hover {
|
||||
background: url("images/btn-cta-orangeleft.png") repeat-x scroll center -30px transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.viewerToolbar-standaloneElement label {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -28,9 +28,9 @@ bin.includes = META-INF/,\
|
||||
com.sap.sailing.gwt.ui.RaceBoard/,\
|
||||
highcharts/,\
|
||||
Spectator.css,\
|
||||
fontface.css,\
|
||||
fontface.css,\
|
||||
webfonts/,\
|
||||
RegattaOverview.css,\
|
||||
RegattaOverview.css,\
|
||||
RegattaOverview.html,\
|
||||
com.sap.sailing.gwt.ui.RegattaOverview/,\
|
||||
com.sap.sailing.gwt.ui.VideoPopup/,\
|
||||
@@ -42,5 +42,7 @@ bin.includes = META-INF/,\
|
||||
com.sap.sailing.gwt.ui.TvView/,\
|
||||
BrowserUnsupported.html,\
|
||||
PolarSheets.css,\
|
||||
PolarSheets.html
|
||||
PolarSheets.html,\
|
||||
ViewerToolbar.css,\
|
||||
CommonGwtControls.css
|
||||
output.. = WEB-INF/classes/
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.sap.sailing.gwt.ui.actions;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.shared.CompetitorDTO;
|
||||
|
||||
public class GetLeaderboardDataEntriesAction extends DefaultAsyncAction<List<Triple<String, List<CompetitorDTO>, List<Double>>>> {
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final DetailType detailType;
|
||||
private final String leaderboardName;
|
||||
private final Date date;
|
||||
|
||||
public GetLeaderboardDataEntriesAction(SailingServiceAsync sailingService, String leaderboardName, Date date, DetailType detailType,
|
||||
AsyncCallback<List<Triple<String, List<CompetitorDTO>, List<Double>>>> callback) {
|
||||
super(callback);
|
||||
this.sailingService = sailingService;
|
||||
this.leaderboardName = leaderboardName;
|
||||
this.date = date;
|
||||
this.detailType = detailType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(AsyncActionsExecutor asyncActionsExecutor) {
|
||||
sailingService.getLeaderboardDataEntriesForAllRaceColumns(leaderboardName, date, detailType,
|
||||
(AsyncCallback<List<Triple<String, List<CompetitorDTO>, List<Double>>>>) getWrapperCallback(asyncActionsExecutor));
|
||||
}
|
||||
}
|
||||
+11
-14
@@ -228,11 +228,7 @@ public class LeaderboardConfigPanel extends FormPanel implements SelectedLeaderb
|
||||
TextColumn<StrippedLeaderboardDTO> leaderboardTypeColumn = new TextColumn<StrippedLeaderboardDTO>() {
|
||||
@Override
|
||||
public String getValue(StrippedLeaderboardDTO leaderboard) {
|
||||
String result = leaderboard.isRegattaLeaderboard ? "Regatta" : "Flexible";
|
||||
if(leaderboard.isMetaLeaderboard) {
|
||||
result += " , Meta";
|
||||
}
|
||||
return result;
|
||||
return leaderboard.type.toString();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -264,10 +260,11 @@ public class LeaderboardConfigPanel extends FormPanel implements SelectedLeaderb
|
||||
List<StrippedLeaderboardDTO> otherExistingLeaderboard = new ArrayList<StrippedLeaderboardDTO>();
|
||||
otherExistingLeaderboard.addAll(availableLeaderboardList);
|
||||
otherExistingLeaderboard.remove(leaderboardDTO);
|
||||
if (leaderboardDTO.isMetaLeaderboard) {
|
||||
if (leaderboardDTO.type.isMetaLeaderboard()) {
|
||||
Window.alert("This is a meta leaderboard. It can't be changed here.");
|
||||
} else {
|
||||
if (leaderboardDTO.isRegattaLeaderboard) {
|
||||
if (leaderboardDTO.type.isRegattaLeaderboard()) {
|
||||
|
||||
LeaderboardDescriptor descriptor = new LeaderboardDescriptor(leaderboardDTO.name,
|
||||
leaderboardDTO.displayName, null, leaderboardDTO.discardThresholds, leaderboardDTO.regattaName, leaderboardDTO.defaultCourseAreaIdAsString);
|
||||
AbstractLeaderboardDialog dialog = new RegattaLeaderboardEditDialog(Collections
|
||||
@@ -411,7 +408,7 @@ public class LeaderboardConfigPanel extends FormPanel implements SelectedLeaderb
|
||||
new DisablableCheckboxCell(new IsEnabled() {
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return getSelectedLeaderboard() != null && !getSelectedLeaderboard().isRegattaLeaderboard;
|
||||
return getSelectedLeaderboard() != null && !getSelectedLeaderboard().type.isRegattaLeaderboard();
|
||||
}
|
||||
})) {
|
||||
@Override
|
||||
@@ -480,7 +477,7 @@ public class LeaderboardConfigPanel extends FormPanel implements SelectedLeaderb
|
||||
addRaceColumnsButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
if (getSelectedLeaderboard().isRegattaLeaderboard) {
|
||||
if (getSelectedLeaderboard().type.isRegattaLeaderboard()) {
|
||||
Window.alert(stringMessages.cannotAddRacesToRegattaLeaderboardButOnlyToRegatta());
|
||||
} else {
|
||||
addRaceColumnsToLeaderboard();
|
||||
@@ -771,7 +768,7 @@ public class LeaderboardConfigPanel extends FormPanel implements SelectedLeaderb
|
||||
}
|
||||
existingRacesWithoutThisRace.remove(raceColumnWithFleet.getA());
|
||||
final RaceColumnInLeaderboardDialog raceDialog = new RaceColumnInLeaderboardDialog(existingRacesWithoutThisRace,
|
||||
raceColumnWithFleet.getA(), getSelectedLeaderboard().isRegattaLeaderboard, stringMessages, new DialogCallback<RaceColumnDescriptor>() {
|
||||
raceColumnWithFleet.getA(), getSelectedLeaderboard().type.isRegattaLeaderboard(), stringMessages, new DialogCallback<RaceColumnDescriptor>() {
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
@@ -906,12 +903,12 @@ public class LeaderboardConfigPanel extends FormPanel implements SelectedLeaderb
|
||||
}
|
||||
selectedLeaderBoardPanel.setVisible(true);
|
||||
selectedLeaderBoardPanel.setCaptionText("Details of leaderboard '" + getSelectedLeaderboard().name + "'");
|
||||
if (!getSelectedLeaderboard().isMetaLeaderboard) {
|
||||
if (!getSelectedLeaderboard().type.isMetaLeaderboard()) {
|
||||
trackedRacesCaptionPanel.setVisible(true);
|
||||
}
|
||||
addRaceColumnsButton.setVisible(!getSelectedLeaderboard().isRegattaLeaderboard);
|
||||
columnMoveUpButton.setVisible(!getSelectedLeaderboard().isRegattaLeaderboard);
|
||||
columnMoveDownButton.setVisible(!getSelectedLeaderboard().isRegattaLeaderboard);
|
||||
addRaceColumnsButton.setVisible(!getSelectedLeaderboard().type.isRegattaLeaderboard());
|
||||
columnMoveUpButton.setVisible(!getSelectedLeaderboard().type.isRegattaLeaderboard());
|
||||
columnMoveDownButton.setVisible(!getSelectedLeaderboard().type.isRegattaLeaderboard());
|
||||
} else {
|
||||
selectedLeaderBoardPanel.setVisible(false);
|
||||
trackedRacesCaptionPanel.setVisible(false);
|
||||
|
||||
+4
-2
@@ -4,8 +4,10 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.sap.sailing.domain.common.LeaderboardType;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.ImagesBarCell;
|
||||
import com.sap.sailing.gwt.ui.shared.StrippedLeaderboardDTO;
|
||||
|
||||
public class LeaderboardRaceConfigImagesBarCell extends ImagesBarCell {
|
||||
public static final String ACTION_REMOVE = "ACTION_REMOVE";
|
||||
@@ -26,8 +28,8 @@ public class LeaderboardRaceConfigImagesBarCell extends ImagesBarCell {
|
||||
List<ImageSpec> result = new ArrayList<ImageSpec>();
|
||||
result.add(new ImageSpec(ACTION_EDIT, stringMessages.actionEdit(), makeImagePrototype(resources.editIcon())));
|
||||
result.add(new ImageSpec(ACTION_UNLINK, stringMessages.actionRaceUnlink(), makeImagePrototype(resources.unlinkIcon())));
|
||||
if (selectedLeaderboardProvider.getSelectedLeaderboard() != null &&
|
||||
!selectedLeaderboardProvider.getSelectedLeaderboard().isRegattaLeaderboard) {
|
||||
StrippedLeaderboardDTO selectedLeaderboard = selectedLeaderboardProvider.getSelectedLeaderboard();
|
||||
if (selectedLeaderboard != null && selectedLeaderboard.type != LeaderboardType.RegattaLeaderboard && selectedLeaderboard.type != LeaderboardType.RegattaMetaLeaderboard) {
|
||||
// race columns cannot be removed from a regatta leaderboard; they need to be removed from the regatta instead
|
||||
result.add(new ImageSpec(ACTION_REMOVE, stringMessages.actionRaceRemove(), makeImagePrototype(resources.removeIcon())));
|
||||
}
|
||||
|
||||
+10
@@ -24,6 +24,10 @@ public class DetailTypeFormatter {
|
||||
return stringMessages.regattaRank();
|
||||
case OVERALL_RANK:
|
||||
return stringMessages.overallRank();
|
||||
case RACE_TOTAL_POINTS:
|
||||
return stringMessages.totalPoints();
|
||||
case REGATTA_TOTAL_POINTS:
|
||||
return stringMessages.totalPoints();
|
||||
case NUMBER_OF_MANEUVERS:
|
||||
return stringMessages.numberOfManeuvers();
|
||||
case CURRENT_SPEED_OVER_GROUND_IN_KNOTS:
|
||||
@@ -154,6 +158,8 @@ public class DetailTypeFormatter {
|
||||
case RACE_RANK:
|
||||
case REGATTA_RANK:
|
||||
case OVERALL_RANK:
|
||||
case RACE_TOTAL_POINTS:
|
||||
case REGATTA_TOTAL_POINTS:
|
||||
case CURRENT_LEG:
|
||||
case TACK:
|
||||
case START_TACK:
|
||||
@@ -246,6 +252,10 @@ public class DetailTypeFormatter {
|
||||
return stringMessages.regattaRankTooltip();
|
||||
case OVERALL_RANK:
|
||||
return stringMessages.overallRankTooltip();
|
||||
case RACE_TOTAL_POINTS:
|
||||
return stringMessages.raceTotalPointsTooltip();
|
||||
case REGATTA_TOTAL_POINTS:
|
||||
return stringMessages.regattaTotalPointsTooltip();
|
||||
case RANK_GAIN:
|
||||
return stringMessages.rankGainTooltip();
|
||||
case TACK:
|
||||
|
||||
+8
-2
@@ -12,6 +12,7 @@ import com.google.gwt.user.client.rpc.RemoteService;
|
||||
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
|
||||
import com.sap.sailing.domain.common.Color;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.LeaderboardType;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.NoWindException;
|
||||
@@ -119,7 +120,7 @@ public interface SailingService extends RemoteService {
|
||||
|
||||
void removeWind(RegattaAndRaceIdentifier raceIdentifier, WindDTO windDTO);
|
||||
|
||||
public List<String> getLeaderboardNames() throws Exception;
|
||||
public List<String> getLeaderboardNames();
|
||||
|
||||
LeaderboardDTO getLeaderboardByName(String leaderboardName, Date date,
|
||||
Collection<String> namesOfRaceColumnsForWhichToLoadLegDetails) throws Exception;
|
||||
@@ -282,7 +283,8 @@ public interface SailingService extends RemoteService {
|
||||
|
||||
List<SwissTimingReplayRaceDTO> listSwissTiminigReplayRaces(String swissTimingUrl);
|
||||
|
||||
List<Pair<String, List<CompetitorDTO>>> getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(String leaderboardName, Date date) throws NoWindException;
|
||||
List<Triple<String, List<CompetitorDTO>, List<Double>>> getLeaderboardDataEntriesForAllRaceColumns(String leaderboardName,
|
||||
Date date, DetailType detailType) throws Exception;
|
||||
|
||||
List<String> getOverallLeaderboardNamesContaining(String leaderboardName);
|
||||
|
||||
@@ -303,4 +305,8 @@ public interface SailingService extends RemoteService {
|
||||
List<RegattaOverviewEntryDTO> getRegattaOverviewEntriesForEvent(String eventIdAsString);
|
||||
|
||||
EventDTO getEventByIdAsString(String eventIdAsString);
|
||||
|
||||
List<Pair<String, String>> getLeaderboardsNamesOfMetaleaderboard(String metaLeaderboardName);
|
||||
|
||||
Pair<String, LeaderboardType> checkLeaderboardName(String leaderboardName);
|
||||
}
|
||||
+9
-3
@@ -11,6 +11,7 @@ import java.util.Set;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.sap.sailing.domain.common.Color;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.LeaderboardType;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
import com.sap.sailing.domain.common.NauticalSide;
|
||||
import com.sap.sailing.domain.common.PolarSheetGenerationTriggerResponse;
|
||||
@@ -428,9 +429,6 @@ public interface SailingServiceAsync {
|
||||
|
||||
void listSwissTiminigReplayRaces(String swissTimingUrl, AsyncCallback<List<SwissTimingReplayRaceDTO>> asyncCallback);
|
||||
|
||||
void getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(String leaderboardName, Date date,
|
||||
AsyncCallback<List<Pair<String, List<CompetitorDTO>>>> callback);
|
||||
|
||||
void getCompetitorsRaceData(RegattaAndRaceIdentifier race, List<CompetitorDTO> competitors, Date from, Date to,
|
||||
long stepSize, DetailType detailType, String leaderboarGroupName, String leaderboardName, AsyncCallback<CompetitorsRaceDataDTO> callback);
|
||||
|
||||
@@ -456,6 +454,14 @@ public interface SailingServiceAsync {
|
||||
void getRegattaOverviewEntriesForEvent(String eventIdAsString, AsyncCallback<List<RegattaOverviewEntryDTO>> asyncCallback);
|
||||
|
||||
void getEventByIdAsString(String eventIdAsString, AsyncCallback<EventDTO> asyncCallback);
|
||||
|
||||
void getLeaderboardDataEntriesForAllRaceColumns(String leaderboardName, Date date, DetailType detailType,
|
||||
AsyncCallback<List<Triple<String, List<CompetitorDTO>, List<Double>>>> callback);
|
||||
|
||||
void getLeaderboardsNamesOfMetaleaderboard(String metaLeaderboardName,
|
||||
AsyncCallback<List<Pair<String, String>>> callback);
|
||||
|
||||
void checkLeaderboardName(String leaderboardName, AsyncCallback<Pair<String, LeaderboardType>> callback);
|
||||
|
||||
}
|
||||
|
||||
+6
-4
@@ -156,7 +156,6 @@ public interface StringMessages extends Messages {
|
||||
String in();
|
||||
String secondsUnit();
|
||||
String metersUnit();
|
||||
String failedToLoadRaceData();
|
||||
String close();
|
||||
String compareCompetitors();
|
||||
String description();
|
||||
@@ -437,11 +436,14 @@ public interface StringMessages extends Messages {
|
||||
String legend();
|
||||
String live();
|
||||
String swissTimingArchiveConnector();
|
||||
String errorFetchingRankingChartData(String message);
|
||||
String errorFetchingChartData(String message);
|
||||
String loadingCompetitorData();
|
||||
String rankNAfterRace(long l, String string);
|
||||
String afterRace();
|
||||
String competitorRegattaDataAfterRaceN(String detailType, String raceColumnName);
|
||||
String showRankChart();
|
||||
String rankChart();
|
||||
String totalPoints();
|
||||
String raceTotalPointsTooltip();
|
||||
String regattaTotalPointsTooltip();
|
||||
String overallLeaderboardSelection();
|
||||
String showOverallLeaderboardOnSamePage();
|
||||
String errorTryingToObtainOverallLeaderboards(String message);
|
||||
|
||||
+6
-4
@@ -171,7 +171,6 @@ distance=Distance
|
||||
in=in
|
||||
secondsUnit=s
|
||||
metersUnit=m
|
||||
failedToLoadRaceData=Failed to laod race data.
|
||||
close=Close
|
||||
compareCompetitors=Compare competitors
|
||||
description=Description
|
||||
@@ -475,10 +474,13 @@ pattern=Pattern
|
||||
legend=Legend
|
||||
live=live
|
||||
swissTimingArchiveConnector=SwissTiming Archived Events
|
||||
errorFetchingRankingChartData=Error fetching ranking chart data: {0}
|
||||
errorFetchingChartData=Error fetching chart data: {0}
|
||||
loadingCompetitorData=Loading competitor data...
|
||||
rankNAfterRace=Rank {0} after race {1}
|
||||
afterRace=after race
|
||||
competitorRegattaDataAfterRaceN={0} after race {1}
|
||||
rankChart=Ranking
|
||||
totalPoints=Total points
|
||||
raceTotalPointsTooltip=Competitor''s total points in the race
|
||||
regattaTotalPointsTooltip=Competitor''s total points in the regatta
|
||||
showRankChart=Show rank chart
|
||||
overallLeaderboardSelection=Overall Leaderboard
|
||||
showOverallLeaderboardOnSamePage=Show overall leaderboard on same page
|
||||
|
||||
+6
-4
@@ -173,7 +173,6 @@ distance=Strecke
|
||||
in=in
|
||||
secondsUnit=s
|
||||
metersUnit=m
|
||||
failedToLoadRaceData=Renndaten konnten nicht geladen werden.
|
||||
close=Schließen
|
||||
compareCompetitors=Teilnehmer vergleichen
|
||||
description=Beschreibung
|
||||
@@ -476,10 +475,13 @@ pattern=Muster
|
||||
legend=Legende
|
||||
live=live
|
||||
swissTimingArchiveConnector=SwissTiming Historische Veranstaltungen
|
||||
errorFetchingRankingChartData=Fehler beim Laden der Daten für das Ranglisten-Chart: {0}
|
||||
errorFetchingChartData=Fehler beim Laden der Chartdaten: {0}
|
||||
loadingCompetitorData=Lade Teilnehmer-Daten
|
||||
rankNAfterRace=Rang {0} nach Rennen {1}
|
||||
afterRace=nach Rennen
|
||||
competitorRegattaDataAfterRaceN={0} nach Rennen {1}
|
||||
rankChart=Ranking
|
||||
totalPoints=Gesamtpunktzahl
|
||||
raceTotalPointsTooltip=Punktzahl des Teilnehmers in dem Rennen
|
||||
regattaTotalPointsTooltip=Punktzahl des Teilnehmers in der Regatta
|
||||
showRankChart=Rang-Diagramm anzeigen
|
||||
overallLeaderboardSelection=Gesamtergebnisse
|
||||
showOverallLeaderboardOnSamePage=Gesamtergebnisse auf derselben Seite anzeigen
|
||||
|
||||
+378
@@ -0,0 +1,378 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.charts;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.moxieapps.gwt.highcharts.client.Axis;
|
||||
import org.moxieapps.gwt.highcharts.client.Chart;
|
||||
import org.moxieapps.gwt.highcharts.client.ChartTitle;
|
||||
import org.moxieapps.gwt.highcharts.client.Color;
|
||||
import org.moxieapps.gwt.highcharts.client.Credits;
|
||||
import org.moxieapps.gwt.highcharts.client.Point;
|
||||
import org.moxieapps.gwt.highcharts.client.Series;
|
||||
import org.moxieapps.gwt.highcharts.client.ToolTip;
|
||||
import org.moxieapps.gwt.highcharts.client.ToolTipData;
|
||||
import org.moxieapps.gwt.highcharts.client.ToolTipFormatter;
|
||||
import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsData;
|
||||
import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsFormatter;
|
||||
import org.moxieapps.gwt.highcharts.client.labels.XAxisLabels;
|
||||
import org.moxieapps.gwt.highcharts.client.plotOptions.LinePlotOptions;
|
||||
import org.moxieapps.gwt.highcharts.client.plotOptions.Marker;
|
||||
import org.moxieapps.gwt.highcharts.client.plotOptions.Marker.Symbol;
|
||||
|
||||
import com.google.gwt.i18n.client.NumberFormat;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.RequiresResize;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Triple;
|
||||
import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
|
||||
import com.sap.sailing.gwt.ui.actions.GetLeaderboardDataEntriesAction;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionChangeListener;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider;
|
||||
import com.sap.sailing.gwt.ui.client.DetailTypeFormatter;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
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.Timer;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
|
||||
import com.sap.sailing.gwt.ui.shared.CompetitorDTO;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.AbstractLazyComponent;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.Component;
|
||||
|
||||
/**
|
||||
* A base class for a leaderboard chart showing competitor data for all race columns of a leaderboard.
|
||||
*/
|
||||
public abstract class AbstractCompetitorLeaderboardChart<SettingsType> extends AbstractLazyComponent<SettingsType> implements Component<SettingsType>,
|
||||
CompetitorSelectionChangeListener, RequiresResize, TimeListener {
|
||||
private static final int LINE_WIDTH = 1;
|
||||
protected final CompetitorSelectionProvider competitorSelectionProvider;
|
||||
protected final Map<CompetitorDTO, Series> competitorSeries;
|
||||
protected Chart chart;
|
||||
protected final Timer timer;
|
||||
private DetailType selectedDetailType;
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final AsyncActionsExecutor asyncActionsExecutor;
|
||||
private final ErrorReporter errorReporter;
|
||||
|
||||
private final List<String> raceColumnNames;
|
||||
private final List<String> raceColumnNamesWithData;
|
||||
protected final String leaderboardName;
|
||||
protected final StringMessages stringMessages;
|
||||
|
||||
public AbstractCompetitorLeaderboardChart(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor, String leaderboardName,
|
||||
DetailType detailType, CompetitorSelectionProvider competitorSelectionProvider, Timer timer,
|
||||
final StringMessages stringMessages, ErrorReporter errorReporter) {
|
||||
this.sailingService = sailingService;
|
||||
this.asyncActionsExecutor = asyncActionsExecutor;
|
||||
this.competitorSelectionProvider = competitorSelectionProvider;
|
||||
this.stringMessages = stringMessages;
|
||||
this.errorReporter = errorReporter;
|
||||
this.timer = timer;
|
||||
this.leaderboardName = leaderboardName;
|
||||
this.selectedDetailType = detailType;
|
||||
|
||||
competitorSeries = new HashMap<CompetitorDTO, Series>();
|
||||
raceColumnNames = new ArrayList<String>();
|
||||
raceColumnNamesWithData = new ArrayList<String>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Widget createWidget() {
|
||||
setSize("100%", "100%");
|
||||
chart = createChart();
|
||||
setSelectedDetailType(selectedDetailType);
|
||||
|
||||
timer.addTimeListener(this);
|
||||
competitorSelectionProvider.addCompetitorSelectionChangeListener(this);
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
protected boolean isCompetitorVisible(CompetitorDTO competitor) {
|
||||
return Util.isEmpty(competitorSelectionProvider.getSelectedCompetitors()) || competitorSelectionProvider.isSelected(competitor);
|
||||
}
|
||||
|
||||
private Chart createChart() {
|
||||
Chart chart = new Chart()
|
||||
.setPersistent(true)
|
||||
.setMarginLeft(40)
|
||||
.setMarginRight(40)
|
||||
.setWidth100()
|
||||
.setBorderColor(new Color("#CACACA"))
|
||||
.setBorderWidth(1)
|
||||
.setBorderRadius(0)
|
||||
.setBackgroundColor(new Color("#EBEBEB"))
|
||||
.setPlotBorderWidth(0)
|
||||
.setCredits(new Credits().setEnabled(false))
|
||||
.setChartTitle(new ChartTitle().setText(stringMessages.rank()))
|
||||
.setLinePlotOptions(new LinePlotOptions().setLineWidth(LINE_WIDTH).setMarker(
|
||||
new Marker().setEnabled(true).setHoverState(
|
||||
new Marker().setEnabled(true).setRadius(4))).setShadow(false)
|
||||
.setHoverStateLineWidth(LINE_WIDTH));
|
||||
ChartUtil.useCheckboxesToShowAndHide(chart);
|
||||
chart.getXAxis().setType(Axis.Type.LINEAR);
|
||||
chart.getXAxis().setLabels(new XAxisLabels().setFormatter(new AxisLabelsFormatter() {
|
||||
@Override
|
||||
public String format(AxisLabelsData axisLabelsData) {
|
||||
Double valueAsDouble = axisLabelsData.getValueAsDouble();
|
||||
return raceColumnNamesWithData.get(valueAsDouble.intValue());
|
||||
}
|
||||
}));
|
||||
chart.getYAxis().setAllowDecimals(false).setStartOnTick(true).setEndOnTick(true);
|
||||
chart.getYAxis().setShowFirstLabel(false).setShowLastLabel(false);
|
||||
// chart.getYAxis().setMinorTickInterval(null).setTickInterval(1).setTickPixelInterval(100);
|
||||
chart.getXAxis().setTickInterval(1);
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
protected void setSelectedDetailType(DetailType newSelectedDetailType) {
|
||||
boolean oldReversedYAxis = hasReversedYAxis(this.selectedDetailType);
|
||||
this.selectedDetailType = newSelectedDetailType;
|
||||
// TODO There is a bug in the highcharts library which prevents to change the reverse property of the YAxis
|
||||
// Because we need this functionality we need to recreate the chart each time the YAxis changes
|
||||
if (oldReversedYAxis != hasReversedYAxis(selectedDetailType)) {
|
||||
chart = createChart();
|
||||
}
|
||||
chart.setTitle(new ChartTitle().setText(DetailTypeFormatter.format(selectedDetailType)), null);
|
||||
final String unit = DetailTypeFormatter.getUnit(getSelectedDetailType());
|
||||
final String label = unit.isEmpty() ? "" : "[" + unit + "]";
|
||||
chart.getYAxis().setAxisTitleText(label);
|
||||
chart.getYAxis().setReversed(isYAxisReversed());
|
||||
|
||||
chart.setToolTip(new ToolTip().setEnabled(true).setFormatter(new ToolTipFormatter() {
|
||||
@Override
|
||||
public String format(ToolTipData toolTipData) {
|
||||
String seriesName = toolTipData.getSeriesName();
|
||||
Double xValue = toolTipData.getXAsDouble();
|
||||
Double yValue = toolTipData.getYAsDouble();
|
||||
String raceColumnName = raceColumnNamesWithData.get(xValue.intValue());
|
||||
NumberFormat numberFormat = DetailTypeFormatter.getNumberFormat(selectedDetailType);
|
||||
|
||||
return "<b>" + seriesName + ":</b> " + " " +
|
||||
stringMessages.competitorRegattaDataAfterRaceN(numberFormat.format(yValue), raceColumnName);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private boolean hasReversedYAxis(DetailType detailType) {
|
||||
return detailType == DetailType.REGATTA_RANK;
|
||||
}
|
||||
|
||||
private boolean isYAxisReversed() {
|
||||
return hasReversedYAxis(selectedDetailType);
|
||||
}
|
||||
|
||||
protected void clearChart() {
|
||||
competitorSeries.clear();
|
||||
chart.removeAllSeries();
|
||||
}
|
||||
|
||||
protected Series getOrCreateSeries(CompetitorDTO competitor) {
|
||||
Series result = competitorSeries.get(competitor);
|
||||
if (result == null) {
|
||||
result = chart.createSeries().setType(Series.Type.LINE).setName(competitor.name);
|
||||
result.setPlotOptions(new LinePlotOptions()
|
||||
.setLineWidth(LINE_WIDTH)
|
||||
.setMarker(new Marker().setEnabled(true).setRadius(4).setSymbol(Symbol.DIAMOND))
|
||||
.setShadow(true).setHoverStateLineWidth(LINE_WIDTH)
|
||||
.setColor(competitorSelectionProvider.getColor(competitor)).setSelected(true));
|
||||
competitorSeries.put(competitor, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResize() {
|
||||
chart.setSizeToMatchContainer();
|
||||
// it's important here to recall the redraw method, otherwise the bug fix for wrong checkbox positions (nativeAdjustCheckboxPosition)
|
||||
// in the BaseChart class would not be called
|
||||
chart.redraw();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timeChanged(Date date) {
|
||||
if(!isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
loadChartData(timer.getPlayMode() == PlayModes.Live ? null : date);
|
||||
}
|
||||
|
||||
protected void loadChartData(Date date) {
|
||||
if(timer.getPlayMode() != PlayModes.Live) {
|
||||
chart.showLoading(stringMessages.loadingCompetitorData());
|
||||
}
|
||||
|
||||
GetLeaderboardDataEntriesAction getLeaderboardDataEntriesAction = new GetLeaderboardDataEntriesAction(sailingService,
|
||||
leaderboardName, /* date */ null, selectedDetailType, new AsyncCallback<List<Triple<String, List<CompetitorDTO>, List<Double>>>>() {
|
||||
@Override
|
||||
public void onSuccess(List<Triple<String, List<CompetitorDTO>, List<Double>>> result) {
|
||||
List<Series> chartSeries = new ArrayList<Series>(Arrays.asList(chart.getSeries()));
|
||||
chart.hideLoading();
|
||||
setWidget(chart);
|
||||
raceColumnNames.clear();
|
||||
|
||||
switch(selectedDetailType) {
|
||||
case REGATTA_RANK:
|
||||
fillTotalRanksSeries(result, chartSeries);
|
||||
break;
|
||||
case RACE_TOTAL_POINTS:
|
||||
fillTotalPointsSeries(result, chartSeries);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
chart.setSizeToMatchContainer();
|
||||
// it's important here to recall the redraw method, otherwise the bug fix for wrong checkbox
|
||||
// positions (nativeAdjustCheckboxPosition)
|
||||
// in the BaseChart class would not be called
|
||||
chart.redraw();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
chart.hideLoading();
|
||||
errorReporter.reportError(stringMessages.errorFetchingChartData(caught.getMessage()),
|
||||
timer.getPlayMode() == PlayModes.Live);
|
||||
}
|
||||
});
|
||||
|
||||
asyncActionsExecutor.execute(getLeaderboardDataEntriesAction);
|
||||
}
|
||||
|
||||
private void fillTotalRanksSeries(List<Triple<String, List<CompetitorDTO>, List<Double>>> result, List<Series> chartSeries) {
|
||||
Set<Series> unusedSeries = new HashSet<Series>(competitorSeries.values());
|
||||
for (Series series : competitorSeries.values()) {
|
||||
for (Point p : new ArrayList<Point>(Arrays.asList(series.getPoints()))) {
|
||||
series.removePoint(p, /* redraw */false, /* animation */false);
|
||||
}
|
||||
}
|
||||
int raceColumnNumber = 0;
|
||||
int maxCompetitorCount = 0;
|
||||
for (Triple<String, List<CompetitorDTO>, List<Double>> entry : result) {
|
||||
List<Double> dataValues = entry.getC();
|
||||
raceColumnNames.add(entry.getA());
|
||||
if(hasValidValues(dataValues)) {
|
||||
raceColumnNamesWithData.add(entry.getA());
|
||||
int index = 0;
|
||||
maxCompetitorCount = Math.max(maxCompetitorCount, entry.getB().size());
|
||||
for (CompetitorDTO competitor : entry.getB()) {
|
||||
if (isCompetitorVisible(competitor)) {
|
||||
Series series = getOrCreateSeries(competitor);
|
||||
Double dataValue = dataValues.get(index);
|
||||
if (dataValue != null) {
|
||||
series.addPoint(raceColumnNumber, dataValue, /* redraw */false, /* shift */false, /* animation */ false);
|
||||
}
|
||||
|
||||
unusedSeries.remove(series);
|
||||
if (!chartSeries.contains(series)) {
|
||||
chart.addSeries(series);
|
||||
chartSeries.add(series);
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
raceColumnNumber++;
|
||||
}
|
||||
}
|
||||
chart.getYAxis().setMaxPadding(0.5 / maxCompetitorCount).setMinPadding(0.5 / maxCompetitorCount);
|
||||
chart.getYAxis().setTickInterval(1.0);
|
||||
chart.setHeight(maxCompetitorCount * 30 + 100 + "px");
|
||||
}
|
||||
|
||||
private void fillTotalPointsSeries(List<Triple<String, List<CompetitorDTO>, List<Double>>> result, List<Series> chartSeries) {
|
||||
Double maxTotalPoints = 0.0;
|
||||
Set<Series> unusedSeries = new HashSet<Series>(competitorSeries.values());
|
||||
for (Series series : competitorSeries.values()) {
|
||||
for (Point p : new ArrayList<Point>(Arrays.asList(series.getPoints()))) {
|
||||
series.removePoint(p, /* redraw */ false, /* animation */ false);
|
||||
}
|
||||
}
|
||||
int raceColumnNumber = 0;
|
||||
int maxCompetitorCount = 0;
|
||||
Map<CompetitorDTO, Double> sumTotalPointsMap = new HashMap<CompetitorDTO, Double>();
|
||||
for (Triple<String, List<CompetitorDTO>, List<Double>> entry : result) {
|
||||
List<Double> dataValues = entry.getC();
|
||||
raceColumnNames.add(entry.getA());
|
||||
if(hasValidValues(dataValues)) {
|
||||
raceColumnNamesWithData.add(entry.getA());
|
||||
int index = 0;
|
||||
maxCompetitorCount = Math.max(maxCompetitorCount, entry.getB().size());
|
||||
for (CompetitorDTO competitor : entry.getB()) {
|
||||
if (isCompetitorVisible(competitor)) {
|
||||
Series series = getOrCreateSeries(competitor);
|
||||
Double dataValue = dataValues.get(index);
|
||||
if(dataValue != null) {
|
||||
Double sumTotalPoints = dataValue;
|
||||
if(sumTotalPointsMap.containsKey(competitor)) {
|
||||
sumTotalPoints += sumTotalPointsMap.get(competitor);
|
||||
}
|
||||
sumTotalPointsMap.put(competitor, sumTotalPoints);
|
||||
series.addPoint(raceColumnNumber, sumTotalPoints, /* redraw */ false, /* shift */ false, /* animation */ false);
|
||||
if(sumTotalPoints > maxTotalPoints) {
|
||||
maxTotalPoints = sumTotalPoints;
|
||||
}
|
||||
}
|
||||
|
||||
unusedSeries.remove(series);
|
||||
if (!chartSeries.contains(series)) {
|
||||
chart.addSeries(series);
|
||||
chartSeries.add(series);
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
raceColumnNumber++;
|
||||
}
|
||||
}
|
||||
chart.getYAxis().setMaxPadding(0.5/maxCompetitorCount).setMinPadding(0.5/maxCompetitorCount);
|
||||
chart.getYAxis().setTickInterval(5.0);
|
||||
chart.setHeight(maxCompetitorCount * 30 + 100 + "px");
|
||||
}
|
||||
|
||||
private boolean hasValidValues(List<Double> values) {
|
||||
boolean result = false;
|
||||
for(Double value: values) {
|
||||
if(value != null) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Widget getEntryWidget() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void competitorsListChanged(Iterable<CompetitorDTO> competitors) {
|
||||
timeChanged(timer.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addedToSelection(CompetitorDTO competitor) {
|
||||
timeChanged(timer.getTime());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removedFromSelection(CompetitorDTO competitor) {
|
||||
timeChanged(timer.getTime());
|
||||
}
|
||||
|
||||
protected DetailType getSelectedDetailType() {
|
||||
return selectedDetailType;
|
||||
}
|
||||
}
|
||||
+14
-19
@@ -58,7 +58,7 @@ import com.sap.sailing.gwt.ui.shared.CompetitorRaceDataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.CompetitorsRaceDataDTO;
|
||||
|
||||
/**
|
||||
* ChartPanel is a GWT panel that can show one sort of competitor data (e.g. current speed over ground, windward
|
||||
* AbstractCompetitorChart is a chart that can show one sort of competitor data (e.g. current speed over ground, windward
|
||||
* distance to leader) for different races in a chart.
|
||||
*
|
||||
* When calling the constructor a chart is created that creates a final amount of series (so the maximum number of
|
||||
@@ -126,12 +126,8 @@ public abstract class AbstractCompetitorRaceChart<SettingsType extends ChartSett
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new chart for the given {@link DetailType} <code>dataToShow</code> and also clears the
|
||||
* {@link #chartData}, the {@link #dataSeriesByCompetitor} and the {@link #markPassingSeriesByCompetitor}.
|
||||
*
|
||||
* @param detailType
|
||||
* The detail type for the new chart.
|
||||
* @return A chart for the given detail Type
|
||||
* Creates a new chart.
|
||||
* Attention: We can't reuse the old chart when the detail changes because HighChart does not support the inverting of the Y-Axis
|
||||
*/
|
||||
private Chart createChart() {
|
||||
Chart chart = new Chart().setZoomType(Chart.ZoomType.X)
|
||||
@@ -242,10 +238,9 @@ public abstract class AbstractCompetitorRaceChart<SettingsType extends ChartSett
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
errorReporter.reportError(
|
||||
getStringMessages().failedToLoadRaceData() + ": " + caught.toString(),
|
||||
timer.getPlayMode() == PlayModes.Live);
|
||||
hideLoading();
|
||||
errorReporter.reportError(stringMessages.errorFetchingChartData(caught.getMessage()),
|
||||
timer.getPlayMode() == PlayModes.Live);
|
||||
}
|
||||
});
|
||||
asyncActionsExecutor.execute(getCompetitorsRaceDataAction);
|
||||
@@ -469,10 +464,6 @@ public abstract class AbstractCompetitorRaceChart<SettingsType extends ChartSett
|
||||
protected DetailType getSelectedDetailType() {
|
||||
return this.selectedDetailType;
|
||||
}
|
||||
|
||||
private boolean hasReversedYAxis(DetailType detailType) {
|
||||
return detailType == DetailType.WINDWARD_DISTANCE_TO_OVERALL_LEADER || detailType == DetailType.GAP_TO_LEADER_IN_SECONDS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the {@link #selectedDetailType} field, clears the chart for the new <code>selectedDetailType</code> and
|
||||
@@ -528,12 +519,16 @@ public abstract class AbstractCompetitorRaceChart<SettingsType extends ChartSett
|
||||
return hasDetailTypeChanged;
|
||||
}
|
||||
|
||||
private boolean isYAxisReversed() {
|
||||
private boolean hasReversedYAxis(DetailType detailType) {
|
||||
return selectedDetailType == DetailType.WINDWARD_DISTANCE_TO_OVERALL_LEADER ||
|
||||
selectedDetailType == DetailType.GAP_TO_LEADER_IN_SECONDS ||
|
||||
selectedDetailType == DetailType.RACE_RANK ||
|
||||
selectedDetailType == DetailType.REGATTA_RANK ||
|
||||
selectedDetailType == DetailType.OVERALL_RANK;
|
||||
selectedDetailType == DetailType.GAP_TO_LEADER_IN_SECONDS ||
|
||||
selectedDetailType == DetailType.RACE_RANK ||
|
||||
selectedDetailType == DetailType.REGATTA_RANK ||
|
||||
selectedDetailType == DetailType.OVERALL_RANK;
|
||||
}
|
||||
|
||||
private boolean isYAxisReversed() {
|
||||
return hasReversedYAxis(selectedDetailType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
-195
@@ -1,195 +0,0 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.charts;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.moxieapps.gwt.highcharts.client.Axis;
|
||||
import org.moxieapps.gwt.highcharts.client.Chart;
|
||||
import org.moxieapps.gwt.highcharts.client.ChartTitle;
|
||||
import org.moxieapps.gwt.highcharts.client.Color;
|
||||
import org.moxieapps.gwt.highcharts.client.Credits;
|
||||
import org.moxieapps.gwt.highcharts.client.Point;
|
||||
import org.moxieapps.gwt.highcharts.client.Series;
|
||||
import org.moxieapps.gwt.highcharts.client.ToolTip;
|
||||
import org.moxieapps.gwt.highcharts.client.ToolTipData;
|
||||
import org.moxieapps.gwt.highcharts.client.ToolTipFormatter;
|
||||
import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsData;
|
||||
import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsFormatter;
|
||||
import org.moxieapps.gwt.highcharts.client.labels.XAxisLabels;
|
||||
import org.moxieapps.gwt.highcharts.client.plotOptions.LinePlotOptions;
|
||||
import org.moxieapps.gwt.highcharts.client.plotOptions.Marker;
|
||||
import org.moxieapps.gwt.highcharts.client.plotOptions.Marker.Symbol;
|
||||
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.RequiresResize;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.sap.sailing.domain.common.impl.Util;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
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.Timer;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
|
||||
import com.sap.sailing.gwt.ui.shared.CompetitorDTO;
|
||||
|
||||
public class LeaderboardRankChart extends SimplePanel implements RequiresResize, TimeListener {
|
||||
private static final int LINE_WIDTH = 1;
|
||||
private final CompetitorSelectionProvider competitorSelectionProvider;
|
||||
private final Map<CompetitorDTO, Series> competitorSeries;
|
||||
private final Chart chart;
|
||||
private final List<String> raceColumnNames;
|
||||
private final Timer timer;
|
||||
private final String leaderboardName;
|
||||
private final StringMessages stringMessages;
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final ErrorReporter errorReporter;
|
||||
|
||||
public LeaderboardRankChart(SailingServiceAsync sailingService, String leaderboardName,
|
||||
CompetitorSelectionProvider competitorSelectionProvider, Timer timer,
|
||||
final StringMessages stringMessages, ErrorReporter errorReporter, boolean compactChart) {
|
||||
this.competitorSelectionProvider = competitorSelectionProvider;
|
||||
this.stringMessages = stringMessages;
|
||||
this.sailingService = sailingService;
|
||||
this.errorReporter = errorReporter;
|
||||
this.timer = timer;
|
||||
timer.addTimeListener(this);
|
||||
this.leaderboardName = leaderboardName;
|
||||
competitorSeries = new HashMap<CompetitorDTO, Series>();
|
||||
raceColumnNames = new ArrayList<String>();
|
||||
chart = new Chart()
|
||||
.setPersistent(true)
|
||||
.setMarginLeft(65)
|
||||
.setMarginRight(65)
|
||||
.setWidth100()
|
||||
.setHeight100()
|
||||
.setBorderColor(new Color("#CACACA"))
|
||||
.setBorderWidth(1)
|
||||
.setBorderRadius(0)
|
||||
.setBackgroundColor(new Color("#EBEBEB"))
|
||||
.setPlotBorderWidth(0)
|
||||
.setCredits(new Credits().setEnabled(false))
|
||||
.setChartTitle(new ChartTitle().setText(stringMessages.rank()))
|
||||
.setLinePlotOptions(new LinePlotOptions().setLineWidth(LINE_WIDTH).setMarker(
|
||||
new Marker().setEnabled(true).setHoverState(
|
||||
new Marker().setEnabled(true).setRadius(4))).setShadow(false)
|
||||
.setHoverStateLineWidth(LINE_WIDTH));
|
||||
ChartUtil.useCheckboxesToShowAndHide(chart);
|
||||
chart.setToolTip(new ToolTip().setEnabled(true).setFormatter(new ToolTipFormatter() {
|
||||
@Override
|
||||
public String format(ToolTipData toolTipData) {
|
||||
String seriesName = toolTipData.getSeriesName();
|
||||
return "<b>" + seriesName + ":</b> " + stringMessages.rankNAfterRace(toolTipData.getYAsLong(),
|
||||
raceColumnNames.get((int) toolTipData.getXAsLong()));
|
||||
}
|
||||
}));
|
||||
chart.getXAxis().setType(Axis.Type.LINEAR).setAxisTitleText(stringMessages.afterRace());
|
||||
chart.getXAxis().setTickInterval(1).setLabels(new XAxisLabels().setFormatter(new AxisLabelsFormatter() {
|
||||
@Override
|
||||
public String format(AxisLabelsData axisLabelsData) {
|
||||
return raceColumnNames.get((int) axisLabelsData.getValueAsLong());
|
||||
}
|
||||
}));
|
||||
chart.getYAxis().setAllowDecimals(false).setStartOnTick(true).setEndOnTick(true).setAxisTitleText(stringMessages.rank())
|
||||
.setShowFirstLabel(false).setShowLastLabel(false).setReversed(true);
|
||||
if (compactChart) {
|
||||
chart.setSpacingBottom(10).setSpacingLeft(10).setSpacingRight(10).setSpacingTop(2)
|
||||
.setOption("legend/margin", 2)
|
||||
.setOption("title/margin", 5)
|
||||
.setChartSubtitle(null)
|
||||
.getXAxis().setAxisTitle(null);
|
||||
}
|
||||
setWidget(chart);
|
||||
setSize("100%", "100%");
|
||||
// show the loading message only upon initial load
|
||||
chart.showLoading(stringMessages.loadingCompetitorData());
|
||||
timeChanged(timer.getTime());
|
||||
}
|
||||
|
||||
private void loadChartData(Date date) {
|
||||
sailingService.getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(leaderboardName,
|
||||
/* date: null means "now" or "live" */ null, new AsyncCallback<List<Pair<String,List<CompetitorDTO>>>>() {
|
||||
@Override
|
||||
public void onSuccess(List<Pair<String, List<CompetitorDTO>>> result) {
|
||||
List<Series> chartSeries = new ArrayList<Series>(Arrays.asList(chart.getSeries()));
|
||||
chart.hideLoading();
|
||||
raceColumnNames.clear();
|
||||
Set<Series> unusedSeries = new HashSet<Series>(competitorSeries.values());
|
||||
for (Series series : competitorSeries.values()) {
|
||||
for (Point p : new ArrayList<Point>(Arrays.asList(series.getPoints()))) {
|
||||
series.removePoint(p, /* redraw */ false, /* animation */ false);
|
||||
}
|
||||
}
|
||||
int raceNumber = 0;
|
||||
int maxCompetitorCount = 0;
|
||||
for (Pair<String, List<CompetitorDTO>> entry : result) {
|
||||
raceColumnNames.add(entry.getA());
|
||||
int rank = 1;
|
||||
maxCompetitorCount = Math.max(maxCompetitorCount, entry.getB().size());
|
||||
for (CompetitorDTO competitor : entry.getB()) {
|
||||
if (Util.isEmpty(competitorSelectionProvider.getSelectedCompetitors()) ||
|
||||
competitorSelectionProvider.isSelected(competitor)) {
|
||||
Series series = getOrCreateSeries(competitor);
|
||||
series.addPoint(raceNumber, rank, /* redraw */ false, /* shift */ false, /* animation */ false);
|
||||
|
||||
unusedSeries.remove(series);
|
||||
if (!chartSeries.contains(series)) {
|
||||
chart.addSeries(series);
|
||||
chartSeries.add(series);
|
||||
}
|
||||
}
|
||||
rank++;
|
||||
}
|
||||
raceNumber++;
|
||||
}
|
||||
chart.getYAxis().setMaxPadding(0.5/maxCompetitorCount).setMinPadding(0.5/maxCompetitorCount);
|
||||
chart.setSizeToMatchContainer();
|
||||
// it's important here to recall the redraw method, otherwise the bug fix for wrong checkbox positions (nativeAdjustCheckboxPosition)
|
||||
// in the BaseChart class would not be called
|
||||
chart.redraw();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
chart.hideLoading();
|
||||
errorReporter.reportError(stringMessages.errorFetchingRankingChartData(caught.getMessage()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Series getOrCreateSeries(CompetitorDTO competitor) {
|
||||
Series result = competitorSeries.get(competitor);
|
||||
if (result == null) {
|
||||
result = chart.createSeries().setType(Series.Type.LINE).setName(competitor.name);
|
||||
result.setPlotOptions(new LinePlotOptions()
|
||||
.setLineWidth(LINE_WIDTH)
|
||||
.setMarker(new Marker().setEnabled(true).setRadius(4).setSymbol(Symbol.DIAMOND))
|
||||
.setShadow(true).setHoverStateLineWidth(LINE_WIDTH)
|
||||
.setColor(competitorSelectionProvider.getColor(competitor)).setSelected(true));
|
||||
competitorSeries.put(competitor, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResize() {
|
||||
if (!competitorSeries.isEmpty()) {
|
||||
chart.setSizeToMatchContainer();
|
||||
// it's important here to recall the redraw method, otherwise the bug fix for wrong checkbox positions (nativeAdjustCheckboxPosition)
|
||||
// in the BaseChart class would not be called
|
||||
chart.redraw();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void timeChanged(Date date) {
|
||||
loadChartData(timer.getPlayMode() == PlayModes.Live ? null : date);
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.charts;
|
||||
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.Timer;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialogComponent;
|
||||
|
||||
public class MultiCompetitorLeaderboardChart extends AbstractCompetitorLeaderboardChart<MultiCompetitorLeaderboardChartSettings> {
|
||||
private MultiCompetitorLeaderboardChartSettings settings;
|
||||
|
||||
public MultiCompetitorLeaderboardChart(SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
|
||||
String leaderboardName, DetailType detailType, CompetitorSelectionProvider competitorSelectionProvider,
|
||||
Timer timer, StringMessages stringMessages, ErrorReporter errorReporter) {
|
||||
super(sailingService, asyncActionsExecutor, leaderboardName, detailType, competitorSelectionProvider, timer, stringMessages, errorReporter);
|
||||
settings = new MultiCompetitorLeaderboardChartSettings(detailType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSettings() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SettingsDialogComponent<MultiCompetitorLeaderboardChartSettings> getSettingsDialogComponent() {
|
||||
MultiCompetitorLeaderboardChartSettings chartSettings = new MultiCompetitorLeaderboardChartSettings(settings.getDetailType());
|
||||
return new MultiCompetitorLeaderboardChartSettingsDialogComponent(chartSettings, stringMessages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSettings(MultiCompetitorLeaderboardChartSettings newSettings) {
|
||||
boolean redraw = false;
|
||||
|
||||
if(settings.getDetailType() != newSettings.getDetailType()) {
|
||||
settings = new MultiCompetitorLeaderboardChartSettings(newSettings.getDetailType());
|
||||
setSelectedDetailType(newSettings.getDetailType());
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
if(redraw) {
|
||||
clearChart();
|
||||
timeChanged(timer.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLocalizedShortName() {
|
||||
return stringMessages.competitorCharts();
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.charts;
|
||||
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
|
||||
public class MultiCompetitorLeaderboardChartSettings {
|
||||
private final DetailType detailType;
|
||||
|
||||
public MultiCompetitorLeaderboardChartSettings(DetailType detailType) {
|
||||
this.detailType = detailType;
|
||||
}
|
||||
|
||||
public DetailType getDetailType() {
|
||||
return detailType;
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.charts;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.ui.FocusWidget;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.ListBox;
|
||||
import com.google.gwt.user.client.ui.VerticalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.gwt.ui.client.DataEntryDialog;
|
||||
import com.sap.sailing.gwt.ui.client.DataEntryDialog.Validator;
|
||||
import com.sap.sailing.gwt.ui.client.DetailTypeFormatter;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialogComponent;
|
||||
|
||||
public class MultiCompetitorLeaderboardChartSettingsDialogComponent implements SettingsDialogComponent<MultiCompetitorLeaderboardChartSettings> {
|
||||
private ListBox chartTypeSelectionListBox;
|
||||
private final DetailType initialDetailType;
|
||||
private final List<DetailType> availableDetailsTypes;
|
||||
private final StringMessages stringMessages;
|
||||
|
||||
public MultiCompetitorLeaderboardChartSettingsDialogComponent(MultiCompetitorLeaderboardChartSettings settings, StringMessages stringMessages) {
|
||||
this.initialDetailType = settings.getDetailType();
|
||||
this.stringMessages = stringMessages;
|
||||
|
||||
availableDetailsTypes = new ArrayList<DetailType>();
|
||||
availableDetailsTypes.add(DetailType.REGATTA_RANK);
|
||||
availableDetailsTypes.add(DetailType.RACE_TOTAL_POINTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Validator<MultiCompetitorLeaderboardChartSettings> getValidator() {
|
||||
return new Validator<MultiCompetitorLeaderboardChartSettings>() {
|
||||
@Override
|
||||
public String getErrorMessage(MultiCompetitorLeaderboardChartSettings valueToValidate) {
|
||||
String errorMessage = null;
|
||||
return errorMessage;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Widget getAdditionalWidget(DataEntryDialog<?> dialog) {
|
||||
VerticalPanel mainPanel = new VerticalPanel();
|
||||
mainPanel.setSpacing(5);
|
||||
|
||||
Label chartSelectionLabel = new Label(stringMessages.chooseChart());
|
||||
mainPanel.add(chartSelectionLabel);
|
||||
chartTypeSelectionListBox = dialog.createListBox(/* isMultiSelect */false);
|
||||
int i = 0;
|
||||
for (DetailType detailType : availableDetailsTypes) {
|
||||
chartTypeSelectionListBox.addItem(DetailTypeFormatter.format(detailType), detailType.name());
|
||||
if (detailType == initialDetailType) {
|
||||
chartTypeSelectionListBox.setSelectedIndex(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
mainPanel.add(chartTypeSelectionListBox);
|
||||
|
||||
return mainPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiCompetitorLeaderboardChartSettings getResult() {
|
||||
DetailType newDetailType = null;
|
||||
int selectedIndex = chartTypeSelectionListBox.getSelectedIndex();
|
||||
String selectedDetailType = chartTypeSelectionListBox.getValue(selectedIndex);
|
||||
for (DetailType detailType : availableDetailsTypes) {
|
||||
if (detailType.name().equals(selectedDetailType)) {
|
||||
newDetailType = detailType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new MultiCompetitorLeaderboardChartSettings(newDetailType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FocusWidget getFocusWidget() {
|
||||
return chartTypeSelectionListBox;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -13,7 +13,7 @@ import com.sap.sailing.gwt.ui.client.shared.components.Component;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialogComponent;
|
||||
|
||||
/**
|
||||
* MultiChartPanel is a GWT panel that can show competitor data (e.g. current speed over ground, windward distance to
|
||||
* MultiCompetitorRaceChart is a GWT panel that can show competitor data (e.g. current speed over ground, windward distance to
|
||||
* leader) for different races in a chart. The chart type can be selected from the settings.
|
||||
*
|
||||
* When calling the constructor a chart is created that creates a final amount of series (so the maximum number of
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.components;
|
||||
|
||||
import com.google.gwt.user.client.ui.LazyPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
|
||||
public abstract class AbstractLazyComponent<SettingsType> extends LazyPanel implements LazyComponent<SettingsType> {
|
||||
|
||||
@Override
|
||||
public Widget getEntryWidget() {
|
||||
ensureWidget();
|
||||
return getWidget();
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.components;
|
||||
|
||||
/**
|
||||
* Used to describe different view modes for a component viewer
|
||||
* The view modes are driven by media types.
|
||||
* @author Frank
|
||||
*
|
||||
*/
|
||||
public enum ComponentViewerViewModes {
|
||||
WEB_VIEW, TV_VIEW
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package com.sap.sailing.gwt.ui.client.shared.components;
|
||||
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
|
||||
public interface LazyComponent<SettingsType> extends Component<SettingsType> {
|
||||
Widget createWidget();
|
||||
}
|
||||
+56
-40
@@ -14,12 +14,14 @@ import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.RootLayoutPanel;
|
||||
import com.google.gwt.user.client.ui.RootPanel;
|
||||
import com.google.gwt.user.client.ui.ScrollPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.LeaderboardType;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.RegattaNameAndRaceName;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
|
||||
import com.sap.sailing.gwt.ui.client.AbstractEntryPoint;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.DataEntryDialog;
|
||||
import com.sap.sailing.gwt.ui.client.LogoAndTitlePanel;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
@@ -45,8 +47,8 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
|
||||
private static final String PARAM_AUTO_EXPAND_LAST_RACE_COLUMN = "autoExpandLastRaceColumn";
|
||||
private static final String PARAM_REGATTA_NAME = "regattaName";
|
||||
private static final String PARAM_REFRESH_INTERVAL_MILLIS = "refreshIntervalMillis";
|
||||
private static final String PARAM_SHOW_OVERALL_LEADERBOARDS_ON_SAME_PAGE = "showOverallLeaderboardsOnSamePage";
|
||||
private static final String PARAM_DELAY_TO_LIVE_MILLIS = "delayToLiveMillis";
|
||||
private static final String PARAM_SHOW_RANK_CHART = "showRankChart";
|
||||
|
||||
/**
|
||||
* Parameter to support scaling the complete page by a given factor. This works by either using the
|
||||
@@ -64,6 +66,7 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
|
||||
private static final String PARAM_NAME_LAST_N = "lastN";
|
||||
private String leaderboardName;
|
||||
private String leaderboardGroupName;
|
||||
private LeaderboardType leaderboardType;
|
||||
private GlobalNavigationPanel globalNavigationPanel;
|
||||
|
||||
@Override
|
||||
@@ -75,28 +78,34 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
|
||||
&& Window.Location.getParameter(PARAM_EMBEDDED).equalsIgnoreCase("true");
|
||||
final long delayToLiveMillis = Window.Location.getParameter(PARAM_DELAY_TO_LIVE_MILLIS) != null ?
|
||||
Long.valueOf(Window.Location.getParameter(PARAM_DELAY_TO_LIVE_MILLIS)) : 5000l; // default 5s
|
||||
sailingService.getLeaderboardNames(new AsyncCallback<List<String>>() {
|
||||
@Override
|
||||
public void onSuccess(List<String> leaderboardNames) {
|
||||
leaderboardName = Window.Location.getParameter("name");
|
||||
leaderboardGroupName = Window.Location.getParameter(PARAM_LEADERBOARD_GROUP_NAME);
|
||||
if (leaderboardNames.contains(leaderboardName)) {
|
||||
createUI(showRaceDetails, embedded, delayToLiveMillis);
|
||||
} else {
|
||||
RootPanel.get().add(new Label(stringMessages.noSuchLeaderboard()));
|
||||
}
|
||||
|
||||
final String zoomTo = Window.Location.getParameter(PARAM_ZOOM_TO);
|
||||
if (zoomTo != null) {
|
||||
RootPanel.getBodyElement().setAttribute("style", "zoom: "+zoomTo+";-moz-transform: scale("+zoomTo+");-moz-transform-origin: 0 0;-o-transform: scale("+zoomTo+");-o-transform-origin: 0 0;-webkit-transform: scale("+zoomTo+");-webkit-transform-origin: 0 0;");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
reportError("Error trying to obtain list of leaderboard names: " + t.getMessage());
|
||||
}
|
||||
});
|
||||
leaderboardName = Window.Location.getParameter("name");
|
||||
leaderboardGroupName = Window.Location.getParameter(PARAM_LEADERBOARD_GROUP_NAME);
|
||||
|
||||
if(leaderboardName != null) {
|
||||
sailingService.checkLeaderboardName(leaderboardName, new AsyncCallback<Pair<String, LeaderboardType>>() {
|
||||
@Override
|
||||
public void onSuccess(Pair<String, LeaderboardType> leaderboardNameAndType) {
|
||||
if (leaderboardNameAndType != null && leaderboardName.equals(leaderboardNameAndType.getA())) {
|
||||
leaderboardType = leaderboardNameAndType.getB();
|
||||
createUI(showRaceDetails, embedded, delayToLiveMillis);
|
||||
} else {
|
||||
RootPanel.get().add(new Label(stringMessages.noSuchLeaderboard()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t) {
|
||||
reportError("Error trying to obtain list of leaderboard names: " + t.getMessage());
|
||||
}
|
||||
});
|
||||
} else {
|
||||
RootPanel.get().add(new Label(stringMessages.noSuchLeaderboard()));
|
||||
}
|
||||
final String zoomTo = Window.Location.getParameter(PARAM_ZOOM_TO);
|
||||
if (zoomTo != null) {
|
||||
RootPanel.getBodyElement().setAttribute("style", "zoom: "+zoomTo+";-moz-transform: scale("+zoomTo+");-moz-transform-origin: 0 0;-o-transform: scale("+zoomTo+");-o-transform-origin: 0 0;-webkit-transform: scale("+zoomTo+");-webkit-transform-origin: 0 0;");
|
||||
}
|
||||
}
|
||||
|
||||
private void createUI(boolean showRaceDetails, boolean embedded, long delayToLiveMillis) {
|
||||
@@ -136,17 +145,28 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
|
||||
if (leaderboardSettings.getDelayBetweenAutoAdvancesInMilliseconds() != null) {
|
||||
timer.setPlayMode(PlayModes.Live); // the leaderboard, viewed via the entry point, always goes "live"
|
||||
}
|
||||
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService, new AsyncActionsExecutor(),
|
||||
leaderboardSettings,
|
||||
preselectedRace, new CompetitorSelectionModel(
|
||||
/* hasMultiSelection */true), timer, leaderboardGroupName, leaderboardName,
|
||||
LeaderboardEntryPoint.this, stringMessages, userAgent, showRaceDetails, /* raceTimesInfoProvider */ null, Window.Location.getParameterMap().containsKey(PARAM_AUTO_EXPAND_LAST_RACE_COLUMN) ?
|
||||
Boolean.valueOf(Window.Location.getParameterMap().get(PARAM_AUTO_EXPAND_LAST_RACE_COLUMN).get(0)) : false);
|
||||
leaderboardPanel.addStyleName(LeaderboardPanel.LEADERBOARD_MARGIN_STYLE);
|
||||
contentScrollPanel.setWidget(leaderboardPanel);
|
||||
|
||||
mainPanel.add(contentScrollPanel);
|
||||
}
|
||||
|
||||
boolean autoExpandLastRaceColumn = Window.Location.getParameterMap().containsKey(
|
||||
PARAM_AUTO_EXPAND_LAST_RACE_COLUMN) ? Boolean.valueOf(Window.Location.getParameterMap()
|
||||
.get(PARAM_AUTO_EXPAND_LAST_RACE_COLUMN).get(0)) : false;
|
||||
boolean showRankChart = Window.Location.getParameterMap().containsKey(
|
||||
PARAM_SHOW_RANK_CHART) ? Boolean.valueOf(Window.Location.getParameterMap()
|
||||
.get(PARAM_SHOW_RANK_CHART).get(0)) : false;
|
||||
|
||||
Widget leaderboardViewer;
|
||||
if(leaderboardType.isMetaLeaderboard()) {
|
||||
leaderboardViewer = new MetaLeaderboardViewer(delayToLiveMillis, sailingService, new AsyncActionsExecutor(),
|
||||
leaderboardSettings, null, preselectedRace, leaderboardGroupName, leaderboardName, this, stringMessages, userAgent,
|
||||
showRaceDetails, autoExpandLastRaceColumn, showRankChart);
|
||||
} else {
|
||||
leaderboardViewer = new LeaderboardViewer(delayToLiveMillis, sailingService, new AsyncActionsExecutor(),
|
||||
leaderboardSettings, preselectedRace, leaderboardGroupName, leaderboardName, this, stringMessages, userAgent,
|
||||
showRaceDetails, autoExpandLastRaceColumn, showRankChart);
|
||||
}
|
||||
|
||||
contentScrollPanel.setWidget(leaderboardViewer);
|
||||
mainPanel.add(contentScrollPanel);
|
||||
}
|
||||
|
||||
private RaceIdentifier getPreselectedRace(Map<String, List<String>> parameterMap) {
|
||||
RaceIdentifier result;
|
||||
@@ -178,9 +198,6 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
|
||||
} else {
|
||||
numberOfLastRacesToShow = null;
|
||||
}
|
||||
boolean showOverallLeaderboardsOnSamePage = parameterMap.containsKey(PARAM_SHOW_OVERALL_LEADERBOARDS_ON_SAME_PAGE) ?
|
||||
Boolean.valueOf(parameterMap.get(PARAM_SHOW_OVERALL_LEADERBOARDS_ON_SAME_PAGE).get(0)) :
|
||||
false;
|
||||
if (parameterMap.containsKey(PARAM_RACE_NAME) || parameterMap.containsKey(PARAM_RACE_DETAIL) ||
|
||||
parameterMap.containsKey(PARAM_LEG_DETAIL) || parameterMap.containsKey(PARAM_MANEUVER_DETAIL) ||
|
||||
parameterMap.containsKey(PARAM_OVERALL_DETAIL)) {
|
||||
@@ -199,13 +216,13 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
|
||||
/* sort by column */ (namesOfRacesToShow != null && !namesOfRacesToShow.isEmpty()) ?
|
||||
namesOfRacesToShow.get(0) : null, /* ascending */ true,
|
||||
/* updateUponPlayStateChange */ raceDetails.isEmpty() && legDetails.isEmpty(),
|
||||
raceColumnSelectionStrategy, showOverallLeaderboardsOnSamePage);
|
||||
raceColumnSelectionStrategy);
|
||||
} else {
|
||||
final List<DetailType> overallDetails = Collections.emptyList();
|
||||
result = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null,
|
||||
/* overallDetails */ overallDetails, null,
|
||||
/* autoExpandFirstRace */false, refreshIntervalMillis, numberOfLastRacesToShow,
|
||||
raceColumnSelectionStrategy, showOverallLeaderboardsOnSamePage);
|
||||
raceColumnSelectionStrategy);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -323,7 +340,6 @@ public class LeaderboardEntryPoint extends AbstractEntryPoint {
|
||||
+ (settings.isShowRaceDetails() ? "&"+PARAM_SHOW_RACE_DETAILS+"=true" : "")
|
||||
+ (leaderboardDisplayName != null ? "&displayName="+leaderboardDisplayName : "")
|
||||
+ (settings.isEmbedded() ? "&"+PARAM_EMBEDDED+"=true" : "")
|
||||
+ (settings.getLeaderboardSettings().isShowOverallLeaderboardsOnSamePage() ? "&"+PARAM_SHOW_OVERALL_LEADERBOARDS_ON_SAME_PAGE+"=true" : "")
|
||||
+ (settings.getLeaderboardSettings().getDelayInMilliseconds() == null &&
|
||||
settings.getLeaderboardSettings().getDelayInMilliseconds() != 0 ? "" :
|
||||
"&"+PARAM_DELAY_TO_LIVE_MILLIS+"="+settings.getLeaderboardSettings().getDelayInMilliseconds())
|
||||
|
||||
+8
-156
@@ -29,18 +29,17 @@ import com.google.gwt.safehtml.shared.SafeHtmlUtils;
|
||||
import com.google.gwt.user.cellview.client.Column;
|
||||
import com.google.gwt.user.cellview.client.Header;
|
||||
import com.google.gwt.user.cellview.client.SafeHtmlHeader;
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.AbstractImagePrototype;
|
||||
import com.google.gwt.user.client.ui.Anchor;
|
||||
import com.google.gwt.user.client.ui.DockPanel;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.FormPanel;
|
||||
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
|
||||
import com.google.gwt.user.client.ui.HasVerticalAlignment;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.ImageResourceRenderer;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
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.google.gwt.view.client.ListDataProvider;
|
||||
@@ -63,7 +62,6 @@ import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
|
||||
import com.sap.sailing.gwt.ui.actions.GetLeaderboardByNameAction;
|
||||
import com.sap.sailing.gwt.ui.client.Collator;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionChangeListener;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.FlagImageResolver;
|
||||
@@ -79,7 +77,6 @@ import com.sap.sailing.gwt.ui.client.Timer.PlayStates;
|
||||
import com.sap.sailing.gwt.ui.client.UserAgentDetails;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.Component;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.IsEmbeddableComponent;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialogComponent;
|
||||
import com.sap.sailing.gwt.ui.client.shared.panels.BusyIndicator;
|
||||
import com.sap.sailing.gwt.ui.client.shared.panels.SimpleBusyIndicator;
|
||||
@@ -100,7 +97,7 @@ import com.sap.sailing.gwt.ui.shared.RaceTimesInfoDTO;
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public class LeaderboardPanel extends FormPanel implements TimeListener, PlayStateListener,
|
||||
public class LeaderboardPanel extends SimplePanel implements TimeListener, PlayStateListener,
|
||||
Component<LeaderboardSettings>, IsEmbeddableComponent, CompetitorSelectionChangeListener, LeaderboardFetcher {
|
||||
private static final int RANK_COLUMN_INDEX = 0;
|
||||
|
||||
@@ -136,8 +133,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
* obtain the leaderboard contents} from the server. It may change in case the leaderboard is renamed.
|
||||
*/
|
||||
private String leaderboardName;
|
||||
|
||||
private String leaderboardGroupName;
|
||||
|
||||
private final ErrorReporter errorReporter;
|
||||
|
||||
@@ -189,15 +184,11 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
|
||||
protected final String TOTAL_COLUMN_STYLE;
|
||||
|
||||
public static final String LEADERBOARD_MARGIN_STYLE = "leaderboardMargin";
|
||||
|
||||
private final Timer timer;
|
||||
|
||||
private boolean autoExpandPreSelectedRace;
|
||||
|
||||
private boolean autoExpandLastRaceColumn;
|
||||
|
||||
private boolean showOverallLeaderboardsOnSamePage;
|
||||
|
||||
/**
|
||||
* Remembers whether the auto-expand of the pre-selected race (see {@link #autoExpandPreSelectedRace}) or last
|
||||
@@ -223,18 +214,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
|
||||
private final VerticalPanel contentPanel;
|
||||
|
||||
/**
|
||||
* Used to display one or more overall leaderboards if selected. See also
|
||||
* {@link LeaderboardSettings#isShowOverallLeaderboardsOnSamePage()}. Always contained by the {@link #contentPanel} at the
|
||||
* right position, but may be empty.
|
||||
*/
|
||||
private final VerticalPanel overallLeaderboardsPanel;
|
||||
|
||||
/**
|
||||
* The leaderboard panels displayed in {@link #overallLeaderboardsPanel}.
|
||||
*/
|
||||
private final List<LeaderboardPanel> overallLeaderboardPanels;
|
||||
|
||||
private final HorizontalPanel refreshAndSettingsPanel;
|
||||
|
||||
private final FlowPanel informationPanel;
|
||||
@@ -292,21 +271,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
*/
|
||||
private RaceTimesInfoProvider raceTimesInfoProvider;
|
||||
|
||||
private final UserAgentDetails userAgent;
|
||||
|
||||
private class SettingsClickHandler implements ClickHandler {
|
||||
private final StringMessages stringMessages;
|
||||
|
||||
private SettingsClickHandler(StringMessages stringMessages) {
|
||||
this.stringMessages = stringMessages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
new SettingsDialog<LeaderboardSettings>(LeaderboardPanel.this, stringMessages).show();
|
||||
}
|
||||
}
|
||||
|
||||
protected StringMessages getStringMessages() {
|
||||
return stringMessages;
|
||||
}
|
||||
@@ -442,67 +406,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
getLeaderboardTable().sortColumn(raceColumnByRaceName, /* ascending */true);
|
||||
}
|
||||
}
|
||||
if (newSettings.isShowOverallLeaderboardsOnSamePage() != showOverallLeaderboardsOnSamePage) {
|
||||
showOverallLeaderboardsOnSamePage = newSettings.isShowOverallLeaderboardsOnSamePage();
|
||||
if (showOverallLeaderboardsOnSamePage) {
|
||||
showOverallLeaderboards();
|
||||
} else {
|
||||
hideOverallLeaderboards();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showOverallLeaderboards() {
|
||||
overallLeaderboardsPanel.clear();
|
||||
final Label overallStandingsLabel = new Label(stringMessages.overallStandings());
|
||||
overallStandingsLabel.setStyleName("leaderboardHeading");
|
||||
overallLeaderboardsPanel.add(overallStandingsLabel);
|
||||
updateOverallLeaderboardsAndAddToPanel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches from the server the list of overall ("meta") leaderboard descriptions in which this main leaderboard occurs and
|
||||
* creates one {@link LeaderboardPanel} for each such overall leaderboard. Those panels are then added to
|
||||
* {@link #overallLeaderboardPanels}, registered with the {@link #timer} for common timing with the main leaderboard panel,
|
||||
* and the panels are made visible by adding them to the {@link #overallLeaderboardsPanel} panel.
|
||||
*/
|
||||
private void updateOverallLeaderboardsAndAddToPanel() {
|
||||
getSailingService().getOverallLeaderboardNamesContaining(leaderboardName, new AsyncCallback<List<String>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
getErrorReporter().reportError(
|
||||
stringMessages.errorTryingToObtainOverallLeaderboards(caught.getMessage()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(List<String> overallLeaderboardNames) {
|
||||
for (String overallLeaderboardName : overallLeaderboardNames) {
|
||||
LeaderboardPanel overallLeaderboardPanel = new LeaderboardPanel(
|
||||
getSailingService(), asyncActionsExecutor, LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(
|
||||
/* namesOfRaceColumnsToShow */ null, /* namesOfRacesToShow */ null, /* nameOfRaceToSort */ null,
|
||||
/* autoExpandPreSelectedRace */ false, /* showOverallLeaderboardsOnSamePage */ false),
|
||||
/* preSelectedRace */ null, new CompetitorSelectionModel(/* hasMultiSelection */ true),
|
||||
timer, leaderboardGroupName, overallLeaderboardName, errorReporter, stringMessages, userAgent,
|
||||
showRaceDetails, /* optionalRaceTimesInfoProvider */ null, /* autoExpandLastRaceColumn */ false);
|
||||
overallLeaderboardPanels.add(overallLeaderboardPanel);
|
||||
overallLeaderboardsPanel.add(overallLeaderboardPanel);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the panel used to display the overall leaderboards, removes all overall leaderboard panels from their listener
|
||||
* relationship with the {@link #timer} and then clears the {@link #overallLeaderboardPanels} list.
|
||||
*/
|
||||
private void hideOverallLeaderboards() {
|
||||
overallLeaderboardsPanel.clear();
|
||||
for (LeaderboardPanel overallLeaderboardPanel : overallLeaderboardPanels) {
|
||||
timer.removeTimeListener(overallLeaderboardPanel);
|
||||
timer.removePlayStateListener(overallLeaderboardPanel);
|
||||
}
|
||||
overallLeaderboardPanels.clear();
|
||||
}
|
||||
|
||||
private void setRaceColumnSelectionToLastNStrategy(final Integer numberOfLastRacesToShow) {
|
||||
@@ -1347,7 +1250,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
this.preSelectedRace = preSelectedRace;
|
||||
this.competitorSelectionProvider = competitorSelectionProvider;
|
||||
competitorSelectionProvider.addCompetitorSelectionChangeListener(this);
|
||||
this.leaderboardGroupName = leaderboardGroupName;
|
||||
this.setLeaderboardName(leaderboardName);
|
||||
this.errorReporter = errorReporter;
|
||||
this.stringMessages = stringMessages;
|
||||
@@ -1356,7 +1258,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
this.selectedOverallDetailColumns = new ArrayList<DetailType>();
|
||||
this.raceTimesInfoProvider = optionalRaceTimesInfoProvider;
|
||||
this.selectedManeuverDetails = new ArrayList<DetailType>();
|
||||
this.showOverallLeaderboardsOnSamePage = settings.isShowOverallLeaderboardsOnSamePage();
|
||||
overallDetailColumnMap = createOverallDetailColumnMap();
|
||||
settingsUpdatedExplicitly = !settings.updateUponPlayStateChange();
|
||||
if (settings.getLegDetailsToShow() != null) {
|
||||
@@ -1402,7 +1303,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
leaderboardTable = new SortedCellTableWithStylableHeaders<LeaderboardRowDTO>(
|
||||
/* pageSize */10000, tableResources);
|
||||
getLeaderboardTable().setWidth("100%");
|
||||
this.userAgent = userAgent;
|
||||
if (userAgent.isMobile() == UserAgentDetails.PlatformTypes.MOBILE) {
|
||||
leaderboardSelectionModel = new ToggleSelectionModel<LeaderboardRowDTO>();
|
||||
} else {
|
||||
@@ -1429,8 +1329,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
}
|
||||
contentPanel = new VerticalPanel();
|
||||
contentPanel.setStyleName(STYLE_LEADERBOARD_CONTENT);
|
||||
overallLeaderboardsPanel = new VerticalPanel();
|
||||
overallLeaderboardPanels = new ArrayList<LeaderboardPanel>();
|
||||
|
||||
// the information panel
|
||||
informationPanel = new FlowPanel();
|
||||
@@ -1468,16 +1366,11 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
}
|
||||
}
|
||||
};
|
||||
ImageResource chartIcon = resources.chartIcon();
|
||||
ImageResource rankChartIcon = resources.rankChartIcon();
|
||||
ImageResource leaderboardSettingsIcon = resources.leaderboardSettingsIcon();
|
||||
pauseIcon = resources.pauseIcon();
|
||||
playIcon = resources.playIcon();
|
||||
pauseIcon = resources.autoRefreshEnabledIcon();
|
||||
playIcon = resources.autoRefreshDisabledIcon();
|
||||
refreshAndSettingsPanel = new HorizontalPanel();
|
||||
refreshAndSettingsPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
HorizontalPanel refreshPanel = new HorizontalPanel();
|
||||
refreshPanel.setSpacing(5);
|
||||
refreshPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
|
||||
FlowPanel refreshPanel = new FlowPanel();
|
||||
refreshPanel.addStyleName("refreshPanel");
|
||||
toolbarPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
|
||||
toolbarPanel.addStyleName("refreshAndSettings");
|
||||
@@ -1485,35 +1378,13 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
playPause.addClickHandler(playPauseHandler);
|
||||
playStateChanged(timer.getPlayState(), timer.getPlayMode());
|
||||
refreshPanel.add(playPause);
|
||||
Anchor rankChartsAnchor = new Anchor(AbstractImagePrototype.create(rankChartIcon).getSafeHtml());
|
||||
rankChartsAnchor.setTitle(stringMessages.showRankChart());
|
||||
rankChartsAnchor.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
showRankChartDialog();
|
||||
}
|
||||
});
|
||||
Anchor chartsAnchor = new Anchor(AbstractImagePrototype.create(chartIcon).getSafeHtml());
|
||||
chartsAnchor.setTitle(stringMessages.showCharts());
|
||||
chartsAnchor.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
showCompareCompetitorsDialog();
|
||||
}
|
||||
});
|
||||
Anchor settingsAnchor = new Anchor(AbstractImagePrototype.create(leaderboardSettingsIcon).getSafeHtml());
|
||||
settingsAnchor.setTitle(stringMessages.settings());
|
||||
settingsAnchor.addClickHandler(new SettingsClickHandler(stringMessages));
|
||||
refreshAndSettingsPanel.add(rankChartsAnchor);
|
||||
refreshAndSettingsPanel.add(chartsAnchor);
|
||||
|
||||
refreshAndSettingsPanel.add(refreshPanel);
|
||||
refreshAndSettingsPanel.add(settingsAnchor);
|
||||
toolbarPanel.add(refreshAndSettingsPanel, DockPanel.EAST);
|
||||
if (!isEmbedded) {
|
||||
contentPanel.add(toolbarPanel);
|
||||
}
|
||||
contentPanel.add(getLeaderboardTable());
|
||||
contentPanel.add(overallLeaderboardsPanel);
|
||||
setWidget(contentPanel);
|
||||
raceNameForDefaultSorting = settings.getNameOfRaceToSort();
|
||||
}
|
||||
@@ -2415,7 +2286,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
: preSelectedRace.getRaceName(),
|
||||
/* don't change nameOfRaceColumnToShow */null,
|
||||
/* set nameOfRaceToShow if race was pre-selected */preSelectedRace == null ? null : preSelectedRace
|
||||
.getRaceName(), getRaceColumnSelection(), showOverallLeaderboardsOnSamePage));
|
||||
.getRaceName(), getRaceColumnSelection()));
|
||||
}
|
||||
currentlyHandlingPlayStateChange = false;
|
||||
oldPlayMode = playMode;
|
||||
@@ -2425,25 +2296,6 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
public void playSpeedFactorChanged(double newPlaySpeedFactor) {
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
private void showCompareCompetitorsDialog() {
|
||||
int selectedCompetitorsCount = Util.size(competitorSelectionProvider.getSelectedCompetitors());
|
||||
if (selectedCompetitorsCount < 1) {
|
||||
Window.alert(stringMessages.selectAtLeastOneCompetitor());
|
||||
} else {
|
||||
List<RegattaAndRaceIdentifier> races = getTrackedRacesIdentifiers();
|
||||
RaceTimesInfoProvider raceTimesInfoProvider = new RaceTimesInfoProvider(sailingService, errorReporter, races, 5000l /* requestInterval*/);
|
||||
CompareCompetitorsChartDialog chartDialog = new CompareCompetitorsChartDialog(sailingService, races, raceTimesInfoProvider,
|
||||
competitorSelectionProvider, timer, stringMessages, errorReporter, leaderboardGroupName, leaderboardName);
|
||||
chartDialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void showRankChartDialog() {
|
||||
RankChartDialog chartDialog = new RankChartDialog(sailingService, leaderboardName, competitorSelectionProvider,
|
||||
timer, stringMessages, errorReporter, /* compactChart */ false);
|
||||
chartDialog.show();
|
||||
}
|
||||
|
||||
private List<RegattaAndRaceIdentifier> getTrackedRacesIdentifiers() {
|
||||
List<RegattaAndRaceIdentifier> result = new ArrayList<RegattaAndRaceIdentifier>();
|
||||
@@ -2473,7 +2325,7 @@ public class LeaderboardPanel extends FormPanel implements TimeListener, PlaySta
|
||||
Collections.unmodifiableList(selectedLegDetails), Collections.unmodifiableList(selectedRaceDetails),
|
||||
Collections.unmodifiableList(selectedOverallDetailColumns), /* All races to select */ leaderboard.getRaceList(),
|
||||
raceColumnSelection.getSelectedRaceColumnsOrderedAsInLeaderboard(leaderboard), raceColumnSelection, autoExpandPreSelectedRace,
|
||||
showOverallLeaderboardsOnSamePage, timer.getRefreshInterval(), timer.getLivePlayDelayInMillis(), stringMessages);
|
||||
timer.getRefreshInterval(), timer.getLivePlayDelayInMillis(), stringMessages);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+15
-9
@@ -4,21 +4,27 @@ import com.google.gwt.resources.client.ClientBundle;
|
||||
import com.google.gwt.resources.client.ImageResource;
|
||||
|
||||
interface LeaderboardResources extends ClientBundle {
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/arrow-gain.png")
|
||||
ImageResource arrowGainIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/arrow-loss.png")
|
||||
ImageResource arrowLossIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/arrow-gain-loss.png")
|
||||
ImageResource arrowGainLossIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/arrow-gain.png")
|
||||
ImageResource arrowGainIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/arrow-loss.png")
|
||||
ImageResource arrowLossIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/arrow-gain-loss.png")
|
||||
ImageResource arrowGainLossIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/settings.png")
|
||||
ImageResource settingsIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/leaderboardsettings.png")
|
||||
ImageResource leaderboardSettingsIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/autorefresh_enabled.png")
|
||||
ImageResource autoRefreshEnabledIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/autorefresh_disabled.png")
|
||||
ImageResource autoRefreshDisabledIcon();
|
||||
|
||||
@Source("com/sap/sailing/gwt/ui/client/images/play.png")
|
||||
ImageResource playIcon();
|
||||
|
||||
|
||||
+1
-7
@@ -30,7 +30,6 @@ public class LeaderboardSettings {
|
||||
private final Long delayBetweenAutoAdvancesInMilliseconds;
|
||||
private final Long delayInMilliseconds;
|
||||
private final boolean updateUponPlayStateChange;
|
||||
private final boolean showOverallLeaderboardsOnSamePage;
|
||||
|
||||
/**
|
||||
* There are two ways to select race columns.
|
||||
@@ -54,7 +53,7 @@ public class LeaderboardSettings {
|
||||
List<String> namesOfRaceColumnsToShow, List<String> namesOfRacesToShow, Integer numberOfLastRacesToShow,
|
||||
boolean autoExpandPreSelectedRace, Long delayBetweenAutoAdvancesInMilliseconds, Long delayInMilliseconds,
|
||||
String nameOfRaceToSort, boolean sortAscending, boolean updateUponPlayStateChange,
|
||||
RaceColumnSelectionStrategies activeRaceColumnSelectionStrategy, boolean showOverallLeaderboardsOnSamePage) {
|
||||
RaceColumnSelectionStrategies activeRaceColumnSelectionStrategy) {
|
||||
if (namesOfRacesToShow != null && namesOfRaceColumnsToShow != null) {
|
||||
throw new IllegalArgumentException("You can identify races either only by their race or by their column names, not both");
|
||||
}
|
||||
@@ -72,7 +71,6 @@ public class LeaderboardSettings {
|
||||
this.nameOfRaceToSort = nameOfRaceToSort;
|
||||
this.sortAscending = sortAscending;
|
||||
this.updateUponPlayStateChange = updateUponPlayStateChange;
|
||||
this.showOverallLeaderboardsOnSamePage = showOverallLeaderboardsOnSamePage;
|
||||
}
|
||||
|
||||
public List<DetailType> getManeuverDetailsToShow() {
|
||||
@@ -153,8 +151,4 @@ public class LeaderboardSettings {
|
||||
public RaceColumnSelectionStrategies getActiveRaceColumnSelectionStrategy() {
|
||||
return activeRaceColumnSelectionStrategy;
|
||||
}
|
||||
|
||||
public boolean isShowOverallLeaderboardsOnSamePage() {
|
||||
return showOverallLeaderboardsOnSamePage;
|
||||
}
|
||||
}
|
||||
+3
-21
@@ -46,7 +46,6 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
private LongBox refreshIntervalInSecondsBox;
|
||||
private LongBox delayInSecondsBox;
|
||||
private final boolean autoExpandPreSelectedRace;
|
||||
private final boolean showOverallLeaderboardOnSamePage;
|
||||
private final long delayBetweenAutoAdvancesInMilliseconds;
|
||||
private final long delayInMilliseconds;
|
||||
private final Integer numberOfLastRacesToShow;
|
||||
@@ -54,14 +53,13 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
private RadioButton explicitRaceColumnSelectionRadioBtn;
|
||||
private RadioButton lastNRacesColumnSelectionRadioBtn;
|
||||
private IntegerBox numberOfLastRacesToShowBox;
|
||||
private CheckBox showOverallLeaderboardOnSamePageCheckbox;
|
||||
|
||||
public LeaderboardSettingsDialogComponent(List<DetailType> maneuverDetailSelection,
|
||||
List<DetailType> legDetailSelection, List<DetailType> raceDetailSelection,
|
||||
List<DetailType> overallDetailSelection, List<RaceColumnDTO> raceAllRaceColumns,
|
||||
Iterable<RaceColumnDTO> raceColumnSelection, RaceColumnSelection raceColumnSelectionStrategy,
|
||||
boolean autoExpandPreSelectedRace, boolean showOverallLeaderboardOnSamePage,
|
||||
long delayBetweenAutoAdvancesInMilliseconds, long delayInMilliseconds, StringMessages stringMessages) {
|
||||
boolean autoExpandPreSelectedRace, long delayBetweenAutoAdvancesInMilliseconds,
|
||||
long delayInMilliseconds, StringMessages stringMessages) {
|
||||
this.raceAllRaceColumns = raceAllRaceColumns;
|
||||
this.numberOfLastRacesToShow = raceColumnSelectionStrategy.getNumberOfLastRaceColumnsToShow();
|
||||
this.activeRaceColumnSelectionStrategy = raceColumnSelectionStrategy.getType();
|
||||
@@ -79,14 +77,12 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
this.autoExpandPreSelectedRace = autoExpandPreSelectedRace;
|
||||
this.delayBetweenAutoAdvancesInMilliseconds = delayBetweenAutoAdvancesInMilliseconds;
|
||||
this.delayInMilliseconds = delayInMilliseconds;
|
||||
this.showOverallLeaderboardOnSamePage = showOverallLeaderboardOnSamePage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Widget getAdditionalWidget(DataEntryDialog<?> dialog) {
|
||||
FlowPanel dialogPanel = new FlowPanel();
|
||||
dialogPanel.add(createSelectedRacesPanel(dialog));
|
||||
dialogPanel.add(createOverallLeaderboardSelectionPanel(dialog));
|
||||
dialogPanel.add(createOverallDetailPanel(dialog));
|
||||
dialogPanel.add(createRaceDetailPanel(dialog));
|
||||
dialogPanel.add(createLegDetailsPanel(dialog));
|
||||
@@ -290,19 +286,6 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
return selectedRacesPanel;
|
||||
}
|
||||
|
||||
private FlowPanel createOverallLeaderboardSelectionPanel(DataEntryDialog<?> dialog) {
|
||||
FlowPanel overallLeaderboardSelectionPanel = new FlowPanel();
|
||||
overallLeaderboardSelectionPanel.addStyleName("SettingsDialogComponent");
|
||||
overallLeaderboardSelectionPanel.add(dialog.createHeadline(stringMessages.overallLeaderboardSelection(), true));
|
||||
FlowPanel overallLeaderboardSelectionContent = new FlowPanel();
|
||||
overallLeaderboardSelectionContent.addStyleName("dialogInnerContent");
|
||||
overallLeaderboardSelectionPanel.add(overallLeaderboardSelectionContent);
|
||||
showOverallLeaderboardOnSamePageCheckbox = dialog.createCheckbox(stringMessages.showOverallLeaderboardOnSamePage());
|
||||
showOverallLeaderboardOnSamePageCheckbox.setValue(showOverallLeaderboardOnSamePage);
|
||||
overallLeaderboardSelectionContent.add(showOverallLeaderboardOnSamePageCheckbox);
|
||||
return overallLeaderboardSelectionPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaderboardSettings getResult() {
|
||||
List<DetailType> maneuverDetailsToShow = new ArrayList<DetailType>();
|
||||
@@ -347,8 +330,7 @@ public class LeaderboardSettingsDialogComponent implements SettingsDialogCompone
|
||||
lastNRacesToShowValue,
|
||||
autoExpandPreSelectedRace, 1000l * (delayBetweenAutoAdvancesValue == null ? 0l : delayBetweenAutoAdvancesValue.longValue()),
|
||||
1000 * (delayInSecondsValue == null ? 0 : delayInSecondsValue.longValue()),
|
||||
null, true, /* updateUponPlayStateChange */ true, activeRaceColumnSelectionStrategy,
|
||||
showOverallLeaderboardOnSamePageCheckbox.getValue());
|
||||
null, true, /* updateUponPlayStateChange */ true, activeRaceColumnSelectionStrategy);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+10
-11
@@ -8,7 +8,7 @@ import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
|
||||
import com.sap.sailing.gwt.ui.leaderboard.LeaderboardSettings.RaceColumnSelectionStrategies;
|
||||
|
||||
/*
|
||||
/**
|
||||
* A factory class creating leaderboard settings for different contexts (user role, live or replay mode, etc.
|
||||
*/
|
||||
public class LeaderboardSettingsFactory {
|
||||
@@ -39,7 +39,7 @@ public class LeaderboardSettingsFactory {
|
||||
* this argument
|
||||
*/
|
||||
public LeaderboardSettings createNewSettingsForPlayMode(PlayModes playMode, String nameOfRaceToSort, String nameOfRaceColumnToShow,
|
||||
String nameOfRaceToShow, RaceColumnSelection raceColumnSelection, boolean showOverallLeaderboardsOnSamePage) {
|
||||
String nameOfRaceToShow, RaceColumnSelection raceColumnSelection) {
|
||||
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");
|
||||
}
|
||||
@@ -70,11 +70,11 @@ public class LeaderboardSettingsFactory {
|
||||
/* set autoExpandPreSelectedRace 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, /* updateUponPlayStateChange */ true,
|
||||
raceColumnSelection.getType(), showOverallLeaderboardsOnSamePage);
|
||||
raceColumnSelection.getType());
|
||||
break;
|
||||
case Replay:
|
||||
settings = createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, nameOfRaceToSort, /* autoExpandFirstRace */
|
||||
nameOfRaceColumnToShow != null, showOverallLeaderboardsOnSamePage);
|
||||
nameOfRaceColumnToShow != null);
|
||||
break;
|
||||
}
|
||||
return settings;
|
||||
@@ -94,9 +94,9 @@ public class LeaderboardSettingsFactory {
|
||||
* such a meta leaderboard exists; if multiple such meta leaderboards exist, they are all shown
|
||||
*/
|
||||
public LeaderboardSettings createNewDefaultSettings(List<String> namesOfRaceColumnsToShow,
|
||||
List<String> namesOfRacesToShow, String nameOfRaceToSort, boolean autoExpandPreSelectedRace, boolean showOverallLeaderboardsOnSamePage) {
|
||||
List<String> namesOfRacesToShow, String nameOfRaceToSort, boolean autoExpandPreSelectedRace) {
|
||||
return createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, /* leave overallDetailsToShow unchanged */ null,
|
||||
nameOfRaceToSort, autoExpandPreSelectedRace, /* refreshIntervalMillis */ null, showOverallLeaderboardsOnSamePage);
|
||||
nameOfRaceToSort, autoExpandPreSelectedRace, /* refreshIntervalMillis */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,17 +105,16 @@ public class LeaderboardSettingsFactory {
|
||||
*/
|
||||
public LeaderboardSettings createNewDefaultSettings(List<String> namesOfRaceColumnsToShow,
|
||||
List<String> namesOfRacesToShow, List<DetailType> overallDetailsToShow, String nameOfRaceToSort,
|
||||
boolean autoExpandPreSelectedRace, Long refreshIntervalMillis, boolean showOverallLeaderboardsOnSamePage) {
|
||||
boolean autoExpandPreSelectedRace, Long refreshIntervalMillis) {
|
||||
return createNewDefaultSettings(namesOfRaceColumnsToShow, namesOfRacesToShow, overallDetailsToShow,
|
||||
nameOfRaceToSort, autoExpandPreSelectedRace, refreshIntervalMillis,
|
||||
/* numberOfLastRacesToShow */null, /* raceColumnSelectionStrategy */ RaceColumnSelectionStrategies.EXPLICIT,
|
||||
showOverallLeaderboardsOnSamePage);
|
||||
/* numberOfLastRacesToShow */null, /* raceColumnSelectionStrategy */ RaceColumnSelectionStrategies.EXPLICIT);
|
||||
}
|
||||
|
||||
public LeaderboardSettings createNewDefaultSettings(List<String> namesOfRaceColumnsToShow,
|
||||
List<String> namesOfRacesToShow, List<DetailType> overallDetailsToShow, String nameOfRaceToSort,
|
||||
boolean autoExpandPreSelectedRace, Long refreshIntervalMillis, Integer numberOfLastRacesToShow,
|
||||
RaceColumnSelectionStrategies raceColumnSelectionStrategy, boolean showOverallLeaderboardsOnSamePage) {
|
||||
RaceColumnSelectionStrategies raceColumnSelectionStrategy) {
|
||||
if (namesOfRaceColumnsToShow != null && namesOfRacesToShow != null) {
|
||||
throw new IllegalArgumentException("Can specify race columns either by column or by race name, not both");
|
||||
}
|
||||
@@ -134,6 +133,6 @@ public class LeaderboardSettingsFactory {
|
||||
namesOfRacesToShow, numberOfLastRacesToShow,
|
||||
autoExpandPreSelectedRace, refreshIntervalMillis, /* delay to live */ null,
|
||||
/* sort by column */ nameOfRaceToSort, /* ascending */ true, /* updateUponPlayStateChange */ true,
|
||||
raceColumnSelectionStrategy, showOverallLeaderboardsOnSamePage);
|
||||
raceColumnSelectionStrategy);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -93,13 +93,12 @@ public class LeaderboardUrlConfigurationDialog extends SettingsDialog<Leaderboar
|
||||
}
|
||||
LeaderboardSettings settings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(
|
||||
namesOfRaceColumnsToShow, /* namesOfRacesToShow */null, /* nameOfRaceToSort */null, /* autoExpandPreSelectedRace */
|
||||
false, /* showMetaLeaderboardsOnSamePage */ false);
|
||||
false);
|
||||
List<DetailType> overallDetailsToShow = Collections.emptyList();
|
||||
leaderboardSettingsDialogComponent = new LeaderboardSettingsDialogComponent(settings.getManeuverDetailsToShow(),
|
||||
settings.getLegDetailsToShow(), settings.getRaceDetailsToShow(), overallDetailsToShow, raceList,
|
||||
/* select all races by default */ raceList, new ExplicitRaceColumnSelection(),
|
||||
/* autoExpandPreSelectedRace */ false,
|
||||
/* showOverallLeaderboardOnSamePage */ false,
|
||||
/* delayBetweenAutoAdvancesInMilliseconds */ 3000l, /* delayInMilliseconds */ 3000l, stringMessages);
|
||||
}
|
||||
|
||||
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
package com.sap.sailing.gwt.ui.leaderboard;
|
||||
|
||||
import com.google.gwt.dom.client.Style;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
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.Timer;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
|
||||
import com.sap.sailing.gwt.ui.client.UserAgentDetails;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChart;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.Component;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
|
||||
|
||||
public class LeaderboardViewer extends SimplePanel {
|
||||
private final StringMessages stringMessages;
|
||||
|
||||
private final LeaderboardPanel leaderboardPanel;
|
||||
private final MultiCompetitorLeaderboardChart multiCompetitorChart;
|
||||
|
||||
private final AsyncActionsExecutor asyncActionsExecutor;
|
||||
private final Timer timer;
|
||||
private FlowPanel componentsNavigationPanel;
|
||||
|
||||
private final CompetitorSelectionModel competitorSelectionProvider;
|
||||
|
||||
private final static String STYLE_VIEWER_TOOLBAR = "viewerToolbar";
|
||||
private final static String STYLE_VIEWER_TOOLBAR_INNERELEMENT = "viewerToolbar-innerElement";
|
||||
private final static String STYLE_VIEWER_TOOLBAR_SETTINGS_BUTTON = "viewerToolbar-settingsButton";
|
||||
|
||||
public LeaderboardViewer(long delayToLiveMillis, SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
|
||||
LeaderboardSettings leaderboardSettings, RaceIdentifier preselectedRace, String leaderboardGroupName,
|
||||
String leaderboardName, ErrorReporter errorReporter, StringMessages stringMessages,
|
||||
UserAgentDetails userAgent, boolean showRaceDetails, boolean autoExpandLastRaceColumn, boolean showRankChart) {
|
||||
this.stringMessages = stringMessages;
|
||||
this.asyncActionsExecutor = asyncActionsExecutor;
|
||||
|
||||
competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */true);
|
||||
|
||||
FlowPanel mainPanel = new FlowPanel();
|
||||
mainPanel.setSize("100%", "100%");
|
||||
setWidget(mainPanel);
|
||||
|
||||
getElement().getStyle().setMarginLeft(12, Unit.PX);
|
||||
getElement().getStyle().setMarginRight(12, Unit.PX);
|
||||
|
||||
componentsNavigationPanel = new FlowPanel();
|
||||
componentsNavigationPanel.addStyleName(STYLE_VIEWER_TOOLBAR);
|
||||
mainPanel.add(componentsNavigationPanel);
|
||||
|
||||
|
||||
timer = new Timer(PlayModes.Replay, /*delayBetweenAutoAdvancesInMilliseconds*/ 3000l);
|
||||
timer.setLivePlayDelayInMillis(delayToLiveMillis);
|
||||
leaderboardPanel = createLeaderboardPanel(delayToLiveMillis, sailingService, leaderboardSettings, preselectedRace,
|
||||
leaderboardGroupName, leaderboardName, errorReporter, stringMessages, userAgent,
|
||||
showRaceDetails, autoExpandLastRaceColumn);
|
||||
|
||||
multiCompetitorChart = new MultiCompetitorLeaderboardChart(sailingService, asyncActionsExecutor, leaderboardName, DetailType.REGATTA_RANK, competitorSelectionProvider, timer,
|
||||
stringMessages, errorReporter);
|
||||
multiCompetitorChart.setVisible(showRankChart);
|
||||
multiCompetitorChart.getElement().getStyle().setMarginTop(10, Unit.PX);
|
||||
multiCompetitorChart.getElement().getStyle().setMarginBottom(10, Unit.PX);
|
||||
|
||||
mainPanel.add(leaderboardPanel);
|
||||
mainPanel.add(multiCompetitorChart);
|
||||
|
||||
addComponentToNavigationMenu(leaderboardPanel, false);
|
||||
addComponentToNavigationMenu(multiCompetitorChart, true);
|
||||
|
||||
if(showRankChart) {
|
||||
multiCompetitorChart.timeChanged(timer.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
private LeaderboardPanel createLeaderboardPanel(long delayToLiveMillis, SailingServiceAsync sailingService,
|
||||
LeaderboardSettings leaderboardSettings, RaceIdentifier preselectedRace, String leaderboardGroupName,
|
||||
String leaderboardName, ErrorReporter leaderboardEntryPoint, StringMessages stringMessages,
|
||||
UserAgentDetails userAgent, boolean showRaceDetails, boolean autoExpandLastRaceColumn) {
|
||||
|
||||
LeaderboardPanel leaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor,
|
||||
leaderboardSettings, preselectedRace, competitorSelectionProvider, timer,
|
||||
leaderboardGroupName, leaderboardName, leaderboardEntryPoint, stringMessages, userAgent,
|
||||
showRaceDetails, /* raceTimesInfoProvider */null, autoExpandLastRaceColumn);
|
||||
|
||||
return leaderboardPanel;
|
||||
}
|
||||
|
||||
private <SettingsType> void addComponentToNavigationMenu(final Component<SettingsType> component, boolean withCheckbox) {
|
||||
final CheckBox checkBox= new CheckBox(component.getLocalizedShortName());
|
||||
checkBox.getElement().getStyle().setFloat(Style.Float.LEFT);
|
||||
|
||||
checkBox.setEnabled(withCheckbox);
|
||||
checkBox.setValue(component.isVisible());
|
||||
checkBox.setTitle(stringMessages.showHideComponent(component.getLocalizedShortName()));
|
||||
checkBox.addStyleName(STYLE_VIEWER_TOOLBAR_INNERELEMENT);
|
||||
|
||||
checkBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<Boolean> newValue) {
|
||||
boolean visible = checkBox.getValue();
|
||||
component.setVisible(visible);
|
||||
|
||||
if (visible && component instanceof TimeListener) {
|
||||
// trigger the component to update its data
|
||||
((TimeListener) component).timeChanged(timer.getTime());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
componentsNavigationPanel.add(checkBox);
|
||||
|
||||
Button settingsButton = new Button("");
|
||||
|
||||
if(component.hasSettings()) {
|
||||
settingsButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
new SettingsDialog<SettingsType>(component, stringMessages).show();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
settingsButton.setEnabled(false);
|
||||
}
|
||||
settingsButton.addStyleName(STYLE_VIEWER_TOOLBAR_SETTINGS_BUTTON);
|
||||
settingsButton.getElement().getStyle().setFloat(Style.Float.LEFT);
|
||||
settingsButton.setTitle(stringMessages.settingsForComponent(component.getLocalizedShortName()));
|
||||
|
||||
componentsNavigationPanel.add(settingsButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible) {
|
||||
super.setVisible(visible);
|
||||
|
||||
if(visible) {
|
||||
timer.addTimeListener(multiCompetitorChart);
|
||||
} else {
|
||||
timer.removeTimeListener(multiCompetitorChart);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+250
@@ -0,0 +1,250 @@
|
||||
package com.sap.sailing.gwt.ui.leaderboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.dom.client.Style;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.event.dom.client.ChangeEvent;
|
||||
import com.google.gwt.event.dom.client.ChangeHandler;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeEvent;
|
||||
import com.google.gwt.event.logical.shared.ValueChangeHandler;
|
||||
import com.google.gwt.user.client.rpc.AsyncCallback;
|
||||
import com.google.gwt.user.client.ui.Button;
|
||||
import com.google.gwt.user.client.ui.CheckBox;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.google.gwt.user.client.ui.ListBox;
|
||||
import com.google.gwt.user.client.ui.SimplePanel;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.RaceIdentifier;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
import com.sap.sailing.gwt.ui.actions.AsyncActionsExecutor;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
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.Timer;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
|
||||
import com.sap.sailing.gwt.ui.client.UserAgentDetails;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.MultiCompetitorLeaderboardChart;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.Component;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.ComponentViewerViewModes;
|
||||
import com.sap.sailing.gwt.ui.client.shared.components.SettingsDialog;
|
||||
|
||||
public class MetaLeaderboardViewer extends SimplePanel {
|
||||
private final StringMessages stringMessages;
|
||||
private final ErrorReporter errorReporter;
|
||||
private final SailingServiceAsync sailingService;
|
||||
private final CompetitorSelectionModel competitorSelectionProvider;
|
||||
|
||||
private FlowPanel componentsNavigationPanel;
|
||||
|
||||
private final LeaderboardPanel metaLeaderboardPanel;
|
||||
private LeaderboardPanel selectedLeaderboardPanel;
|
||||
private final MultiCompetitorLeaderboardChart multiCompetitorChart;
|
||||
|
||||
private String selectedLeaderboardName;
|
||||
|
||||
private final AsyncActionsExecutor asyncActionsExecutor;
|
||||
private final String metaLeaderboardName;
|
||||
private final String leaderboardGroupName;
|
||||
private final UserAgentDetails userAgent;
|
||||
private final boolean showRaceDetails;
|
||||
private final Timer timer;
|
||||
private final ComponentViewerViewModes viewMode;
|
||||
|
||||
private final FlowPanel mainPanel;
|
||||
private final List<String> leaderboards;
|
||||
private ListBox leaderboardSelectionListBox;
|
||||
|
||||
private final static String STYLE_VIEWER_TOOLBAR = "viewerToolbar";
|
||||
private final static String STYLE_VIEWER_TOOLBAR_INNERELEMENT = "viewerToolbar-innerElement";
|
||||
private final static String STYLE_VIEWER_TOOLBAR_SETTINGS_BUTTON = "viewerToolbar-settingsButton";
|
||||
|
||||
public MetaLeaderboardViewer(long delayToLiveMillis, SailingServiceAsync sailingService, AsyncActionsExecutor asyncActionsExecutor,
|
||||
LeaderboardSettings leaderboardSettings, String preselectedLeaderboardName, RaceIdentifier preselectedRace, String leaderboardGroupName,
|
||||
String metaLeaderboardName, ErrorReporter errorReporter, StringMessages stringMessages,
|
||||
UserAgentDetails userAgent, boolean showRaceDetails, boolean autoExpandLastRaceColumn, boolean showRankChart) {
|
||||
this.stringMessages = stringMessages;
|
||||
this.errorReporter = errorReporter;
|
||||
this.sailingService = sailingService;
|
||||
this.asyncActionsExecutor = asyncActionsExecutor;
|
||||
|
||||
asyncActionsExecutor = new AsyncActionsExecutor();
|
||||
this.metaLeaderboardName = metaLeaderboardName;
|
||||
this.leaderboardGroupName = leaderboardGroupName;
|
||||
this.userAgent = userAgent;
|
||||
this.showRaceDetails = showRaceDetails;
|
||||
this.selectedLeaderboardName = preselectedLeaderboardName;
|
||||
|
||||
viewMode = ComponentViewerViewModes.WEB_VIEW;
|
||||
|
||||
competitorSelectionProvider = new CompetitorSelectionModel(/* hasMultiSelection */true);
|
||||
|
||||
mainPanel = new FlowPanel();
|
||||
mainPanel.setSize("100%", "100%");
|
||||
setWidget(mainPanel);
|
||||
|
||||
getElement().getStyle().setMarginLeft(12, Unit.PX);
|
||||
getElement().getStyle().setMarginRight(12, Unit.PX);
|
||||
|
||||
final Label overallStandingsLabel = new Label(stringMessages.overallStandings());
|
||||
overallStandingsLabel.setStyleName("leaderboardHeading");
|
||||
|
||||
componentsNavigationPanel = new FlowPanel();
|
||||
componentsNavigationPanel.addStyleName(STYLE_VIEWER_TOOLBAR);
|
||||
mainPanel.add(componentsNavigationPanel);
|
||||
|
||||
timer = new Timer(PlayModes.Replay, /*delayBetweenAutoAdvancesInMilliseconds*/ 3000l);
|
||||
timer.setLivePlayDelayInMillis(delayToLiveMillis);
|
||||
|
||||
metaLeaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor,
|
||||
leaderboardSettings, preselectedRace, competitorSelectionProvider, timer,
|
||||
leaderboardGroupName, metaLeaderboardName, errorReporter, stringMessages, userAgent,
|
||||
showRaceDetails, /* raceTimesInfoProvider */null, autoExpandLastRaceColumn);
|
||||
|
||||
multiCompetitorChart = new MultiCompetitorLeaderboardChart(sailingService, asyncActionsExecutor, metaLeaderboardName, DetailType.REGATTA_RANK, competitorSelectionProvider, timer,
|
||||
stringMessages, errorReporter);
|
||||
multiCompetitorChart.setVisible(showRankChart);
|
||||
multiCompetitorChart.getElement().getStyle().setMarginTop(10, Unit.PX);
|
||||
multiCompetitorChart.getElement().getStyle().setMarginBottom(10, Unit.PX);
|
||||
|
||||
mainPanel.add(metaLeaderboardPanel);
|
||||
mainPanel.add(multiCompetitorChart);
|
||||
|
||||
addComponentToNavigationMenu(metaLeaderboardPanel, false, stringMessages.overallStandings());
|
||||
addComponentToNavigationMenu(multiCompetitorChart, true, null);
|
||||
|
||||
leaderboards = new ArrayList<String>();
|
||||
leaderboardSelectionListBox = new ListBox();
|
||||
leaderboardSelectionListBox.addChangeHandler(new ChangeHandler() {
|
||||
@Override
|
||||
public void onChange(ChangeEvent event) {
|
||||
int selIndex =leaderboardSelectionListBox.getSelectedIndex();
|
||||
if(selIndex >= 0) {
|
||||
updateSelectedLeaderboard(leaderboardSelectionListBox.getItemText(selIndex));
|
||||
}
|
||||
}
|
||||
});
|
||||
leaderboardSelectionListBox.setVisible(false);
|
||||
mainPanel.add(leaderboardSelectionListBox);
|
||||
|
||||
updateLeaderboardsOfMetaleaderboard();
|
||||
|
||||
if (selectedLeaderboardName != null) {
|
||||
updateSelectedLeaderboard(selectedLeaderboardName);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLeaderboardsOfMetaleaderboard() {
|
||||
sailingService.getLeaderboardsNamesOfMetaleaderboard(metaLeaderboardName, new AsyncCallback<List<Pair<String, String>>>() {
|
||||
|
||||
@Override
|
||||
public void onSuccess(List<Pair<String, String>> leaderboardNamesAndDisplayNames) {
|
||||
leaderboardSelectionListBox.clear();
|
||||
|
||||
int index = 0;
|
||||
for (Pair<String, String> leaderboardNameAndDisplayName : leaderboardNamesAndDisplayNames) {
|
||||
leaderboardSelectionListBox.addItem(leaderboardNameAndDisplayName.getB(), leaderboardNameAndDisplayName.getA());
|
||||
if(selectedLeaderboardName != null && selectedLeaderboardName.equals(leaderboardNameAndDisplayName.getA())) {
|
||||
leaderboardSelectionListBox.setSelectedIndex(index);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
leaderboardSelectionListBox.setVisible(leaderboardNamesAndDisplayNames.size() > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private <SettingsType> void addComponentToNavigationMenu(final Component<SettingsType> component, boolean isCheckboxEnabled,
|
||||
String componentDisplayName) {
|
||||
final String componentName = componentDisplayName != null ? componentDisplayName : component.getLocalizedShortName();
|
||||
final CheckBox checkBox= new CheckBox(componentName);
|
||||
checkBox.getElement().getStyle().setFloat(Style.Float.LEFT);
|
||||
|
||||
checkBox.setEnabled(isCheckboxEnabled);
|
||||
checkBox.setValue(component.isVisible());
|
||||
checkBox.setTitle(stringMessages.showHideComponent(componentName));
|
||||
checkBox.addStyleName(STYLE_VIEWER_TOOLBAR_INNERELEMENT);
|
||||
|
||||
checkBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
|
||||
@Override
|
||||
public void onValueChange(ValueChangeEvent<Boolean> newValue) {
|
||||
boolean visible = checkBox.getValue();
|
||||
component.setVisible(visible);
|
||||
|
||||
if (visible && component instanceof TimeListener) {
|
||||
// trigger the component to update its data
|
||||
((TimeListener) component).timeChanged(timer.getTime());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
componentsNavigationPanel.add(checkBox);
|
||||
|
||||
Button settingsButton = new Button("");
|
||||
|
||||
if(component.hasSettings()) {
|
||||
settingsButton.addClickHandler(new ClickHandler() {
|
||||
@Override
|
||||
public void onClick(ClickEvent event) {
|
||||
new SettingsDialog<SettingsType>(component, stringMessages).show();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
settingsButton.setEnabled(false);
|
||||
}
|
||||
settingsButton.addStyleName(STYLE_VIEWER_TOOLBAR_SETTINGS_BUTTON);
|
||||
settingsButton.getElement().getStyle().setFloat(Style.Float.LEFT);
|
||||
settingsButton.setTitle(stringMessages.settingsForComponent(componentName));
|
||||
|
||||
componentsNavigationPanel.add(settingsButton);
|
||||
}
|
||||
|
||||
private void updateSelectedLeaderboard(String selectedLeaderboardName) {
|
||||
if(selectedLeaderboardName != null) {
|
||||
if(selectedLeaderboardPanel == null) {
|
||||
LeaderboardSettings newDefaultSettings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, null, false);
|
||||
selectedLeaderboardPanel = new LeaderboardPanel(sailingService, asyncActionsExecutor,
|
||||
newDefaultSettings, /* preselectedRace*/ null, competitorSelectionProvider, timer,
|
||||
leaderboardGroupName, metaLeaderboardName, errorReporter, stringMessages, userAgent,
|
||||
showRaceDetails, /* raceTimesInfoProvider */null, false);
|
||||
}
|
||||
} else {
|
||||
if(selectedLeaderboardPanel != null) {
|
||||
remove(selectedLeaderboardPanel);
|
||||
selectedLeaderboardPanel = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches from the server the list of overall ("meta") leaderboard descriptions in which this main leaderboard occurs and
|
||||
* creates one {@link LeaderboardPanel} for each such overall leaderboard. Those panels are then added to
|
||||
* {@link #overallLeaderboardPanels}, registered with the {@link #timer} for common timing with the main leaderboard panel,
|
||||
* and the panels are made visible by adding them to the {@link #overallLeaderboardsPanel} panel.
|
||||
*/
|
||||
private void updateOverallLeaderboardsAndAddToPanel() {
|
||||
sailingService.getOverallLeaderboardNamesContaining(metaLeaderboardName, new AsyncCallback<List<String>>() {
|
||||
@Override
|
||||
public void onFailure(Throwable caught) {
|
||||
errorReporter.reportError(stringMessages.errorTryingToObtainOverallLeaderboards(caught.getMessage()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(List<String> overallLeaderboardNames) {
|
||||
for (String overallLeaderboardName : overallLeaderboardNames) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
package com.sap.sailing.gwt.ui.leaderboard;
|
||||
|
||||
import com.google.gwt.user.client.Window;
|
||||
import com.google.gwt.user.client.ui.Label;
|
||||
import com.sap.sailing.gwt.ui.client.CompetitorSelectionProvider;
|
||||
import com.sap.sailing.gwt.ui.client.ErrorReporter;
|
||||
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.Timer;
|
||||
import com.sap.sailing.gwt.ui.client.shared.charts.LeaderboardRankChart;
|
||||
|
||||
public class RankChartDialog extends DialogBoxExt {
|
||||
public RankChartDialog(SailingServiceAsync sailingService, String leaderboardName, CompetitorSelectionProvider competitorSelectionProvider,
|
||||
Timer timer, StringMessages stringMessages, ErrorReporter errorReporter, boolean compactChart) {
|
||||
super(new Label(stringMessages.close()));
|
||||
this.setPopupPosition(15, 15);
|
||||
this.setHTML(stringMessages.compareCompetitors());
|
||||
this.setWidth(Window.getClientWidth() - 250 + "px");
|
||||
this.setAnimationEnabled(true);
|
||||
setWidget(new LeaderboardRankChart(sailingService, leaderboardName, competitorSelectionProvider, timer,
|
||||
stringMessages, errorReporter, compactChart));
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -563,8 +563,7 @@ public class EditableLeaderboardPanel extends LeaderboardPanel {
|
||||
String leaderboardName, String leaderboardGroupName, final ErrorReporter errorReporter,
|
||||
final StringMessages stringMessages, UserAgentDetails userAgent) {
|
||||
super(sailingService, asyncActionsExecutor, LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(
|
||||
/* racesToShow */ null, /* namesOfRacesToShow */ null, null, /* autoExpandFirstRace */ false,
|
||||
/* showMetaLeaderboardsOnSamePage */ false),
|
||||
/* racesToShow */ null, /* namesOfRacesToShow */ null, null, /* autoExpandFirstRace */ false),
|
||||
new CompetitorSelectionModel(/* hasMultiSelection */true),
|
||||
leaderboardName, errorReporter, stringMessages, userAgent, /* showRaceDetails */ true);
|
||||
suppressedCompetitorsShown = new ListDataProvider<CompetitorDTO>(new ArrayList<CompetitorDTO>());
|
||||
|
||||
+17
-38
@@ -78,7 +78,6 @@ public class RaceBoardPanel extends SimplePanel implements RegattaDisplayer, Rac
|
||||
*/
|
||||
private int scrollOffset;
|
||||
|
||||
private final List<ComponentViewer> componentViewers;
|
||||
private FlowPanel componentsNavigationPanel;
|
||||
private FlowPanel settingsPanel;
|
||||
private RaceTimePanel timePanel;
|
||||
@@ -125,17 +124,14 @@ public class RaceBoardPanel extends SimplePanel implements RegattaDisplayer, Rac
|
||||
setWidget(mainPanel);
|
||||
this.timer = timer;
|
||||
timeRangeWithZoomModel = new TimeRangeWithZoomModel();
|
||||
componentViewers = new ArrayList<ComponentViewer>();
|
||||
competitorSelectionModel = new CompetitorSelectionModel(/* hasMultiSelection */ true);
|
||||
componentsNavigationPanel = new FlowPanel();
|
||||
componentsNavigationPanel.addStyleName("raceBoardNavigation");
|
||||
switch (getConfiguration().getViewMode()) {
|
||||
case ONESCREEN:
|
||||
createOneScreenView(leaderboardName, leaderboardGroupName, mainPanel);
|
||||
getElement().getStyle().setMarginLeft(12, Unit.PX);
|
||||
getElement().getStyle().setMarginRight(12, Unit.PX);
|
||||
break;
|
||||
}
|
||||
|
||||
createOneScreenView(leaderboardName, leaderboardGroupName, mainPanel);
|
||||
getElement().getStyle().setMarginLeft(12, Unit.PX);
|
||||
getElement().getStyle().setMarginRight(12, Unit.PX);
|
||||
|
||||
timePanel = new RaceTimePanel(timer, timeRangeWithZoomModel, stringMessages, raceTimesInfoProvider, canReplayWhileLiveIsPossible);
|
||||
timeRangeWithZoomModel.addTimeZoomChangeListener(timePanel);
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(timePanel);
|
||||
@@ -146,7 +142,7 @@ public class RaceBoardPanel extends SimplePanel implements RegattaDisplayer, Rac
|
||||
private void createOneScreenView(String leaderboardName, String leaderboardGroupName, FlowPanel mainPanel) {
|
||||
// create the default leaderboard and select the right race
|
||||
leaderboardPanel = createLeaderboardPanel(leaderboardName, leaderboardGroupName);
|
||||
leaderboardPanel.addStyleName(LeaderboardPanel.LEADERBOARD_MARGIN_STYLE);
|
||||
leaderboardPanel.getElement().getStyle().setMargin(5, Unit.PX);
|
||||
RaceMap raceMap = new RaceMap(sailingService, asyncActionsExecutor, errorReporter, timer, competitorSelectionModel, stringMessages);
|
||||
raceTimesInfoProvider.addRaceTimesInfoProviderListener(raceMap);
|
||||
raceMap.onRaceSelectionChange(Collections.singletonList(selectedRaceIdentifier));
|
||||
@@ -160,10 +156,10 @@ public class RaceBoardPanel extends SimplePanel implements RegattaDisplayer, Rac
|
||||
windChart.onRaceSelectionChange(raceSelectionProvider.getSelectedRaces());
|
||||
components.add(windChart);
|
||||
leaderboardAndMapViewer = new SideBySideComponentViewer(leaderboardPanel, raceMap, components);
|
||||
componentViewers.add(leaderboardAndMapViewer);
|
||||
for (ComponentViewer componentViewer : componentViewers) {
|
||||
mainPanel.add(componentViewer.getViewerWidget());
|
||||
}
|
||||
mainPanel.add(leaderboardAndMapViewer.getViewerWidget());
|
||||
mainPanel.add(windChart);
|
||||
mainPanel.add(competitorChart);
|
||||
|
||||
setLeaderboardVisible(getConfiguration().isShowLeaderboard());
|
||||
setWindChartVisible(getConfiguration().isShowWindChart());
|
||||
setCompetitorChartVisible(getConfiguration().isShowCompetitorsChart());
|
||||
@@ -203,8 +199,7 @@ public class RaceBoardPanel extends SimplePanel implements RegattaDisplayer, Rac
|
||||
.createNewSettingsForPlayMode(timer.getPlayMode(),
|
||||
/* nameOfRaceToSort */ selectedRaceIdentifier.getRaceName(),
|
||||
/* nameOfRaceColumnToShow */ null, /* nameOfRaceToShow */ selectedRaceIdentifier.getRaceName(),
|
||||
new ExplicitRaceColumnSelectionWithPreselectedRace(selectedRaceIdentifier),
|
||||
/* showOverallLeaderboardsOnSamePage */ false);
|
||||
new ExplicitRaceColumnSelectionWithPreselectedRace(selectedRaceIdentifier));
|
||||
return new LeaderboardPanel(sailingService, asyncActionsExecutor, leaderBoardSettings, selectedRaceIdentifier,
|
||||
competitorSelectionModel, timer, leaderboardGroupName, leaderboardName, errorReporter, stringMessages,
|
||||
userAgent, /* showRaceDetails */ true, raceTimesInfoProvider, /* autoExpandLastRaceColumn */ false);
|
||||
@@ -262,51 +257,35 @@ public class RaceBoardPanel extends SimplePanel implements RegattaDisplayer, Rac
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collapsable panel for the leaderboard open or close, if in <code>CASCADE</code> view mode.<br />
|
||||
* Displays or hides the leaderboard, if in <code>ONESCREEN</code> view mode.<br /><br />
|
||||
* Displays or hides the leaderboard.<br /><br />
|
||||
*
|
||||
* The race board should be completely rendered before this method is called, or a few exceptions could be thrown.
|
||||
*
|
||||
* @param visible <code>true</code> if the leaderboard shall be open/visible
|
||||
*/
|
||||
public void setLeaderboardVisible(boolean visible) {
|
||||
switch (getConfiguration().getViewMode()) {
|
||||
case ONESCREEN:
|
||||
setComponentVisible(leaderboardAndMapViewer, leaderboardPanel, visible);
|
||||
break;
|
||||
}
|
||||
setComponentVisible(leaderboardAndMapViewer, leaderboardPanel, visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collapsable panel for the wind chart open or close, if in <code>CASCADE</code> view mode.<br />
|
||||
* Displays or hides the wind chart, if in <code>ONESCREEN</code> view mode.<br /><br />
|
||||
*
|
||||
* Displays or hides the wind chart.<br /><br />
|
||||
* The race board should be completely rendered before this method is called, or a few exceptions could be thrown.
|
||||
*
|
||||
* @param visible <code>true</code> if the wind chart shall be open/visible
|
||||
*/
|
||||
public void setWindChartVisible(boolean visible) {
|
||||
switch (getConfiguration().getViewMode()) {
|
||||
case ONESCREEN:
|
||||
setComponentVisible(leaderboardAndMapViewer, windChart, visible);
|
||||
break;
|
||||
}
|
||||
setComponentVisible(leaderboardAndMapViewer, windChart, visible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the collapsable panel for the competitor chart open or close, if in <code>CASCADE</code> view mode.<br />
|
||||
* Displays or hides the competitor chart, if in <code>ONESCREEN</code> view mode.<br /><br />
|
||||
* Displays or hides the competitor chart.<br /><br />
|
||||
*
|
||||
* The race board should be completely rendered before this method is called, or a few exceptions could be thrown.
|
||||
*
|
||||
* @param visible <code>true</code> if the competitor chart shall be open/visible
|
||||
*/
|
||||
public void setCompetitorChartVisible(boolean visible) {
|
||||
switch (getConfiguration().getViewMode()) {
|
||||
case ONESCREEN:
|
||||
setComponentVisible(leaderboardAndMapViewer, competitorChart, visible);
|
||||
break;
|
||||
}
|
||||
setComponentVisible(leaderboardAndMapViewer, competitorChart, visible);
|
||||
}
|
||||
|
||||
public Widget getNavigationWidget() {
|
||||
|
||||
+86
-29
@@ -76,6 +76,7 @@ import com.sap.sailing.domain.common.CountryCode;
|
||||
import com.sap.sailing.domain.common.DetailType;
|
||||
import com.sap.sailing.domain.common.Distance;
|
||||
import com.sap.sailing.domain.common.LeaderboardNameConstants;
|
||||
import com.sap.sailing.domain.common.LeaderboardType;
|
||||
import com.sap.sailing.domain.common.LegType;
|
||||
import com.sap.sailing.domain.common.ManeuverType;
|
||||
import com.sap.sailing.domain.common.MaxPointsReason;
|
||||
@@ -2143,10 +2144,30 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getLeaderboardNames() throws Exception {
|
||||
public List<String> getLeaderboardNames() {
|
||||
return new ArrayList<String>(getService().getLeaderboards().keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<String, LeaderboardType> checkLeaderboardName(String leaderboardName) {
|
||||
Pair<String, LeaderboardType> result = null;
|
||||
|
||||
if(getService().getLeaderboards().containsKey(leaderboardName)) {
|
||||
Leaderboard leaderboard = getService().getLeaderboards().get(leaderboardName);
|
||||
boolean isMetaLeaderboard = leaderboard instanceof MetaLeaderboard ? true : false;
|
||||
boolean isRegattaLeaderboard = leaderboard instanceof RegattaLeaderboard ? true : false;
|
||||
LeaderboardType type;
|
||||
if(isMetaLeaderboard) {
|
||||
type = isRegattaLeaderboard ? LeaderboardType.RegattaMetaLeaderboard : LeaderboardType.FlexibleMetaLeaderboard;
|
||||
} else {
|
||||
type = isRegattaLeaderboard ? LeaderboardType.RegattaLeaderboard : LeaderboardType.FlexibleLeaderboard;
|
||||
}
|
||||
result = new Pair<String, LeaderboardType>(leaderboard.getName(), type);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StrippedLeaderboardDTO createFlexibleLeaderboard(String leaderboardName, String leaderboardDisplayName, int[] discardThresholds, ScoringSchemeType scoringSchemeType,
|
||||
String courseAreaId) {
|
||||
@@ -2245,15 +2266,14 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
leaderboardDTO.name = leaderboard.getName();
|
||||
leaderboardDTO.displayName = leaderboard.getDisplayName();
|
||||
leaderboardDTO.competitorDisplayNames = new HashMap<CompetitorDTO, String>();
|
||||
leaderboardDTO.isMetaLeaderboard = leaderboard instanceof MetaLeaderboard ? true : false;
|
||||
if (leaderboard instanceof RegattaLeaderboard) {
|
||||
RegattaLeaderboard regattaLeaderboard = (RegattaLeaderboard) leaderboard;
|
||||
Regatta regatta = regattaLeaderboard.getRegatta();
|
||||
leaderboardDTO.regattaName = regatta.getName();
|
||||
leaderboardDTO.isRegattaLeaderboard = true;
|
||||
leaderboardDTO.type = leaderboard instanceof MetaLeaderboard ? LeaderboardType.RegattaMetaLeaderboard : LeaderboardType.RegattaLeaderboard;
|
||||
leaderboardDTO.scoringScheme = regatta.getScoringScheme().getType();
|
||||
} else {
|
||||
leaderboardDTO.isRegattaLeaderboard = false;
|
||||
leaderboardDTO.type = leaderboard instanceof MetaLeaderboard ? LeaderboardType.FlexibleMetaLeaderboard : LeaderboardType.FlexibleLeaderboard;
|
||||
leaderboardDTO.scoringScheme = leaderboard.getScoringScheme().getType();
|
||||
}
|
||||
if (leaderboard.getDefaultCourseArea() != null) {
|
||||
@@ -2806,6 +2826,68 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
return result;
|
||||
}
|
||||
|
||||
private Triple<String, List<CompetitorDTO>, List<Double>> getLeaderboardDataEntriesForRaceColumn(DetailType detailType,
|
||||
LeaderboardDTO leaderboard, RaceColumnDTO raceColumn) throws NoWindException {
|
||||
List<Double> values = new ArrayList<Double>();
|
||||
List<CompetitorDTO> competitorDTOs = new ArrayList<CompetitorDTO>();
|
||||
if(detailType != null) {
|
||||
switch (detailType) {
|
||||
case RACE_TOTAL_POINTS:
|
||||
for (Map.Entry<CompetitorDTO, LeaderboardRowDTO> entry : leaderboard.rows.entrySet()) {
|
||||
LeaderboardEntryDTO leaderboardEntryDTO = entry.getValue().fieldsByRaceColumnName.get(raceColumn.name);
|
||||
values.add(leaderboardEntryDTO != null ? leaderboardEntryDTO.totalPoints : null);
|
||||
competitorDTOs.add(entry.getKey());
|
||||
}
|
||||
|
||||
break;
|
||||
case REGATTA_RANK:
|
||||
List<CompetitorDTO> competitorsFromBestToWorst = leaderboard.getCompetitorsFromBestToWorst(raceColumn);
|
||||
int rank = 1;
|
||||
for(CompetitorDTO competitor: competitorsFromBestToWorst) {
|
||||
values.add(new Double(rank));
|
||||
competitorDTOs.add(competitor);
|
||||
rank++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new Triple<String, List<CompetitorDTO>, List<Double>>(raceColumn.name, competitorDTOs, values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Triple<String, List<CompetitorDTO>, List<Double>>> getLeaderboardDataEntriesForAllRaceColumns(String leaderboardName,
|
||||
Date date, DetailType detailType) throws Exception {
|
||||
List<Triple<String, List<CompetitorDTO>, List<Double>>> result = new ArrayList<Util.Triple<String,List<CompetitorDTO>,List<Double>>>();
|
||||
|
||||
// Attention: The reason why we read the data from the LeaderboardDTO and not from the leaderboard directly is to ensure
|
||||
// the use of the leaderboard cache and the reuse of all the logic in the getLeaderboardByName method
|
||||
LeaderboardDTO leaderboardDTO = getLeaderboardByName(leaderboardName, date, Collections.<String> emptyList());
|
||||
for (RaceColumnDTO raceColumnDTO : leaderboardDTO.getRaceList()) {
|
||||
result.add(getLeaderboardDataEntriesForRaceColumn(detailType, leaderboardDTO, raceColumnDTO));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<String, String>> getLeaderboardsNamesOfMetaleaderboard(String metaLeaderboardName) {
|
||||
Leaderboard leaderboard = getService().getLeaderboardByName(metaLeaderboardName);
|
||||
if (leaderboard == null) {
|
||||
throw new IllegalArgumentException("Couldn't find leaderboard named "+metaLeaderboardName);
|
||||
}
|
||||
if(!(leaderboard instanceof MetaLeaderboard)) {
|
||||
throw new IllegalArgumentException("The leaderboard "+metaLeaderboardName + " is not a metaleaderboard");
|
||||
}
|
||||
List<Pair<String, String>> result = new ArrayList<Pair<String, String>>();
|
||||
MetaLeaderboard metaLeaderboard = (MetaLeaderboard) leaderboard;
|
||||
for(Leaderboard containedLeaderboard: metaLeaderboard.getLeaderboards()) {
|
||||
result.add(new Pair<String, String>(containedLeaderboard.getName(),
|
||||
containedLeaderboard.getDisplayName() != null ? containedLeaderboard.getDisplayName() : containedLeaderboard.getName()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<CompetitorDTO, List<GPSFixDTO>> getDouglasPoints(RegattaAndRaceIdentifier raceIdentifier,
|
||||
Map<CompetitorDTO, Date> from, Map<CompetitorDTO, Date> to,
|
||||
@@ -3357,31 +3439,6 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<String, List<CompetitorDTO>>> getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(String leaderboardName, Date date) throws NoWindException {
|
||||
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
final TimePoint timePoint;
|
||||
if (date == null) {
|
||||
final TimePoint nowMinusDelay = leaderboard.getNowMinusDelay();
|
||||
final TimePoint timePointOfLatestModification = leaderboard.getTimePointOfLatestModification();
|
||||
if (timePointOfLatestModification != null && !nowMinusDelay.before(timePointOfLatestModification)) {
|
||||
timePoint = timePointOfLatestModification;
|
||||
} else {
|
||||
timePoint = nowMinusDelay;
|
||||
}
|
||||
} else {
|
||||
timePoint = new MillisecondsTimePoint(date);
|
||||
}
|
||||
Map<RaceColumn, List<Competitor>> preResult = leaderboard
|
||||
.getRankedCompetitorsFromBestToWorstAfterEachRaceColumn(timePoint);
|
||||
List<Pair<String, List<CompetitorDTO>>> result = new ArrayList<Util.Pair<String,List<CompetitorDTO>>>();
|
||||
for (RaceColumn raceColumn : leaderboard.getRaceColumns()) {
|
||||
List<CompetitorDTO> competitorList = getCompetitorDTOList(preResult.get(raceColumn));
|
||||
result.add(new Pair<String, List<CompetitorDTO>>(raceColumn.getName(), competitorList));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getOverallLeaderboardNamesContaining(String leaderboardName) {
|
||||
Leaderboard leaderboard = getService().getLeaderboardByName(leaderboardName);
|
||||
|
||||
+3
-3
@@ -10,6 +10,7 @@ import java.util.Set;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
import com.sap.sailing.domain.base.RaceColumn;
|
||||
import com.sap.sailing.domain.common.LeaderboardType;
|
||||
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
|
||||
import com.sap.sailing.domain.common.ScoringSchemeType;
|
||||
import com.sap.sailing.domain.common.impl.Util.Pair;
|
||||
@@ -27,8 +28,7 @@ public abstract class AbstractLeaderboardDTO implements IsSerializable {
|
||||
public String defaultCourseAreaIdAsString;
|
||||
public String defaultCourseAreaName;
|
||||
public ScoringSchemeType scoringScheme;
|
||||
public boolean isMetaLeaderboard;
|
||||
public boolean isRegattaLeaderboard;
|
||||
public LeaderboardType type;
|
||||
|
||||
private Long delayToLiveInMillisForLatestRace;
|
||||
|
||||
@@ -329,7 +329,7 @@ public abstract class AbstractLeaderboardDTO implements IsSerializable {
|
||||
return false;
|
||||
if (hasCarriedPoints != other.hasCarriedPoints)
|
||||
return false;
|
||||
if (isMetaLeaderboard != other.isMetaLeaderboard)
|
||||
if (type != other.type)
|
||||
return false;
|
||||
if (scoringScheme != other.scoringScheme)
|
||||
return false;
|
||||
|
||||
+17
-16
@@ -15,12 +15,13 @@ public class LeaderboardGroupDTO extends NamedDTO implements IsSerializable {
|
||||
public String description;
|
||||
public List<StrippedLeaderboardDTO> leaderboards;
|
||||
public boolean displayLeaderboardsInReverseOrder;
|
||||
|
||||
|
||||
private int[] overallLeaderboardDiscardThresholds;
|
||||
private ScoringSchemeType overallLeaderboardScoringSchemeType;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new LeaderboardGroupDTO with empty but non-null name, description and an empty but non-null list for the leaderboards.<br />
|
||||
* Creates a new LeaderboardGroupDTO with empty but non-null name, description and an empty but non-null list for
|
||||
* the leaderboards.<br />
|
||||
* The additional data (start dates and places for the races) will be initialized but empty.
|
||||
*/
|
||||
public LeaderboardGroupDTO() {
|
||||
@@ -37,11 +38,11 @@ public class LeaderboardGroupDTO extends NamedDTO implements IsSerializable {
|
||||
this.description = description;
|
||||
this.leaderboards = leaderboards;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasOverallLeaderboard() {
|
||||
return getOverallLeaderboardScoringSchemeType() != null;
|
||||
}
|
||||
|
||||
|
||||
public int[] getOverallLeaderboardDiscardThresholds() {
|
||||
return overallLeaderboardDiscardThresholds;
|
||||
}
|
||||
@@ -57,17 +58,17 @@ public class LeaderboardGroupDTO extends NamedDTO implements IsSerializable {
|
||||
public void setOverallLeaderboardScoringSchemeType(ScoringSchemeType overallLeaderboardScoringSchemeType) {
|
||||
this.overallLeaderboardScoringSchemeType = overallLeaderboardScoringSchemeType;
|
||||
}
|
||||
|
||||
|
||||
public List<StrippedLeaderboardDTO> getLeaderboardsInReverseOrder() {
|
||||
List<StrippedLeaderboardDTO> leaderboardsInReverseOrder = new ArrayList<StrippedLeaderboardDTO>(leaderboards);
|
||||
Collections.reverse(leaderboardsInReverseOrder);
|
||||
return Collections.unmodifiableList(leaderboardsInReverseOrder);
|
||||
}
|
||||
|
||||
|
||||
public boolean containsRegattaLeaderboard() {
|
||||
boolean result = false;
|
||||
for (StrippedLeaderboardDTO leaderboard : leaderboards) {
|
||||
if(leaderboard.isRegattaLeaderboard) {
|
||||
if (leaderboard.type.isRegattaLeaderboard()) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
@@ -77,8 +78,7 @@ public class LeaderboardGroupDTO extends NamedDTO implements IsSerializable {
|
||||
|
||||
public boolean containsRace(RaceIdentifier race) {
|
||||
boolean containsRace = false;
|
||||
leaderboardsLoop:
|
||||
for (StrippedLeaderboardDTO leaderboard : leaderboards) {
|
||||
leaderboardsLoop: for (StrippedLeaderboardDTO leaderboard : leaderboards) {
|
||||
for (RaceColumnDTO raceInLeaderboard : leaderboard.getRaceList()) {
|
||||
for (FleetDTO fleet : raceInLeaderboard.getFleets()) {
|
||||
final RegattaAndRaceIdentifier raceIdentifierForFleet = raceInLeaderboard.getRaceIdentifier(fleet);
|
||||
@@ -91,9 +91,10 @@ public class LeaderboardGroupDTO extends NamedDTO implements IsSerializable {
|
||||
}
|
||||
return containsRace;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return The earliest date in the start dates of the leaderboards, or <code>null</code> if no start dates are contained
|
||||
* @return The earliest date in the start dates of the leaderboards, or <code>null</code> if no start dates are
|
||||
* contained
|
||||
*/
|
||||
public Date getGroupStartDate() {
|
||||
Date groupStart = null;
|
||||
@@ -108,7 +109,7 @@ public class LeaderboardGroupDTO extends NamedDTO implements IsSerializable {
|
||||
}
|
||||
return groupStart;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Uses {@link LeaderboardGroupDTO#getLeaderboardPlaces(leaderboard) LeaderboardGroupDTO.getLeaderboardPlaces} to
|
||||
* create the {@link PlacemarkOrderDTO places} for all contained leaderboards and returns them as a list.
|
||||
@@ -126,7 +127,7 @@ public class LeaderboardGroupDTO extends NamedDTO implements IsSerializable {
|
||||
}
|
||||
return places;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the group contains a race which is live.
|
||||
*/
|
||||
@@ -138,7 +139,7 @@ public class LeaderboardGroupDTO extends NamedDTO implements IsSerializable {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
@@ -173,5 +174,5 @@ public class LeaderboardGroupDTO extends NamedDTO implements IsSerializable {
|
||||
public List<StrippedLeaderboardDTO> getLeaderboards() {
|
||||
return leaderboards;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+1
-1
@@ -283,7 +283,7 @@ public class LeaderboardGroupPanel extends SimplePanel implements HasWelcomeWidg
|
||||
|
||||
private SafeHtml leaderboardRacesToHtml(StrippedLeaderboardDTO leaderboard) {
|
||||
SafeHtmlBuilder b = new SafeHtmlBuilder();
|
||||
if (leaderboard.isRegattaLeaderboard && leaderboard.regattaName != null) {
|
||||
if (leaderboard.type.isRegattaLeaderboard()) {
|
||||
RegattaDTO regatta = regattasByName.get(leaderboard.regattaName);
|
||||
boolean renderSeriesName = Util.size(regatta.series) > 1;
|
||||
for (SeriesDTO series : regatta.series) {
|
||||
|
||||
+3
-3
@@ -6,6 +6,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.user.client.ui.DockLayoutPanel;
|
||||
import com.google.gwt.user.client.ui.FlowPanel;
|
||||
import com.google.gwt.user.client.ui.ScrollPanel;
|
||||
@@ -94,8 +95,7 @@ public class TVViewController implements RaceTimesInfoProviderListener {
|
||||
|
||||
showWindChart = false;
|
||||
leaderboard = null;
|
||||
leaderboardSettings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, null, /* autoExpandFirstRace */ false,
|
||||
/* showMetaLeaderboardsOnSamePage */ false);
|
||||
leaderboardSettings = LeaderboardSettingsFactory.getInstance().createNewDefaultSettings(null, null, null, /* autoExpandFirstRace */ false);
|
||||
|
||||
leaderboardTimer = new Timer(PlayModes.Live, /* delayBetweenAutoAdvancesInMilliseconds */1000l);
|
||||
leaderboardTimer.setLivePlayDelayInMillis(delayToLiveInMillis);
|
||||
@@ -122,7 +122,7 @@ public class TVViewController implements RaceTimesInfoProviderListener {
|
||||
updateRaceTimesInfoProvider();
|
||||
}
|
||||
};
|
||||
leaderboardPanel.addStyleName(LeaderboardPanel.LEADERBOARD_MARGIN_STYLE);
|
||||
leaderboardPanel.getElement().getStyle().setMargin(5, Unit.PX);
|
||||
return leaderboardPanel;
|
||||
}
|
||||
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
Reference in new issue
Block a user