Couple of changes for the Windchart

- Removed TimeSeries for marking the time
- Retreival of confidence values for the wind
- Improved settings
This commit is contained in:
fmittag committed 2012-05-10 20:14:50 +02:00
1 parent 16bb72aab8
commit f675fc476b
11 files changed
+132 -140

No files matched your search

@@ -8,7 +8,7 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ClassPath: . Bundle-ClassPath: .
Export-Package: com.sap.sailing.domain.base, Export-Package: com.sap.sailing.domain.base,
com.sap.sailing.domain.base.impl, com.sap.sailing.domain.base.impl,
com.sap.sailing.domain.confidence;x-friends:="com.sap.sailing.domain.test", com.sap.sailing.domain.confidence,
com.sap.sailing.domain.confidence.impl;x-friends:="com.sap.sailing.domain.test", com.sap.sailing.domain.confidence.impl;x-friends:="com.sap.sailing.domain.test",
com.sap.sailing.domain.leaderboard, com.sap.sailing.domain.leaderboard,
com.sap.sailing.domain.leaderboard.impl, com.sap.sailing.domain.leaderboard.impl,
@@ -13,7 +13,6 @@ import org.moxieapps.gwt.highcharts.client.Chart;
import org.moxieapps.gwt.highcharts.client.ChartSubtitle; import org.moxieapps.gwt.highcharts.client.ChartSubtitle;
import org.moxieapps.gwt.highcharts.client.ChartTitle; import org.moxieapps.gwt.highcharts.client.ChartTitle;
import org.moxieapps.gwt.highcharts.client.Color; import org.moxieapps.gwt.highcharts.client.Color;
import org.moxieapps.gwt.highcharts.client.Extremes;
import org.moxieapps.gwt.highcharts.client.PlotLine; import org.moxieapps.gwt.highcharts.client.PlotLine;
import org.moxieapps.gwt.highcharts.client.Point; import org.moxieapps.gwt.highcharts.client.Point;
import org.moxieapps.gwt.highcharts.client.Series; import org.moxieapps.gwt.highcharts.client.Series;
@@ -70,6 +69,8 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
private final StringMessages stringMessages; private final StringMessages stringMessages;
private final Set<WindSourceType> windSourceTypesToDisplay; private final Set<WindSourceType> windSourceTypesToDisplay;
private long resolutionInMilliseconds; private long resolutionInMilliseconds;
private boolean showWindSpeedSeries;
private boolean showWindDirectionsSeries;
/** /**
* Holds one series for each wind source for which data has been received. * Holds one series for each wind source for which data has been received.
@@ -81,8 +82,6 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
private final AsyncActionsExecutor asyncActionsExecutor; private final AsyncActionsExecutor asyncActionsExecutor;
private final SailingServiceAsync sailingService; private final SailingServiceAsync sailingService;
private final Chart chart; private final Chart chart;
private Series timeLineSeries;
private final boolean allowTimeAdjust;
private boolean ignoreClickOnce; private boolean ignoreClickOnce;
private final DateTimeFormat dateFormat = DateTimeFormat.getFormat("HH:mm:ss"); private final DateTimeFormat dateFormat = DateTimeFormat.getFormat("HH:mm:ss");
@@ -108,17 +107,18 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
*/ */
public WindChart(SailingServiceAsync sailingService, RaceSelectionProvider raceSelectionProvider, Timer timer, public WindChart(SailingServiceAsync sailingService, RaceSelectionProvider raceSelectionProvider, Timer timer,
WindChartSettings settings, final StringMessages stringMessages, AsyncActionsExecutor asyncActionsExecutor, WindChartSettings settings, final StringMessages stringMessages, AsyncActionsExecutor asyncActionsExecutor,
ErrorReporter errorReporter, boolean compactChart, boolean allowTimeAdjust) { ErrorReporter errorReporter, boolean compactChart) {
super(timer); super(timer);
this.sailingService = sailingService; this.sailingService = sailingService;
this.asyncActionsExecutor = asyncActionsExecutor; this.asyncActionsExecutor = asyncActionsExecutor;
this.stringMessages = stringMessages; this.stringMessages = stringMessages;
this.errorReporter = errorReporter; this.errorReporter = errorReporter;
this.allowTimeAdjust = allowTimeAdjust;
this.windSourceDirectionSeries = new HashMap<WindSource, Series>(); this.windSourceDirectionSeries = new HashMap<WindSource, Series>();
this.windSourceSpeedSeries = new HashMap<WindSource, Series>(); this.windSourceSpeedSeries = new HashMap<WindSource, Series>();
this.colorMap = new ColorMap<WindSource>(); this.colorMap = new ColorMap<WindSource>();
this.windSourceTypesToDisplay = new HashSet<WindSourceType>(); this.windSourceTypesToDisplay = new HashSet<WindSourceType>();
this.showWindSpeedSeries = false;
this.showWindDirectionsSeries = true;
chart = new Chart() chart = new Chart()
.setZoomType(Chart.ZoomType.X) .setZoomType(Chart.ZoomType.X)
.setMarginLeft(65) .setMarginLeft(65)
@@ -137,7 +137,6 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
@Override @Override
public String format(ToolTipData toolTipData) { public String format(ToolTipData toolTipData) {
String seriesName = toolTipData.getSeriesName(); String seriesName = toolTipData.getSeriesName();
if (seriesName.equals(WindChart.this.stringMessages.time())) { if (seriesName.equals(WindChart.this.stringMessages.time())) {
return "<b>" + seriesName + ":</b> " + dateFormat.format(new Date(toolTipData.getXAsLong())) return "<b>" + seriesName + ":</b> " + dateFormat.format(new Date(toolTipData.getXAsLong()))
+ "<br/>(" + stringMessages.clickChartToSetTime() + ")"; + "<br/>(" + stringMessages.clickChartToSetTime() + ")";
@@ -158,7 +157,6 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
chart.setBackgroundColor(new Color("#ebebec")); chart.setBackgroundColor(new Color("#ebebec"));
if (allowTimeAdjust) {
chart.setClickEventHandler(new ChartClickEventHandler() { chart.setClickEventHandler(new ChartClickEventHandler() {
@Override @Override
public boolean onClick(ChartClickEvent chartClickEvent) { public boolean onClick(ChartClickEvent chartClickEvent) {
@@ -171,6 +169,7 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
return true; return true;
} }
}); });
chart.setSelectionEventHandler(new ChartSelectionEventHandler() { chart.setSelectionEventHandler(new ChartSelectionEventHandler() {
@Override @Override
public boolean onSelection(ChartSelectionEvent chartSelectionEvent) { public boolean onSelection(ChartSelectionEvent chartSelectionEvent) {
@@ -191,7 +190,7 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
return true; return true;
} }
}); });
}
chart.getXAxis().setType(Axis.Type.DATE_TIME).setMaxZoom(10000) // ten seconds chart.getXAxis().setType(Axis.Type.DATE_TIME).setMaxZoom(10000) // ten seconds
.setAxisTitleText(stringMessages.time()); .setAxisTitleText(stringMessages.time());
chart.getYAxis(0).setAxisTitleText(stringMessages.fromDeg()).setStartOnTick(false).setShowFirstLabel(false) chart.getYAxis(0).setAxisTitleText(stringMessages.fromDeg()).setStartOnTick(false).setShowFirstLabel(false)
@@ -202,6 +201,7 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
return new Long(value < 0 ? value + 360 : value).toString(); return new Long(value < 0 ? value + 360 : value).toString();
} }
})); }));
chart.getYAxis(1).setOpposite(true).setAxisTitleText(stringMessages.speed()+" ("+stringMessages.averageSpeedInKnotsUnit()+")") chart.getYAxis(1).setOpposite(true).setAxisTitleText(stringMessages.speed()+" ("+stringMessages.averageSpeedInKnotsUnit()+")")
.setStartOnTick(false).setShowFirstLabel(false).setGridLineWidth(0).setMinorGridLineWidth(0); .setStartOnTick(false).setShowFirstLabel(false).setGridLineWidth(0).setMinorGridLineWidth(0);
@@ -213,8 +213,6 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
.getXAxis().setAxisTitle(null); .getXAxis().setAxisTitle(null);
} }
timeLineSeries = createTimeLineSeries();
setWidget(chart); setWidget(chart);
setSize("100%", "100%"); setSize("100%", "100%");
updateSettings(settings); updateSettings(settings);
@@ -237,37 +235,40 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
} }
private void showVisibleSeries() { private void showVisibleSeries() {
Series[] currentlyVisible = chart.getSeries(); Set<Series> visibleSeries = new HashSet<Series>(Arrays.asList(chart.getSeries()));
Set<Series> seriesToRemove = new HashSet<Series>();
for (Series series : currentlyVisible) {
seriesToRemove.add(series);
}
for (Map.Entry<WindSource, Series> e : windSourceDirectionSeries.entrySet()) {
if (windSourceTypesToDisplay.contains(e.getKey().getType())) {
if (!seriesToRemove.contains(e.getValue())) {
chart.addSeries(e.getValue());
e.getValue().select(true); // ensures that the checkbox will be ticked
} else {
seriesToRemove.remove(e.getValue());
}
}
}
for (Map.Entry<WindSource, Series> e : windSourceSpeedSeries.entrySet()) {
if (windSourceTypesToDisplay.contains(e.getKey().getType())) {
if (!seriesToRemove.contains(e.getValue())) {
chart.addSeries(e.getValue());
e.getValue().select(true); // ensures that the checkbox will be ticked
} else {
seriesToRemove.remove(e.getValue());
}
}
}
// never remove the timeLineSeries if(showWindDirectionsSeries) {
seriesToRemove.remove(timeLineSeries); for (Map.Entry<WindSource, Series> e : windSourceDirectionSeries.entrySet()) {
for (Series series : seriesToRemove) { Series series = e.getValue();
chart.removeSeries(series); if (windSourceTypesToDisplay.contains(e.getKey().getType())) {
if (!visibleSeries.contains(series)) {
chart.addSeries(series, false, false);
series.select(true); // ensures that the checkbox will be ticked
}
} else {
if(visibleSeries.contains(series)) {
chart.removeSeries(series, false);
}
}
}
}
if(showWindSpeedSeries) {
for (Map.Entry<WindSource, Series> e : windSourceSpeedSeries.entrySet()) {
Series series = e.getValue();
if (windSourceTypesToDisplay.contains(e.getKey().getType())) {
if (!visibleSeries.contains(series)) {
chart.addSeries(series, false, false);
series.select(true); // ensures that the checkbox will be ticked
}
} else {
if(visibleSeries.contains(series)) {
chart.removeSeries(series, false);
}
}
}
} }
chart.redraw();
} }
/** /**
@@ -279,7 +280,7 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
if (result == null) { if (result == null) {
result = createSpeedSeries(windSource); result = createSpeedSeries(windSource);
windSourceSpeedSeries.put(windSource, result); windSourceSpeedSeries.put(windSource, result);
if (windSourceTypesToDisplay.contains(windSource.getType())) { if (showWindSpeedSeries && windSourceTypesToDisplay.contains(windSource.getType())) {
chart.addSeries(result); chart.addSeries(result);
} }
} }
@@ -316,15 +317,6 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
return newSeries; return newSeries;
} }
private Series createTimeLineSeries() {
return chart
.createSeries()
.setType(Series.Type.LINE)
.setName(stringMessages.time())
.setYAxis(0)
.setPlotOptions(new LinePlotOptions().setShowInLegend(false).setHoverStateEnabled(false).setLineWidth(2));
}
/** /**
* Updates the wind charts with the wind data from <code>result</code>. If <code>append</code> is <code>true</code>, previously * Updates the wind charts with the wind data from <code>result</code>. If <code>append</code> is <code>true</code>, previously
* existing points in the chart are left unchanged. Otherwise, the existing wind series are replaced. * existing points in the chart are left unchanged. Otherwise, the existing wind series are replaced.
@@ -346,15 +338,17 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
int i=0; int i=0;
for (WindDTO wind : windTrackInfo.windFixes) { for (WindDTO wind : windTrackInfo.windFixes) {
if (timeOfEarliestRequestInMillis == null || wind.timepoint<timeOfEarliestRequestInMillis) { if (timeOfEarliestRequestInMillis == null || wind.timepoint<timeOfEarliestRequestInMillis) {
timeOfEarliestRequestInMillis = wind.timepoint; timeOfEarliestRequestInMillis = wind.originTimepoint;
} }
if (timeOfLatestRequestInMillis == null || wind.timepoint>timeOfLatestRequestInMillis) { if (timeOfLatestRequestInMillis == null || wind.timepoint>timeOfLatestRequestInMillis) {
timeOfLatestRequestInMillis = wind.timepoint; timeOfLatestRequestInMillis = wind.originTimepoint;
} }
Point newDirectionPoint = new Point(wind.timepoint, wind.dampenedTrueWindFromDeg); Point newDirectionPoint = new Point(wind.originTimepoint, wind.dampenedTrueWindFromDeg);
if (wind.dampenedTrueWindSpeedInKnots != null) { if (wind.dampenedTrueWindSpeedInKnots != null) {
newDirectionPoint.setName(numberFormat.format(wind.dampenedTrueWindSpeedInKnots)+stringMessages.averageSpeedInKnotsUnit()); String name = numberFormat.format(wind.dampenedTrueWindSpeedInKnots)+ stringMessages.averageSpeedInKnotsUnit();
// name += " Confidence:" + wind.confidence;
newDirectionPoint.setName(name);
} }
newDirectionPoint = recalculateDirectionPoint(directionMax, directionMin, newDirectionPoint); newDirectionPoint = recalculateDirectionPoint(directionMax, directionMin, newDirectionPoint);
directionPoints[i] = newDirectionPoint; directionPoints[i] = newDirectionPoint;
@@ -367,7 +361,7 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
directionMin = direction; directionMin = direction;
} }
Point newSpeedPoint = new Point(wind.timepoint, wind.dampenedTrueWindSpeedInKnots); Point newSpeedPoint = new Point(wind.originTimepoint, wind.dampenedTrueWindSpeedInKnots);
speedPoints[i++] = newSpeedPoint; speedPoints[i++] = newSpeedPoint;
} }
Point[] newDirectionPoints; Point[] newDirectionPoints;
@@ -425,7 +419,7 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
@Override @Override
public SettingsDialogComponent<WindChartSettings> getSettingsDialogComponent() { public SettingsDialogComponent<WindChartSettings> getSettingsDialogComponent() {
return new WindChartSettingsDialogComponent(new WindChartSettings(windSourceTypesToDisplay, resolutionInMilliseconds), stringMessages); return new WindChartSettingsDialogComponent(new WindChartSettings(showWindSpeedSeries, showWindDirectionsSeries, windSourceTypesToDisplay, resolutionInMilliseconds), stringMessages);
} }
/** /**
@@ -438,10 +432,11 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
resolutionInMilliseconds = newSettings.getResolutionInMilliseconds(); resolutionInMilliseconds = newSettings.getResolutionInMilliseconds();
clearCacheAndReload(); clearCacheAndReload();
} }
showWindDirectionsSeries = newSettings.isShowWindDirectionsSeries();
showWindSpeedSeries = newSettings.isShowWindSpeedSeries();
windSourceTypesToDisplay.clear(); windSourceTypesToDisplay.clear();
windSourceTypesToDisplay.addAll(newSettings.getWindSourceTypesToDisplay()); windSourceTypesToDisplay.addAll(newSettings.getWindSourceTypesToDisplay());
showVisibleSeries(); showVisibleSeries();
chart.redraw();
} }
private void clearCacheAndReload() { private void clearCacheAndReload() {
@@ -460,7 +455,7 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
if (result == null) { if (result == null) {
result = createDirectionSeries(windSource); result = createDirectionSeries(windSource);
windSourceDirectionSeries.put(windSource, result); windSourceDirectionSeries.put(windSource, result);
if (windSourceTypesToDisplay.contains(windSource.getType())) { if (showWindDirectionsSeries && windSourceTypesToDisplay.contains(windSource.getType())) {
chart.addSeries(result); chart.addSeries(result);
} }
} }
@@ -492,8 +487,6 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
xAxis.setStartOnTick(false); xAxis.setStartOnTick(false);
xAxis.setEndOnTick(false); xAxis.setEndOnTick(false);
xAxis.setPlotLines(xAxis.createPlotLine().setColor("#CC0000").setValue(WindChart.this.timer.getTime().getTime()));
updateStripChartSeries(result, append); updateStripChartSeries(result, append);
} else { } else {
if (!append) { if (!append) {
@@ -560,49 +553,13 @@ public class WindChart extends SimpleChartPanel implements Component<WindChartSe
loadData(selectedRaceIdentifier, minTimepoint, maxTimepoint, /* append */false); // replace old series loadData(selectedRaceIdentifier, minTimepoint, maxTimepoint, /* append */false); // replace old series
} }
} }
updateTimeLine(date);
} }
/**
* Forces the chart to {@link #updateTimeLine(Date) update} the position and to {@link #ensureTimeLineIsVisible()
* ensure}, that the time line is visible.
*/
public void forceTimeLineUpdate() {
updateTimeLine(timer.getTime());
}
/**
* Updates the position of the time line for the given {@link Date}, if {@link #allowTimeAdjust} is <code>true</code>.<br />
* @param date Defines the x-Value of the line points
*/
private void updateTimeLine(Date date) {
if (allowTimeAdjust) {
Long x = date.getTime();
try {
Extremes extremes = chart.getYAxis(0).getExtremes();
Point[] points = new Point[2];
points[0] = new Point(x, extremes.getMin());
points[1] = new Point(x, extremes.getMax());
timeLineSeries.setPoints(points);
ensureTimeLineIsVisible();
} catch (NullPointerException e) {
// explicitly do nothing; it means that getExtremes() has thrown an exception, so we don't know how to set them
}
}
}
/**
* Checks if the series of the chart contain the {@link #timeLineSeries}. If not, it is added to the chart.
*/
private void ensureTimeLineIsVisible() {
if (!Arrays.asList(chart.getSeries()).contains(timeLineSeries)) {
chart.addSeries(timeLineSeries);
}
}
@Override @Override
public void onResize() { public void onResize() {
chart.setSizeToMatchContainer(); if(isVisible()) {
chart.setSizeToMatchContainer();
}
} }
private boolean needsDataLoading() { private boolean needsDataLoading() {
@@ -1,8 +1,5 @@
package com.sap.sailing.gwt.ui.adminconsole; package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import com.sap.sailing.domain.common.WindSourceType; import com.sap.sailing.domain.common.WindSourceType;
@@ -12,21 +9,21 @@ public class WindChartSettings {
private final long resolutionInMilliseconds; private final long resolutionInMilliseconds;
public WindChartSettings(Set<WindSourceType> windSourceTypesToDisplay, long resolutionInMilliseconds) { private final boolean showWindSpeedSeries;
private final boolean showWindDirectionsSeries;
public WindChartSettings(boolean showWindSpeedSeries, boolean showWindDirectionsSeries, Set<WindSourceType> windSourceTypesToDisplay, long resolutionInMilliseconds) {
this.windSourceTypesToDisplay = windSourceTypesToDisplay; this.windSourceTypesToDisplay = windSourceTypesToDisplay;
this.resolutionInMilliseconds = resolutionInMilliseconds; this.resolutionInMilliseconds = resolutionInMilliseconds;
this.showWindDirectionsSeries = showWindDirectionsSeries;
this.showWindSpeedSeries = showWindSpeedSeries;
} }
/** /**
* Uses {@link WindChart#DEFAULT_RESOLUTION_IN_MILLISECONDS} as resolution * Uses {@link WindChart#DEFAULT_RESOLUTION_IN_MILLISECONDS} as resolution
*/ */
public WindChartSettings(WindSourceType... windSourceTypesToDisplay) { public WindChartSettings(boolean showWindSpeedSeries, boolean showWindDirectionsSeries, Set<WindSourceType> windSourceTypesToDisplay) {
this(WindChart.DEFAULT_RESOLUTION_IN_MILLISECONDS, windSourceTypesToDisplay); this(showWindSpeedSeries, showWindDirectionsSeries, windSourceTypesToDisplay, WindChart.DEFAULT_RESOLUTION_IN_MILLISECONDS);
}
public WindChartSettings(long resolutionInMilliseconds, WindSourceType... windSourceTypesToDisplay) {
this(new HashSet<WindSourceType>(windSourceTypesToDisplay == null ? new ArrayList<WindSourceType>()
: Arrays.asList(windSourceTypesToDisplay)), resolutionInMilliseconds);
} }
public Set<WindSourceType> getWindSourceTypesToDisplay() { public Set<WindSourceType> getWindSourceTypesToDisplay() {
@@ -36,5 +33,13 @@ public class WindChartSettings {
public long getResolutionInMilliseconds() { public long getResolutionInMilliseconds() {
return resolutionInMilliseconds; return resolutionInMilliseconds;
} }
public boolean isShowWindSpeedSeries() {
return showWindSpeedSeries;
}
public boolean isShowWindDirectionsSeries() {
return showWindDirectionsSeries;
}
} }
@@ -23,6 +23,9 @@ public class WindChartSettingsDialogComponent implements SettingsDialogComponent
private final WindChartSettings initialSettings; private final WindChartSettings initialSettings;
private IntegerBox resolutionInSecondsBox; private IntegerBox resolutionInSecondsBox;
private final Map<WindSourceType, CheckBox> checkboxes; private final Map<WindSourceType, CheckBox> checkboxes;
private CheckBox showWindSpeedSeriesCheckbox;
private CheckBox showWindDirectionsSeriesCheckbox;
private final StringMessages stringMessages; private final StringMessages stringMessages;
public WindChartSettingsDialogComponent(WindChartSettings initialSettings, StringMessages stringMessages) { public WindChartSettingsDialogComponent(WindChartSettings initialSettings, StringMessages stringMessages) {
@@ -36,10 +39,22 @@ public class WindChartSettingsDialogComponent implements SettingsDialogComponent
public Widget getAdditionalWidget(DataEntryDialog<?> dialog) { public Widget getAdditionalWidget(DataEntryDialog<?> dialog) {
VerticalPanel vp = new VerticalPanel(); VerticalPanel vp = new VerticalPanel();
resolutionInSecondsBox = dialog.createIntegerBox((int) (initialSettings.getResolutionInMilliseconds()/1000), /* visibleLength */ 5); resolutionInSecondsBox = dialog.createIntegerBox((int) (initialSettings.getResolutionInMilliseconds()/1000), /* visibleLength */ 5);
HorizontalPanel hp = new HorizontalPanel(); HorizontalPanel hp = new HorizontalPanel();
hp.add(new Label(stringMessages.stepSizeInSeconds())); hp.add(new Label(stringMessages.stepSizeInSeconds()));
hp.add(resolutionInSecondsBox); hp.add(resolutionInSecondsBox);
vp.add(hp); vp.add(hp);
showWindSpeedSeriesCheckbox = dialog.createCheckbox(stringMessages.showWindSpeedSeries());
showWindSpeedSeriesCheckbox.setValue(initialSettings.isShowWindSpeedSeries());
vp.add(showWindSpeedSeriesCheckbox);
showWindDirectionsSeriesCheckbox = dialog.createCheckbox(stringMessages.showWindDirectionSeries());
showWindDirectionsSeriesCheckbox.setValue(initialSettings.isShowWindDirectionsSeries());
vp.add(showWindDirectionsSeriesCheckbox);
Label createHeadlineLabel = dialog.createHeadlineLabel(stringMessages.windSourcesUsed());
vp.add(createHeadlineLabel);
for (WindSourceType windSourceType : WindSourceType.values()) { for (WindSourceType windSourceType : WindSourceType.values()) {
CheckBox checkbox = dialog.createCheckbox(WindSourceTypeFormatter.format(windSourceType, stringMessages)); CheckBox checkbox = dialog.createCheckbox(WindSourceTypeFormatter.format(windSourceType, stringMessages));
checkboxes.put(windSourceType, checkbox); checkboxes.put(windSourceType, checkbox);
@@ -57,7 +72,8 @@ public class WindChartSettingsDialogComponent implements SettingsDialogComponent
windSourceTypesToDisplay.add(e.getKey()); windSourceTypesToDisplay.add(e.getKey());
} }
} }
return new WindChartSettings(windSourceTypesToDisplay, resolutionInSecondsBox.getValue() == null ? -1 : resolutionInSecondsBox.getValue()*1000); return new WindChartSettings(showWindSpeedSeriesCheckbox.getValue(), showWindDirectionsSeriesCheckbox.getValue(),
windSourceTypesToDisplay, resolutionInSecondsBox.getValue() == null ? -1 : resolutionInSecondsBox.getValue()*1000);
} }
@Override @Override
@@ -1,10 +1,12 @@
package com.sap.sailing.gwt.ui.adminconsole; package com.sap.sailing.gwt.ui.adminconsole;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@@ -180,8 +182,8 @@ public class WindPanel extends FormPanel implements EventDisplayer, WindShower,
}); });
windSourceSelectionPanel.add(showConfigAnchor); windSourceSelectionPanel.add(showConfigAnchor);
grid.setWidget(1, 0, windSourceSelectionPanel); grid.setWidget(1, 0, windSourceSelectionPanel);
windChart = new WindChart(sailingService, raceSelectionProvider, new Timer( WindChartSettings windChartSettings = new WindChartSettings(false, true, new HashSet<WindSourceType>(Arrays.asList(WindSourceType.values())));
PlayModes.Replay), new WindChartSettings(WindSourceType.values()), stringMessages, asyncActionsExecutor, errorReporter, false, false); windChart = new WindChart(sailingService, raceSelectionProvider, new Timer(PlayModes.Replay), windChartSettings, stringMessages, asyncActionsExecutor, errorReporter, false);
windChart.onResize(); windChart.onResize();
grid.setWidget(2, 0, windChart.getEntryWidget()); grid.setWidget(2, 0, windChart.getEntryWidget());
grid.getCellFormatter().setVerticalAlignment(1, 1, HasVerticalAlignment.ALIGN_TOP); grid.getCellFormatter().setVerticalAlignment(1, 1, HasVerticalAlignment.ALIGN_TOP);
@@ -298,4 +298,6 @@ public interface StringMessages extends Messages {
String servletPortNumber(); String servletPortNumber();
String registeredAt(String string); String registeredAt(String string);
String replicatingFromMaster(String hostname, int jmsPort, int servletPort); String replicatingFromMaster(String hostname, int jmsPort, int servletPort);
String showWindSpeedSeries();
String showWindDirectionSeries();
} }
@@ -292,4 +292,6 @@ courseMiddleLine=Course middle line
jmsPortNumber=JMS port number jmsPortNumber=JMS port number
servletPortNumber=Servlet port number servletPortNumber=Servlet port number
registeredAt=Registered at {0} registeredAt=Registered at {0}
replicatingFromMaster=Replicating from master {0}, JMS port {1}, servlet port {2} replicatingFromMaster=Replicating from master {0}, JMS port {1}, servlet port {2}
showWindSpeedSeries=Show wind speed data
showWindDirectionSeries=Show wind directions data
@@ -293,4 +293,6 @@ courseMiddleLine=Kursmittellinie
jmsPortNumber=JMS Portnummer jmsPortNumber=JMS Portnummer
servletPortNumber=Servlet Portnummer servletPortNumber=Servlet Portnummer
registeredAt=Registriert {0} registeredAt=Registriert {0}
replicatingFromMaster=Repliziert von master {0}, JMS Port {1}, Servlet Port {2} replicatingFromMaster=Repliziert von master {0}, JMS Port {1}, Servlet Port {2}
showWindSpeedSeries=Daten für Windgeschwindigkeit zeigen
showWindDirectionSeries=Daten für Windrichtung zeigen
@@ -1,8 +1,10 @@
package com.sap.sailing.gwt.ui.raceboard; package com.sap.sailing.gwt.ui.raceboard;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -321,9 +323,9 @@ public class RaceBoardPanel extends FormPanel implements EventDisplayer, RaceSel
} }
private WindChart createWindChart(AsyncActionsExecutor asyncActionsExecutor) { private WindChart createWindChart(AsyncActionsExecutor asyncActionsExecutor) {
WindChartSettings windChartSettings = new WindChartSettings(WindSourceType.values()); WindChartSettings windChartSettings = new WindChartSettings(false, true, new HashSet<WindSourceType>(Arrays.asList(WindSourceType.values())));
return new WindChart(sailingService, raceSelectionProvider, timer, windChartSettings, return new WindChart(sailingService, raceSelectionProvider, timer, windChartSettings,
stringMessages, asyncActionsExecutor, errorReporter, viewMode == RaceBoardViewModes.ONESCREEN, true); stringMessages, asyncActionsExecutor, errorReporter, viewMode == RaceBoardViewModes.ONESCREEN);
} }
private void addComponentAsToogleButtonToNavigationMenu(final ComponentViewer componentViewer, private void addComponentAsToogleButtonToNavigationMenu(final ComponentViewer componentViewer,
@@ -100,6 +100,7 @@ import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace; import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sailing.domain.tracking.Wind; import com.sap.sailing.domain.tracking.Wind;
import com.sap.sailing.domain.tracking.WindTrack; import com.sap.sailing.domain.tracking.WindTrack;
import com.sap.sailing.domain.tracking.WindWithConfidence;
import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl; import com.sap.sailing.domain.tracking.impl.TrackedRaceImpl;
import com.sap.sailing.domain.tracking.impl.WindImpl; import com.sap.sailing.domain.tracking.impl.WindImpl;
import com.sap.sailing.domain.tractracadapter.DomainFactory; import com.sap.sailing.domain.tractracadapter.DomainFactory;
@@ -661,8 +662,9 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
/** /**
* Uses <code>wind</code> for both, the non-dampened and dampened fields of the {@link WindDTO} object returned * Uses <code>wind</code> for both, the non-dampened and dampened fields of the {@link WindDTO} object returned
*/ */
protected WindDTO createWindDTOFromAlreadyAveraged(Wind wind, WindTrack windTrack) { protected WindDTO createWindDTOFromAlreadyAveraged(Wind wind, WindTrack windTrack, TimePoint originTimepoint) {
WindDTO windDTO = new WindDTO(); WindDTO windDTO = new WindDTO();
windDTO.originTimepoint = originTimepoint.asMillis();
windDTO.trueWindBearingDeg = wind.getBearing().getDegrees(); windDTO.trueWindBearingDeg = wind.getBearing().getDegrees();
windDTO.trueWindFromDeg = wind.getBearing().reverse().getDegrees(); windDTO.trueWindFromDeg = wind.getBearing().reverse().getDegrees();
windDTO.trueWindSpeedInKnots = wind.getKnots(); windDTO.trueWindSpeedInKnots = wind.getKnots();
@@ -717,9 +719,11 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
.getMillisecondsOverWhichToAverageWind(); .getMillisecondsOverWhichToAverageWind();
TimePoint timePoint = fromTimePoint; TimePoint timePoint = fromTimePoint;
for (int i = 0; i < numberOfFixes; i++) { for (int i = 0; i < numberOfFixes; i++) {
Wind wind = windTrack.getAveragedWind(position, timePoint); WindWithConfidence<Pair<Position, TimePoint>> averagedWindWithConfidence = windTrack.getAveragedWindWithConfidence(position, timePoint);
if (wind != null) {
WindDTO windDTO = createWindDTOFromAlreadyAveraged(wind, windTrack); if (averagedWindWithConfidence != null) {
WindDTO windDTO = createWindDTOFromAlreadyAveraged(averagedWindWithConfidence.getObject(), windTrack, timePoint);
windDTO.confidence = averagedWindWithConfidence.getConfidence();
windTrackInfoDTO.windFixes.add(windDTO); windTrackInfoDTO.windFixes.add(windDTO);
} }
timePoint = new MillisecondsTimePoint(timePoint.asMillis() + millisecondsStepWidth); timePoint = new MillisecondsTimePoint(timePoint.asMillis() + millisecondsStepWidth);
@@ -737,12 +741,12 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
assert from != null; assert from != null;
TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier); TrackedRace trackedRace = getExistingTrackedRace(raceIdentifier);
WindInfoForRaceDTO result = getAveragedWindInfo(new MillisecondsTimePoint(from), trackedRace.getTimePointOfNewestEvent(), millisecondsStepWidth, numberOfFixes, WindInfoForRaceDTO result = getAveragedWindInfo(new MillisecondsTimePoint(from), millisecondsStepWidth, numberOfFixes,
windSourceTypeNames, trackedRace); windSourceTypeNames, trackedRace);
return result; return result;
} }
private WindInfoForRaceDTO getAveragedWindInfo(TimePoint from, TimePoint to, long millisecondsStepWidth, int numberOfFixes, private WindInfoForRaceDTO getAveragedWindInfo(TimePoint from, long millisecondsStepWidth, int numberOfFixes,
Collection<String> windSourceTypeNames, TrackedRace trackedRace) { Collection<String> windSourceTypeNames, TrackedRace trackedRace) {
WindInfoForRaceDTO result = null; WindInfoForRaceDTO result = null;
if (trackedRace != null) { if (trackedRace != null) {
@@ -770,12 +774,11 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
.getMillisecondsOverWhichToAverageWind(); .getMillisecondsOverWhichToAverageWind();
TimePoint timePoint = from; TimePoint timePoint = from;
for (int i = 0; i < numberOfFixes && newestEvent != null && timePoint.compareTo(newestEvent) < 0; i++) { for (int i = 0; i < numberOfFixes && newestEvent != null && timePoint.compareTo(newestEvent) < 0; i++) {
Wind wind = windTrack.getAveragedWind(null, timePoint); WindWithConfidence<Pair<Position, TimePoint>> averagedWindWithConfidence = windTrack.getAveragedWindWithConfidence(null, timePoint);
if (wind != null) { if (averagedWindWithConfidence != null) {
if(wind.getTimePoint().compareTo(from) > 0 && wind.getTimePoint().compareTo(to) < 0) { WindDTO windDTO = createWindDTOFromAlreadyAveraged(averagedWindWithConfidence.getObject(), windTrack, timePoint);
WindDTO windDTO = createWindDTOFromAlreadyAveraged(wind, windTrack); windDTO.confidence = averagedWindWithConfidence.getConfidence();
windTrackInfoDTO.windFixes.add(windDTO); windTrackInfoDTO.windFixes.add(windDTO);
}
} }
timePoint = new MillisecondsTimePoint(timePoint.asMillis() + millisecondsStepWidth); timePoint = new MillisecondsTimePoint(timePoint.asMillis() + millisecondsStepWidth);
} }
@@ -805,7 +808,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
} }
if(fromTimePoint != null && toTimePoint != null) { if(fromTimePoint != null && toTimePoint != null) {
int numberOfFixes = (int) ((toTimePoint.asMillis() - fromTimePoint.asMillis())/resolutionInMilliseconds); int numberOfFixes = (int) ((toTimePoint.asMillis() - fromTimePoint.asMillis())/resolutionInMilliseconds);
result = getAveragedWindInfo(fromTimePoint, toTimePoint, resolutionInMilliseconds, numberOfFixes, windSourceTypeNames, trackedRace); result = getAveragedWindInfo(fromTimePoint, resolutionInMilliseconds, numberOfFixes, windSourceTypeNames, trackedRace);
} }
} }
return result; return result;
@@ -900,9 +903,9 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
fix.getTimePoint()); fix.getTimePoint());
LegType legType = trackedLegOfCompetitor == null ? null : trackedRace.getTrackedLeg( LegType legType = trackedLegOfCompetitor == null ? null : trackedRace.getTrackedLeg(
trackedLegOfCompetitor.getLeg()).getLegType(fix.getTimePoint()); trackedLegOfCompetitor.getLeg()).getLegType(fix.getTimePoint());
GPSFixDTO fixDTO = createGPSFixDTO(fix, fix.getSpeed(), createWindDTOFromAlreadyAveraged(trackedRace.getWind(fix.getPosition(), Wind wind = trackedRace.getWind(fix.getPosition(),toTimePointExcluding);
toTimePointExcluding), trackedRace WindDTO windDTO = createWindDTOFromAlreadyAveraged(wind, trackedRace.getOrCreateWindTrack(windSource), toTimePointExcluding);
.getOrCreateWindTrack(windSource)), tack, legType, /* extrapolate */ GPSFixDTO fixDTO = createGPSFixDTO(fix, fix.getSpeed(), windDTO, tack, legType, /* extrapolate */
false); false);
fixesForCompetitor.add(fixDTO); fixesForCompetitor.add(fixDTO);
if (fixIter.hasNext()) { if (fixIter.hasNext()) {
@@ -916,13 +919,12 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
.getTrackedLeg(trackedLegOfCompetitor.getLeg()).getLegType( .getTrackedLeg(trackedLegOfCompetitor.getLeg()).getLegType(
fix.getTimePoint()); fix.getTimePoint());
SpeedWithBearing speedWithBearing = track.getEstimatedSpeed(toTimePointExcluding); SpeedWithBearing speedWithBearing = track.getEstimatedSpeed(toTimePointExcluding);
Wind wind2 = trackedRace.getWind(position, toTimePointExcluding);
WindDTO windDTO2 = createWindDTOFromAlreadyAveraged(wind2, trackedRace.getOrCreateWindTrack(windSource), toTimePointExcluding);
GPSFixDTO extrapolated = new GPSFixDTO( GPSFixDTO extrapolated = new GPSFixDTO(
to.get(competitorDTO), to.get(competitorDTO),
new PositionDTO(position.getLatDeg(), position.getLngDeg()), new PositionDTO(position.getLatDeg(), position.getLngDeg()),
createSpeedWithBearingDTO(speedWithBearing), createSpeedWithBearingDTO(speedWithBearing), windDTO2, /* extrapolated */
createWindDTOFromAlreadyAveraged(trackedRace.getWind(position,
toTimePointExcluding), trackedRace
.getOrCreateWindTrack(windSource)), /* extrapolated */
tack2, legType2, true); tack2, legType2, true);
fixesForCompetitor.add(extrapolated); fixesForCompetitor.add(extrapolated);
} }
@@ -1601,9 +1603,9 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
TrackedLegOfCompetitor trackedLegOfCompetitor = trackedRace.getTrackedLeg(competitor, fix.getTimePoint()); TrackedLegOfCompetitor trackedLegOfCompetitor = trackedRace.getTrackedLeg(competitor, fix.getTimePoint());
LegType legType = trackedLegOfCompetitor == null ? null : trackedRace.getTrackedLeg( LegType legType = trackedLegOfCompetitor == null ? null : trackedRace.getTrackedLeg(
trackedLegOfCompetitor.getLeg()).getLegType(fix.getTimePoint()); trackedLegOfCompetitor.getLeg()).getLegType(fix.getTimePoint());
GPSFixDTO fixDTO = createGPSFixDTO(fix, speedWithBearing, createWindDTOFromAlreadyAveraged(trackedRace.getWind( Wind wind = trackedRace.getWind(fix.getPosition(), fix.getTimePoint());
fix.getPosition(), fix.getTimePoint()), WindDTO windDTO = createWindDTOFromAlreadyAveraged(wind, trackedRace.getOrCreateWindTrack(windSource), fix.getTimePoint());
trackedRace.getOrCreateWindTrack(windSource)), tack, legType, /* extrapolated */false); GPSFixDTO fixDTO = createGPSFixDTO(fix, speedWithBearing, windDTO, tack, legType, /* extrapolated */false);
gpsFixDouglasList.add(fixDTO); gpsFixDouglasList.add(fixDTO);
} }
result.put(competitorDTO, gpsFixDouglasList); result.put(competitorDTO, gpsFixDouglasList);
@@ -13,6 +13,8 @@ public class WindDTO implements IsSerializable {
public Double dampenedTrueWindFromDeg; public Double dampenedTrueWindFromDeg;
public PositionDTO position; public PositionDTO position;
public Long timepoint; public Long timepoint;
public Long originTimepoint;
public Double confidence;
public WindDTO() {} public WindDTO() {}
} }