Merge branch 'master' into bug2851

Conflicts:
	java/com.sap.sailing.domain/src/com/sap/sailing/domain/leaderboard/impl/FlexibleLeaderboardImpl.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingService.java
	java/com.sap.sailing.gwt.ui/src/main/java/com/sap/sailing/gwt/ui/client/SailingServiceAsync.java

Change-Id: Ifd8c60c6f7d2d2274a68681607a1b5df7b4040b7
This commit is contained in:
Axel Uhl committed 2016-01-13 09:39:02 +01:00
commit e6fef6c04f
534 files changed
+14442 -51916

No files matched your search

@@ -25,7 +25,11 @@ Require-Bundle: com.sap.sailing.domain,
com.sap.sse.gwt.adminconsole,
org.apache.commons.math;bundle-version="2.1.0"
Bundle-ActivationPolicy: lazy
Import-Package: org.osgi.framework;version="1.5.0",
Import-Package: com.sap.sse.util,
javax.servlet;version="3.1.0",
javax.servlet.descriptor;version="3.1.0",
javax.servlet.http;version="3.1.0",
org.osgi.framework;version="1.5.0",
org.osgi.util.tracker
Web-ContextPath: /dashboards
Bundle-ClassPath: WEB-INF/classes/,
@@ -18,18 +18,6 @@
</init-param>
</servlet>
<servlet>
<display-name>Rib Dashboard Service</display-name>
<servlet-name>RibDashboardService</servlet-name>
<servlet-class>com.sap.sailing.dashboards.gwt.server.RibDashboardServiceImpl
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RibDashboardService</servlet-name>
<url-pattern>/service/ribdashboard
</url-pattern>
</servlet-mapping>
<servlet>
<display-name>Sailing Service</display-name>
<servlet-name>SailingService</servlet-name>
@@ -39,6 +27,16 @@
<servlet-name>SailingService</servlet-name>
<url-pattern>/service/sailing</url-pattern>
</servlet-mapping>
<servlet>
<display-name>Dispatch Service</display-name>
<servlet-name>DispatchService</servlet-name>
<servlet-class>com.sap.sailing.dashboards.gwt.server.DashboardDispatchRPCServletImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DispatchService</servlet-name>
<url-pattern>/service/dispatch</url-pattern>
</servlet-mapping>
<!-- enabling remote logging -->
<servlet>
@@ -0,0 +1,18 @@
package com.sap.sailing.dashboards.gwt.client;
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardDispatchSystem;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sse.gwt.client.player.Timer;
/**
* @author Alexander Ries (D062114)
*
*/
public interface DashboardClientFactory{
DashboardDispatchSystem getDispatch();
SailingServiceAsync getSailingService();
Timer getDashboardFiveSecondsTimer();
}
@@ -0,0 +1,49 @@
package com.sap.sailing.dashboards.gwt.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardDispatchSystem;
import com.sap.sailing.dashboards.gwt.shared.dispatch.impl.DashboardDispatchSystemImpl;
import com.sap.sailing.gwt.ui.client.SailingService;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sse.gwt.client.EntryPointHelper;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.player.Timer.PlayModes;
/**
* @author Alexander Ries (D062114)
*
*/
public class DashboardClientFactoryImpl implements DashboardClientFactory{
private final DashboardDispatchSystem dispatch;
private final SailingServiceAsync sailingService;
private final Timer dashboardFiveSecondsTimer;
private static final int DASHBOARD_RERFRESH_INTERVAL = 5000;
public DashboardClientFactoryImpl() {
dispatch = new DashboardDispatchSystemImpl();
sailingService = GWT.create(SailingService.class);
EntryPointHelper.registerASyncService((ServiceDefTarget) sailingService, RemoteServiceMappingConstants.WEB_CONTEXT_PATH, RemoteServiceMappingConstants.sailingServiceRemotePath);
dashboardFiveSecondsTimer = new Timer(PlayModes.Live);
dashboardFiveSecondsTimer.setRefreshInterval(DASHBOARD_RERFRESH_INTERVAL);
}
@Override
public DashboardDispatchSystem getDispatch() {
return dispatch;
}
@Override
public SailingServiceAsync getSailingService() {
return sailingService;
}
@Override
public Timer getDashboardFiveSecondsTimer() {
return dashboardFiveSecondsTimer;
}
}
@@ -17,5 +17,5 @@ public interface RemoteServiceMappingConstants {
public static final String WEB_CONTEXT_PATH = "dashboards";
public static final String sailingServiceRemotePath = "service/sailing";
public static final String ribdashboardServiceRemotePath = "service/ribdashboard";
public static final String ribdashboardDispatchServiceRemotePath = "service/dispatch";
}
@@ -1,22 +1,15 @@
package com.sap.sailing.dashboards.gwt.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.googlecode.mgwt.ui.client.MGWT;
import com.googlecode.mgwt.ui.client.MGWTSettings;
import com.googlecode.mgwt.ui.client.MGWTSettings.StatusBarStyle;
import com.googlecode.mgwt.ui.client.MGWTSettings.ViewPort;
import com.googlecode.mgwt.ui.client.MGWTStyle;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetriever;
import com.sap.sailing.dashboards.gwt.client.dashboardpanel.DashboardPanel;
import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetriever;
import com.sap.sailing.gwt.ui.client.SailingService;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.gwt.client.AbstractEntryPoint;
import com.sap.sse.gwt.client.EntryPointHelper;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.player.Timer.PlayModes;
/**
*
@@ -25,28 +18,14 @@ import com.sap.sse.gwt.client.player.Timer.PlayModes;
*/
public class RibDashboardEntryPoint extends AbstractEntryPoint<StringMessages> {
private static final int DASHBOARD_RERFRESH_INTERVAL = 5000;
@Override
public void doOnModuleLoad() {
SailingServiceAsync sailingService = GWT.create(SailingService.class);
EntryPointHelper.registerASyncService((ServiceDefTarget) sailingService, RemoteServiceMappingConstants.WEB_CONTEXT_PATH, RemoteServiceMappingConstants.sailingServiceRemotePath);
RibDashboardServiceAsync ribdashboardService = GWT.create(RibDashboardService.class);
EntryPointHelper.registerASyncService((ServiceDefTarget) ribdashboardService, RemoteServiceMappingConstants.WEB_CONTEXT_PATH, RemoteServiceMappingConstants.ribdashboardServiceRemotePath);
RibDashboardDataRetriever dataRetriever = new RibDashboardDataRetriever(ribdashboardService);
applyMGWTSettings();
RibDashboardPanel ribDashboardPanel = new RibDashboardPanel(ribdashboardService, sailingService, dataRetriever);
RootLayoutPanel.get().add(ribDashboardPanel);
WindBotDataRetriever windBotDataRetriever = new WindBotDataRetriever(ribdashboardService, sailingService);
windBotDataRetriever.addNumberOfWindBotsChangeListeners(ribDashboardPanel);
Timer dashboardTimer = new Timer(PlayModes.Live);
dashboardTimer.setRefreshInterval(DASHBOARD_RERFRESH_INTERVAL);
dashboardTimer.addTimeListener(windBotDataRetriever);
dashboardTimer.addTimeListener(dataRetriever);
DashboardClientFactory dashboardClientFactory = new DashboardClientFactoryImpl();
DashboardPanel rootPanel = new DashboardPanel(dashboardClientFactory);
RootLayoutPanel.get().add(rootPanel);
WindBotDataRetriever windBotDataRetriever = new WindBotDataRetriever(dashboardClientFactory);
windBotDataRetriever.addNumberOfWindBotsChangeListeners(rootPanel);
}
private void applyMGWTSettings() {
@@ -1,47 +0,0 @@
/**
*
*/
package com.sap.sailing.dashboards.gwt.client;
import com.google.gwt.core.shared.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
/**
* @author Alexander Ries
*
*/
public interface RibDashboardImageResources extends ClientBundle {
public static final RibDashboardImageResources INSTANCE = GWT.create(RibDashboardImageResources.class);
@Source("images/logo_sap.png")
ImageResource logo_sap();
@Source("images/logoess.png")
ImageResource logoess();
@Source("images/leftarrow.png")
ImageResource left();
@Source("images/rightarrow.png")
ImageResource right();
@Source("images/leftarrow_disabled.png")
ImageResource leftdisabled();
@Source("images/rightarrow_disabled.png")
ImageResource rightdisabled();
@Source("images/compass.png")
ImageResource compass();
@Source("images/watch.png")
ImageResource watch();
@Source("images/settings.png")
ImageResource settings();
@Source("images/rotatedevice.png")
ImageResource rotatedevice();
}
@@ -1,55 +0,0 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:client="urn:import:com.sap.sailing.dashboards.gwt.client"
xmlns:startlineadvantage="urn:import:com.sap.sailing.dashboards.gwt.client.startlineadvantage"
xmlns:startanalysis="urn:import:com.sap.sailing.dashboards.gwt.client.startanalysis"
xmlns:mgwtcarousel="urn:import:com.googlecode.mgwt.ui.client.widget.carousel"
xmlns:mgwtpanel="urn:import:com.googlecode.mgwt.ui.client.widget.panel">
<ui:style
type='com.sap.sailing.dashboards.gwt.client.RibDashboardPanelStyle' src='resources/Ribstyle.css'></ui:style>
<g:LayoutPanel ui:field="root">
<g:layer left="0%" top="0%" right="0%" height="35pt">
<g:HTMLPanel ui:field="header" styleName="{style.bar}"></g:HTMLPanel>
</g:layer>
<g:layer left="0pt" top="35pt" right="0pt" bottom="0pt">
<mgwtcarousel:Carousel ui:field="carousel">
<mgwtpanel:Panel styleName="{style.page}">
<g:HTMLPanel ui:field="leftwindbotcontainer" styleName="{style.collumn} {style.left}">
<div class="{style.windloadinghint}">
<div ui:field="windloadinghintleft" class="{style.windloadinghinttext}"></div>
</div>
</g:HTMLPanel>
<g:HTMLPanel ui:field="rightwindbotcontainer"
styleName="{style.collumn} {style.right}">
<div class="{style.windloadinghint}">
<div ui:field="windloadinghintright" class="{style.windloadinghinttext}"></div>
</div>
</g:HTMLPanel>
<g:HTMLPanel ui:field="windcharthint" styleName="{style.windcharthint}"></g:HTMLPanel>
</mgwtpanel:Panel>
<mgwtpanel:Panel styleName="{style.page}">
<g:HTMLPanel styleName="{style.collumn} {style.startanalysiscollumn}">
<startanalysis:StartlineAnalysisComponent
ui:field="startanalysisComponent"></startanalysis:StartlineAnalysisComponent>
</g:HTMLPanel>
<g:HTMLPanel styleName="{style.collumn} {style.collumn3}">
<g:HTMLPanel styleName="{style.startline_advantage_by_geometry_container}">
<startlineadvantage:StartLineAdvantageByGeometryComponent ui:field="startlineAdvantageByGeometryComponent"></startlineadvantage:StartLineAdvantageByGeometryComponent>
</g:HTMLPanel>
<g:HTMLPanel styleName="{style.startline_advantage_by_wind_container}">
<startlineadvantage:StartlineAdvantagesByWindComponent
ui:field="startlineAdvantagesByWindComponent"></startlineadvantage:StartlineAdvantagesByWindComponent>
</g:HTMLPanel>
</g:HTMLPanel>
</mgwtpanel:Panel>
</mgwtcarousel:Carousel>
</g:layer>
<g:layer left="0%" bottom="0%" right="0%" height="30pt">
<g:HTMLPanel ui:field="bottombar" styleName="{style.bar}">
</g:HTMLPanel>
</g:layer>
</g:LayoutPanel>
</ui:UiBinder>
@@ -1,8 +0,0 @@
package com.sap.sailing.dashboards.gwt.client;
import com.google.gwt.resources.client.CssResource;
public interface RibDashboardPanelStyle extends CssResource {
String logo();
String start();
}
@@ -1,23 +0,0 @@
package com.sap.sailing.dashboards.gwt.client;
import java.util.List;
import com.google.gwt.user.client.rpc.RemoteService;
import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO;
import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.dto.CompetitorDTO;
public interface RibDashboardService extends RemoteService {
RibDashboardRaceInfoDTO getLiveRaceInfo(String leaderboardName) throws NoWindException;
RegattaAndRaceIdentifier getIDFromRaceThatTakesWindFixesNow(String leaderboardName);
List<StartAnalysisDTO> getStartAnalysisListForCompetitorIDAndLeaderboardName(String competitorIdAsString, String leaderboardName);
List<CompetitorDTO> getCompetitorsInLeaderboard(String leaderboardName);
StartlineAdvantagesWithMaxAndAverageDTO getAdvantagesOnStartline(String leaderboardName);
}
@@ -1,24 +0,0 @@
package com.sap.sailing.dashboards.gwt.client;
import java.util.List;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO;
import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.dto.CompetitorDTO;
public interface RibDashboardServiceAsync {
void getLiveRaceInfo(String leaderboardName, AsyncCallback<RibDashboardRaceInfoDTO> callback);
void getStartAnalysisListForCompetitorIDAndLeaderboardName(String competitorIdAsString, String leaderboardName, AsyncCallback<List<StartAnalysisDTO>> callback);
void getCompetitorsInLeaderboard(String leaderboardName, AsyncCallback<List<CompetitorDTO>> callback);
void getAdvantagesOnStartline(String leaderboardName, AsyncCallback<StartlineAdvantagesWithMaxAndAverageDTO> callback);
void getIDFromRaceThatTakesWindFixesNow(String leaderboardName, AsyncCallback<RegattaAndRaceIdentifier> callback);
}
@@ -0,0 +1,35 @@
package com.sap.sailing.dashboards.gwt.client.actions;
import com.google.gwt.core.shared.GwtIncompatible;
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardAction;
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardDispatchContext;
import com.sap.sailing.dashboards.gwt.shared.dto.LeaderboardCompetitorsDTO;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.gwt.dispatch.client.exceptions.DispatchException;
import com.sap.sse.common.impl.MillisecondsTimePoint;
/**
* @author Alexander Ries (D062114)
*
*/
public class GetCompetitorInLeaderboardAction implements DashboardAction<LeaderboardCompetitorsDTO> {
private String leaderboarName;
@SuppressWarnings("unused")
private GetCompetitorInLeaderboardAction() {
}
public GetCompetitorInLeaderboardAction(String leaderboardName) {
this.leaderboarName = leaderboardName;
}
@Override
@GwtIncompatible
public LeaderboardCompetitorsDTO execute(DashboardDispatchContext dashboardDispatchContext) throws DispatchException {
LeaderboardCompetitorsDTO result = new LeaderboardCompetitorsDTO();
Leaderboard lb = dashboardDispatchContext.getRacingEventService().getLeaderboardByName(this.leaderboarName);
result.setCompetitors(dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorDTOList(lb.getCompetitorsFromBestToWorst(MillisecondsTimePoint.now())));
return result;
}
}
@@ -0,0 +1,32 @@
package com.sap.sailing.dashboards.gwt.client.actions;
import com.google.gwt.core.shared.GwtIncompatible;
import com.sap.sailing.dashboards.gwt.shared.dispatch.RequiresLiveRaceAction;
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardDispatchContext;
import com.sap.sailing.dashboards.gwt.shared.dto.RaceIdDTO;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.gwt.dispatch.client.exceptions.DispatchException;
/**
* @author Alexander Ries (D062114)
*
*/
public class GetIDFromRaceThatIsLiveAction extends RequiresLiveRaceAction<RaceIdDTO> {
public GetIDFromRaceThatIsLiveAction() {}
public GetIDFromRaceThatIsLiveAction(String leaderboardName) {
super(leaderboardName);
}
@Override
@GwtIncompatible
public RaceIdDTO execute(DashboardDispatchContext dashboardDispatchContext) throws DispatchException {
RaceIdDTO result = new RaceIdDTO();
TrackedRace liveRace = super.getLiveRace(dashboardDispatchContext);
if (liveRace != null) {
result.setRaceId(liveRace.getRaceIdentifier());
}
return result;
}
}
@@ -1,26 +1,47 @@
package com.sap.sailing.dashboards.gwt.client.actions;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sse.gwt.client.async.AsyncAction;
import com.google.gwt.core.shared.GwtIncompatible;
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardAction;
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardDispatchContext;
import com.sap.sailing.dashboards.gwt.shared.dto.RaceIdDTO;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.gwt.dispatch.client.exceptions.DispatchException;
import com.sap.sse.common.impl.MillisecondsTimePoint;
/**
* @author Alexander Ries (D062114)
*
*/
public class GetIDFromRaceThatTakesWindFixesNowAction implements AsyncAction<RegattaAndRaceIdentifier> {
public class GetIDFromRaceThatTakesWindFixesNowAction implements DashboardAction<RaceIdDTO> {
private final RibDashboardServiceAsync ribDashboardService;
private final String leaderboardName;
private String leaderboardName;
public GetIDFromRaceThatTakesWindFixesNowAction(RibDashboardServiceAsync ribDashboardService, String leaderboardName) {
this.ribDashboardService = ribDashboardService;
@SuppressWarnings("unused")
private GetIDFromRaceThatTakesWindFixesNowAction() {
}
public GetIDFromRaceThatTakesWindFixesNowAction(String leaderboardName) {
this.leaderboardName = leaderboardName;
}
@Override
public void execute(AsyncCallback<RegattaAndRaceIdentifier> callback) {
ribDashboardService.getIDFromRaceThatTakesWindFixesNow(leaderboardName, callback);
@GwtIncompatible
public RaceIdDTO execute(DashboardDispatchContext dashboardDispatchContext) throws DispatchException {
RaceIdDTO result = new RaceIdDTO();
Leaderboard leaderboard = dashboardDispatchContext.getRacingEventService().getLeaderboardByName(this.leaderboardName);
if (leaderboard != null) {
for (RaceColumn column : leaderboard.getRaceColumns()) {
for (Fleet fleet : column.getFleets()) {
TrackedRace race = column.getTrackedRace(fleet);
if (race != null && race.takesWindFixWithTimePoint(MillisecondsTimePoint.now())) {
result.setRaceId(race.getRaceIdentifier());
}
}
}
}
return result;
}
}
@@ -1,22 +0,0 @@
package com.sap.sailing.dashboards.gwt.client.actions;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync;
import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
import com.sap.sse.gwt.client.async.AsyncAction;
public class GetRibDashboardRaceInfoAction implements AsyncAction<RibDashboardRaceInfoDTO> {
private final RibDashboardServiceAsync ribDashboardService;
private final String leaderboardName;
public GetRibDashboardRaceInfoAction(RibDashboardServiceAsync ribDashboardService, String leaderboardName) {
this.ribDashboardService = ribDashboardService;
this.leaderboardName = leaderboardName;
}
@Override
public void execute(AsyncCallback<RibDashboardRaceInfoDTO> callback) {
ribDashboardService.getLiveRaceInfo(leaderboardName, callback);
}
}
@@ -0,0 +1,68 @@
package com.sap.sailing.dashboards.gwt.client.actions;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.shared.GwtIncompatible;
import com.sap.sailing.dashboards.gwt.server.util.actions.startanalysis.StartAnalysisCreationController;
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardAction;
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardDispatchContext;
import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysesDTO;
import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisDTO;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.base.Fleet;
import com.sap.sailing.domain.base.RaceColumn;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.gwt.dispatch.client.exceptions.DispatchException;
/**
* @author Alexander Ries (D062114)
*
*/
public class GetStartAnalysesAction implements DashboardAction<StartAnalysesDTO> {
private String leaderboarName;
private String competitorIdAsString;
@SuppressWarnings("unused")
private GetStartAnalysesAction() {
}
public GetStartAnalysesAction(String leaderboardName, String competitorIdAsString) {
this.leaderboarName = leaderboardName;
this.competitorIdAsString = competitorIdAsString;
}
@Override
@GwtIncompatible
public StartAnalysesDTO execute(DashboardDispatchContext dashboardDispatchContext) throws DispatchException {
StartAnalysesDTO result = new StartAnalysesDTO();
List<StartAnalysisDTO> startanalyses = new ArrayList<StartAnalysisDTO>();
if (competitorIdAsString != null && leaderboarName != null) {
try {
Competitor competitor = dashboardDispatchContext.getRacingEventService().getBaseDomainFactory().getCompetitorStore().getExistingCompetitorByIdAsString(
competitorIdAsString);
Leaderboard leaderboard = dashboardDispatchContext.getRacingEventService().getLeaderboardByName(this.leaderboarName);
if (leaderboard != null) {
for (RaceColumn column : leaderboard.getRaceColumns()) {
for (Fleet fleet : column.getFleets()) {
TrackedRace race = column.getTrackedRace(fleet);
if (race != null) {
StartAnalysisDTO startAnalysisDTO = StartAnalysisCreationController.checkStartAnalysisForCompetitorInTrackedRace(dashboardDispatchContext, competitor, race);
if (startAnalysisDTO != null) {
startanalyses.add(startAnalysisDTO);
}
}
}
}
}
} catch (NullPointerException e) {
// logger.log(Level.INFO, "", e);
}
}
result.setStartAnalyses(startanalyses);
return result;
}
}
@@ -0,0 +1,48 @@
package com.sap.sailing.dashboards.gwt.client.actions;
import com.google.gwt.core.shared.GwtIncompatible;
import com.sap.sailing.dashboards.gwt.server.util.actions.startlineadvantage.StartlineAdvantageByGeometryCalculator;
import com.sap.sailing.dashboards.gwt.shared.StartlineAdvantageType;
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardDispatchContext;
import com.sap.sailing.dashboards.gwt.shared.dispatch.RequiresLiveRaceAndCachesMovingAverageAction;
import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.gwt.dispatch.client.exceptions.DispatchException;
/**
* @author Alexander Ries (D062114)
*
*/
public class GetStartlineAdvantageByGeometryAction extends RequiresLiveRaceAndCachesMovingAverageAction<StartLineAdvantageDTO> {
public GetStartlineAdvantageByGeometryAction() {}
public GetStartlineAdvantageByGeometryAction(String leaderboardName) {
super(leaderboardName);
}
@Override
@GwtIncompatible
public StartLineAdvantageDTO execute(DashboardDispatchContext dashboardDispatchContext) throws DispatchException {
StartLineAdvantageDTO result = new StartLineAdvantageDTO();
Double startlineAdvantageByGeometry = null;
TrackedRace liveRace = super.getLiveRace(dashboardDispatchContext);
if (liveRace != null) {
startlineAdvantageByGeometry = StartlineAdvantageByGeometryCalculator.calculateStartlineAdvantageByGeometry(liveRace);
}
result.startLineAdvatageType = StartlineAdvantageType.GEOMETRIC;
result.startLineAdvantage = startlineAdvantageByGeometry;
Double average = null;
if (startlineAdvantageByGeometry != null) {
super.addValueToMovingAverage(startlineAdvantageByGeometry.doubleValue(), dashboardDispatchContext.getMovingAveragesCache());
average = dashboardDispatchContext.getMovingAveragesCache().getValueForKey(getKeyForMovingAverage());
}
result.average = average;
return result;
}
@Override
protected String getKeyForMovingAverage() {
return super.getLeaderboardName();
}
}
@@ -1,26 +0,0 @@
package com.sap.sailing.dashboards.gwt.client.actions;
/**
* @author Alexander Ries (D062114)
*
*/
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync;
import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO;
import com.sap.sse.gwt.client.async.AsyncAction;
public class GetStartlineAdvantagesAction implements AsyncAction<StartlineAdvantagesWithMaxAndAverageDTO> {
private final RibDashboardServiceAsync ribDashboardService;
private final String leaderboardName;
public GetStartlineAdvantagesAction(RibDashboardServiceAsync ribDashboardService, String leaderboardName) {
this.ribDashboardService = ribDashboardService;
this.leaderboardName = leaderboardName;
}
@Override
public void execute(AsyncCallback<StartlineAdvantagesWithMaxAndAverageDTO> callback) {
ribDashboardService.getAdvantagesOnStartline(leaderboardName, callback);
}}
@@ -0,0 +1,45 @@
package com.sap.sailing.dashboards.gwt.client.actions;
/**
* @author Alexander Ries (D062114)
*
*/
import com.google.gwt.core.shared.GwtIncompatible;
import com.sap.sailing.dashboards.gwt.server.util.actions.startlineadvantage.StartlineAdvantagesByWindCalculator;
import com.sap.sailing.dashboards.gwt.shared.dispatch.DashboardDispatchContext;
import com.sap.sailing.dashboards.gwt.shared.dispatch.RequiresLiveRaceAndCachesMovingAverageAction;
import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.gwt.dispatch.client.exceptions.DispatchException;
import com.sap.sse.common.impl.MillisecondsTimePoint;
public class GetStartlineAdvantagesByWindAction extends RequiresLiveRaceAndCachesMovingAverageAction<StartlineAdvantagesWithMaxAndAverageDTO> {
public GetStartlineAdvantagesByWindAction() {}
public GetStartlineAdvantagesByWindAction(String leaderboardName) {
super(leaderboardName);
}
@Override
@GwtIncompatible
public StartlineAdvantagesWithMaxAndAverageDTO execute(DashboardDispatchContext dashboardDispatchContext) throws DispatchException {
StartlineAdvantagesWithMaxAndAverageDTO result = new StartlineAdvantagesWithMaxAndAverageDTO();
TrackedRace liveRace = super.getLiveRace(dashboardDispatchContext);
if (liveRace != null) {
StartlineAdvantagesByWindCalculator startlineAdvantagesByWindCalculator = new StartlineAdvantagesByWindCalculator(dashboardDispatchContext);
result = startlineAdvantagesByWindCalculator.getStartLineAdvantagesAccrossLineFromTrackedRaceAtTimePoint(liveRace, MillisecondsTimePoint.now());
}
if(result != null && result.maximum != null) {
super.addValueToMovingAverage(result.maximum, dashboardDispatchContext.getMovingAveragesCache());
result.average = dashboardDispatchContext.getMovingAveragesCache().getValueForKey(getKeyForMovingAverage());
}
return result;
}
@Override
protected String getKeyForMovingAverage() {
return super.getLeaderboardName();
}
}
@@ -0,0 +1,118 @@
@require 'theme';
.bar {
height: 100%;
margin-top: 20pt;
line-height: 15pt;
vertical-align: middle;
font-size: 15pt;
font-family: DASHBOARD_FONT_FAMILY;
width: 100%;
text-align: center;
font-weight: bold;
overflow: visible;
}
.page {
position: absolute;
border: none;
border-radius: 0;
left: 0;
right: 0;
top: 0;
bottom: 30pt;
margin: 5pt;
}
.logo {
position: absolute;
width: 48pt;
height: 23.5pt;
margin-top: 17.5pt;
margin-left: 10pt;
z-index: 1;
}
.collumn {
position: absolute;
top: 5pt;
bottom: 15pt;
margin: 5pt;
}
.startanalysiscollumn {
right: 33.3%;
left: 0%;
}
.collumnthree {
left: 66.8%;
right: 0pt;
}
.left {
left: 0pt;
right: 50%;
}
.right {
left: 50%;
right: 0pt;
}
.startline_advantage_by_wind_container {
position: absolute;
background-color: white;
top: 27%;
right: 0pt;
left: 0pt;
bottom: 0%;
}
.startline_advantage_by_geometry_container {
position: absolute;
background-color: white;
top: 0%;
right: 0pt;
left: 0pt;
bottom: 73%;
margin-bottom: 10pt;
}
.windcharthint {
position: absolute;
bottom: 0pt;
height: 15pt;
line-height: 15pt;
margin-top: 0pt;
vertical-align: middle;
font-size: 12pt;
font-family: DASHBOARD_FONT_FAMILY;
width: 100%;
text-align: center;
}
.windloadinghint {
position: absolute;
background-color: white;
opacity: 0.4;
width: 100%;
height: 100%;
vertical-align: middle;
text-align: center;
z-index: 0;
}
.windloadinghinttext {
position: absolute;
bottom: 0pt;
height: 15pt;
line-height: 15pt;
margin-top: 0pt;
vertical-align: middle;
font-size: 12pt;
font-family: DASHBOARD_FONT_FAMILY;
width: 100%;
text-align: center;
top: 50%;
}
@@ -1,6 +1,7 @@
package com.sap.sailing.dashboards.gwt.client;
package com.sap.sailing.dashboards.gwt.client.dashboardpanel;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -10,24 +11,26 @@ import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.Widget;
import com.googlecode.mgwt.ui.client.widget.carousel.Carousel;
import com.sap.sailing.dashboards.gwt.client.DashboardClientFactory;
import com.sap.sailing.dashboards.gwt.client.actions.GetIDFromRaceThatIsLiveAction;
import com.sap.sailing.dashboards.gwt.client.dataretriever.NumberOfWindBotsChangeListener;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetriever;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetrieverListener;
import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetrieverProvider;
import com.sap.sailing.dashboards.gwt.client.eventlogo.EventLogo;
import com.sap.sailing.dashboards.gwt.client.notifications.WrongDeviceOrientationNotification;
import com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAnalysisComponent;
import com.sap.sailing.dashboards.gwt.client.startlineadvantage.StartLineAdvantageByGeometryComponent;
import com.sap.sailing.dashboards.gwt.client.startlineadvantage.StartlineAdvantagesByWindComponent;
import com.sap.sailing.dashboards.gwt.client.windchart.WindBotComponent;
import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
import com.sap.sailing.dashboards.gwt.client.notifications.orientation.WrongDeviceOrientationNotification;
import com.sap.sailing.dashboards.gwt.client.widgets.PollsLiveDataEvery5Seconds;
import com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.StartAnalysisWidget;
import com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.course.StartLineAdvantageByGeometryWidget;
import com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.wind.StartlineAdvantagesByWindWidget;
import com.sap.sailing.dashboards.gwt.client.widgets.windbot.WindBotWidget;
import com.sap.sailing.dashboards.gwt.shared.DashboardURLParameters;
import com.sap.sailing.dashboards.gwt.shared.dto.RaceIdDTO;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.client.StringMessages;
@@ -38,17 +41,12 @@ import com.sap.sailing.gwt.ui.client.StringMessages;
* @author Alexander Ries
*
*/
public class RibDashboardPanel extends Composite implements RibDashboardDataRetrieverListener,
NumberOfWindBotsChangeListener {
public class DashboardPanel extends Composite implements NumberOfWindBotsChangeListener, PollsLiveDataEvery5Seconds {
interface RootUiBinder extends UiBinder<Widget, RibDashboardPanel> {
}
interface RootUiBinder extends UiBinder<Widget, DashboardPanel> {}
private static RootUiBinder uiBinder = GWT.create(RootUiBinder.class);
@UiField
RibDashboardPanelStyle style;
@UiField
LayoutPanel root;
@@ -65,7 +63,7 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr
HTMLPanel rightwindbotcontainer;
@UiField(provided = true)
StartlineAdvantagesByWindComponent startlineAdvantagesByWindComponent;
StartlineAdvantagesByWindWidget startlineAdvantagesByWindComponent;
@UiField
public DivElement windloadinghintleft;
@@ -80,41 +78,43 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr
public HTMLPanel windcharthint;
@UiField(provided = true)
public StartlineAnalysisComponent startanalysisComponent;
public StartAnalysisWidget startanalysisComponent;
@UiField(provided = true)
public StartLineAdvantageByGeometryComponent startlineAdvantageByGeometryComponent;
public StartLineAdvantageByGeometryWidget startlineAdvantageByGeometryComponent;
private List<WindBotComponent> windBotComponents;
private List<WindBotWidget> windBotComponents;
private StringMessages stringConstants;
private final String EVENT_ID_PARAMETER = "eventId";
private static final Logger logger = Logger.getLogger(RibDashboardPanel.class.getName());
DashboardClientFactory dashboardClientFactory;
private static final Logger logger = Logger.getLogger(DashboardPanel.class.getName());
public RibDashboardPanel(RibDashboardServiceAsync ribDashboardService, SailingServiceAsync sailingServiceAsync, RibDashboardDataRetriever ribDashboardDataRetriever) {
windBotComponents = new ArrayList<WindBotComponent>();
ribDashboardDataRetriever.addDataObserver(this);
startanalysisComponent = new StartlineAnalysisComponent(ribDashboardService, sailingServiceAsync);
startlineAdvantagesByWindComponent = new StartlineAdvantagesByWindComponent(ribDashboardService);
startlineAdvantageByGeometryComponent = new StartLineAdvantageByGeometryComponent(ribDashboardDataRetriever);
public DashboardPanel(DashboardClientFactory dashboardClientFactory) {
DashboardPanelResources.INSTANCE.style().ensureInjected();
this.dashboardClientFactory = dashboardClientFactory;
windBotComponents = new ArrayList<WindBotWidget>();
startanalysisComponent = new StartAnalysisWidget(this.dashboardClientFactory);
startlineAdvantagesByWindComponent = new StartlineAdvantagesByWindWidget(this.dashboardClientFactory);
startlineAdvantageByGeometryComponent = new StartLineAdvantageByGeometryWidget(this.dashboardClientFactory);
stringConstants = StringMessages.INSTANCE;
initWidget(uiBinder.createAndBindUi(this));
initLogos();
windcharthint.getElement().setInnerText(stringConstants.dashboardWindChartHint());
windloadinghintleft.setInnerHTML(stringConstants.dashboardWindBotLoadingText()+"<br>"+stringConstants.dashboardWindBotLoadingMessage());
windloadinghintright.setInnerHTML(stringConstants.dashboardWindBotLoadingText()+"<br>"+stringConstants.dashboardWindBotLoadingMessage());
loadAndAddEventLogo(sailingServiceAsync);
loadAndAddEventLogo(dashboardClientFactory.getSailingService());
initAndAddWrongOrientationNotification();
registerForDashboardFiveSecondsTimer(dashboardClientFactory);
}
private void initLogos() {
Image logo = new Image();
logo.setResource(RibDashboardImageResources.INSTANCE.logo_sap());
logo.getElement().addClassName(style.logo());
logo.setResource(DashboardPanelResources.INSTANCE.logo_sap());
logo.getElement().addClassName(DashboardPanelResources.INSTANCE.style().logo());
Document.get().getBody().appendChild(logo.getElement());
}
private void loadAndAddEventLogo(SailingServiceAsync sailingServiceAsync){
String eventId = Window.Location.getParameter(EVENT_ID_PARAMETER);
String eventId = DashboardURLParameters.EVENT_ID.getValue();
if (eventId != null) {
EventLogo eventLogo = EventLogo.getEventLogoFromEventId(sailingServiceAsync, eventId);
if (eventLogo != null) {
@@ -136,12 +136,12 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr
windBotComponents.clear();
for (String windBotID : windBotIDs) {
if (windBotAddedCounterTOConsiderForPanels == 0) {
WindBotComponent leftwindBotComponent = new WindBotComponent(windBotID);
WindBotWidget leftwindBotComponent = new WindBotWidget(windBotID);
leftwindbotcontainer.add(leftwindBotComponent);
windBotComponents.add(leftwindBotComponent);
windloadinghintleft.getStyle().setOpacity(0.0);
} else if (windBotAddedCounterTOConsiderForPanels == 1) {
WindBotComponent rightwindBotComponent = new WindBotComponent(windBotID);
WindBotWidget rightwindBotComponent = new WindBotWidget(windBotID);
rightwindbotcontainer.add(rightwindBotComponent);
windBotComponents.add(rightwindBotComponent);
windloadinghintright.getStyle().setOpacity(0.0);
@@ -157,7 +157,7 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr
}
private void addWindBotComponentsAsDataRetrieverListener(WindBotDataRetrieverProvider windBotDataRetrieverProvider) {
for (WindBotComponent windBotComponent : windBotComponents) {
for (WindBotWidget windBotComponent : windBotComponents) {
logger.log(Level.INFO, "Registering WindBotDataRetrieverListener");
windBotDataRetrieverProvider.addWindBotDataRetrieverListener(windBotComponent);
}
@@ -165,19 +165,47 @@ public class RibDashboardPanel extends Composite implements RibDashboardDataRetr
private void removeWindBotComponentsAsDataRetrieverListener(
WindBotDataRetrieverProvider windBotDataRetrieverProvider) {
for (WindBotComponent windBotComponent : windBotComponents) {
for (WindBotWidget windBotComponent : windBotComponents) {
windBotDataRetrieverProvider.removeWindBotDataRetrieverListener(windBotComponent);
}
}
private void setHeaderText(String raceName) {
this.header.getElement().setInnerText(raceName);
}
@Override
public void updateUIWithNewLiveRaceInfo(RibDashboardRaceInfoDTO liveRaceInfoDTO) {
if (liveRaceInfoDTO != null && liveRaceInfoDTO.idOfLastTrackedRace != null) {
logger.log(Level.INFO, "Updating UI with RibDashboardRaceInfoDTO race name");
this.header.getElement().setInnerText(liveRaceInfoDTO.idOfLastTrackedRace.getRaceName());
public void timeChanged(Date newTime, Date oldTime) {
String leaderboardNameParameterValue = DashboardURLParameters.LEADERBOARD_NAME.getValue();
if (leaderboardNameParameterValue != null) {
dashboardClientFactory.getDispatch().execute(
new GetIDFromRaceThatIsLiveAction(leaderboardNameParameterValue), new AsyncCallback<RaceIdDTO>() {
@Override
public void onSuccess(RaceIdDTO result) {
if (result != null && result.getRaceId() != null) {
logger.log(Level.INFO, "Updating UI with live race id");
setHeaderText(result.getRaceId().getRaceName());
} else {
logger.log(Level.INFO, "Received null for live race id");
}
}
@Override
public void onFailure(Throwable caught) {
logger.log(Level.INFO, "Failed to received live race id" + caught.getMessage());
}
});
}
}
@Override
public void registerForDashboardFiveSecondsTimer(DashboardClientFactory dashboardClientFactory) {
if (dashboardClientFactory != null) {
dashboardClientFactory.getDashboardFiveSecondsTimer().addTimeListener(this);
}
}
@Override
public void numberOfWindBotsReceivedChanged(List<String> windBotIDs,
WindBotDataRetrieverProvider windBotDataRetrieverProvider) {
@@ -0,0 +1,55 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:client="urn:import:com.sap.sailing.dashboards.gwt.client"
xmlns:startlineadvantagegeometry="urn:import:com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.course"
xmlns:startlineadvantagewind="urn:import:com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.wind"
xmlns:startanalysis="urn:import:com.sap.sailing.dashboards.gwt.client.widgets.startanalysis"
xmlns:mgwtcarousel="urn:import:com.googlecode.mgwt.ui.client.widget.carousel"
xmlns:mgwtpanel="urn:import:com.googlecode.mgwt.ui.client.widget.panel">
<ui:with field="resources" type="com.sap.sailing.dashboards.gwt.client.dashboardpanel.DashboardPanelResources"/>
<g:LayoutPanel ui:field="root">
<g:layer left="0%" top="0%" right="0%" height="35pt">
<g:HTMLPanel ui:field="header" styleName="{resources.style.bar}"></g:HTMLPanel>
</g:layer>
<g:layer left="0pt" top="35pt" right="0pt" bottom="0pt">
<mgwtcarousel:Carousel ui:field="carousel">
<mgwtpanel:Panel styleName="{resources.style.page}">
<g:HTMLPanel ui:field="leftwindbotcontainer" styleName="{resources.style.collumn} {resources.style.left}">
<div class="{resources.style.windloadinghint}">
<div ui:field="windloadinghintleft" class="{resources.style.windloadinghinttext}"></div>
</div>
</g:HTMLPanel>
<g:HTMLPanel ui:field="rightwindbotcontainer"
styleName="{resources.style.collumn} {resources.style.right}">
<div class="{resources.style.windloadinghint}">
<div ui:field="windloadinghintright" class="{resources.style.windloadinghinttext}"></div>
</div>
</g:HTMLPanel>
<g:HTMLPanel ui:field="windcharthint" styleName="{resources.style.windcharthint}"></g:HTMLPanel>
</mgwtpanel:Panel>
<mgwtpanel:Panel styleName="{resources.style.page}">
<g:HTMLPanel styleName="{resources.style.collumn} {resources.style.startanalysiscollumn}">
<startanalysis:StartAnalysisWidget
ui:field="startanalysisComponent"></startanalysis:StartAnalysisWidget>
</g:HTMLPanel>
<g:HTMLPanel styleName="{resources.style.collumn} {resources.style.collumnthree}">
<g:HTMLPanel styleName="{resources.style.startline_advantage_by_geometry_container}">
<startlineadvantagegeometry:StartLineAdvantageByGeometryWidget ui:field="startlineAdvantageByGeometryComponent"></startlineadvantagegeometry:StartLineAdvantageByGeometryWidget>
</g:HTMLPanel>
<g:HTMLPanel styleName="{resources.style.startline_advantage_by_wind_container}">
<startlineadvantagewind:StartlineAdvantagesByWindWidget
ui:field="startlineAdvantagesByWindComponent"></startlineadvantagewind:StartlineAdvantagesByWindWidget>
</g:HTMLPanel>
</g:HTMLPanel>
</mgwtpanel:Panel>
</mgwtcarousel:Carousel>
</g:layer>
<g:layer left="0%" bottom="0%" right="0%" height="30pt">
<g:HTMLPanel ui:field="bottombar" styleName="{resources.style.bar}">
</g:HTMLPanel>
</g:layer>
</g:LayoutPanel>
</ui:UiBinder>
@@ -0,0 +1,40 @@
package com.sap.sailing.dashboards.gwt.client.dashboardpanel;
/**
* @author Alexander Ries (D062114)
*
*/
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.ImageResource;
public interface DashboardPanelResources extends ClientBundle {
public static final DashboardPanelResources INSTANCE = GWT.create(DashboardPanelResources.class);
@Source("com/sap/sailing/dashboards/gwt/client/images/logo_sap.png")
ImageResource logo_sap();
@Source("com/sap/sailing/dashboards/gwt/client/images/settings.png")
ImageResource settings();
@Source({"com/sap/sailing/dashboards/gwt/client/theme/theme.gss", "DashboardPanel.gss"})
DashboardGSS style();
public interface DashboardGSS extends CssResource {
String bar();
String page();
String collumn();
String startanalysiscollumn();
String collumnthree();
String logo();
String right();
String left();
String startline_advantage_by_wind_container();
String startline_advantage_by_geometry_container();
String windcharthint();
String windloadinghint();
String windloadinghinttext();
}
}
@@ -1,167 +0,0 @@
package com.sap.sailing.dashboards.gwt.client.dataretriever;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync;
import com.sap.sailing.dashboards.gwt.client.actions.GetRibDashboardRaceInfoAction;
import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.gwt.ui.client.RaceSelectionChangeListener;
import com.sap.sailing.gwt.ui.client.RaceSelectionProvider;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.TimeListener;
/**
* Class calls method {@link #requestLiveRaceInfoFromRibDashboadService()) to retrieve new
* data for the dashboard widgets on a regularly basis.
* The request interval is 5 seconds.
*
* @author Alexander Ries
*
*/
public class RibDashboardDataRetriever implements TimeListener, RaceSelectionProvider {
private String leaderboardName;
private ArrayList<RibDashboardDataRetrieverListener> dataRetrieverListener;
private ArrayList<RaceSelectionChangeListener> raceSelectionChangeListener;
private AsyncActionsExecutor asyncActionsExecutor;
private final RibDashboardServiceAsync ribDashboardService;
private final Object MUTEX;
private static final String PARAM_LEADERBOARD_NAME = "leaderboardName";
private static final Logger logger = Logger.getLogger(RibDashboardDataRetriever.class.getName());
public RibDashboardDataRetriever(RibDashboardServiceAsync ribDashboardService) {
initNonFinalMemberVariablesWithNoArgumentConstructor();
MUTEX = new Object();
this.ribDashboardService = ribDashboardService;
this.leaderboardName = Window.Location.getParameter(PARAM_LEADERBOARD_NAME);
asyncActionsExecutor = new AsyncActionsExecutor();
}
private void initNonFinalMemberVariablesWithNoArgumentConstructor() {
dataRetrieverListener = new ArrayList<RibDashboardDataRetrieverListener>();
raceSelectionChangeListener = new ArrayList<RaceSelectionChangeListener>();
}
private void loadLiveRaceInfoFromRibDashboadService() {
GetRibDashboardRaceInfoAction getRibDashboardRaceInfoAction = new GetRibDashboardRaceInfoAction(ribDashboardService, leaderboardName);
logger.log(Level.INFO, "Executing GetRibDashboardRaceInfoAction");
asyncActionsExecutor.execute(getRibDashboardRaceInfoAction, new AsyncCallback<RibDashboardRaceInfoDTO>() {
@Override
public void onSuccess(RibDashboardRaceInfoDTO result) {
logger.log(Level.INFO, "Received RibDashboardRaceInfoDTO");
if (result != null) {
switch (result.responseMessage) {
case RACE_LIVE:
logger.log(Level.INFO, "RibDashboardRaceInfoDTO.responseMessage is RACE_LIVE");
if(result.idOfLastTrackedRace != null) {
logger.log(Level.INFO, "RibDashboardRaceInfoDTO idOfLastTrackedRace is "+result.idOfLastTrackedRace);
List<RegattaAndRaceIdentifier> singletonList = Collections.singletonList(result.idOfLastTrackedRace);
setSelection(singletonList);
} else {
logger.log(Level.INFO, "RibDashboardRaceInfoDTO.idOfLastTrackedRace is null");
}
notifyDataObservers(result);
break;
case NO_RACE_LIVE:
logger.log(Level.INFO, "RibDashboardRaceInfoDTO.responseMessage is NO_RACE_LIVE");
break;
default:
logger.log(Level.INFO, "RibDashboardRaceInfoDTO.responseMessage is null");
break;
}
} else {
logger.log(Level.INFO, "RibDashboardRaceInfoDTO is null");
}
}
@Override
public void onFailure(Throwable caught) {
logger.log(Level.INFO, "Failed to received RibDashboardRaceInfoDTO, "+caught.getMessage());
}
});
}
public void addDataObserver(RibDashboardDataRetrieverListener o) {
synchronized (MUTEX) {
if (o != null) {
dataRetrieverListener.add(o);
}
}
}
public void removeDataObserver(RibDashboardDataRetrieverListener o) {
synchronized (MUTEX) {
this.dataRetrieverListener.remove(o);
}
}
public void notifyDataObservers(RibDashboardRaceInfoDTO liveRaceInfoDTO) {
logger.log(Level.INFO, "Notifing RibDashboardDataRetrieverListener about new RibDashboardRaceInfoDTO");
List<RibDashboardDataRetrieverListener> dataObserverCopy;
synchronized (MUTEX) {
dataObserverCopy = new ArrayList<RibDashboardDataRetrieverListener>(dataRetrieverListener);
}
for (RibDashboardDataRetrieverListener o : dataObserverCopy) {
o.updateUIWithNewLiveRaceInfo(liveRaceInfoDTO);
}
}
@Override
public void timeChanged(Date newTime, Date oldTime) {
loadLiveRaceInfoFromRibDashboadService();
}
@Override
public void addRaceSelectionChangeListener(RaceSelectionChangeListener listener) {
synchronized (MUTEX) {
if (listener != null) {
raceSelectionChangeListener.add(listener);
}
}
}
@Override
public void removeRaceSelectionChangeListener(RaceSelectionChangeListener listener) {
synchronized (MUTEX) {
raceSelectionChangeListener.remove(listener);
}
}
@Override
public void setSelection(List<RegattaAndRaceIdentifier> newSelection,
RaceSelectionChangeListener... listenersNotToNotify) {
synchronized (MUTEX) {
for (RaceSelectionChangeListener currentRaceSelectionChangeListener : raceSelectionChangeListener) {
currentRaceSelectionChangeListener.onRaceSelectionChange(newSelection);
}
}
}
@Override
public List<RegattaAndRaceIdentifier> getAllRaces() {
return null;
}
@Override
public void setAllRaces(List<RegattaAndRaceIdentifier> newAllRaces,
RaceSelectionChangeListener... listenersNotToNotify) {
}
@Override
public List<RegattaAndRaceIdentifier> getSelectedRaces() {
return null;
}
}
@@ -1,16 +0,0 @@
/**
*
*/
package com.sap.sailing.dashboards.gwt.client.dataretriever;
import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
/**
*
* @author Alexander Ries
*
*/
public interface RibDashboardDataRetrieverListener {
public void updateUIWithNewLiveRaceInfo(RibDashboardRaceInfoDTO liveRaceInfoDTO);
}
@@ -8,49 +8,46 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync;
import com.sap.sailing.dashboards.gwt.client.DashboardClientFactory;
import com.sap.sailing.dashboards.gwt.client.actions.GetIDFromRaceThatTakesWindFixesNowAction;
import com.sap.sailing.dashboards.gwt.client.widgets.PollsLiveDataEvery5Seconds;
import com.sap.sailing.dashboards.gwt.shared.DashboardURLParameters;
import com.sap.sailing.dashboards.gwt.shared.dto.RaceIdDTO;
import com.sap.sailing.domain.common.RegattaAndRaceIdentifier;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.gwt.ui.actions.GetWindInfoAction;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.TimeListener;
public class WindBotDataRetriever implements TimeListener, WindBotDataRetrieverProvider {
public class WindBotDataRetriever implements PollsLiveDataEvery5Seconds, WindBotDataRetrieverProvider {
private AsyncActionsExecutor asyncActionsExecutor;
private final RibDashboardServiceAsync ribDashboardService;
private final SailingServiceAsync sailingService;
private List<NumberOfWindBotsChangeListener> numberOfWindBotsChangeListeners;
private List<WindBotDataRetrieverListener> windBotDataRetrieverListeners;
private List<String> windBotIDsInLiveRace;
private String leaderboardName;
private final Set<String> windSourceTypeNames;
private final int WIND_CHART_RESOLUTION_IN_MILLISECONDS = 5000;
private final int ONE_HOUR_IN_MILLISECONDS = 1000*60*60;
private final String LODA_WIND_CHART_DATA_CATEGORY = "loadWindChartData";
private static final String PARAM_LEADERBOARD_NAME = "leaderboardName";
private boolean didInitialLoading;
private DashboardClientFactory dashboardClientFactory;
private static final Logger logger = Logger.getLogger(WindBotDataRetriever.class.getName());
public WindBotDataRetriever(RibDashboardServiceAsync ribDashboardService, SailingServiceAsync sailingService) {
this.ribDashboardService = ribDashboardService;
this.sailingService = sailingService;
public WindBotDataRetriever(DashboardClientFactory dashboardClientFactory) {
this.dashboardClientFactory = dashboardClientFactory;
didInitialLoading = false;
asyncActionsExecutor = new AsyncActionsExecutor();
numberOfWindBotsChangeListeners = new ArrayList<NumberOfWindBotsChangeListener>();
windBotDataRetrieverListeners = new ArrayList<WindBotDataRetrieverListener>();
windBotIDsInLiveRace = new ArrayList<String>();
windSourceTypeNames = new HashSet<>();
this.leaderboardName = Window.Location.getParameter(PARAM_LEADERBOARD_NAME);
windSourceTypeNames.add(WindSourceType.EXPEDITION.name());
registerForDashboardFiveSecondsTimer(dashboardClientFactory);
}
private void loadWindBotData(Date from, Date to, RegattaAndRaceIdentifier selectedRaceIdentifier) {
@@ -59,7 +56,7 @@ public class WindBotDataRetriever implements TimeListener, WindBotDataRetrieverP
from = new Date(from.getTime()-ONE_HOUR_IN_MILLISECONDS);
}
logger.log(Level.INFO, "Executing GetWindInfoAction with from "+from+" and to "+to);
GetWindInfoAction getWindInfoAction = new GetWindInfoAction(sailingService, selectedRaceIdentifier, from, to,
GetWindInfoAction getWindInfoAction = new GetWindInfoAction(dashboardClientFactory.getSailingService(), selectedRaceIdentifier, from, to,
WIND_CHART_RESOLUTION_IN_MILLISECONDS, windSourceTypeNames, /*
* onlyUpToNewestEvent==true because we don't want to
* overshoot the evidence so far
@@ -146,26 +143,38 @@ public class WindBotDataRetriever implements TimeListener, WindBotDataRetrieverP
public void timeChanged(Date newTime, Date oldTime) {
final Date finalNewTime = newTime;
final Date finaloldTime = oldTime;
GetIDFromRaceThatTakesWindFixesNowAction getIDFromRaceThatTakesWindFixesNowAction = new GetIDFromRaceThatTakesWindFixesNowAction(ribDashboardService, leaderboardName);
logger.log(Level.INFO, "Executing GetIDFromRaceThatTakesWindFixesNowAction");
asyncActionsExecutor.execute(getIDFromRaceThatTakesWindFixesNowAction, new AsyncCallback<RegattaAndRaceIdentifier>() {
@Override
public void onSuccess(RegattaAndRaceIdentifier result) {
logger.log(Level.INFO, "Received RegattaAndRaceIdentifier from race that takes wind fixes now");
if(result != null) {
loadWindBotData(finaloldTime, finalNewTime, result);
} else {
notifyListenersAboutNumberOfWindBotsReceivedIsZero();
logger.log(Level.INFO, "Can´t load wind data because RegattaAndRaceIdentifier for race which takes wind is null");
}
}
dashboardClientFactory.getDispatch().execute(
new GetIDFromRaceThatTakesWindFixesNowAction(DashboardURLParameters.LEADERBOARD_NAME.getValue()),
new AsyncCallback<RaceIdDTO>() {
@Override
public void onFailure(Throwable caught) {
notifyListenersAboutNumberOfWindBotsReceivedIsZero();
logger.log(Level.INFO, " Failed to received RegattaAndRaceIdentifier from race that takes wind fixes now");
logger.log(Level.INFO, caught.getMessage());
}
});
@Override
public void onSuccess(RaceIdDTO result) {
if (result != null) {
RegattaAndRaceIdentifier raceId = result.getRaceId();
if (raceId != null) {
logger.log(Level.INFO, "Received RegattaAndRaceIdentifier from race that takes wind fixes now");
loadWindBotData(finaloldTime, finalNewTime, raceId);
} else {
notifyListenersAboutNumberOfWindBotsReceivedIsZero();
logger.log(Level.INFO, "Can´t load wind data because RegattaAndRaceIdentifier for race which takes wind is null");
}
}
}
@Override
public void onFailure(Throwable caught) {
notifyListenersAboutNumberOfWindBotsReceivedIsZero();
logger.log(Level.INFO, "Failed to received RegattaAndRaceIdentifier from race that takes wind fixes now");
logger.log(Level.INFO, caught.getMessage());
}
});
}
@Override
public void registerForDashboardFiveSecondsTimer(DashboardClientFactory dashboardClientFactory) {
if (dashboardClientFactory != null) {
dashboardClientFactory.getDashboardFiveSecondsTimer().addTimeListener(this);
}
}
}
@@ -5,6 +5,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.safehtml.shared.UriUtils;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Image;
@@ -33,7 +34,7 @@ public class EventLogo extends Image {
if (event != null) {
final ImageDTO logo = event.getLogoImage();
if (logo != null) {
eventLogo.getElement().setAttribute("src", logo.getSourceRef());
eventLogo.getElement().setAttribute("src", UriUtils.fromString(logo.getSourceRef()).asString());
} else {
eventLogo.getElement().getStyle().setVisibility(Visibility.HIDDEN);
}
@@ -1,100 +0,0 @@
@CHARSET "UTF-8";
.bottomnotification {
position: absolute !important;
opacity: 0.9;
background-color: #F0AB00;
height: 0pt;
line-height: 0pt;
width: 100%;
bottom: 0pt;
text-align: center;
font-size: 15pt;
line-height: 30pt;
color: black;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
z-index: 2;
}
.bottomnotification_shown {
-webkit-transition: all 700ms cubic-bezier(0.480, 0, 0.000, 1);
/* older webkit */
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
/* custom */
height: 30pt;
line-height: 30pt;
}
.bottomnotification_hidden {
-webkit-transition: all 700ms cubic-bezier(0.480, 0, 0.000, 1);
/* older webkit */
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
/* custom */
height: 0pt;
line-height: 0pt;
}
.wrongorientationnotification {
position: absolute !important;
top: 50%;
right: 50%;
background-color: white;
z-index: 2;
}
.wrongorientationnotification_shown {
width: 200px;
height: 200px;
margin-right: -100px;
margin-top: -100px;
border-radius: 100px;
-webkit-transition: all 700ms cubic-bezier(0.480, 0, 0.000, 1);
/* older webkit */
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
opacity: 1.0;
}
.wrongorientationnotification_hidden {
width: 0px;
height: 0px;
marin-right: 0px;
margin-top: 0px;
border-radius: 0px;
overflow: hidden;
-webkit-transition: all 300ms;
/* older webkit */
-webkit-transition: all 300ms;
-moz-transition: all 300ms;
-o-transition: all 300ms;
transition: all 300ms;
opacity: 0.0;
}
.wrongorientationnotification_logo {
max-width: 40%;
max-height: 40%;
margin: 30%;
margin-top: 23%
}
.wrongorientationnotification_text {
position: absolute;
width: 100%;
height: 14px;
top: 76%;
line-height: 10px;
text-align: center;
font-weight: bold;
font-size: 13px;
color: grey;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
}
@@ -1,25 +0,0 @@
package com.sap.sailing.dashboards.gwt.client.notifications;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
/**
* @author Alexander Ries (D062114)
*
*/
public interface NotificationsResources extends ClientBundle {
@Source("Notifications.css")
NotificationsStyle notificationsStyle();
public interface NotificationsStyle extends CssResource {
public String bottomnotification();
public String bottomnotification_shown();
public String bottomnotification_hidden();
public String wrongorientationnotification();
public String wrongorientationnotification_shown();
public String wrongorientationnotification_hidden();
public String wrongorientationnotification_logo();
public String wrongorientationnotification_text();
}
}
@@ -0,0 +1,34 @@
@require 'theme';
.notification {
position: absolute !important;
opacity: 0.9;
background-color: #F0AB00;
height: 0pt;
width: 100%;
bottom: 0pt;
text-align: center;
font-size: 15pt;
line-height: 30pt;
color: black;
font-family: DASHBOARD_FONT_FAMILY;
z-index: 2;
}
.shown {
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 2.650);
height: 30pt;
line-height: 30pt;
}
.hidden {
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.650);
height: 0pt;
line-height: 0pt;
}
@@ -1,9 +1,8 @@
package com.sap.sailing.dashboards.gwt.client.notifications;
package com.sap.sailing.dashboards.gwt.client.notifications.bottom;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
@@ -22,11 +21,9 @@ public class BottomNotification extends FocusPanel {
private Timer timer;
private List<BottomNotificationClickListener> bottomNotificationClickListeners;
private static NotificationsResources resources = GWT.create(NotificationsResources.class);
public BottomNotification() {
resources.notificationsStyle().ensureInjected();
this.addStyleName(resources.notificationsStyle().bottomnotification());
BottomNotificationResources.INSTANCE.gss().ensureInjected();
this.addStyleName(BottomNotificationResources.INSTANCE.gss().notification());
this.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
@@ -42,8 +39,8 @@ public class BottomNotification extends FocusPanel {
public void show(BottomNotificationType bottomNotificationType) {
if (shown == false) {
this.removeStyleName(resources.notificationsStyle().bottomnotification_hidden());
this.addStyleName(resources.notificationsStyle().bottomnotification_shown());
this.removeStyleName(BottomNotificationResources.INSTANCE.gss().hidden());
this.addStyleName(BottomNotificationResources.INSTANCE.gss().shown());
this.getElement().setInnerHTML(bottomNotificationType.getMessage());
this.getElement().getStyle().setBackgroundColor(bottomNotificationType.getBackgroundColorAsHex());
this.getElement().getStyle().setColor(bottomNotificationType.getTextColorAsHex());
@@ -61,8 +58,8 @@ public class BottomNotification extends FocusPanel {
if (timer != null) {
timer.cancel();
}
this.removeStyleName(resources.notificationsStyle().bottomnotification_shown());
this.addStyleName(resources.notificationsStyle().bottomnotification_hidden());
this.removeStyleName(BottomNotificationResources.INSTANCE.gss().shown());
this.addStyleName(BottomNotificationResources.INSTANCE.gss().hidden());
this.getElement().setInnerHTML("");
shown = false;
}
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.notifications;
package com.sap.sailing.dashboards.gwt.client.notifications.bottom;
public interface BottomNotificationClickListener {
@@ -0,0 +1,23 @@
package com.sap.sailing.dashboards.gwt.client.notifications.bottom;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
/**
* @author Alexander Ries (D062114)
*
*/
public interface BottomNotificationResources extends ClientBundle{
public static final BottomNotificationResources INSTANCE = GWT.create(BottomNotificationResources.class);
@Source({"com/sap/sailing/dashboards/gwt/client/theme/theme.gss", "BottomNotification.gss"})
NotificationsGSS gss();
public interface NotificationsGSS extends CssResource {
public String notification();
public String shown();
public String hidden();
}
}
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.notifications;
package com.sap.sailing.dashboards.gwt.client.notifications.bottom;
import com.sap.sailing.gwt.ui.client.StringMessages;
@@ -0,0 +1,56 @@
@require 'theme';
.notification {
position: absolute !important;
top: 50%;
right: 50%;
background-color: white;
z-index: 2;
}
.shown {
width: 200px;
height: 200px;
margin-right: -100px;
margin-top: -100px;
border-radius: 100px;
-webkit-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
-moz-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
-o-transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
transition: all 700ms cubic-bezier(0.480, -0.035, 0.000, 1.250);
opacity: 1.0;
}
.hidden {
width: 0px;
height: 0px;
marin-right: 0px;
margin-top: 0px;
border-radius: 0px;
overflow: hidden;
-webkit-transition: all 300ms;
-moz-transition: all 300ms;
-o-transition: all 300ms;
transition: all 300ms;
opacity: 0.0;
}
.logo {
max-width: 40%;
max-height: 40%;
margin: 30%;
margin-top: 23%
}
.text {
position: absolute;
width: 100%;
height: 14px;
top: 76%;
line-height: 10px;
text-align: center;
font-weight: bold;
font-size: 13px;
color: grey;
font-family: DASHBOARD_FONT_FAMILY;
}
@@ -1,11 +1,9 @@
package com.sap.sailing.dashboards.gwt.client.notifications;
package com.sap.sailing.dashboards.gwt.client.notifications.orientation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.sap.sailing.dashboards.gwt.client.RibDashboardImageResources;
import com.sap.sailing.dashboards.gwt.client.device.Orientation;
import com.sap.sailing.dashboards.gwt.client.device.OrientationListener;
import com.sap.sailing.dashboards.gwt.client.device.OrientationType;
@@ -16,21 +14,19 @@ public class WrongDeviceOrientationNotification extends AbsolutePanel implements
private Label rotateDeviceLabel;
private static NotificationsResources resources = GWT.create(NotificationsResources.class);
public WrongDeviceOrientationNotification() {
super();
resources.notificationsStyle().ensureInjected();
this.addStyleName(resources.notificationsStyle().wrongorientationnotification());
this.addStyleName(resources.notificationsStyle().wrongorientationnotification_hidden());
WrongDeviceOrientationNotificationResources.INSTANCE.gss().ensureInjected();
this.addStyleName(WrongDeviceOrientationNotificationResources.INSTANCE.gss().notification());
this.addStyleName(WrongDeviceOrientationNotificationResources.INSTANCE.gss().hidden());
Image rotateDeviceIcon = new Image();
rotateDeviceIcon.setResource(RibDashboardImageResources.INSTANCE.rotatedevice());
rotateDeviceIcon.getElement().addClassName(resources.notificationsStyle().wrongorientationnotification_logo());
rotateDeviceIcon.setResource(WrongDeviceOrientationNotificationResources.INSTANCE.rotatedevice());
rotateDeviceIcon.getElement().addClassName(WrongDeviceOrientationNotificationResources.INSTANCE.gss().logo());
add(rotateDeviceIcon);
rotateDeviceLabel = new Label();
rotateDeviceLabel.getElement().addClassName(resources.notificationsStyle().wrongorientationnotification_text());
rotateDeviceLabel.getElement().addClassName(WrongDeviceOrientationNotificationResources.INSTANCE.gss().text());
rotateDeviceLabel.setText("Rotate Device");
add(rotateDeviceLabel);
@@ -39,14 +35,14 @@ public class WrongDeviceOrientationNotification extends AbsolutePanel implements
}
public void show() {
this.removeStyleName(resources.notificationsStyle().wrongorientationnotification_hidden());
this.addStyleName(resources.notificationsStyle().wrongorientationnotification_shown());
this.removeStyleName(WrongDeviceOrientationNotificationResources.INSTANCE.gss().hidden());
this.addStyleName(WrongDeviceOrientationNotificationResources.INSTANCE.gss().shown());
BlurEffect.getInstance().addToView(RootLayoutPanel.get());
}
public void hide() {
this.removeStyleName(resources.notificationsStyle().wrongorientationnotification_shown());
this.addStyleName(resources.notificationsStyle().wrongorientationnotification_hidden());
this.removeStyleName(WrongDeviceOrientationNotificationResources.INSTANCE.gss().shown());
this.addStyleName(WrongDeviceOrientationNotificationResources.INSTANCE.gss().hidden());
BlurEffect.getInstance().removeFromView(RootLayoutPanel.get());
}
@@ -0,0 +1,29 @@
package com.sap.sailing.dashboards.gwt.client.notifications.orientation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.ImageResource;
/**
* @author Alexander Ries (D062114)
*
*/
public interface WrongDeviceOrientationNotificationResources extends ClientBundle {
public static final WrongDeviceOrientationNotificationResources INSTANCE = GWT.create(WrongDeviceOrientationNotificationResources.class);
@Source("com/sap/sailing/dashboards/gwt/client/images/rotatedevice.png")
ImageResource rotatedevice();
@Source({ "com/sap/sailing/dashboards/gwt/client/theme/theme.gss", "WrongDeviceOrientationNotification.gss"})
WrongDeviceNotificationGSS gss();
public interface WrongDeviceNotificationGSS extends CssResource {
public String notification();
public String shown();
public String hidden();
public String logo();
public String text();
}
}
@@ -61,7 +61,7 @@
padding: 0px;
margin-top: 5pt;
margin-left: 0px;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
font-family: DASHBOARD_FONT_FAMILY;
}
.popup_button:active {
@@ -77,7 +77,7 @@
font-weight: bold;
font-size: 15px;
color: grey;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
font-family: DASHBOARD_FONT_FAMILY;
}
.blurred {
@@ -1,5 +1,13 @@
@CHARSET "UTF-8";
.competitorselectionbackground {
position: absolute;
background-color: rgba(0, 0, 0, 0.6);
width: 100%;
height: 100%;
z-index: 1;
}
.competitorselectionpopup {
position: absolute;
left: 50%;
@@ -8,7 +16,7 @@
height: 200pt;
margin-top: -600pt;
margin-left: -100pt;
background-color: white;
background-color: rgba(255, 255, 255, 1);
border-radius: 0px;
z-index: 2;
}
@@ -23,7 +31,7 @@
vertical-align: middle;
text-align: center;
font-weight: bold;
text-shadow: 0 1px 1px rgba(255, 255, 255, .7);
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.7);
width: 100%;
z-index: 3;
}
@@ -15,24 +15,27 @@ import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.visualeffects.BlurEffect;
import com.sap.sailing.domain.common.dto.CompetitorDTO;
public class CompetitorSelectionPopup extends Composite implements HasWidgets, CompetitorTableRowSelectionListener {
interface CompetitorSelectionPopupStyle extends CssResource {
String popupshow();
String popuphide();
String buttonshow();
}
@UiField
CompetitorSelectionPopupStyle style;
@UiField
HTMLPanel competitorselectionbackground;
@UiField
VerticalPanel competitorselectionpopup;
@UiField
HTMLPanel header;
@@ -61,19 +64,17 @@ public class CompetitorSelectionPopup extends Composite implements HasWidgets, C
public void show(List<CompetitorDTO> competitorList) {
competitortable.setTableContent(competitorList);
RootPanel.get().add(this);
RootLayoutPanel.get().add(this);
this.button.setText("OK");
this.getElement().addClassName(style.popupshow());
this.getElement().removeClassName(style.popuphide());
BlurEffect.getInstance().addToView(RootLayoutPanel.get());
competitorselectionpopup.addStyleName(style.popupshow());
competitorselectionpopup.removeStyleName(style.popuphide());
isVisible = true;
}
public void hide() {
this.getElement().addClassName(style.popuphide());
this.getElement().removeClassName(style.popupshow());
BlurEffect.getInstance().removeFromView(RootLayoutPanel.get());
RootPanel.get().remove(this);
competitorselectionpopup.addStyleName(style.popuphide());
competitorselectionpopup.removeStyleName(style.popupshow());
RootLayoutPanel.get().remove(this);
isVisible = false;
}
@@ -1,22 +1,25 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:popups="urn:import:com.sap.sailing.dashboards.gwt.client.popups.competitorselection"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:popups="urn:import:com.sap.sailing.dashboards.gwt.client.popups.competitorselection"
xmlns:mgwts="urn:import:com.googlecode.mgwt.ui.client.widget.panel.scroll">
<ui:style
type='com.sap.sailing.dashboards.gwt.client.popups.competitorselection.CompetitorSelectionPopup.CompetitorSelectionPopupStyle'
src='CompetitorSelectionPopup.css'></ui:style>
<g:VerticalPanel ui:field="competitorselectionpopup"
styleName="{style.competitorselectionpopup}">
<g:HTMLPanel ui:field="header" styleName="{style.header}">Select your Team</g:HTMLPanel>
<mgwts:ScrollPanel styleName="{style.scrollpanel}"
scrollingEnabledX="false">
<g:FlowPanel>
<popups:CompetitorTable ui:field="competitortable"></popups:CompetitorTable>
</g:FlowPanel>
</mgwts:ScrollPanel>
<g:Button ui:field="button" styleName="{style.button}"></g:Button>
</g:VerticalPanel>
<g:HTMLPanel ui:field="competitorselectionbackground"
styleName="{style.competitorselectionbackground}">
<g:VerticalPanel ui:field="competitorselectionpopup"
styleName="{style.competitorselectionpopup}">
<g:HTMLPanel ui:field="header" styleName="{style.header}">Select your Team</g:HTMLPanel>
<mgwts:ScrollPanel styleName="{style.scrollpanel}"
scrollingEnabledX="false">
<g:FlowPanel>
<popups:CompetitorTable ui:field="competitortable"></popups:CompetitorTable>
</g:FlowPanel>
</mgwts:ScrollPanel>
<g:Button ui:field="button" styleName="{style.button}"></g:Button>
</g:VerticalPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -3,7 +3,8 @@ package com.sap.sailing.dashboards.gwt.client.popups.competitorselection;
import com.google.gwt.user.cellview.client.CellTable;
public interface CompetitorTableStyleResource extends CellTable.Resources {
@Source({ CellTable.Style.DEFAULT_CSS, "CompetitorTableStyle.css"})
@Source({CellTable.Style.DEFAULT_CSS, "CompetitorTableStyle.css"})
TableStyle cellTableStyle();
@@ -10,7 +10,7 @@ import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.RibDashboardImageResources;
import com.sap.sailing.dashboards.gwt.client.dashboardpanel.DashboardPanelResources;
public class SettingsButtonWithSelectionIndicationLabel extends Composite {
@@ -38,7 +38,7 @@ public class SettingsButtonWithSelectionIndicationLabel extends Composite {
public SettingsButtonWithSelectionIndicationLabel() {
initWidget(uiBinder.createAndBindUi(this));
settingsButtonImage.setResource(RibDashboardImageResources.INSTANCE.settings());
settingsButtonImage.setResource(DashboardPanelResources.INSTANCE.settings());
}
public void addClickHandlerToSettingsButton(ClickHandler clickHandler){
@@ -1,15 +0,0 @@
package com.sap.sailing.dashboards.gwt.client.resources;
/**
* @author Alexander Ries (D062114)
*
*/
public class Colors {
/* -> App colors -- */
public static final String C_PRIMARY = "#000000";
public static final String C_SECONDARY = "#000000";
/* -> Default colors -- */
public static final String C_BACKGROUND = "#000000";
public static final String C_TEXT = "#000000";
public static final String C_TEXT_LIGHT = "#000000";
}
@@ -1,19 +0,0 @@
package com.sap.sailing.dashboards.gwt.client.resources;
/**
* @author Alexander Ries (D062114)
*
*/
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
public interface DashboardResources extends ClientBundle {
interface Style extends CssResource {
// Your classes here
}
// We only need to source the theme file
@Source({"colors.gss", "Ribstyle.css"})
Style style();
}
@@ -1,295 +0,0 @@
@require "colors";
.bar {
height: 100%;
margin-top: 20pt;
line-height: 15pt;
vertical-align: middle;
font-size: 15pt;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
width: 100%;
text-align: center;
font-weight: bold;
overflow: visible;
}
.page {
position: absolute;
border: none;
border-radius: 0;
background-color: C_PRIMARY;
left: 0;
right: 0;
top: 0;
bottom: 30pt;
margin: 5pt;
}
.logo {
position: absolute;
width: 48pt;
height: 23.5pt;
margin-top: 17.5pt;
margin-left: 10pt;
z-index: 1;
}
.collumn {
position: absolute;
top: 5pt;
bottom: 15pt;
margin: 5pt;
}
.startanalysiscollumn {
right: 33.3%;
left: 0%;
}
/*deprecated*/
.collumn1 {
width: 33.3%;
}
/*deprecated*/
.collumn2 {
width: 33.3%;
left: 33.3%;
}
/*deprecated*/
.collumn3 {
left: 66.8%;
right: 0pt;
}
.left {
left: 0pt;
right: 50%;
}
.right {
left: 50%;
right: 0pt;
}
/*+++++++++++++++++++++++++++++++++++++++++*/
/* .content { */
/* width: 100%; */
/* height: 50pt; */
/* margin: 0pt; */
/* } */
.stripe {
background-color: black;
maring: 0pt;
padding: 0pt;
width: 1%;
height: 90%;
float: left;
}
.chart {
width: 100%;
height: 100%;
}
.rootpanel {
background-color: C_PRIMARY;
width: 100%;
height: 200%;
}
.startline_advantage_by_wind_container {
position: absolute;
background-color: white;
top: 27%;
right: 0pt;
left: 0pt;
bottom: 0%;
}
.startline_advantage_by_geometry_container {
position: absolute;
background-color: white;
top: 0%;
right: 0pt;
left: 0pt;
bottom: 73%;
margin-bottom: 10pt;
}
.hintpanel {
position: absolute;
background-color: white;
height: 25pt;
right: 0pt;
left: 0pt;
bottom: 0pt;
}
.leaderboardpanel {
position: absolute;
top: 30%;
right: 0pt;
left: 0pt;
bottom: 0pt;
margin-top: 5pt;
}
.hint {
height: 100%;
line-height: 25pt;
margin-top: 0pt;
vertical-align: middle;
font-size: 12pt;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
width: 100%;
text-align: center;
}
.windcharthint {
position: absolute;
bottom: 0pt;
height: 15pt;
line-height: 15pt;
margin-top: 0pt;
vertical-align: middle;
font-size: 12pt;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
width: 100%;
text-align: center;
}
.scrollLayoutPanel {
height: 100%;
width: 100%;
}
windchartcontainer {
position: absolute;
left: 0pt;
right: 0pt;
top: 0pt;
bottom: 0pt;
}
.windchartwrapper {
position: absolute;
top: 0pt;
bottom: 0pt;
left: 0pt;
right: 0pt;
}
/*??????*/
.windchart {
position: absolute;
left: 0pt;
right: 0pt;
top: 0pt;
bottom: 0pt;
}
.startlineanalysis {
position: absolute;
top: 0pt;
right: 0pt;
left: 0pt;
bottom: 10pt;
background-color: #0DBFFF;
}
.collumncontent {
height: 100%;
width: 100%;
background-color: white;
}
/*Test*/
.scrollHorizontal {
overflow-y: hidden !important;
overflow-x: hidden !important;
position: absolute !important;
top: 0pt;
right: 0pt;
left: 0pt;
bottom: 0pt;
}
.scrollAbsPanel {
overflow-y: hidden !important;
overflow-x: hidden !important;
position: absolute !important;
top: 0pt;
right: 0pt;
left: 0pt;
bottom: 0pt;
}
.scrollcontainer {
position: absolute;
top: 15pt;
right: 15pt;
width: 300%;
bottom: 15pt;
background-color: white;
}
.start {
position: absolute;
top: 0pt;
right: 0pt;
left: 0pt;
bottom: 0pt;
height: 100%;
/* height: 300pt; */ /* width: 400pt; */ /* margin: 10pt; */
background-color: #0DBFFF;
}
.scrollPage1 {
position: absolute;
height: 80%;
width: 80%;
margin: 10%;
background-color: #0DBFFF;
}
.scrollPage2 {
position: absolute;
height: 80%;
width: 80%;
left: 170%;
background-color: #0DBFFF;
}
.scrollPage3 {
position: absolute;
height: 80%;
width: 80%;
left: 260%;
background-color: #0DBFFF;
}
.windloadinghint {
position: absolute;
background-color: white;
opacity: 0.4;
width: 100%;
height: 100%;
vertical-align: middle;
text-align: center;
z-index: 0;
}
.windloadinghinttext {
position: absolute;
bottom: 0pt;
height: 15pt;
line-height: 15pt;
margin-top: 0pt;
vertical-align: middle;
font-size: 12pt;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
width: 100%;
text-align: center;
top: 50%;
margin-top: -7pt;
}
@@ -1,7 +0,0 @@
@provide 'colors';
@def C_PRIMARY eval("com.company.project.client.resources.Colors.C_PRIMARY");
@def C_SECONDARY eval("com.company.project.client.resources.Colors.C_SECONDARY");
@def C_BACKGROUND eval("com.company.project.client.resources.Colors.C_BACKGROUND");
@def C_TEXT eval("com.company.project.client.resources.Colors.C_TEXT");
@def C_TEXT_LIGHT eval("com.company.project.client.resources.Colors.C_TEXT_LIGHT");
@@ -1,14 +0,0 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
import com.sap.sailing.gwt.ui.client.shared.racemap.CombinedWindPanelStyle;
interface StartAnalysisResources extends ClientBundle {
@Source("com/sap/sailing/dashboards/gwt/client/images/windarrow.png")
ImageResource combinedWindIcon();
@Source("StartAnalysisCombinedWindPanel.css")
CombinedWindPanelStyle combinedWindPanelStyle();
}
@@ -1,19 +0,0 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:style
type='com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAnalysisCard.StartlineAnalysis'
src='StartlineAnalysis.css'></ui:style>
<g:HTMLPanel ui:field="startanalysis_card" styleName="{style.startanalysis_card}">
<div class="{style.startanalysis_card_wind_line_data_container}">
<div ui:field="startanalysis_card_line_advantage"
class="{style.startanalysis_card_data} {style.startanalysis_card_line_advantage}"></div>
</div>
<div ui:field="startanalysis_card_race_time"
class="{style.startanalysis_card_race_time}">Time: 00:05:00</div>
<g:HTMLPanel ui:field="startanalysis_card_table"
styleName="{style.startanalysis_card_table}"></g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -1,30 +0,0 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:my="urn:import:com.sap.sailing.dashboards.gwt.client.startanalysis"
xmlns:mgwts="urn:import:com.googlecode.mgwt.ui.client.widget.panel.scroll"
xmlns:maps="urn:import:com.google.gwt.maps.client">
<ui:style
type='com.sap.sailing.dashboards.gwt.client.startanalysis.StartlineAnalysisComponent.StartlineAnalysis'
src='StartlineAnalysis.css'></ui:style>
<ui:with field='res'
type='com.sap.sailing.dashboards.gwt.client.RibDashboardImageResources' />
<g:HTMLPanel styleName="{style.startanalysis}">
<g:HTMLPanel ui:field="header" styleName="{style.panelHeader}">
No Starts Available
</g:HTMLPanel>
<g:Image resource="{res.left}" ui:field="leftButton"
styleName="{style.startanalysis_controll_header_button} {style.startanalysis_controll_header_button_left}"></g:Image>
<g:Image resource="{res.right}" ui:field="rightButton"
styleName="{style.startanalysis_controll_header_button} {style.startanalysis_controll_header_button_right}"></g:Image>
<g:FocusPanel ui:field="left_focus_panel" styleName="{style.left_focus_panel}"></g:FocusPanel>
<g:FocusPanel ui:field="right_focus_panel" styleName="{style.right_focus_panel}"></g:FocusPanel>
<g:HTMLPanel ui:field="startanalysis_card_container"
styleName="{style.startanalysis_card_container}">
</g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -1,41 +0,0 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:style type='com.sap.sailing.dashboards.gwt.client.startlineadvantage.LiveAverageComponent.LiveAverageComponentStyle' src='LiveAverageComponent.css'></ui:style>
<g:HTMLPanel ui:field="liveAveragePanel" styleName="{style.liveAverageCompoment_panel}">
<g:HTMLPanel styleName="{style.liveAverageCompoment_header_container}">
<div class="{style.liveAverageCompoment_header}" ui:field="header"></div>
</g:HTMLPanel>
<g:HTMLPanel ui:field="livePanel" styleName="{style.liveAverageCompoment_live_container}">
<div class="{style.liveAverageCompoment_value_panel}">
<span class="{style.liveAverageCompoment_panel_value_number}" ui:field="liveNumber"></span>
<span class="{style.liveAverageCompoment_panel_value_unit}" ui:field="liveUnit"></span>
</div>
</g:HTMLPanel>
<g:HTMLPanel ui:field="middleLine" styleName="{style.liveAverageCompoment_middle_line}">
</g:HTMLPanel>
<g:HTMLPanel ui:field="averagePanel" styleName="{style.liveAverageCompoment_average_container}">
<div class="{style.liveAverageCompoment_value_panel}">
<span class="{style.liveAverageCompoment_panel_value_number}" ui:field="averageNumber"></span>
<span class="{style.liveAverageCompoment_panel_value_unit}" ui:field="averageUnit"></span>
</div>
</g:HTMLPanel>
<g:HTMLPanel styleName="{style.liveAverageCompoment_liveLabelContainer}">
<div class="{style.liveAverageCompoment_label_text}" ui:field="liveLabel"></div>
</g:HTMLPanel>
<g:HTMLPanel styleName="{style.liveAverageCompoment_averageLabelContainer}">
<div class="{style.liveAverageCompoment_label_text}" ui:field="averageLabel"></div>
</g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -1,55 +0,0 @@
package com.sap.sailing.dashboards.gwt.client.startlineadvantage;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.i18n.client.NumberFormat;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetriever;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetrieverListener;
import com.sap.sailing.dashboards.gwt.shared.dto.RibDashboardRaceInfoDTO;
import com.sap.sailing.gwt.ui.client.StringMessages;
/**
* The purpose of the class is to display the live and average start line advantage either by wind or by geometry. There
* is only one advantage display at once, so the user can switch between these following two
* {@link StartLineAdvantageComponentState}s {@link StartLineAdvantageComponentStateShowsAdvantageByWind} and
* {@link StartLineAdvantageComponentStateShowsAdvantageByGeometry} by tabing somewhere at the widget. The class extends
* from {@link LiveAverageComponent} to get necessary Ui Elements but customizes these with own CSS.
*
* @author Alexander Ries (D062114)
*
*/
public class StartLineAdvantageByGeometryComponent extends LiveAverageComponent implements RibDashboardDataRetrieverListener {
private static StringMessages stringConstants = StringMessages.INSTANCE;
private static final Logger logger = Logger.getLogger(StartLineAdvantageByGeometryComponent.class.getName());
public StartLineAdvantageByGeometryComponent(RibDashboardDataRetriever ribDashboardDataRetriever) {
super(stringConstants.dashboardStartlineAdvantageByGeometry(), "m");
StartLineAdvantageComponentRessources.INSTANCE.css().ensureInjected();
this.header.setInnerText(stringConstants.dashboardStartlineAdvantageByGeometry());
this.header.addClassName(StartLineAdvantageComponentRessources.INSTANCE.css().startLineAdvantageComponent_header());
liveAveragePanel.getElement().addClassName(StartLineAdvantageComponentRessources.INSTANCE.css().startLineAdvantageComponent_liveAveragePanel());
livePanel.getElement().addClassName(StartLineAdvantageComponentRessources.INSTANCE.css().startLineAdvantageComponent_livePanel());
middleLine.getElement().addClassName(StartLineAdvantageComponentRessources.INSTANCE.css().startLineAdvantageComponent_middleLine());
averagePanel.getElement().addClassName(StartLineAdvantageComponentRessources.INSTANCE.css().startLineAdvantageComponent_averagePanel());
this.liveLabel.setInnerHTML(stringConstants.dashboardLiveWind());
this.averageLabel.setInnerHTML(stringConstants.dashboardAverageWind()+"<br>"+stringConstants.dashboardAverageWindMinutes(15));
ribDashboardDataRetriever.addDataObserver(this);
}
public void setStartLineAdvantageValues(RibDashboardRaceInfoDTO liveRaceInfoDTO) {
if (liveRaceInfoDTO.startLineAdvantageDTO != null) {
logger.log(Level.INFO, "Updating UI with RibDashboardRaceInfoDTO.startLineAdvantageDTO");
setLiveValue(NumberFormat.getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.startLineAdvantage));
setAverageValue(NumberFormat.getFormat("#0.0").format(liveRaceInfoDTO.startLineAdvantageDTO.average));
} else {
logger.log(Level.INFO, "RibDashboardRaceInfoDTO.startLineAdvantageDTO is null");
}
}
@Override
public void updateUIWithNewLiveRaceInfo(RibDashboardRaceInfoDTO liveRaceInfoDTO) {
setStartLineAdvantageValues(liveRaceInfoDTO);
}
}
@@ -1,126 +0,0 @@
package com.sap.sailing.dashboards.gwt.client.startlineadvantage;
import java.util.Date;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync;
import com.sap.sailing.dashboards.gwt.client.actions.GetStartlineAdvantagesAction;
import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetriever;
import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.TimeListener;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.player.Timer.PlayModes;
/**
* @author Alexander Ries (D062114)
*
*/
public class StartlineAdvantagesByWindComponent extends Composite implements HasWidgets, TimeListener {
private static StartlineAdvantagesByWindComponentUiBinder uiBinder = GWT
.create(StartlineAdvantagesByWindComponentUiBinder.class);
interface StartlineAdvantagesByWindComponentUiBinder extends UiBinder<Widget, StartlineAdvantagesByWindComponent> {
}
interface StartlineAdvantagesByWindComponentStyle extends CssResource {
}
@UiField(provided = true)
LiveAverageComponent advantageMaximumLiveAverage;
@UiField(provided = true)
StartlineAdvantagesOnLineChart startlineAdvantagesOnLineChart;
@UiField
StartlineAdvantagesByWindComponentStyle style;
private RibDashboardServiceAsync ribDashboardService;
private AsyncActionsExecutor asyncActionsExecutor;
private static final Logger logger = Logger.getLogger(WindBotDataRetriever.class.getName());
public StartlineAdvantagesByWindComponent(RibDashboardServiceAsync ribDashboardService) {
startlineAdvantagesOnLineChart = new StartlineAdvantagesOnLineChart();
advantageMaximumLiveAverage = new LiveAverageComponent(StringMessages.INSTANCE.dashboardStartlineAdvantagesByWind(), "m");
advantageMaximumLiveAverage.header.getStyle().setFontSize(14, Unit.PT);
advantageMaximumLiveAverage.liveLabel.setInnerHTML("advantage max.");
advantageMaximumLiveAverage.averageLabel.setInnerHTML("advantage max. average "+StringMessages.INSTANCE.dashboardAverageWindMinutes(15));
initWidget(uiBinder.createAndBindUi(this));
this.ribDashboardService = ribDashboardService;
this.asyncActionsExecutor = new AsyncActionsExecutor();
initSampleTimer();
}
private void loadData() {
GetStartlineAdvantagesAction getRibDashboardRaceInfoAction = new GetStartlineAdvantagesAction(ribDashboardService, "");
logger.log(Level.INFO, "Executing GetStartlineAdvantagesAction");
asyncActionsExecutor.execute(getRibDashboardRaceInfoAction,
new AsyncCallback<StartlineAdvantagesWithMaxAndAverageDTO>() {
@Override
public void onSuccess(StartlineAdvantagesWithMaxAndAverageDTO result) {
logger.log(Level.INFO, "Received StartlineAdvantagesWithMaxAndAverageDTO");
if (result != null) {
logger.log(Level.INFO, "Updating UI with StartlineAdvantagesWithMaxAndAverageDTO");
startlineAdvantagesOnLineChart.setStartlineAdvantages(result.advantages);
advantageMaximumLiveAverage.setLiveValue("" + result.maximum);
advantageMaximumLiveAverage.setAverageValue("" + result.average);
} else {
logger.log(Level.INFO, "StartlineAdvantagesWithMaxAndAverageDTO is null");
}
}
@Override
public void onFailure(Throwable caught) {
logger.log(Level.INFO, "Failed to received StartlineAdvantagesWithMaxAndAverageDTO, "+caught.getMessage());
}
});
}
private void initSampleTimer(){
Timer timer = new Timer(PlayModes.Live);
timer.setRefreshInterval(5000);
timer.addTimeListener(this);
timer.play();
}
@Override
public void add(Widget w) {
throw new UnsupportedOperationException("The method add(Widget w) is not supported.");
}
@Override
public void clear() {
throw new UnsupportedOperationException("The method clear() is not supported.");
}
@Override
public Iterator<Widget> iterator() {
return null;
}
@Override
public boolean remove(Widget w) {
return false;
}
@Override
public void timeChanged(Date newTime, Date oldTime) {
loadData();
}
}
@@ -1,17 +0,0 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:startlineadvantage="urn:import:com.sap.sailing.dashboards.gwt.client.startlineadvantage">
<ui:style type='com.sap.sailing.dashboards.gwt.client.startlineadvantage.StartlineAdvantagesByWindComponent.StartlineAdvantagesByWindComponentStyle'
src='StartlineAdvantagesByWindComponentStyle.css'></ui:style>
<g:HTMLPanel styleName="{style.startline_advantages_by_wind_component_container}">
<g:HTMLPanel styleName="{style.advantage_maximum_live_average}">
<startlineadvantage:LiveAverageComponent ui:field="advantageMaximumLiveAverage"></startlineadvantage:LiveAverageComponent>
</g:HTMLPanel>
<g:HTMLPanel styleName="{style.advantages_on_line_chart_container}">
<startlineadvantage:StartlineAdvantagesOnLineChart ui:field="startlineAdvantagesOnLineChart"></startlineadvantage:StartlineAdvantagesOnLineChart>
</g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -1,18 +0,0 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:highcharts="urn:import:org.moxieapps.gwt.highcharts.client">
<ui:style
type='com.sap.sailing.dashboards.gwt.client.startlineadvantage.StartlineAdvantagesOnLineChart.StartlineAdvantagesOnLineChartStyle'
src='StartlineAdvantagesOnLineChartStyle.css'></ui:style>
<g:HTMLPanel>
<g:HTMLPanel ui:field="chartContainer" styleName="{style.advantages_on_line_chart_container}"></g:HTMLPanel>
<div class="{style.confidence_bar_container}">
<div class="{style.confidence_bar}"></div>
<div ui:field="confidenceBarHeader" class="{style.confidence_bar_header}"></div>
<div ui:field="confidenceBarMinLabel" class="{style.confidence_bar_label} {style.confidence_bar_min_label}"></div>
<div ui:field="confidenceBarMaxLabel" class="{style.confidence_bar_label} {style.confidence_bar_max_label}"></div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,16 @@
package com.sap.sailing.dashboards.gwt.client.theme;
/**
* @author Alexander Ries (D062114)
*
*/
public class Colors {
public static final String WHITE = "#FFFFFF";
public static final String LIGHT_GREY = "#FFFFFF";
public static final String DARK_GREY = "#FFFFFF";
public static final String LIGHT_TEXT_COLOR = "#FFFFFF";
public static final String DARK_TEXT_COLOR = "#FFFFFF";
public static final String DARK_BLUE = "#FFFFFF";
public static final String LIGHT_BLUE = "#FFFFFF";
public static final String YELLOW = "#FFFFFF";
}
@@ -0,0 +1,9 @@
package com.sap.sailing.dashboards.gwt.client.theme;
/**
* @author Alexander Ries (D062114)
*
*/
public class Fonts {
public static final String DASHBOARD_FONT_FAMILY = "'Open Sans', Arial, Verdana, sans-serif";
}
@@ -0,0 +1,13 @@
package com.sap.sailing.dashboards.gwt.client.theme;
/**
* @author Alexander Ries (D062114)
*
*/
public class Sizes {
public static final String DASHBOARD_FONT_SIZE_VERY_SMALL = "12px";
public static final String DASHBOARD_FONT_SIZE_SMALL = "12px";
public static final String DASHBOARD_FONT_SIZE_MEDIUM = "12px";
public static final String DASHBOARD_FONT_SIZE_BIG = "12px";
public static final String DASHBOARD_FONT_SIZE_VERY_BIG = "12px";
}
@@ -0,0 +1,7 @@
@provide 'theme';
/*Colors*/
@def WHITE eval("com.sap.sailing.dashboards.gwt.client.theme.Colors.WHITE");
/*Fonts*/
@def DASHBOARD_FONT_FAMILY eval("com.sap.sailing.dashboards.gwt.client.theme.Fonts.DASHBOARD_FONT_FAMILY");
@@ -0,0 +1,37 @@
package com.sap.sailing.dashboards.gwt.client.util;
import org.moxieapps.gwt.highcharts.client.Chart;
import com.google.gwt.user.client.Timer;
/**
* @author Alexander Ries (D062114)
*
*/
public class HighchartsUtil {
/**
* The {@link Chart} spacing is not consistent
* so there is a need to correct the top, bottom and right spacing
* of the chart to make it look visually right.
* */
public static void correctSpacingOfChart(Chart chart) {
chart.setSpacingTop(17)
.setSpacingBottom(13)
.setSpacingRight(35);
}
/**
* In cases where it is necessary to initialize a {@link Chart} with dynamic size during the same browser loop, where it´s dynamic container is initialized,
* the {@link Chart.setSizeToMatchContainer()} method will not work. The solution to that problem is to call {@link Chart#setSizeToMatchContainer()} later,
* when the container of the chart is completely initialized and its size is available to the {@link Chart}.
* */
public static void setSizeToMatchContainerDelayed(final Chart chart) {
Timer elapsedTimer = new Timer() {
public void run() {
chart.setSizeToMatchContainer();
}
};
elapsedTimer.schedule(500);
}
}
@@ -1,11 +1,11 @@
@CHARSET "UTF-8";
.blurred {
-webkit-filter: blur(10pt) brightness(0.92);
filter: blur(10pt) brightness(0.92);
-webkit-filter: brightness(0.7);
filter: brightness(0.7);
}
.not_blurred {
-webkit-filter: blur(0pt) brightness(1);
filter: blur(0pt) brightness(1);
-webkit-filter: brightness(1);
filter: brightness(1);
}
@@ -0,0 +1,13 @@
package com.sap.sailing.dashboards.gwt.client.widgets;
import com.sap.sailing.dashboards.gwt.client.DashboardClientFactory;
import com.sap.sse.gwt.client.player.TimeListener;
/**
* @author Alexander Ries (D062114)
*
*/
public interface PollsLiveDataEvery5Seconds extends TimeListener {
public void registerForDashboardFiveSecondsTimer(DashboardClientFactory dashboardClientFactory);
}
@@ -1,4 +1,4 @@
@CHARSET "UTF-8";
@require 'theme';
.combinedWindPanel {
margin-top: 10pt;
@@ -18,7 +18,7 @@
line-height: 25pt;
vertical-align: middle;
font-size: 11pt;
font-family: "Arial";
font-family: DASHBOARD_FONT_FAMILY;
text-align: center;
}
@@ -1,6 +1,6 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis;
package com.sap.sailing.dashboards.gwt.client.widgets.startanalysis;
import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO;
import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisDTO;
public interface StartAnalysisPageChangeListener {
@@ -1,4 +1,4 @@
@CHARSET "UTF-8";
@require 'theme';
.startanalysis {
position: absolute;
@@ -10,13 +10,13 @@
bottom: 0pt;
}
.panelHeader {
.panel_header {
height: 100%;
margin-top: 0;
line-height: 30pt;
vertical-align: middle;
font-size: 14pt;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
font-family: DASHBOARD_FONT_FAMILY;
width: 100%;
text-align: center;
font-weight: bold;
@@ -24,22 +24,22 @@
background-color: white;
}
.startanalysis_controll_header_button {
.controll_header_button {
position: absolute;
top: 10pt;
height: 17.5pt;
width: 17.5pt;
}
.startanalysis_controll_header_button_left {
.controll_header_button_left {
left: 10%;
}
.startanalysis_controll_header_button_right {
.controll_header_button_right {
right: 10%;
}
.startanalysis_card_container {
.card_container {
position: absolute;
overflow: visible;
top: 33.5pt;
@@ -51,7 +51,7 @@
transition: left 0.7s ease-in-out;
}
.startanalysis_card {
.card {
position: absolute;
display: inline;
width: 80%;
@@ -62,7 +62,7 @@
overflow: hidden;
}
.startanalysis_card_table {
.card_table {
position: absolute;
bottom: 0pt;
right: 0pt;
@@ -74,7 +74,7 @@
z-index: 2;
}
.startanalysis_card_wind_line_data_container {
.card_wind_line_data_container {
position: absolute;
top: 10pt;
left: 10pt;
@@ -83,7 +83,7 @@
z-index: 1;
}
.startanalysis_card_data {
.card_data {
position: absolute;
right: 0pt;
width: 45pt;
@@ -91,11 +91,11 @@
line-height: 25pt;
vertical-align: middle;
font-size: 11pt;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
font-family: DASHBOARD_FONT_FAMILY;
text-align: center;
}
.startanalysis_card_line_advantage {
.card_line_advantage {
top: 0pt;
left: 55pt;
width: 215pt;
@@ -104,7 +104,7 @@
background-color: white;
}
.startanalysis_card_race_time{
.card_race_time{
position: absolute;
top: 10pt;
right: 10pt;
@@ -113,11 +113,11 @@
color: white;
line-height: 25pt;
font-size: 11pt;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
font-family: DASHBOARD_FONT_FAMILY;
z-index: 1;
}
.startanalysis_card_line_data_geo {
.card_line_data_geo {
top: 0pt;
left: 220pt;
width: 100pt;
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis;
package com.sap.sailing.dashboards.gwt.client.widgets.startanalysis;
import java.util.ArrayList;
import java.util.Date;
@@ -12,10 +12,10 @@ 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.resources.client.CssResource;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusPanel;
@@ -24,44 +24,43 @@ import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.RibDashboardImageResources;
import com.sap.sailing.dashboards.gwt.client.RibDashboardServiceAsync;
import com.sap.sailing.dashboards.gwt.client.notifications.BottomNotification;
import com.sap.sailing.dashboards.gwt.client.notifications.BottomNotificationClickListener;
import com.sap.sailing.dashboards.gwt.client.notifications.BottomNotificationType;
import com.sap.sailing.dashboards.gwt.client.DashboardClientFactory;
import com.sap.sailing.dashboards.gwt.client.actions.GetCompetitorInLeaderboardAction;
import com.sap.sailing.dashboards.gwt.client.actions.GetStartAnalysesAction;
import com.sap.sailing.dashboards.gwt.client.notifications.bottom.BottomNotification;
import com.sap.sailing.dashboards.gwt.client.notifications.bottom.BottomNotificationClickListener;
import com.sap.sailing.dashboards.gwt.client.notifications.bottom.BottomNotificationType;
import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.CompetitorSelectionListener;
import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.CompetitorSelectionPopup;
import com.sap.sailing.dashboards.gwt.client.popups.competitorselection.SettingsButtonWithSelectionIndicationLabel;
import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO;
import com.sap.sailing.dashboards.gwt.client.widgets.PollsLiveDataEvery5Seconds;
import com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.card.StartAnalysisCard;
import com.sap.sailing.dashboards.gwt.shared.DashboardURLParameters;
import com.sap.sailing.dashboards.gwt.shared.dto.LeaderboardCompetitorsDTO;
import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysesDTO;
import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisDTO;
import com.sap.sailing.domain.common.dto.CompetitorDTO;
import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
import com.sap.sse.gwt.client.player.TimeListener;
import com.sap.sse.gwt.client.player.Timer;
import com.sap.sse.gwt.client.player.Timer.PlayModes;
/**
* The class contains an collection of {@link StartlineAnalysisCard}s that are displayed in horizontal aligned pages. It
* shows only one {@link StartlineAnalysisCard} at a time and enables the user to switch between
* {@link StartlineAnalysisCard}s with left and right buttons represented by {@link #left_focus_panel} and
* {@link #right_focus_panel}. When a new {@link StartlineAnalysisCard} gets added to the component it shows a
* The class contains an collection of {@link StartAnalysisCard}s that are displayed in horizontal aligned pages. It
* shows only one {@link StartAnalysisCard} at a time and enables the user to switch between
* {@link StartAnalysisCard}s with left and right buttons represented by {@link #left_focus_panel} and
* {@link #right_focus_panel}. When a new {@link StartAnalysisCard} gets added to the component it shows a
* {@link BottomNotification}.
*
* @author Alexander Ries (D062114)
*
*/
public class StartlineAnalysisComponent extends Composite implements HasWidgets {
public class StartAnalysisWidget extends Composite implements HasWidgets, PollsLiveDataEvery5Seconds {
private static StartlineAnalysisComponentUiBinder uiBinder = GWT.create(StartlineAnalysisComponentUiBinder.class);
private static StartAnalysisWidgetUiBinder uiBinder = GWT.create(StartAnalysisWidgetUiBinder.class);
interface StartlineAnalysisComponentUiBinder extends UiBinder<Widget, StartlineAnalysisComponent> {
interface StartAnalysisWidgetUiBinder extends UiBinder<Widget, StartAnalysisWidget> {
}
interface StartlineAnalysis extends CssResource {
}
@UiField
StartlineAnalysis style;
@UiField
HTMLPanel header;
@@ -78,7 +77,7 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
FocusPanel right_focus_panel;
/**
* Gets populated with new {@link StartlineAnalysisCard}s when the method
* Gets populated with new {@link StartAnalysisCard}s when the method
* {@link #addStartAnalysisCard(StartAnalysisDTO)} gets called.
* */
@UiField
@@ -90,65 +89,57 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
private double currentScrollPosition = 0;
/**
* The page or {@link StartlineAnalysisCard} the {@link #startanalysis_card_container} displays. Begins with 0.
* The page or {@link StartAnalysisCard} the {@link #startanalysis_card_container} displays. Begins with 0.
* */
private int page = 0;
/**
* Amount of {@link StartlineAnalysisCard}s in {@link #startanalysis_card_container}.
* Amount of {@link StartAnalysisCard}s in {@link #startanalysis_card_container}.
* */
private int numberOfStartAnalysisCards = 0;
private boolean displaysCards;
private List<StartAnalysisDTO> starts;
private List<StartlineAnalysisCard> pageChangeListener;
private List<StartAnalysisCard> pageChangeListener;
private BottomNotification bottomNotification;
private Timer timer;
private RibDashboardServiceAsync ribDashboardServiceAsync;
private SailingServiceAsync sailingServiceAsync;
private static final int RERFRESH_INTERVAL = 10000;
private CompetitorSelectionPopup competitorSelectionPopup;
private SettingsButtonWithSelectionIndicationLabel settingsButtonWithSelectionIndicationLabel;
private DashboardClientFactory dashboardClientFactory;
private String leaderboardName;
private static final String PARAM_LEADERBOARD_NAME = "leaderboardName";
private static final String SELECTED_COMPETITOR_ID_COOKIE_KEY = "selectedCompetitorId";
private static final int SELECTED_COMPETITOR_ID_COOKIE_KEY_EXPIRE_TIME_IN_MILLIS = 60 * 1000 * 60 * 5;
private static final int SCROLL_OFFSET_STARTANALYSIS_CARDS = 83;
private static final Logger logger = Logger.getLogger(StartlineAnalysisComponent.class.getName());
private static final Logger logger = Logger.getLogger(StartAnalysisWidget.class.getName());
/**
* Component that contains handles, displays and loads startanalysis cards.
* */
public StartlineAnalysisComponent(RibDashboardServiceAsync ribDashboardServiceAsync, SailingServiceAsync sailingServiceAsync) {
this.ribDashboardServiceAsync = ribDashboardServiceAsync;
this.sailingServiceAsync = sailingServiceAsync;
pageChangeListener = new ArrayList<StartlineAnalysisCard>();
public StartAnalysisWidget(DashboardClientFactory dashboardClientFactory) {
StartAnalysisWidgetResources.INSTANCE.gss().ensureInjected();
StartAnalysisWidgetResources.INSTANCE.combinedWindPanelStyle().ensureInjected();
this.dashboardClientFactory = dashboardClientFactory;
pageChangeListener = new ArrayList<StartAnalysisCard>();
starts = new ArrayList<StartAnalysisDTO>();
this.leaderboardName = Window.Location.getParameter(PARAM_LEADERBOARD_NAME);
initWidget(uiBinder.createAndBindUi(this));
initCompetitorSelectionPopupAndAddCompetitorSelectionListener();
initLeftRightButtons();
initTimer();
initAndAddBottomNotification();
getCachedSelectedCompetitorOrAskForWithPopup();
initAndAddSettingsButtonWithSelectionIndicationLabel();
registerForDashboardFiveSecondsTimer(dashboardClientFactory);
}
private void initLeftRightButtons() {
leftButton.setResource(RibDashboardImageResources.INSTANCE.leftdisabled());
leftButton.setResource(StartAnalysisWidgetResources.INSTANCE.leftdisabled());
left_focus_panel.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
clickedArrowButton(false);
}
});
rightButton.setResource(RibDashboardImageResources.INSTANCE.rightdisabled());
rightButton.setResource(StartAnalysisWidgetResources.INSTANCE.rightdisabled());
right_focus_panel.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
@@ -157,53 +148,33 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
});
}
private void initTimer() {
timer = new Timer(PlayModes.Live);
timer.setRefreshInterval(RERFRESH_INTERVAL);
timer.addTimeListener(new TimeListener() {
@Override
public void timeChanged(Date newTime, Date oldTime) {
String selectedCompetitorId = Cookies.getCookie(SELECTED_COMPETITOR_ID_COOKIE_KEY);
if (selectedCompetitorId != null) {
loadStartAnalysisDTOsForCompetitorID(selectedCompetitorId);
} else {
loadCompetitorsAndShowCompetitorSelectionPopup();
}
}
});
}
private void loadStartAnalysisDTOsForCompetitorID(String competitorIdAsString){
logger.log(Level.INFO, "Loading startanalysis for competitor id " + competitorIdAsString);
ribDashboardServiceAsync.getStartAnalysisListForCompetitorIDAndLeaderboardName(
competitorIdAsString, leaderboardName, new AsyncCallback<List<StartAnalysisDTO>>() {
@Override
public void onSuccess(List<StartAnalysisDTO> result) {
logger.log(Level.INFO, "Received startanalysis list");
if (result != null && !result.isEmpty()) {
if (displayedStartAnalysisCompetitorDifferentToRequestedOne()) {
removeAllStartAnalysisCards();
}
if (result.size() != starts.size()) {
showNotificationForNewStartAnalysis();
}
logger.log(Level.INFO, "Updating UI with startanalysis list");
addNewStartAnalysisCards(result);
settingsButtonWithSelectionIndicationLabel
.setSelectionIndicationTextOnLabel(result.get(0).competitor.getName());
} else {
logger.log(Level.INFO, "Received startanalysis list is null or empty");
}
}
dashboardClientFactory.getDispatch().execute(new GetStartAnalysesAction(DashboardURLParameters.LEADERBOARD_NAME.getValue(), competitorIdAsString), new AsyncCallback<StartAnalysesDTO>() {
@Override
public void onFailure(Throwable caught) {
logger.log(Level.INFO, "Failed to received startanalysis list, "+caught.getMessage());
}
});
@Override
public void onFailure(Throwable caught) {
logger.log(Level.INFO, "Failed to received startanalysis list, "+caught.getMessage());
}
@Override
public void onSuccess(StartAnalysesDTO result) {
logger.log(Level.INFO, "Received startanalysis list");
if (result != null && !result.getStartAnalyses().isEmpty()) {
if (displayedStartAnalysisCompetitorDifferentToRequestedOne()) {
removeAllStartAnalysisCards();
}
if (result.getStartAnalyses().size() != starts.size()) {
showNotificationForNewStartAnalysis();
}
logger.log(Level.INFO, "Updating UI with startanalysis list");
addNewStartAnalysisCards(result.getStartAnalyses());
settingsButtonWithSelectionIndicationLabel.setSelectionIndicationTextOnLabel(result.getStartAnalyses().get(0).competitor.getName());
} else {
logger.log(Level.INFO, "Received startanalysis list is null or empty");
}
}
});
}
private void initAndAddBottomNotification() {
@@ -247,27 +218,28 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
private void loadCompetitorsAndShowCompetitorSelectionPopup() {
logger.log(Level.INFO, "Requesting Competitors in Leaderboard");
ribDashboardServiceAsync.getCompetitorsInLeaderboard(leaderboardName, new AsyncCallback<List<CompetitorDTO>>() {
@Override
public void onSuccess(List<CompetitorDTO> result) {
logger.log(Level.INFO, "Received competitors for leaderboard name");
if (result != null && result.size() > 0) {
if (!competitorSelectionPopup.isShown()) {
logger.log(Level.INFO, "Showing CompetitorSelectionPopup with competitors");
competitorSelectionPopup.show(result);
} else {
logger.log(Level.INFO, "CompetitorSelectionPopup aleady shown");
}
} else {
logger.log(Level.INFO, "Received competitors are null or empty");
}
}
dashboardClientFactory.getDispatch().execute(new GetCompetitorInLeaderboardAction(DashboardURLParameters.LEADERBOARD_NAME.getValue()), new AsyncCallback<LeaderboardCompetitorsDTO>() {
@Override
public void onFailure(Throwable caught) {
logger.log(Level.INFO, "Failed to received competitors for leaderboard name, "+caught.getMessage());
}
});
@Override
public void onSuccess(LeaderboardCompetitorsDTO result) {
logger.log(Level.INFO, "Received competitors for leaderboard name");
if (result.getCompetitors() != null && result.getCompetitors().size() > 0) {
if (!competitorSelectionPopup.isShown()) {
logger.log(Level.INFO, "Showing CompetitorSelectionPopup with competitors");
competitorSelectionPopup.show(result.getCompetitors());
} else {
logger.log(Level.INFO, "CompetitorSelectionPopup aleady shown");
}
} else {
logger.log(Level.INFO, "Received competitors are null or empty");
}
}
@Override
public void onFailure(Throwable caught) {
logger.log(Level.INFO, "Failed to received competitors for leaderboard name, "+caught.getMessage());
}
});
}
private void initAndAddSettingsButtonWithSelectionIndicationLabel() {
@@ -298,11 +270,11 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
int displayPage = page + 1;
header.getElement().setInnerHTML("Start " + starts.get(displayPage - 1).raceName);
if (page != numberOfStartAnalysisCards - 1) {
rightButton.setResource(RibDashboardImageResources.INSTANCE.right());
rightButton.setResource(StartAnalysisWidgetResources.INSTANCE.right());
rightButton.getElement().getStyle().setProperty("disabled", "false");
}
if (page == 0) {
leftButton.setResource(RibDashboardImageResources.INSTANCE.leftdisabled());
leftButton.setResource(StartAnalysisWidgetResources.INSTANCE.leftdisabled());
leftButton.getElement().getStyle().setProperty("disabled", "true");
}
}
@@ -315,11 +287,11 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
int displayPage = page + 1;
header.getElement().setInnerHTML("Start " + starts.get(displayPage - 1).raceName);
if (page >= 0) {
leftButton.setResource(RibDashboardImageResources.INSTANCE.left());
leftButton.setResource(StartAnalysisWidgetResources.INSTANCE.left());
leftButton.getElement().getStyle().setProperty("disabled", "false");
}
if (page == numberOfStartAnalysisCards - 1) {
rightButton.setResource(RibDashboardImageResources.INSTANCE.rightdisabled());
rightButton.setResource(StartAnalysisWidgetResources.INSTANCE.rightdisabled());
rightButton.getElement().getStyle().setProperty("disabled", "true");
}
}
@@ -335,9 +307,9 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
startanalysis_card_container.getElement().getStyle().setLeft(currentScrollPosition, Unit.PCT);
header.getElement().setInnerHTML("Start " + starts.get(page).raceName);
notifyStartAnalysisPageChangeListener(page);
rightButton.setResource(RibDashboardImageResources.INSTANCE.rightdisabled());
rightButton.setResource(StartAnalysisWidgetResources.INSTANCE.rightdisabled());
rightButton.getElement().getStyle().setProperty("disabled", "true");
leftButton.setResource(RibDashboardImageResources.INSTANCE.left());
leftButton.setResource(StartAnalysisWidgetResources.INSTANCE.left());
leftButton.getElement().getStyle().setProperty("disabled", "false");
}
}
@@ -346,14 +318,14 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
logger.log(Level.INFO, "Adding Startanalysis Card");
if (displaysCards == false) {
displaysCards = true;
header.getElement().setInnerHTML("Start " + startAnalysisDTO.raceName);
header.getElement().setInnerHTML("Start " + SafeHtmlUtils.fromString(startAnalysisDTO.raceName));
}
if (numberOfStartAnalysisCards > 0) {
rightButton.setResource(RibDashboardImageResources.INSTANCE.right());
rightButton.setResource(StartAnalysisWidgetResources.INSTANCE.right());
}
final StartlineAnalysisCard startlineAnalysisCard = new StartlineAnalysisCard(numberOfStartAnalysisCards
final StartAnalysisCard startlineAnalysisCard = new StartAnalysisCard(numberOfStartAnalysisCards
* SCROLL_OFFSET_STARTANALYSIS_CARDS + 10, numberOfStartAnalysisCards, startAnalysisDTO,
sailingServiceAsync);
dashboardClientFactory.getSailingService());
startanalysis_card_container.add(startlineAnalysisCard);
startlineAnalysisCard.startAnalysisComponentPageChangedToIndexAndStartAnalysis(page, startAnalysisDTO);
registerPageChangeListener(startlineAnalysisCard);
@@ -370,7 +342,7 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
this.bottomNotification.show(BottomNotificationType.NEW_STARTANALYSIS_AVAILABLE);
}
public void registerPageChangeListener(StartlineAnalysisCard s) {
public void registerPageChangeListener(StartAnalysisCard s) {
pageChangeListener.add(s);
}
@@ -412,6 +384,23 @@ public class StartlineAnalysisComponent extends Composite implements HasWidgets
return false;
}
}
@Override
public void timeChanged(Date newTime, Date oldTime) {
String selectedCompetitorId = Cookies.getCookie(SELECTED_COMPETITOR_ID_COOKIE_KEY);
if (selectedCompetitorId != null) {
loadStartAnalysisDTOsForCompetitorID(selectedCompetitorId);
} else {
loadCompetitorsAndShowCompetitorSelectionPopup();
}
}
@Override
public void registerForDashboardFiveSecondsTimer(DashboardClientFactory dashboardClientFactory) {
if (dashboardClientFactory != null) {
dashboardClientFactory.getDashboardFiveSecondsTimer().addTimeListener(this);
}
}
@Override
public void add(Widget w) {
@@ -0,0 +1,22 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="resources" type="com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.StartAnalysisWidgetResources"/>
<g:HTMLPanel styleName="{resources.gss.startanalysis}">
<g:HTMLPanel ui:field="header" styleName="{resources.gss.panel_header}">
No Starts Available
</g:HTMLPanel>
<g:Image resource="{resources.left}" ui:field="leftButton"
styleName="{resources.gss.controll_header_button} {resources.gss.controll_header_button_left}"></g:Image>
<g:Image resource="{resources.right}" ui:field="rightButton"
styleName="{resources.gss.controll_header_button} {resources.gss.controll_header_button_right}"></g:Image>
<g:FocusPanel ui:field="left_focus_panel" styleName="{resources.gss.left_focus_panel}"></g:FocusPanel>
<g:FocusPanel ui:field="right_focus_panel" styleName="{resources.gss.right_focus_panel}"></g:FocusPanel>
<g:HTMLPanel ui:field="startanalysis_card_container"
styleName="{resources.gss.card_container}">
</g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,51 @@
package com.sap.sailing.dashboards.gwt.client.widgets.startanalysis;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.ImageResource;
import com.sap.sailing.gwt.ui.client.shared.racemap.CombinedWindPanelStyle;
public interface StartAnalysisWidgetResources extends ClientBundle {
public static final StartAnalysisWidgetResources INSTANCE = GWT.create(StartAnalysisWidgetResources.class);
@Source("com/sap/sailing/dashboards/gwt/client/images/leftarrow.png")
ImageResource left();
@Source("com/sap/sailing/dashboards/gwt/client/images/rightarrow.png")
ImageResource right();
@Source("com/sap/sailing/dashboards/gwt/client/images/leftarrow_disabled.png")
ImageResource leftdisabled();
@Source("com/sap/sailing/dashboards/gwt/client/images/rightarrow_disabled.png")
ImageResource rightdisabled();
@Source("com/sap/sailing/dashboards/gwt/client/images/windarrow.png")
ImageResource combinedWindIcon();
@Source({"com/sap/sailing/dashboards/gwt/client/theme/theme.gss", "StartAnalysisWidget.gss"})
StartAnalysisGSS gss();
@Source({"com/sap/sailing/dashboards/gwt/client/theme/theme.gss", "StartAnalysisCombinedWindPanel.gss"})
CombinedWindPanelStyle combinedWindPanelStyle();
public interface StartAnalysisGSS extends CssResource {
String startanalysis();
String panel_header();
String controll_header_button();
String controll_header_button_left();
String controll_header_button_right();
String card_container();
String card();
String card_table();
String card_wind_line_data_container();
String card_data();
String card_line_advantage();
String card_race_time();
String card_line_data_geo();
String left_focus_panel();
String right_focus_panel();
}
}
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis;
package com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.card;
import java.util.ArrayList;
import java.util.Collections;
@@ -12,14 +12,18 @@ import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.startanalysis.rankingtable.StartAnalysisStartRankTable;
import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisDTO;
import com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.StartAnalysisPageChangeListener;
import com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.StartAnalysisWidgetResources;
import com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.rankingtable.StartAnalysisStartRankTable;
import com.sap.sailing.dashboards.gwt.shared.StartlineAdvantageType;
import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisDTO;
import com.sap.sailing.domain.common.racelog.RacingProcedureType;
import com.sap.sailing.gwt.ui.client.CompetitorColorProvider;
import com.sap.sailing.gwt.ui.client.CompetitorColorProviderImpl;
@@ -35,19 +39,16 @@ import com.sap.sailing.gwt.ui.client.shared.racemap.RaceMapZoomSettings.ZoomType
import com.sap.sse.gwt.client.async.AsyncActionsExecutor;
import com.sap.sse.gwt.client.player.Timer.PlayModes;
public class StartlineAnalysisCard extends Composite implements HasWidgets, StartAnalysisPageChangeListener {
public class StartAnalysisCard extends Composite implements HasWidgets, StartAnalysisPageChangeListener {
private static StartlineAnalysisCardUiBinder uiBinder = GWT.create(StartlineAnalysisCardUiBinder.class);
interface StartlineAnalysisCardUiBinder extends UiBinder<Widget, StartlineAnalysisCard> {
interface StartlineAnalysisCardUiBinder extends UiBinder<Widget, StartAnalysisCard> {
}
interface StartlineAnalysis extends CssResource {
}
@UiField
StartlineAnalysis style;
@UiField
HTMLPanel startanalysis_card;
@@ -74,12 +75,8 @@ public class StartlineAnalysisCard extends Composite implements HasWidgets, Star
private final int TABLE_MARGIN_IN_PT = 10;
private final String RACE_TIME_START = "00:00:00";
private static StartAnalysisResources resources = GWT.create(StartAnalysisResources.class);
public StartlineAnalysisCard(double leftCSSProperty, int cardId, StartAnalysisDTO startAnalysisDTO,
SailingServiceAsync sailingServiceAsync) {
public StartAnalysisCard(double leftCSSProperty, int cardId, StartAnalysisDTO startAnalysisDTO, SailingServiceAsync sailingServiceAsync) {
stringMessages = StringMessages.INSTANCE;
resources.combinedWindPanelStyle().ensureInjected();
this.sailingServiceAsync = sailingServiceAsync;
colorProvider = new CompetitorColorProviderImpl();
competitorSelectionModel = new CompetitorSelectionModel(/* hasMultiSelection */true, colorProvider);
@@ -96,20 +93,20 @@ public class StartlineAnalysisCard extends Composite implements HasWidgets, Star
private void fillWindAndStartLineData(StartAnalysisDTO startAnalysisDTO) {
if (startAnalysisDTO.startAnalysisWindLineInfoDTO != null) {
setLineAdvantageDivWidth(startAnalysisDTO.startAnalysisWindLineInfoDTO.startLineAdvantage.startLineAdvatageType);
String startLineAdvantageType;
final String startLineAdvantageType;
if (startAnalysisDTO.startAnalysisWindLineInfoDTO.startLineAdvantage.startLineAdvatageType
.equals(StartlineAdvantageType.GEOMETRIC)) {
startLineAdvantageType = stringMessages.dashboardStartlineAdvantageByGeometry();
}else{
} else {
startLineAdvantageType = stringMessages.dashboardStartlineAdvantagesByWind();
}
startanalysis_card_line_advantage
.setInnerHTML(startLineAdvantageType
.setInnerHTML(SafeHtmlUtils.fromString(startLineAdvantageType
+ ": "
+ NumberFormat
.getFormat("#0.0")
.format(startAnalysisDTO.startAnalysisWindLineInfoDTO.startLineAdvantage.startLineAdvantage)
+ " m");
+ " m").asString());
String formattedTimeSinceStart;
if (startAnalysisDTO.racingProcedureType.equals(RacingProcedureType.GateStart)) {
formattedTimeSinceStart = getRaceTimeStringFromMilliseconds(startAnalysisDTO.tailLenghtInMilliseconds);
@@ -152,8 +149,7 @@ public class StartlineAnalysisCard extends Composite implements HasWidgets, Star
asyncActionsExecutor, null, Collections.singletonList(startAnalysisDTO.regattaAndRaceIdentifier), 5000l /* requestInterval */);
raceMap = new RaceMap(sailingServiceAsync, asyncActionsExecutor, null, timer, competitorSelectionModel,
StringMessages.INSTANCE, false, false, false, false, startAnalysisDTO.regattaAndRaceIdentifier,
resources.combinedWindPanelStyle(), /* showHeaderPanel */ true);
raceMap.onRaceSelectionChange(Collections.singletonList(startAnalysisDTO.regattaAndRaceIdentifier));
StartAnalysisWidgetResources.INSTANCE.combinedWindPanelStyle(), /* showHeaderPanel */ true);
raceMap.getSettings().setZoomSettings(new RaceMapZoomSettings(zoomTypes, false));
raceMap.getSettings().setHelpLinesSettings(getHelpLineSettings());
raceMap.getSettings().setTailLengthInMilliseconds(startAnalysisDTO.tailLenghtInMilliseconds);
@@ -0,0 +1,16 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="resources" type="com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.StartAnalysisWidgetResources"/>
<g:HTMLPanel ui:field="startanalysis_card" styleName="{resources.gss.card}">
<div class="{resources.gss.card_wind_line_data_container}">
<div ui:field="startanalysis_card_line_advantage"
class="{resources.gss.card_data} {resources.gss.card_line_advantage}"></div>
</div>
<div ui:field="startanalysis_card_race_time" class="{resources.gss.card_race_time}">Time: 00:05:00</div>
<g:HTMLPanel ui:field="startanalysis_card_table"
styleName="{resources.gss.card_table}"></g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis.rankingtable;
package com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.rankingtable;
import java.util.List;
@@ -9,7 +9,7 @@ import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.sap.sailing.dashboards.gwt.shared.dto.startanalysis.StartAnalysisCompetitorDTO;
import com.sap.sailing.dashboards.gwt.shared.dto.StartAnalysisCompetitorDTO;
import com.sap.sailing.gwt.ui.client.CompetitorSelectionModel;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.common.Util.Pair;
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis.rankingtable;
package com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.rankingtable;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis.rankingtable;
package com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.rankingtable;
import com.google.gwt.user.cellview.client.Column;
import com.sap.sse.common.Util.Pair;
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis.rankingtable;
package com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.rankingtable;
import com.google.gwt.user.cellview.client.CellTable;
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis.rankingtable;
package com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.rankingtable;
import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.Cell;
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.startanalysis.rankingtable;
package com.sap.sailing.dashboards.gwt.client.widgets.startanalysis.rankingtable;
import com.google.gwt.user.cellview.client.Column;
import com.sap.sse.common.Util.Pair;
@@ -1,4 +1,4 @@
@CHARSET "UTF-8";
@require 'theme';
.startLineAdvantageComponent_liveAveragePanel {
bottom: 5pt;
@@ -19,12 +19,12 @@
bottom: 20%;
}
.startLineAdvantageComponent_middleLine{
top: 35%
.startLineAdvantageComponent_middleLine {
top: 35%;
bottom: 20%;
}
.startLineAdvantageComponent_wrapper{
.startLineAdvantageComponent_wrapper {
position: absolute;
width: 100%;
height: 100%;
@@ -0,0 +1,82 @@
package com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.course;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.sap.sailing.dashboards.gwt.client.DashboardClientFactory;
import com.sap.sailing.dashboards.gwt.client.actions.GetStartlineAdvantageByGeometryAction;
import com.sap.sailing.dashboards.gwt.client.widgets.PollsLiveDataEvery5Seconds;
import com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.util.LiveAverageComponent;
import com.sap.sailing.dashboards.gwt.shared.DashboardURLParameters;
import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO;
import com.sap.sailing.gwt.ui.client.StringMessages;
/**
* The purpose of the class is to display the live and average start line advantage either by wind or by geometry. There
* is only one advantage display at once, so the user can switch between these following two
* {@link StartLineAdvantageComponentState}s {@link StartLineAdvantageComponentStateShowsAdvantageByWind} and
* {@link StartLineAdvantageComponentStateShowsAdvantageByGeometry} by tabing somewhere at the widget. The class extends
* from {@link LiveAverageComponent} to get necessary Ui Elements but customizes these with own CSS.
*
* @author Alexander Ries (D062114)
*
*/
public class StartLineAdvantageByGeometryWidget extends LiveAverageComponent implements PollsLiveDataEvery5Seconds {
private DashboardClientFactory dashboardClientFactory;
private static StringMessages stringConstants = StringMessages.INSTANCE;
private static final Logger logger = Logger.getLogger(StartLineAdvantageByGeometryWidget.class.getName());
public StartLineAdvantageByGeometryWidget(DashboardClientFactory dashboardClientFactory) {
super(stringConstants.dashboardStartlineAdvantageByGeometry(), "m");
this.dashboardClientFactory = dashboardClientFactory;
StartLineAdvantageByGeometryWidgetRessources.INSTANCE.gss().ensureInjected();
this.header.setInnerText(stringConstants.dashboardStartlineAdvantageByGeometry());
this.header.addClassName(StartLineAdvantageByGeometryWidgetRessources.INSTANCE.gss().startLineAdvantageComponent_header());
liveAveragePanel.getElement().addClassName(StartLineAdvantageByGeometryWidgetRessources.INSTANCE.gss().startLineAdvantageComponent_liveAveragePanel());
livePanel.getElement().addClassName(StartLineAdvantageByGeometryWidgetRessources.INSTANCE.gss().startLineAdvantageComponent_livePanel());
middleLine.getElement().addClassName(StartLineAdvantageByGeometryWidgetRessources.INSTANCE.gss().startLineAdvantageComponent_middleLine());
averagePanel.getElement().addClassName(StartLineAdvantageByGeometryWidgetRessources.INSTANCE.gss().startLineAdvantageComponent_averagePanel());
this.liveLabel.setInnerHTML(stringConstants.dashboardLiveWind());
this.averageLabel.setInnerHTML(stringConstants.dashboardAverageWind()+"<br>"+stringConstants.dashboardAverageWindMinutes(15));
registerForDashboardFiveSecondsTimer(dashboardClientFactory);
}
@Override
public void timeChanged(Date newTime, Date oldTime) {
String leaderboardNameParameterValue = DashboardURLParameters.LEADERBOARD_NAME.getValue();
if (leaderboardNameParameterValue != null) {
dashboardClientFactory.getDispatch().execute(
new GetStartlineAdvantageByGeometryAction(leaderboardNameParameterValue),
new AsyncCallback<StartLineAdvantageDTO>() {
@Override
public void onFailure(Throwable caught) {
logger.log(Level.INFO, "Failed to received startline advantage by geometry");
}
@Override
public void onSuccess(StartLineAdvantageDTO result) {
if (result.startLineAdvantage != null) {
logger.log(Level.INFO, "Updating UI with RibDashboardRaceInfoDTO.startLineAdvantageDTO");
setLiveValue(NumberFormat.getFormat("#0.0").format(result.startLineAdvantage.doubleValue()));
setAverageValue(NumberFormat.getFormat("#0.0").format(result.average.doubleValue()));
} else {
logger.log(Level.INFO, "RibDashboardRaceInfoDTO.startLineAdvantageDTO is 0");
}
}
});
}
}
@Override
public void registerForDashboardFiveSecondsTimer(DashboardClientFactory dashboardClientFactory) {
if (dashboardClientFactory != null) {
dashboardClientFactory.getDashboardFiveSecondsTimer().addTimeListener(this);
}
}
}
@@ -1,18 +1,19 @@
package com.sap.sailing.dashboards.gwt.client.startlineadvantage;
package com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.course;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.CssResource.Shared;
public interface StartLineAdvantageComponentRessources extends ClientBundle {
public static final StartLineAdvantageComponentRessources INSTANCE = GWT.create(StartLineAdvantageComponentRessources.class);
public interface StartLineAdvantageByGeometryWidgetRessources extends ClientBundle {
public static final StartLineAdvantageByGeometryWidgetRessources INSTANCE = GWT.create(StartLineAdvantageByGeometryWidgetRessources.class);
@Source("StartLineAdvantageComponent.css")
LocalCss css();
@Source({"com/sap/sailing/dashboards/gwt/client/theme/theme.gss", "StartLineAdvantageByGeometryWidget.gss"})
StartLineAdvantageByGeometryGss gss();
@Shared
public interface LocalCss extends CssResource {
public interface StartLineAdvantageByGeometryGss extends CssResource {
public String startLineAdvantageComponent_liveAveragePanel();
public String startLineAdvantageComponent_header();
@@ -1,5 +1,6 @@
@require 'theme';
.liveAverageCompoment_panel {
.live_average_component {
position: absolute;
left: 0px;
right: 0px;
@@ -7,7 +8,7 @@
bottom: 0px;
}
.liveAverageCompoment_header_container {
.header_container {
position: absolute;
left: 0px;
right: 0px;
@@ -15,20 +16,20 @@
height: 35%;
}
.liveAverageCompoment_header {
.header {
height: 100%;
margin-top: 5pt;
line-height: 15pt;
vertical-align: middle;
font-size: 13pt;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
font-family: DASHBOARD_FONT_FAMILY;
width: 100%;
text-align: center;
overflow: visible;
font-weight: bold;
}
.liveAverageCompoment_live_container {
.live_container {
position: absolute;
top: 35%;
bottom: 30%;
@@ -36,7 +37,7 @@
left: 0%;
}
.liveAverageCompoment_average_container {
.average_container {
position: absolute;
top: 35%;
bottom: 30%;
@@ -44,7 +45,7 @@
left: 52%;
}
.liveAverageCompoment_middle_line {
.middle_line {
position: absolute;
top: 35%;
height: 30pt;
@@ -54,42 +55,42 @@
z-index: 100;
}
.liveAverageCompoment_panel_value_number {
font-family: 'Open Sans', Arial, Verdana, sans-serif;
.panel_value_number {
font-family: DASHBOARD_FONT_FAMILY;
font-size: 26pt;
}
.liveAverageCompoment_panel_value_unit {
font-family: 'Open Sans', Arial, Verdana, sans-serif;
.panel_value_unit {
font-family: DASHBOARD_FONT_FAMILY;
font-size: 15pt;
}
.liveAverageCompoment_panel_value_unit_degrees {
.panel_value_unit_degrees {
position: absolute;
font-size: 20pt;
font-weight: lighter;
}
.liveAverageCompoment_value_panel {
.value_panel {
margin: 0px;
width: 100%;
height: 90%;
text-align: center;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
font-family: DASHBOARD_FONT_FAMILY;
font-weight: bolder;
}
.liveAverageCompoment_label_text {
.label_text {
margin: 0px;
width: 100%;
height: 100%;
text-align: center;
font-size: 11pt;
color: grey;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
font-family: DASHBOARD_FONT_FAMILY;
}
.liveAverageCompoment_liveLabelContainer {
.live_label_container {
position: absolute;
bottom: 0px;
left: 0px;
@@ -97,7 +98,7 @@
height: 35%;
}
.liveAverageCompoment_averageLabelContainer {
.average_label_container {
position: absolute;
bottom: 0px;
right: 0px;
@@ -1,25 +1,24 @@
package com.sap.sailing.dashboards.gwt.client.startlineadvantage;
package com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.util;
import java.util.Iterator;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.SpanElement;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.visualeffects.NumberTickingAnimation;
import com.sap.sailing.dashboards.gwt.client.windchart.VerticalWindChartClickListener;
import com.sap.sailing.dashboards.gwt.client.windchart.WindBotComponent;
import com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.course.StartLineAdvantageByGeometryWidget;
import com.sap.sailing.dashboards.gwt.client.widgets.windbot.WindBotWidget;
import com.sap.sailing.dashboards.gwt.client.widgets.windbot.charts.VerticalWindChartClickListener;
import com.sap.sailing.gwt.ui.client.StringMessages;
/**
* The purpose of the class is to display a live and an average value of a continuously updating data source.
* {@link StartLineAdvantageByGeometryComponent} extends from it and the class {@link WindBotComponent} uses it to display wind
* {@link StartLineAdvantageByGeometryWidget} extends from it and the class {@link WindBotWidget} uses it to display wind
* data.
*
* @author Alexander Ries (D062114)
@@ -31,17 +30,12 @@ public class LiveAverageComponent extends Composite implements HasWidgets, Verti
interface LiveAverageComponentUiBinder extends UiBinder<Widget, LiveAverageComponent> {
}
interface LiveAverageComponentStyle extends CssResource {
String liveAverageCompoment_panel_value_unit_degrees();
}
@UiField
HTMLPanel liveAveragePanel;
public HTMLPanel liveAveragePanel;
@UiField
DivElement header;
public DivElement header;
@UiField
SpanElement liveNumber;
@@ -56,28 +50,24 @@ public class LiveAverageComponent extends Composite implements HasWidgets, Verti
SpanElement averageUnit;
@UiField
DivElement liveLabel;
public DivElement liveLabel;
@UiField
DivElement averageLabel;
public DivElement averageLabel;
@UiField
HTMLPanel livePanel;
public HTMLPanel livePanel;
@UiField
HTMLPanel middleLine;
public HTMLPanel middleLine;
@UiField
HTMLPanel averagePanel;
@UiField
LiveAverageComponentStyle style;
public HTMLPanel averagePanel;
private StringMessages stringConstants;
private NumberTickingAnimation liveTickingAnimation;
private NumberTickingAnimation averageTickingAnimation;
public LiveAverageComponent() {
LiveAverageComponentResources.INSTANCE.gss().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
}
@@ -89,8 +79,8 @@ public class LiveAverageComponent extends Composite implements HasWidgets, Verti
*
* */
public LiveAverageComponent(String header, String unit) {
LiveAverageComponentResources.INSTANCE.gss().ensureInjected();
stringConstants = StringMessages.INSTANCE;
initTickingAnimations();
initWidget(uiBinder.createAndBindUi(this));
liveAveragePanel.getElement().getStyle().setProperty("backgroundColor", "white");
this.header.setInnerText(header);
@@ -98,37 +88,19 @@ public class LiveAverageComponent extends Composite implements HasWidgets, Verti
this.averageUnit.setInnerText(unit);
// Lifts the degrees unit string "°". Otherwise it would be too small.
if (unit.equals("°")) {
this.liveUnit.addClassName(style.liveAverageCompoment_panel_value_unit_degrees());
this.averageUnit.setClassName(style.liveAverageCompoment_panel_value_unit_degrees());
this.liveUnit.addClassName(LiveAverageComponentResources.INSTANCE.gss().panel_value_unit_degrees());
this.averageUnit.setClassName(LiveAverageComponentResources.INSTANCE.gss().panel_value_unit_degrees());
}
this.liveLabel.setInnerHTML(stringConstants.dashboardLiveWind());
this.averageLabel.setInnerHTML(stringConstants.dashboardAverageWind()+"<br>"+stringConstants.dashboardAverageWindMinutes(15));
}
private void initTickingAnimations() {
liveTickingAnimation = new NumberTickingAnimation() {
@Override
public void setValueInUI(String value) {
liveNumber.setInnerText(value);
}
};
averageTickingAnimation = new NumberTickingAnimation() {
@Override
public void setValueInUI(String value) {
averageNumber.setInnerText(value);
}
};
}
public void setLiveValue(String liveValue) {
liveTickingAnimation.execute(liveValue);
liveNumber.setInnerText(liveValue);
}
public void setAverageValue(String averageValue) {
averageTickingAnimation.execute(averageValue);
averageNumber.setInnerText(averageValue);
}
@Override
@@ -0,0 +1,41 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<ui:with field="resources" type="com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.util.LiveAverageComponentResources"/>
<g:HTMLPanel ui:field="liveAveragePanel" styleName="{resources.gss.live_average_component}">
<g:HTMLPanel styleName="{resources.gss.header_container}">
<div class="{resources.gss.header}" ui:field="header"></div>
</g:HTMLPanel>
<g:HTMLPanel ui:field="livePanel" styleName="{resources.gss.live_container}">
<div class="{resources.gss.value_panel}">
<span class="{resources.gss.panel_value_number}" ui:field="liveNumber"></span>
<span class="{resources.gss.panel_value_unit}" ui:field="liveUnit"></span>
</div>
</g:HTMLPanel>
<g:HTMLPanel ui:field="middleLine" styleName="{resources.gss.middle_line}">
</g:HTMLPanel>
<g:HTMLPanel ui:field="averagePanel" styleName="{resources.gss.average_container}">
<div class="{resources.gss.value_panel}">
<span class="{resources.gss.panel_value_number}" ui:field="averageNumber"></span>
<span class="{resources.gss.panel_value_unit}" ui:field="averageUnit"></span>
</div>
</g:HTMLPanel>
<g:HTMLPanel styleName="{resources.gss.live_label_container}">
<div class="{resources.gss.label_text}" ui:field="liveLabel"></div>
</g:HTMLPanel>
<g:HTMLPanel styleName="{resources.gss.average_label_container}">
<div class="{resources.gss.label_text}" ui:field="averageLabel"></div>
</g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,33 @@
package com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.util;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
/**
* @author Alexander Ries (D062114)
*
*/
public interface LiveAverageComponentResources extends ClientBundle {
public static final LiveAverageComponentResources INSTANCE = GWT.create(LiveAverageComponentResources.class);
@Source({"com/sap/sailing/dashboards/gwt/client/theme/theme.gss", "LiveAverageComponent.gss"})
LiveAverageComponentGss gss();
interface LiveAverageComponentGss extends CssResource {
String live_average_component();
String header();
String header_container();
String live_container();
String average_container();
String middle_line();
String panel_value_number();
String panel_value_unit();
String panel_value_unit_degrees();
String value_panel();
String label_text();
String live_label_container();
String average_label_container();
}
}
@@ -1,6 +1,6 @@
@CHARSET "UTF-8";
@require 'theme';
.startline_advantages_by_wind_component_container{
.start_line_advantages_by_wind_component{
position: absolute;
height: 100%;
width: 100%;
@@ -0,0 +1,127 @@
package com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.wind;
import java.util.Date;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.DashboardClientFactory;
import com.sap.sailing.dashboards.gwt.client.actions.GetStartlineAdvantagesByWindAction;
import com.sap.sailing.dashboards.gwt.client.widgets.PollsLiveDataEvery5Seconds;
import com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.util.LiveAverageComponent;
import com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.wind.charts.StartlineAdvantagesOnLineChart;
import com.sap.sailing.dashboards.gwt.shared.DashboardURLParameters;
import com.sap.sailing.dashboards.gwt.shared.dto.StartlineAdvantagesWithMaxAndAverageDTO;
import com.sap.sailing.gwt.ui.client.StringMessages;
/**
* @author Alexander Ries (D062114)
*
*/
public class StartlineAdvantagesByWindWidget extends Composite implements HasWidgets, PollsLiveDataEvery5Seconds {
private static StartlineAdvantagesByWindComponentUiBinder uiBinder = GWT
.create(StartlineAdvantagesByWindComponentUiBinder.class);
interface StartlineAdvantagesByWindComponentUiBinder extends UiBinder<Widget, StartlineAdvantagesByWindWidget> {
}
interface StartlineAdvantagesByWindComponentStyle extends CssResource {
}
@UiField(provided = true)
LiveAverageComponent advantageMaximumLiveAverage;
@UiField(provided = true)
StartlineAdvantagesOnLineChart startlineAdvantagesOnLineChart;
public DashboardClientFactory dashboardClientFactory;
private static final Logger logger = Logger.getLogger(StartlineAdvantagesByWindWidget.class.getName());
public StartlineAdvantagesByWindWidget(DashboardClientFactory dashboardClientFactory) {
StartlineAdvantagesByWindWidgetResources.INSTANCE.gss().ensureInjected();
this.dashboardClientFactory = dashboardClientFactory;
startlineAdvantagesOnLineChart = new StartlineAdvantagesOnLineChart();
advantageMaximumLiveAverage = new LiveAverageComponent(StringMessages.INSTANCE.dashboardStartlineAdvantagesByWind(), "m");
advantageMaximumLiveAverage.header.getStyle().setFontSize(14, Unit.PT);
advantageMaximumLiveAverage.liveLabel.setInnerHTML("advantage max.");
advantageMaximumLiveAverage.averageLabel.setInnerHTML("advantage max. average "+StringMessages.INSTANCE.dashboardAverageWindMinutes(15));
initWidget(uiBinder.createAndBindUi(this));
registerForDashboardFiveSecondsTimer(dashboardClientFactory);
}
private void loadData() {
logger.log(Level.INFO, "Executing GetStartlineAdvantagesAction");
String leaderboardNameParameterValue = DashboardURLParameters.LEADERBOARD_NAME.getValue();
if (leaderboardNameParameterValue != null) {
dashboardClientFactory.getDispatch().execute(
new GetStartlineAdvantagesByWindAction(leaderboardNameParameterValue),
new AsyncCallback<StartlineAdvantagesWithMaxAndAverageDTO>() {
@Override
public void onSuccess(StartlineAdvantagesWithMaxAndAverageDTO result) {
logger.log(Level.INFO, "Received StartlineAdvantagesWithMaxAndAverageDTO");
if (result != null && result.maximum != null && result.average != null) {
logger.log(Level.INFO, "Updating UI with StartlineAdvantagesWithMaxAndAverageDTO");
startlineAdvantagesOnLineChart.setStartlineAdvantagesAndConfidences(result.distanceToRCBoatToStartlineAdvantage, result.distanceToRCBoatToConfidence);
advantageMaximumLiveAverage.setLiveValue(NumberFormat.getFormat("#0.0").format(
result.maximum.doubleValue()));
advantageMaximumLiveAverage.setAverageValue(NumberFormat.getFormat("#0.0").format(
result.average.doubleValue()));
} else {
logger.log(Level.INFO, "StartlineAdvantagesWithMaxAndAverageDTO is null");
}
}
@Override
public void onFailure(Throwable caught) {
logger.log(Level.INFO, "Failed to received StartlineAdvantagesWithMaxAndAverageDTO, "
+ caught.getMessage());
}
});
}
}
@Override
public void timeChanged(Date newTime, Date oldTime) {
loadData();
}
@Override
public void registerForDashboardFiveSecondsTimer(DashboardClientFactory dashboardClientFactory) {
if (dashboardClientFactory != null) {
dashboardClientFactory.getDashboardFiveSecondsTimer().addTimeListener(this);
}
}
@Override
public void add(Widget w) {
throw new UnsupportedOperationException("The method add(Widget w) is not supported.");
}
@Override
public void clear() {
throw new UnsupportedOperationException("The method clear() is not supported.");
}
@Override
public Iterator<Widget> iterator() {
return null;
}
@Override
public boolean remove(Widget w) {
return false;
}
}
@@ -0,0 +1,17 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui"
xmlns:util="urn:import:com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.util"
xmlns:chart="urn:import:com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.wind.charts">
<ui:with field="resources" type="com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.wind.StartlineAdvantagesByWindWidgetResources"/>
<g:HTMLPanel styleName="{resources.gss.start_line_advantages_by_wind_component}">
<g:HTMLPanel styleName="{resources.gss.advantage_maximum_live_average}">
<util:LiveAverageComponent ui:field="advantageMaximumLiveAverage"></util:LiveAverageComponent>
</g:HTMLPanel>
<g:HTMLPanel styleName="{resources.gss.advantages_on_line_chart_container}">
<chart:StartlineAdvantagesOnLineChart ui:field="startlineAdvantagesOnLineChart"></chart:StartlineAdvantagesOnLineChart>
</g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,23 @@
package com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.wind;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
/**
* @author Alexander Ries (D062114)
*
*/
public interface StartlineAdvantagesByWindWidgetResources extends ClientBundle {
public static final StartlineAdvantagesByWindWidgetResources INSTANCE = GWT.create(StartlineAdvantagesByWindWidgetResources.class);
@Source({"com/sap/sailing/dashboards/gwt/client/theme/theme.gss", "StartlineAdvantagesByWindWidget.gss"})
StartlineAdvantagesOnLineChartGSS gss();
public interface StartlineAdvantagesOnLineChartGSS extends CssResource {
String start_line_advantages_by_wind_component();
String advantage_maximum_live_average();
String advantages_on_line_chart_container();
}
}
@@ -1,4 +1,4 @@
@CHARSET "UTF-8";
@require 'theme';
.advantages_on_line_chart_container {
position: absolute !important;
@@ -6,7 +6,7 @@
bottom: 50px;
left: 0px;
right: 0px;
font-family: 'Open Sans', Arial, Verdana, sans-serif !important;
font-family: DASHBOARD_FONT_FAMILY !important;
}
.confidence_bar_container {
@@ -23,12 +23,12 @@
left: 15px;
right: 15px;
height: 15px;
background: -moz-linear-gradient(left, #FFDD00 0%, #008FFF 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left bottom, right bottom, color-stop(0%,#FFDD00), color-stop(100%,#008FFF)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(left, #FFDD00 0%,#008FFF 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(left, #FFDD00 0%,#008FFF 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(left, #FFDD00 0%,#008FFF 100%); /* IE10+ */
background: linear-gradient(to right, #FFDD00 0%,#008FFF 100%); /* W3C */
/* @alternate */ background: -moz-linear-gradient(left, #FFDD00 0%, #008FFF 100%); /* FF3.6+ */
/* @alternate */ background: -webkit-gradient(linear, left bottom, right bottom, color-stop(0%,#FFDD00), color-stop(100%,#008FFF)); /* Chrome,Safari4+ */
/* @alternate */ background: -webkit-linear-gradient(left, #FFDD00 0%,#008FFF 100%); /* Chrome10+,Safari5.1+ */
/* @alternate */ background: -o-linear-gradient(left, #FFDD00 0%,#008FFF 100%); /* Opera 11.10+ */
/* @alternate */ background: -ms-linear-gradient(left, #FFDD00 0%,#008FFF 100%); /* IE10+ */
/* @alternate */ background: linear-gradient(to right, #FFDD00 0%,#008FFF 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFDD00', endColorstr='#008FFF',GradientType=0 ); /* IE6*/
}
@@ -42,7 +42,7 @@
font-size: 11px;
text-align: center;
vertical-align: center;
font-family: 'Open Sans', Arial, Verdana, sans-serif !important;
font-family: DASHBOARD_FONT_FAMILY !important;
}
.confidence_bar_label {
@@ -50,7 +50,7 @@
top: 20px;
font-size: 12px;
color: grey;
font-family: 'Open Sans', Arial, Verdana, sans-serif !important;
font-family: DASHBOARD_FONT_FAMILY !important;
}
.confidence_bar_min_label {
@@ -1,17 +1,15 @@
package com.sap.sailing.dashboards.gwt.client.startlineadvantage;
package com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.wind.charts;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.moxieapps.gwt.highcharts.client.Animation;
import org.moxieapps.gwt.highcharts.client.Animation.Easing;
import org.moxieapps.gwt.highcharts.client.AxisTitle;
import org.moxieapps.gwt.highcharts.client.Chart;
import org.moxieapps.gwt.highcharts.client.Color;
import org.moxieapps.gwt.highcharts.client.Credits;
import org.moxieapps.gwt.highcharts.client.Legend;
import org.moxieapps.gwt.highcharts.client.PlotLine.DashStyle;
import org.moxieapps.gwt.highcharts.client.Point;
import org.moxieapps.gwt.highcharts.client.Series;
import org.moxieapps.gwt.highcharts.client.Style;
import org.moxieapps.gwt.highcharts.client.ToolTip;
@@ -31,9 +29,8 @@ import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.shared.dto.StartLineAdvantageDTO;
import com.sap.sailing.dashboards.gwt.client.util.HighchartsUtil;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sse.common.Util.Pair;
/**
* @author Alexander Ries (D062114)
@@ -63,28 +60,32 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg
private Chart chart;
private Series series;
private static final int POINT_ADDING_ANIMATION_DURATION_IN_MILLIS = 2000;
private static final Logger logger = Logger.getLogger(StartlineAdvantagesOnLineChart.class.getName());
public StartlineAdvantagesOnLineChart() {
StartlineAdvantagesOnLineChartResources.INSTANCE.gss().ensureInjected();
initWidget(uiBinder.createAndBindUi(this));
initAndAddChart();
setConfidenceColorBarLabelValues();
//TODO Remove and centralize data retrieving
}
public void setStartlineAdvantagesAndConfidences(Number [][] distanceToRCBoatToStartlineAdvantages, Number [][] distanceToRCBoatToConfidences) {
if (distanceToRCBoatToStartlineAdvantages != null) {
series.setPoints(distanceToRCBoatToStartlineAdvantages, true);
}
setConfidenceGradientColorToSeries(series, distanceToRCBoatToConfidences);
chart.redraw();
}
private void initAndAddChart() {
chart = initChart();
/**
* Highcharts default chart element spacing is not consistent
* so there is a need to correct the right spacing
* of the chart to make it look visually right.
* */
setCorrectChartSpacing(chart);
HighchartsUtil.correctSpacingOfChart(chart);
setXAxisOfChart(chart);
setYAxisOfChart(chart);
series = createSeries(chart);
chart.addSeries(series);
chartContainer.add(chart);
HighchartsUtil.setSizeToMatchContainerDelayed(chart);
}
private Chart initChart() {
@@ -97,22 +98,16 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg
.setBackgroundColor("#FFFFFF")
.setBorderColor("#FFFFFF")
.setPlotShadow(false)
.setWidth100()
.setHeight100()
.setPlotBorderColor("#FFFFFF")
.setOption("/exporting/enabled", false)
.setShadow(false)
.setStyle(new Style().setPosition("absolute").setTop("0px").setBottom("0px").setLeft("0px").setRight("0px"))
.setAnimation(true);
chart.setSize("100%", "100%");
chart.setSizeToMatchContainer();
return chart;
}
private void setCorrectChartSpacing(Chart chart){
chart.setSpacingTop(17)
.setSpacingBottom(13)
.setSpacingRight(35);
}
private void setXAxisOfChart(Chart chart){
chart.getXAxis()
.setAxisTitle(new AxisTitle().setText(StringMessages.INSTANCE.dashboardDistanceToRCBoat()).setStyle(new Style().setFontFamily("Open Sans")
@@ -156,10 +151,9 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg
Series series = chart
.createSeries()
.setName(null)
.setPlotOptions(
new AreaPlotOptions().setDashStyle(DashStyle.SOLID).setLineWidth(1)
.setPlotOptions(new AreaPlotOptions().setDashStyle(DashStyle.SOLID).setLineWidth(1)
.setMarker(new Marker().setEnabled(false)).setShadow(false).setHoverStateEnabled(false)
.setLineColor("#FFFFFF").setFillColor("#FFFFFF"));
.setLineColor("white").setFillColor("white"));
return series;
}
@@ -170,71 +164,18 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg
}
private String getAxisLabelValueForLabelData(double labelData) {
String result = String.valueOf(labelData);
com.sap.sse.common.Util.Pair<Double, Double> firstAndLastXValue = getFirstnAndLastXValueOfSeries();
if (firstAndLastXValue != null && firstAndLastXValue.getA() != null && firstAndLastXValue.getB() != null) {
chart.getXAxis().setTickInterval(firstAndLastXValue.getB()/2);
if (labelData == firstAndLastXValue.getA().doubleValue()) {
result = StringMessages.INSTANCE.dashboardRCBoat();
} else if (labelData == firstAndLastXValue.getB().doubleValue()) {
result = StringMessages.INSTANCE.dashboardPinEnd();
}
}
return result;
}
private com.sap.sse.common.Util.Pair<Double, Double> getFirstnAndLastXValueOfSeries(){
if(series != null &&
series.getPoints() != null &&
series.getPoints().length > 1){
Double firstValue = new Double(series.getPoints()[0].getX().doubleValue());
Double lastValue = new Double(series.getPoints()[series.getPoints().length-1].getX().doubleValue());
com.sap.sse.common.Util.Pair<Double, Double> firstAndLastXValue = new Pair<Double, Double>(firstValue, lastValue);
return firstAndLastXValue;
}else{
return null;
if(labelData != 0) {
return labelData+"";
}else {
return "RC Boat";
}
}
public void setStartlineAdvantages(List<StartLineAdvantageDTO> startlineAdvantages) {
if (startlineAdvantages != null) {
if (series.getPoints() != null && series.getPoints().length > 0) {
updateStartlineAdvantages(startlineAdvantages, series);
} else {
addStartlineAdvantages(startlineAdvantages, series);
chart.addSeries(series, true, new Animation().setDuration(POINT_ADDING_ANIMATION_DURATION_IN_MILLIS).setEasing(Easing.SWING));
}
}
chart.setSizeToMatchContainer();
}
private void updateStartlineAdvantages(List<StartLineAdvantageDTO> startlineAdvantages, Series series) {
removeAllSeriesPoints(chart.getSeries()[0]);
addStartlineAdvantages(startlineAdvantages, series);
}
private void removeAllSeriesPoints(Series series) {
for (Point point : series.getPoints()) {
series.removePoint(point);
}
}
private void addStartlineAdvantages(List<StartLineAdvantageDTO> startlineAdvantages, Series series){
//TODO Build this with forEach consumer as soon as the bundle uses GWT 2.8 with Java 8 Support.
for (StartLineAdvantageDTO startlineAdvantage : startlineAdvantages) {
Point point = new Point(startlineAdvantage.distanceToRCBoatInMeters, startlineAdvantage.startLineAdvantage);
series.addPoint(point, false, false, false);
}
setConfidenceGradientColorToSeries(series, startlineAdvantages);
chart.redraw();
}
private void setConfidenceGradientColorToSeries(Series series, List<StartLineAdvantageDTO> startlineAdvantages) {
Color confidenceGradientColor = ConfidenceColorCalculator.getColorWithConfidenceGradients(startlineAdvantages);
series.setPlotOptions(
new AreaPlotOptions().setDashStyle(DashStyle.SOLID).setLineWidth(1)
.setMarker(new Marker().setEnabled(false)).setShadow(false).setHoverStateEnabled(false)
.setLineColor("#FFFFFF").setFillColor(confidenceGradientColor));
private void setConfidenceGradientColorToSeries(Series series, Number [][] distanceToRCBoatToConfidences) {
Color confidenceGradientColor = ConfidenceColorCalculator.getColorWithConfidenceGradients(distanceToRCBoatToConfidences);
String fillColor = confidenceGradientColor.getOptions().toString();
logger.log(Level.INFO, fillColor);
series.updateSeriesFillColor(fillColor);
}
@Override
@@ -261,26 +202,21 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg
private static final String LOW_CONFIDENCE_COLOR_AS_HEX = "#43cea2";
private static final String HIGHT_CONFIDENCE_COLOR_AS_HEX = "#008FFF";
public static Color getColorWithConfidenceGradients(List<StartLineAdvantageDTO> startlineAdvantages) {
public static Color getColorWithConfidenceGradients(Number [][] distanceToRCBoatToConfidences) {
Color color = new Color().setLinearGradient(200, 0, 0, 0);
double lineLenght = getBiggestDistanceToRCBoat(startlineAdvantages);
//TODO Need to find a prettier way of at adding color stops
double lastConfidence = 2;
for (StartLineAdvantageDTO startlineAdvantageDTO : startlineAdvantages) {
if (lastConfidence != startlineAdvantageDTO.confidence) {
lastConfidence = startlineAdvantageDTO.confidence;
double gradientPosition = getGradientStopPositionFromStartlineLenghtAndDistanceToRCBoat(lineLenght,
startlineAdvantageDTO.distanceToRCBoatInMeters);
color.addColorStop(gradientPosition, getColorAsHexStringFromConfidence(startlineAdvantageDTO.confidence));
int previousIndex = 0;
for (int i = 0; i < distanceToRCBoatToConfidences.length; i++) {
double previousConfidence = distanceToRCBoatToConfidences[previousIndex][1].doubleValue();
double currentConfidence = distanceToRCBoatToConfidences[i][1].doubleValue();
if (previousConfidence != currentConfidence || i == 0) {
logger.log(Level.INFO, previousConfidence+" "+currentConfidence);
color.addColorStop(i, getColorAsHexStringFromConfidence(distanceToRCBoatToConfidences[i][0].doubleValue()));
}
previousIndex++;
}
return color;
}
private static double getGradientStopPositionFromStartlineLenghtAndDistanceToRCBoat(double startlineLenght, double distanceToRCBoat) {
return distanceToRCBoat/startlineLenght;
}
private static String getColorAsHexStringFromConfidence(double position) {
if(position > 0.6) {
return HIGHT_CONFIDENCE_COLOR_AS_HEX;
@@ -288,10 +224,5 @@ public class StartlineAdvantagesOnLineChart extends Composite implements HasWidg
return LOW_CONFIDENCE_COLOR_AS_HEX;
}
}
private static double getBiggestDistanceToRCBoat(List<StartLineAdvantageDTO> startlineAdvantages) {
StartLineAdvantageDTO startlineAdvantageDTO = startlineAdvantages.get(startlineAdvantages.size()-1);
return startlineAdvantageDTO.distanceToRCBoatInMeters;
}
}
}
@@ -0,0 +1,16 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:highcharts="urn:import:org.moxieapps.gwt.highcharts.client">
<ui:with field="resources" type="com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.wind.charts.StartlineAdvantagesOnLineChartResources"/>
<g:HTMLPanel>
<g:HTMLPanel ui:field="chartContainer" styleName="{resources.gss.advantages_on_line_chart_container}"></g:HTMLPanel>
<div class="{resources.gss.confidence_bar_container}">
<div class="{resources.gss.confidence_bar}"></div>
<div ui:field="confidenceBarHeader" class="{resources.gss.confidence_bar_header}"></div>
<div ui:field="confidenceBarMinLabel" class="{resources.gss.confidence_bar_label} {resources.gss.confidence_bar_min_label}"></div>
<div ui:field="confidenceBarMaxLabel" class="{resources.gss.confidence_bar_label} {resources.gss.confidence_bar_max_label}"></div>
</div>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,27 @@
package com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.wind.charts;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
/**
* @author Alexander Ries (D062114)
*
*/
public interface StartlineAdvantagesOnLineChartResources extends ClientBundle {
public static final StartlineAdvantagesOnLineChartResources INSTANCE = GWT.create(StartlineAdvantagesOnLineChartResources.class);
@Source({"com/sap/sailing/dashboards/gwt/client/theme/theme.gss", "StartlineAdvantagesOnLineChart.gss"})
StartlineAdvantagesOnLineChartGSS gss();
public interface StartlineAdvantagesOnLineChartGSS extends CssResource {
String advantages_on_line_chart_container();
String confidence_bar_container();
String confidence_bar();
String confidence_bar_header();
String confidence_bar_label();
String confidence_bar_min_label();
String confidence_bar_max_label();
}
}
@@ -1,18 +1,18 @@
@CHARSET "UTF-8";
@require 'theme';
.windBotComponent{
.wind_bot_component{
position: absolute;
height: 100%;
width: 100%;
z-index: 5;
}
.windBotNamePanel {
.name_panel {
height: 45pt;
line-height: 45pt;
vertical-align: middle;
font-size: 14pt;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
font-family: DASHBOARD_FONT_FAMILY;
width: 100%;
text-align: center;
font-weight: bold;
@@ -20,7 +20,7 @@
background-color: white;
}
.wind_bot_component_live_average_container {
.live_average_container {
position: absolute;
border: none;
border-radius: 0pt;
@@ -29,17 +29,17 @@
bottom: 65%;
}
.wind_bot_component_left {
.left {
left: 0pt;
right: 50%;
}
.wind_bot_component_right {
.right {
left: 50%;
right: 0pt;
}
.wind_bot_component_windchart_container {
.windchart_container {
position: absolute;
border: none;
border-radius: 0pt;
@@ -48,7 +48,7 @@
bottom: 0pt;
}
.wind_bot_component_windchart{
.windchart{
position: absolute;
left: 0pt;
right: 0pt;
@@ -56,7 +56,7 @@
bottom: 0pt;
}
.wind_bot_component_compass_container{
.compass_container{
position: absolute;
height: 45pt;
width: 45pt;
@@ -1,33 +1,30 @@
package com.sap.sailing.dashboards.gwt.client.windchart;
package com.sap.sailing.dashboards.gwt.client.widgets.windbot;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.moxieapps.gwt.highcharts.client.Point;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.dataretriever.RibDashboardDataRetrieverListener;
import com.sap.sailing.dashboards.gwt.client.dataretriever.WindBotDataRetrieverListener;
import com.sap.sailing.dashboards.gwt.client.startlineadvantage.LiveAverageComponent;
import com.sap.sailing.dashboards.gwt.client.windchart.compass.LocationPointerCompass;
import com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.util.LiveAverageComponent;
import com.sap.sailing.dashboards.gwt.client.widgets.windbot.charts.VerticalWindChart;
import com.sap.sailing.dashboards.gwt.client.widgets.windbot.compass.LocationPointerCompass;
import com.sap.sailing.dashboards.gwt.shared.MovingAverage;
import com.sap.sailing.dashboards.gwt.shared.SinWave;
import com.sap.sailing.dashboards.gwt.shared.WindType;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.gwt.dispatch.client.batching.SplitScheduler;
import com.sap.sailing.gwt.ui.client.StringMessages;
import com.sap.sailing.gwt.ui.client.shared.charts.ChartPointRecalculator;
import com.sap.sailing.gwt.ui.shared.WindDTO;
import com.sap.sailing.gwt.ui.shared.WindInfoForRaceDTO;
import com.sap.sailing.gwt.ui.shared.WindTrackInfoDTO;
@@ -42,20 +39,15 @@ import com.sap.sailing.gwt.ui.shared.WindTrackInfoDTO;
* @author Alexander Ries (D062114)
*
*/
public class WindBotComponent extends Composite implements HasWidgets, WindBotDataRetrieverListener {
private SinWave speedSinWave;
private SinWave directionSinWave;
private boolean inSimulationMode;
public class WindBotWidget extends Composite implements HasWidgets, WindBotDataRetrieverListener {
private MovingAverage movingAverageSpeed;
private MovingAverage movingAverageDirection;
private static WindBotComponentUiBinder uiBinder = GWT.create(WindBotComponentUiBinder.class);
private static final String IN_SIMULATION_MODE = "simulation";
private static final Logger logger = Logger.getLogger(WindBotComponent.class.getName());
private static WindBotWidgetUiBinder uiBinder = GWT.create(WindBotWidgetUiBinder.class);
private static final Logger logger = Logger.getLogger(WindBotWidget.class.getName());
interface WindBotComponentUiBinder extends UiBinder<Widget, WindBotComponent> {
interface WindBotWidgetUiBinder extends UiBinder<Widget, WindBotWidget> {
}
interface WindBotComponentStyle extends CssResource {
@@ -109,17 +101,10 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa
private StringMessages stringConstants;
private final static String UNIT_WIND_DIRECTION = "°";
public WindBotComponent(String windBotId) {
public WindBotWidget(String windBotId) {
WindBotWidgetResources.INSTANCE.gss().ensureInjected();
this.windBotId = windBotId;
stringConstants = StringMessages.INSTANCE;
String inSimulationModeParameter = Window.Location.getParameter(IN_SIMULATION_MODE);
if (inSimulationModeParameter != null && inSimulationModeParameter.equals("true")) {
inSimulationMode = true;
this.speedSinWave = new SinWave(50, 8);
this.directionSinWave = new SinWave(100, 8);
} else {
inSimulationMode = false;
}
movingAverageSpeed = new MovingAverage(500);
movingAverageDirection = new MovingAverage(500);
trueWindSpeedLiveAverageComponent = new LiveAverageComponent(stringConstants.dashboardTrueWindSpeed(), stringConstants.dashboardTrueWindSpeedUnit());
@@ -169,30 +154,42 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa
* */
@Override
public void updateWindBotUI(WindInfoForRaceDTO windInfoForRaceDTO) {
logger.log(Level.INFO, "WindBotComponent with id "+windBotId+" got notified about new WindInfoForRaceDTO");
logger.log(Level.INFO, "WindBotComponent with id " + windBotId + " got notified about new WindInfoForRaceDTO");
if (windInfoForRaceDTO != null) {
WindTrackInfoDTO windTrackInfoDTO = getWindTrackInfoDTOFromAndWindBotID(windInfoForRaceDTO, windBotId);
final WindTrackInfoDTO windTrackInfoDTO = getWindTrackInfoDTOFromAndWindBotID(windInfoForRaceDTO, windBotId);
if (windTrackInfoDTO != null) {
logger.log(Level.INFO, "WindInfoForRaceDTO contains WindTrackInfoDTO for Windbot id "+ windBotId);
logger.log(Level.INFO, "WindInfoForRaceDTO contains WindTrackInfoDTO for Windbot id " + windBotId);
if (windTrackInfoDTO.windFixes != null) {
if (windTrackInfoDTO.windFixes.size() > 0) {
logger.log(Level.INFO, "Upating UI with Wind Fixes for WindBot id "+ windBotId);
Point[] speedPoints = convertWindFixListIntoPointsArray(windTrackInfoDTO.windFixes, WindType.SPEED);
Point[] directionPoints = convertWindFixListIntoPointsArray(windTrackInfoDTO.windFixes,
WindType.DIRECTION);
logger.log(Level.INFO, "Upating UI with Wind Fixes for WindBot id " + windBotId);
SplitScheduler.get().schedule(new ScheduledCommand() {
trueWindSpeedLiveAverageComponent.setLiveValue(""+NumberFormat.getFormat("#0.0").format(speedPoints[speedPoints.length - 1].getY().doubleValue()));
trueWindSpeedLiveAverageComponent.setAverageValue(""+NumberFormat.getFormat("#0.0").format(movingAverageSpeed.getAverage()));
trueWindDirectionLiveAverageComponent.setLiveValue(""+NumberFormat.getFormat("#0.0").format(directionPoints[directionPoints.length - 1].getY().doubleValue()));
trueWindDirectionLiveAverageComponent.setAverageValue(""+NumberFormat.getFormat("#0.0").format(movingAverageDirection.getAverage()));
@Override
public void execute() {
updateMovingAverages(windTrackInfoDTO.windFixes);
}
});
SplitScheduler.get().schedule(new ScheduledCommand() {
trueWindSpeedVerticalWindChart.addPointsToSeriesWithAverage(speedPoints,
movingAverageSpeed.getAverage());
trueWindDirectionVerticalWindChart.addPointsToSeriesWithAverage(directionPoints,
movingAverageDirection.getAverage());
locationPointerCompass.windBotPositionChanged(windTrackInfoDTO.windFixes
.get(windTrackInfoDTO.windFixes.size() - 1).position);
@Override
public void execute() {
updateWindSpeedLabelsAndChart(windTrackInfoDTO);
}
});
SplitScheduler.get().schedule(new ScheduledCommand() {
@Override
public void execute() {
updateWindDirectionLabelsAndChart(windTrackInfoDTO);
}
});
SplitScheduler.get().schedule(new ScheduledCommand() {
@Override
public void execute() {
updateLocationPointerCompass(windTrackInfoDTO);
}
});
} else {
logger.log(Level.INFO, "WindTrackInfoDTO.windFixes is empty");
}
@@ -200,52 +197,37 @@ public class WindBotComponent extends Composite implements HasWidgets, WindBotDa
logger.log(Level.INFO, "WindTrackInfoDTO.windFixes is null");
}
} else {
logger.log(Level.INFO, "WindInfoForRaceDTO does not contains WindTrackInfoDTO for Windbot id "+ windBotId);
logger.log(Level.INFO, "WindInfoForRaceDTO does not contains WindTrackInfoDTO for Windbot id "
+ windBotId);
}
} else {
logger.log(Level.INFO, "WindInfoForRaceDTO is null");
}
}
private Point[] convertWindFixListIntoPointsArray(List<WindDTO> windFixes, WindType windtype) {
if (windFixes != null && windFixes.size() > 0) {
Point[] points = new Point[windFixes.size()];
int counter = 0;
if (windtype.equals(WindType.DIRECTION)) {
Point previouspoint = new Point(windFixes.get(0).requestTimepoint, windFixes.get(0).trueWindFromDeg);
for (WindDTO windDTO : windFixes) {
double nextSinusValue = 0;
if (inSimulationMode == true) {
nextSinusValue = directionSinWave.getNexNumber();
}
points[counter] = new Point(windDTO.requestTimepoint, windDTO.trueWindFromDeg + nextSinusValue);
points[counter] = adaptWindDirectionPointToStayCloseToLastPoint(previouspoint, points[counter]);
previouspoint = points[counter];
movingAverageDirection.add(windDTO.trueWindFromDeg + nextSinusValue);
counter++;
}
} else if (windtype.equals(WindType.SPEED)) {
Point previouspoint = new Point(windFixes.get(0).requestTimepoint,
windFixes.get(0).trueWindSpeedInKnots);
for (WindDTO windDTO : windFixes) {
double nextSinusValue = 0;
if (inSimulationMode == true) {
nextSinusValue = speedSinWave.getNexNumber();
}
points[counter] = new Point(windDTO.requestTimepoint, windDTO.trueWindSpeedInKnots + nextSinusValue);
points[counter] = adaptWindDirectionPointToStayCloseToLastPoint(previouspoint, points[counter]);
previouspoint = points[counter];
movingAverageSpeed.add(windDTO.trueWindSpeedInKnots + nextSinusValue);
counter++;
}
}
return points;
} else {
return null;
private void updateWindSpeedLabelsAndChart(final WindTrackInfoDTO windTrackInfoDTO) {
int size = windTrackInfoDTO.windFixes.size();
trueWindSpeedLiveAverageComponent.setLiveValue(""+NumberFormat.getFormat("#0.0").format(windTrackInfoDTO.windFixes.get(size-1).trueWindSpeedInKnots));
trueWindSpeedVerticalWindChart.addPointsToSeriesWithAverageAndWindType(windTrackInfoDTO.windFixes, movingAverageSpeed.getAverage(), WindType.SPEED);
trueWindSpeedLiveAverageComponent.setAverageValue(""+NumberFormat.getFormat("#0.0").format(movingAverageSpeed.getAverage()));
}
private void updateWindDirectionLabelsAndChart(final WindTrackInfoDTO windTrackInfoDTO) {
int size = windTrackInfoDTO.windFixes.size();
trueWindDirectionLiveAverageComponent.setLiveValue(""+NumberFormat.getFormat("#0.0").format(windTrackInfoDTO.windFixes.get(size-1).trueWindFromDeg));
trueWindDirectionVerticalWindChart.addPointsToSeriesWithAverageAndWindType(windTrackInfoDTO.windFixes, movingAverageDirection.getAverage(), WindType.DIRECTION);
trueWindDirectionLiveAverageComponent.setAverageValue(""+NumberFormat.getFormat("#0.0").format(movingAverageDirection.getAverage()));
}
private void updateLocationPointerCompass(final WindTrackInfoDTO windTrackInfoDTO) {
locationPointerCompass.windBotPositionChanged(windTrackInfoDTO.windFixes
.get(windTrackInfoDTO.windFixes.size() - 1).position);
}
private void updateMovingAverages(List<WindDTO> windFixes) {
for(WindDTO windDTO : windFixes) {
movingAverageSpeed.add(windDTO.trueWindSpeedInKnots);
movingAverageDirection.add(windDTO.trueWindFromDeg);
}
}
private Point adaptWindDirectionPointToStayCloseToLastPoint(Point previousPoint, Point point) {
return ChartPointRecalculator.stayClosestToPreviousPoint(previousPoint, point);
}
}
@@ -0,0 +1,35 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:client="urn:import:com.sap.sailing.dashboards.gwt.client"
xmlns:util="urn:import:com.sap.sailing.dashboards.gwt.client.widgets.startlineadvantage.util"
xmlns:windchart="urn:import:com.sap.sailing.dashboards.gwt.client.widgets.windbot.charts"
xmlns:compass="urn:import:com.sap.sailing.dashboards.gwt.client.widgets.windbot.compass">
<ui:with field="resources" type="com.sap.sailing.dashboards.gwt.client.widgets.windbot.WindBotWidgetResources"/>
<g:HTMLPanel ui:field="windBotComponent" styleName="{resources.gss.wind_bot_component}">
<g:HTMLPanel ui:field="windBotNamePanel" styleName="{resources.gss.name_panel}"></g:HTMLPanel>
<g:HTMLPanel
styleName="{resources.gss.live_average_container} {resources.gss.left}">
<util:LiveAverageComponent ui:field="trueWindSpeedLiveAverageComponent"></util:LiveAverageComponent>
</g:HTMLPanel>
<g:HTMLPanel
styleName="{resources.gss.live_average_container} {resources.gss.right}">
<util:LiveAverageComponent ui:field="trueWindDirectionLiveAverageComponent"></util:LiveAverageComponent>
</g:HTMLPanel>
<g:HTMLPanel
styleName="{resources.gss.windchart_container} {resources.gss.left}">
<windchart:VerticalWindChart ui:field="trueWindSpeedVerticalWindChart"
styleName="{resources.gss.windchart}"></windchart:VerticalWindChart>
</g:HTMLPanel>
<g:HTMLPanel
styleName="{resources.gss.windchart_container} {resources.gss.right}">
<windchart:VerticalWindChart ui:field="trueWindDirectionVerticalWindChart"
styleName="{resources.gss.windchart}"></windchart:VerticalWindChart>
</g:HTMLPanel>
<g:HTMLPanel styleName="{resources.gss.compass_container}">
<compass:LocationPointerCompass
ui:field="locationPointerCompass"></compass:LocationPointerCompass>
</g:HTMLPanel>
</g:HTMLPanel>
</ui:UiBinder>
@@ -0,0 +1,28 @@
package com.sap.sailing.dashboards.gwt.client.widgets.windbot;
import com.google.gwt.core.client.GWT;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
/**
* @author Alexander Ries (D062114)
*
*/
public interface WindBotWidgetResources extends ClientBundle {
public static final WindBotWidgetResources INSTANCE = GWT.create(WindBotWidgetResources.class);
@Source({"com/sap/sailing/dashboards/gwt/client/theme/theme.gss", "WindBotWidget.gss"})
WindBotComponentGss gss();
public interface WindBotComponentGss extends CssResource {
String wind_bot_component();
String name_panel();
String live_average_container();
String left();
String right();
String windchart_container();
String windchart();
String compass_container();
}
}
@@ -1,18 +1,12 @@
@CHARSET "UTF-8";
@require 'theme';
.flowPanelContainer {
.verical_wind_chart {
position: absolute;
height: 100%;
width: 100%;
}
.verticalWindChartClickArea {
position: absolute;
height: 100%;
width: 100%;
}
.verticalWindChart {
.chart {
position: absolute;
top: 0px;
bottom: 5px;
@@ -20,7 +14,13 @@
right: 0px;
}
.verticalWindChartClickHint {
.click_area {
position: absolute;
height: 100%;
width: 100%;
}
.click_hint {
position: absolute;
height: 35px;
bottom: 0px;
@@ -29,12 +29,12 @@
line-height: 35px;
vertical-align: middle;
font-size: 12px;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
font-family: DASHBOARD_FONT_FAMILY;
text-align: center;
color: black;
}
.windloadinghint {
.loading_hint {
position: absolute;
background-color: white;
opacity: 0.4;
@@ -45,21 +45,20 @@
z-index: 0;
}
.windloadinghinttext {
.loading_hint_text {
position: absolute;
bottom: 0pt;
height: 15pt;
line-height: 15pt;
margin-top: 0pt;
vertical-align: middle;
font-size: 12pt;
font-family: 'Open Sans', Arial, Verdana, sans-serif;
font-family: DASHBOARD_FONT_FAMILY;
width: 100%;
text-align: center;
top: 50%;
margin-top: -7pt;
}
.clickHintMinutesSpan{
.click_hint_minutes {
font-weight: bolder;
}
@@ -1,9 +1,8 @@
package com.sap.sailing.dashboards.gwt.client.windchart;
package com.sap.sailing.dashboards.gwt.client.widgets.windbot.charts;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.moxieapps.gwt.highcharts.client.Axis.Type;
@@ -28,8 +27,6 @@ import org.moxieapps.gwt.highcharts.client.plotOptions.BarPlotOptions;
import org.moxieapps.gwt.highcharts.client.plotOptions.Marker;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.uibinder.client.UiBinder;
@@ -40,6 +37,10 @@ import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.dashboards.gwt.client.util.HighchartsUtil;
import com.sap.sailing.dashboards.gwt.shared.WindType;
import com.sap.sailing.gwt.ui.client.shared.charts.ChartPointRecalculator;
import com.sap.sailing.gwt.ui.shared.WindDTO;
/**
* The class represents a wind chart that is displayed vertically. Because it is meant to be used to display wind fixes,
@@ -53,8 +54,7 @@ import com.google.gwt.user.client.ui.Widget;
public class VerticalWindChart extends Composite implements HasWidgets {
private Series verticalWindChartSeries;
private String positiveSeriesColorAsHex;
private String negativeSeriesColorAsHex;
private Point lastPoint;
private List<VerticalWindChartClickListener> verticalWindChartClickListeners;
/**
@@ -74,6 +74,7 @@ public class VerticalWindChart extends Composite implements HasWidgets {
private static VerticalWindChartUiBinder uiBinder = GWT.create(VerticalWindChartUiBinder.class);
@SuppressWarnings("unused")
private static final Logger logger = Logger.getLogger(VerticalWindChart.class.getName());
interface VerticalWindChartUiBinder extends UiBinder<Widget, VerticalWindChart> {
@@ -97,6 +98,7 @@ public class VerticalWindChart extends Composite implements HasWidgets {
}
public @UiConstructor VerticalWindChart(String positiveFillColorAsHex, String negativeFillColorAsHex) {
VerticalWindChartResources.INSTANCE.gss().ensureInjected();
initVerticalWindChartWithColors(positiveFillColorAsHex, negativeFillColorAsHex);
initWidget(uiBinder.createAndBindUi(this));
}
@@ -111,9 +113,9 @@ public class VerticalWindChart extends Composite implements HasWidgets {
setChartOptions();
setXAxisOptions();
setYAxisOptions();
positiveSeriesColorAsHex = positiveFillColor;
negativeSeriesColorAsHex = negativeFillColor;
initVerticalWindChartSeries(positiveFillColor, negativeFillColor);
verticalWindChartClickListeners = new ArrayList<VerticalWindChartClickListener>();
HighchartsUtil.setSizeToMatchContainerDelayed(verticalWindChart);
}
private void setChartOptions() {
@@ -171,13 +173,13 @@ public class VerticalWindChart extends Composite implements HasWidgets {
}));
}
private void initVerticalWindChartSeries() {
private void initVerticalWindChartSeries(String positivSeriesColorAsHex, String negativeSeriesColorAsHex) {
verticalWindChartSeries = verticalWindChart.createSeries();
AreaPlotOptions areaPlotOptions = new AreaPlotOptions();
verticalWindChart.addSeries(verticalWindChartSeries.setName(null).setPlotOptions(
areaPlotOptions.setDashStyle(DashStyle.SOLID).setLineWidth(0.1)
.setMarker(new Marker().setEnabled(false)).setShadow(false).setHoverStateEnabled(false)
.setLineColor("#FFFFFF").setFillColor(positiveSeriesColorAsHex)
.setLineColor("#FFFFFF").setFillColor(positivSeriesColorAsHex)
.setOption("negativeFillColor", negativeSeriesColorAsHex)).setOption("turboThreshold", MAX_SERIES_POINTS));
}
@@ -190,34 +192,52 @@ public class VerticalWindChart extends Composite implements HasWidgets {
* {@link #setXAxisExtremesForSeriesPointRangeIsSmallerThanChartDisplayIntervall()} and
* {@link #setXAxisExtremesForSeriesPointRangeIsBiggerThanChartDisplayIntervall()}.
* */
public void addPointsToSeriesWithAverage(final Point[] points, final double average) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
if (verticalWindChartSeries == null) {
initVerticalWindChartSeries();
verticalWindChartSeries.setPoints(points, true);
logger.log(Level.INFO, "Set Points");
} else {
for (Point point : points) {
verticalWindChartSeries.addPoint(point, true, false, false);
logger.log(Level.INFO, "Add Point");
}
}
verticalWindChartSeries.updateThreshold("" + average);
adaptVerticalWindChartExtemes();
verticalWindChart.setSizeToMatchContainer();
}
});
public void addPointsToSeriesWithAverageAndWindType(List<WindDTO> windFixes, final double average, WindType windType) {
if(windType.equals(WindType.SPEED)) {
addPointsToSeriesOfTypeSpeed(windFixes);
} else {
addPointsToSeriesOfTypeDirection(windFixes);
}
verticalWindChartSeries.updateThreshold(""+average);
adaptVerticalWindChartExtemes(lastPoint.getX().longValue());
}
private Point createSpeedPoint(WindDTO windDTO) {
Point result = new Point(windDTO.measureTimepoint, windDTO.trueWindSpeedInKnots);
if (lastPoint != null) {
adaptWindDirectionPointToStayCloseToLastPoint(lastPoint, result);
}
lastPoint = result;
return result;
}
private Point createDirectionPoint(WindDTO windDTO) {
Point result = new Point(windDTO.measureTimepoint, windDTO.trueWindFromDeg);
if (lastPoint != null) {
adaptWindDirectionPointToStayCloseToLastPoint(lastPoint, result);
}
lastPoint = result;
return result;
}
private void addPointsToSeriesOfTypeSpeed(List<WindDTO> windFixes) {
for (WindDTO windDTO : windFixes) {
verticalWindChartSeries.addPoint(createSpeedPoint(windDTO), false, false, false);
}
}
private void addPointsToSeriesOfTypeDirection(List<WindDTO> windFixes) {
for (WindDTO windDTO : windFixes) {
verticalWindChartSeries.addPoint(createDirectionPoint(windDTO), false, false, false);
}
}
/**
* Depending on the series points time range and the selected display interval, the series fits into the display
* interval or not. So there are two cases where the extreme points of the x-axis get calculated differently.
* */
private void adaptVerticalWindChartExtemes() {
setXAxisExtremesForSeriesPointRangeIsBiggerThanChartDisplayIntervall();
private void adaptVerticalWindChartExtemes(Long lastTimePoint) {
setXAxisExtremesForSeriesPointRangeIsBiggerThanChartDisplayIntervall(lastTimePoint.longValue());
}
/**
@@ -226,23 +246,10 @@ public class VerticalWindChart extends Composite implements HasWidgets {
* the the max value minus the selected display interval and the max value the last points time value. The chart
* gets other extremes, because the values do not fit anymore into the selected display interval.
* */
private void setXAxisExtremesForSeriesPointRangeIsBiggerThanChartDisplayIntervall() {
long maximumExtremeValueInMillis = getLastPointOfVerticalWindChartSeries().getX().longValue();
private void setXAxisExtremesForSeriesPointRangeIsBiggerThanChartDisplayIntervall(long lastTimePoint) {
long maximumExtremeValueInMillis = lastTimePoint;
long minimumExtremeValueInMillis = maximumExtremeValueInMillis - chartIntervallinMinutes * 60 * 1000;
verticalWindChart.getXAxis().setExtremes(minimumExtremeValueInMillis, maximumExtremeValueInMillis, true, true);
}
private Point getLastPointOfVerticalWindChartSeries() {
Point lastPointOfVerticalWindChartSeries = null;
if (verticalWindChartSeries != null) {
Point[] seriesPoints = verticalWindChartSeries.getPoints();
int seriesPointsLenght = seriesPoints.length;
if (seriesPointsLenght > 0) {
lastPointOfVerticalWindChartSeries = seriesPoints[seriesPointsLenght - 1];
}
}
return lastPointOfVerticalWindChartSeries;
verticalWindChart.getXAxis().setExtremes(minimumExtremeValueInMillis, maximumExtremeValueInMillis, true, false);
}
public void addVerticalWindChartClickListener(VerticalWindChartClickListener verticalWindChartClickListener) {
@@ -258,6 +265,10 @@ public class VerticalWindChart extends Composite implements HasWidgets {
verticalWindChartClickListener.clickedWindChartWithNewIntervalChangeInMillis(intervalInMillis);
}
}
private Point adaptWindDirectionPointToStayCloseToLastPoint(Point previousPoint, Point point) {
return ChartPointRecalculator.stayClosestToPreviousPoint(previousPoint, point);
}
/**
* The method handles a click on the vertical wind charts focus panel. It changes the display interval of the x-axis
@@ -270,13 +281,8 @@ public class VerticalWindChart extends Composite implements HasWidgets {
} else {
chartIntervallinMinutes = SMALL_DISPLAY_INTERVALL_IN_MINUTES;
}
Scheduler.get().scheduleFinally(new ScheduledCommand() {
@Override
public void execute() {
adaptVerticalWindChartExtemes();
notifyVerticalWindChartClickListeners(chartIntervallinMinutes);
}});
adaptVerticalWindChartExtemes(lastPoint.getX().longValue());
notifyVerticalWindChartClickListeners(chartIntervallinMinutes);
}
@Override
@@ -0,0 +1,11 @@
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:highcharts="urn:import:org.moxieapps.gwt.highcharts.client">
<ui:with field="resources" type="com.sap.sailing.dashboards.gwt.client.widgets.windbot.charts.VerticalWindChartResources"/>
<g:FlowPanel styleName="{resources.gss.verical_wind_chart}">
<highcharts:Chart ui:field="verticalWindChart" styleName="{resources.gss.chart}"></highcharts:Chart>
<g:FocusPanel ui:field="verticalWindChartClickArea" styleName="{resources.gss.click_area}"></g:FocusPanel>
</g:FlowPanel>
</ui:UiBinder>
@@ -1,4 +1,4 @@
package com.sap.sailing.dashboards.gwt.client.windchart;
package com.sap.sailing.dashboards.gwt.client.widgets.windbot.charts;
public interface VerticalWindChartClickListener {
public void clickedWindChartWithNewIntervalChangeInMillis(int windChartIntervallInMillis);
Loaded 100 of 534 files, more files were not shown because too many files have changed in this diff. Show more