mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-30 17:36:40 +00:00
Improvements for the updatable chart
This commit is contained in:
1 parent
5f400bf95d
commit
f43b50153b
10 files changed
+200
-103
No files matched your search
+1
-1
@@ -11,7 +11,7 @@ import com.sap.sailing.domain.swisstimingadapter.SailMasterMessage;
|
||||
public class SailMasterLiveSimulatorConnectorImpl extends SailMasterConnectorImpl {
|
||||
private final List<SailMasterMessage> bufferedMessageList;
|
||||
|
||||
private long messageDeliveryIntervalInMs = 250;
|
||||
private long messageDeliveryIntervalInMs = 500;
|
||||
|
||||
public SailMasterLiveSimulatorConnectorImpl(String host, int port, RaceSpecificMessageLoader messageLoader, boolean canSendRequests) throws InterruptedException {
|
||||
super(host, port, messageLoader, canSendRequests);
|
||||
|
||||
+4
-2
@@ -39,11 +39,13 @@ public class SwissTimingFactoryImpl implements SwissTimingFactory {
|
||||
Triple<String, Integer, RaceSpecificMessageLoader> key = new Triple<String, Integer, RaceSpecificMessageLoader>(host, port, messageLoader);
|
||||
SailMasterConnector result = connectors.get(key);
|
||||
if (result == null) {
|
||||
result = new SailMasterConnectorImpl(host, port, messageLoader, canSendRequests);
|
||||
// result = new SailMasterConnectorImpl(host, port, messageLoader, canSendRequests);
|
||||
result = new SailMasterLiveSimulatorConnectorImpl(host, port, messageLoader, canSendRequests);
|
||||
connectors.put(key, result);
|
||||
// TODO how do connectors get stopped, terminated and removed from the connectors map again?
|
||||
} else if (result.isStopped()) {
|
||||
result = new SailMasterConnectorImpl(host, port, messageLoader, canSendRequests);
|
||||
// result = new SailMasterConnectorImpl(host, port, messageLoader, canSendRequests);
|
||||
result = new SailMasterLiveSimulatorConnectorImpl(host, port, messageLoader, canSendRequests);
|
||||
connectors.put(key, result);
|
||||
}
|
||||
return result;
|
||||
|
||||
+3
-2
@@ -277,10 +277,11 @@ public interface SailingServiceAsync {
|
||||
|
||||
/**
|
||||
* Returns the mark passings and the data for the given {@link DetailType} of all competitors in
|
||||
* <code>competitorsQuery</code> in the <code>race</code>.<br />
|
||||
* <code>competitorsQuery</code> in the <code>race</code>, including the first dates in the query.<br />
|
||||
* The Long part in the <code>competitorsQuery</code> defines the time point, from which on the data should be
|
||||
* returned. If this time point is lesser than the start of race, all available data for this competitor is
|
||||
* returned.
|
||||
* returned.<br />
|
||||
* Returns <code>null</code>, if <code>race</code> isn't tracked.
|
||||
*/
|
||||
void getCompetitorsRaceData(RaceIdentifier race, List<Pair<Date,CompetitorDTO>> competitorsToLoad, long stepSize,
|
||||
DetailType detailType, AsyncCallback<MultiCompetitorRaceDataDTO> callback);
|
||||
|
||||
+54
-28
@@ -45,7 +45,6 @@ import com.sap.sailing.gwt.ui.client.SailingServiceAsync;
|
||||
import com.sap.sailing.gwt.ui.client.StringMessages;
|
||||
import com.sap.sailing.gwt.ui.client.TimeListener;
|
||||
import com.sap.sailing.gwt.ui.client.Timer;
|
||||
import com.sap.sailing.gwt.ui.client.Timer.PlayModes;
|
||||
import com.sap.sailing.gwt.ui.shared.CompetitorDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.CompetitorRaceDataDTO;
|
||||
import com.sap.sailing.gwt.ui.shared.MultiCompetitorRaceDataDTO;
|
||||
@@ -119,7 +118,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
|
||||
List<RaceIdentifier> selectedRaces = raceSelectionProvider.getSelectedRaces();
|
||||
if(!selectedRaces.isEmpty()) {
|
||||
loadData();
|
||||
loadData(true);
|
||||
}
|
||||
timer.addTimeListener(this);
|
||||
}
|
||||
@@ -176,20 +175,31 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
|
||||
protected abstract Component<SettingsType> getComponent();
|
||||
|
||||
protected void loadData() {
|
||||
if (competitorSelectionProvider.getSelectedCompetitors().iterator().hasNext()) {
|
||||
setWidget(busyIndicatorPanel);
|
||||
/**
|
||||
* Loads the needed data (data which isn't in the {@link #chartData cache}) for the {@link #getVisibleCompetitors()
|
||||
* visible competitors} via
|
||||
* {@link SailingServiceAsync#getCompetitorsRaceData(RaceIdentifier, List, long, DetailType, AsyncCallback)}. After
|
||||
* loading is the method {@link #drawChartData()} called.<br />
|
||||
* If no competitor is visible, is the {@link #noCompetitorsSelectedLabel} displayed.
|
||||
*
|
||||
* @param showBusyIndicator If <code>true</code> is the busy indicator shown while loading the data from the server.
|
||||
*/
|
||||
protected void loadData(boolean showBusyIndicator) {
|
||||
if (hasVisibleCompetitors()) {
|
||||
if (showBusyIndicator) {
|
||||
setWidget(busyIndicatorPanel);
|
||||
}
|
||||
if (chartData == null || chartData.getDetailType() != getDataToShow()) {
|
||||
chartData = new MultiCompetitorRaceDataDTO(getDataToShow());
|
||||
}
|
||||
|
||||
final ArrayList<Pair<Date, CompetitorDTO>> competitorsToLoad = new ArrayList<Pair<Date, CompetitorDTO>>();
|
||||
for (CompetitorDTO competitor : competitorSelectionProvider.getSelectedCompetitors()) {
|
||||
for (CompetitorDTO competitor : getVisibleCompetitors()) {
|
||||
Date chartDataDateOfNewestData = chartData.getDateOfNewestData();
|
||||
if (!chartData.contains(competitor)) {
|
||||
competitorsToLoad.add(new Pair<Date, CompetitorDTO>(new Date(0), competitor));
|
||||
} else if (chartData.getCompetitorRaceData(competitor).getDateOfNewestData().before(chartDataDateOfNewestData)) {
|
||||
Date competitorDateOfNewestData = chartData.getCompetitorRaceData(competitor).getDateOfNewestData();
|
||||
} else if (chartData.getCompetitorData(competitor).getDateOfNewestData().before(chartDataDateOfNewestData)) {
|
||||
Date competitorDateOfNewestData = chartData.getCompetitorData(competitor).getDateOfNewestData();
|
||||
competitorsToLoad.add(new Pair<Date, CompetitorDTO>(new Date(competitorDateOfNewestData.getTime() + getStepSize()), competitor));
|
||||
}
|
||||
}
|
||||
@@ -207,7 +217,14 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
public void onSuccess(MultiCompetitorRaceDataDTO result) {
|
||||
fireEvent(new DataLoadedEvent());
|
||||
if (result != null) {
|
||||
chartData.addAllRaceData(result);
|
||||
for (CompetitorRaceDataDTO competitorData : result.getAllRaceData()) {
|
||||
if (chartData.contains(competitorData.getCompetitor())) {
|
||||
chartData.addCompetitorRaceData(competitorData);
|
||||
chartData.setCompetitorMarkPassingsData(competitorData);
|
||||
} else {
|
||||
chartData.setCompetitorData(competitorData.getCompetitor(), competitorData);
|
||||
}
|
||||
}
|
||||
}
|
||||
drawChartData();
|
||||
setWidget(chart);
|
||||
@@ -229,7 +246,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
|
||||
@Override
|
||||
public void addedToSelection(CompetitorDTO competitor) {
|
||||
loadData();
|
||||
loadData(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -242,7 +259,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
if (competitorMarkPassingSeries != null) {
|
||||
chart.removeSeries(competitorMarkPassingSeries);
|
||||
}
|
||||
if (!competitorSelectionProvider.getSelectedCompetitors().iterator().hasNext()) {
|
||||
if (!hasVisibleCompetitors()) {
|
||||
setWidget(noCompetitorsSelectedLabel);
|
||||
}
|
||||
}
|
||||
@@ -250,7 +267,9 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
/**
|
||||
* Creates the series for all selected competitors if these aren't created yet.<br />
|
||||
* Fills the series for the selected competitors with the data in {@link AbstractChartPanel#chartData}.<br />
|
||||
* Removes series of competitors, which aren't selected and adds series for competitors, which are newly selected.
|
||||
* Removes series of competitors, which aren't selected and adds series for competitors, which are newly selected.<br /><br />
|
||||
*
|
||||
* The data for all {@link #getVisibleCompetitors() visible competitors} needs to be filled before calling this method.
|
||||
*/
|
||||
private synchronized void drawChartData() {
|
||||
//Make sure the busy indicator is removed at this point, or plotting the data results in an exception
|
||||
@@ -262,8 +281,8 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
Series compSeries = getCompetitorSeries(competitor);
|
||||
Series markSeries = getCompetitorMarkPassingSeries(competitor);
|
||||
if (isCompetitorVisible(competitor)) {
|
||||
CompetitorRaceDataDTO competitorData = chartData.getCompetitorRaceData(competitor);
|
||||
if (competitorData != null) { //TODO Exception?
|
||||
CompetitorRaceDataDTO competitorData = chartData.getCompetitorData(competitor);
|
||||
if (competitorData != null) {
|
||||
List<Triple<String, Date, Double>> markPassingsData = competitorData.getMarkPassingsData();
|
||||
List<Point> markPassingPoints = new ArrayList<Point>();
|
||||
for (Triple<String, Date, Double> markPassingData : markPassingsData) {
|
||||
@@ -273,17 +292,17 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
markPassingPoints.add(markPassingPoint);
|
||||
}
|
||||
}
|
||||
|
||||
markSeries.setPoints(markPassingPoints.toArray(new Point[0]));
|
||||
List<Pair<Date, Double>> raceData = competitorData.getRaceData();
|
||||
List<Point> competitorPoints = new ArrayList<Point>();
|
||||
|
||||
Point[] compSeriesPoints = compSeries.getPoints();
|
||||
Date dateOfNewestSeriesPoint = new Date(compSeriesPoints[compSeriesPoints.length - 1].getX().longValue());
|
||||
List<Pair<Date, Double>> raceData = competitorData.getRaceDataAfterDate(dateOfNewestSeriesPoint);
|
||||
for (Pair<Date, Double> data : raceData) {
|
||||
if (data.getA() != null && data.getB() != null) {
|
||||
Point competitorPoint = new Point(data.getA().getTime(), data.getB());
|
||||
competitorPoints.add(competitorPoint);
|
||||
compSeries.addPoint(competitorPoint);
|
||||
}
|
||||
}
|
||||
compSeries.setPoints(competitorPoints.toArray(new Point[0]));
|
||||
|
||||
//Adding the series if chart doesn't contain it
|
||||
if (!chartSeries.contains(compSeries)) {
|
||||
@@ -329,6 +348,14 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
}
|
||||
}
|
||||
|
||||
private Iterable<CompetitorDTO> getVisibleCompetitors() {
|
||||
return competitorSelectionProvider.getSelectedCompetitors();
|
||||
}
|
||||
|
||||
private boolean hasVisibleCompetitors() {
|
||||
return getVisibleCompetitors().iterator().hasNext();
|
||||
}
|
||||
|
||||
private boolean isCompetitorVisible(CompetitorDTO competitor) {
|
||||
return competitorSelectionProvider.isSelected(competitor);
|
||||
}
|
||||
@@ -416,7 +443,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
|
||||
/**
|
||||
* Updates the settings known to be contained in {@link ChartSettings}. Subclasses have to update settings provided
|
||||
* by subclasses thereof. Subclasses also need to call {@link #clearChart()} and {@link #loadData()}, if this method returns <code>true</code>;
|
||||
* by subclasses thereof. Subclasses also need to call {@link #clearChart()} and {@link #loadData(boolean)}, if this method returns <code>true</code>;
|
||||
*
|
||||
* @return <code>true</code> if the settings had been changed and a clearing and loading is needed.
|
||||
*/
|
||||
@@ -447,7 +474,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
|
||||
/**
|
||||
* Updates the {@link #dataToShow} field, creates a new chart for the new <code>dataToShow</code> and clears the {@link #chartData}.<br />
|
||||
* Doesn't {@link #loadData() load the data}.
|
||||
* Doesn't {@link #loadData(boolean) load the data}.
|
||||
*
|
||||
* @return <code>true</code> if the data to show changed
|
||||
*/
|
||||
@@ -476,7 +503,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
setChartData(null);
|
||||
clearChart();
|
||||
loadData();
|
||||
loadData(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -521,12 +548,11 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
|
||||
@Override
|
||||
public void timeChanged(Date date) {
|
||||
//Load the new data only if the timer is in live mode and the data has been initialized by loadData()
|
||||
if (timer.getPlayMode() == PlayModes.Live && getChartData() != null) {
|
||||
Date newestEvent = getChartData().getDateOfNewestData();
|
||||
if (competitorSelectionProvider.getSelectedCompetitors().iterator().hasNext() &&
|
||||
newestEvent.before(date) && (date.getTime() - newestEvent.getTime()) >= getStepSize()) {
|
||||
loadData();
|
||||
if (getChartData() != null) {
|
||||
Date newestEvent = getChartData().getOldestDateOfNewestData();
|
||||
if (hasVisibleCompetitors()
|
||||
&& ((newestEvent.before(date) && (date.getTime() - newestEvent.getTime()) >= getStepSize()) || newestEvent == null)) {
|
||||
loadData(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public class ChartPanel extends AbstractChartPanel<ChartSettings> implements Com
|
||||
public void updateSettings(ChartSettings newSettings) {
|
||||
updateSettingsOnly(newSettings);
|
||||
clearChart();
|
||||
loadData();
|
||||
loadData(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
@@ -58,6 +58,7 @@ public class CompareCompetitorsChartDialog extends DialogBox {
|
||||
multiChartPanel = new MultiChartPanel(sailingService, competitorSelectionProvider, raceSelectionProvider,
|
||||
timer, stringConstants, errorReporter);
|
||||
multiChartPanel.setSize("100%", "100%");
|
||||
//TODO Delete DataLoadedHandler
|
||||
multiChartPanel.addDataLoadedHandler(new DataLoadedHandler() {
|
||||
@Override
|
||||
public void onDataLoaded(DataLoadedEvent event) {
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ public class MultiChartPanel extends AbstractChartPanel<MultiChartSettings> impl
|
||||
boolean dataToShowChanged = setDataToShow(newSettings.getDataToShow());
|
||||
if (dataToShowChanged || settingsChanged) {
|
||||
clearChart();
|
||||
loadData();
|
||||
loadData(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-16
@@ -1347,43 +1347,36 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
MultiCompetitorRaceDataDTO data = null;
|
||||
TrackedRace trackedRace = getExistingTrackedRace(race);
|
||||
if (trackedRace != null) {
|
||||
data = getMultiCompetitorRaceDataDTO(trackedRace, competitorsQuery, trackedRace.getStart().asDate(),
|
||||
trackedRace.getTimePointOfNewestEvent().asDate(), stepSize, detailType);
|
||||
data = getMultiCompetitorRaceDataDTO(trackedRace, competitorsQuery, trackedRace.getStart(),
|
||||
trackedRace.getTimePointOfNewestEvent(), stepSize, detailType);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private MultiCompetitorRaceDataDTO getMultiCompetitorRaceDataDTO(TrackedRace race,
|
||||
List<Pair<Date, CompetitorDTO>> competitorsQuery, Date startDate, Date endDate, long stepSize,
|
||||
List<Pair<Date, CompetitorDTO>> competitorsQuery, TimePoint startTime, TimePoint endTime, long stepSize,
|
||||
DetailType detailType) throws NoWindException {
|
||||
MultiCompetitorRaceDataDTO data = new MultiCompetitorRaceDataDTO(detailType);
|
||||
// Fetching the data from the TrackedRace
|
||||
for (Pair<Date, CompetitorDTO> competitorQuery : competitorsQuery) {
|
||||
List<Long> timePoints = new ArrayList<Long>();
|
||||
for (long i = competitorQuery.getA().before(startDate) ? startDate.getTime() : competitorQuery.getA()
|
||||
.getTime(); i <= endDate.getTime(); i += stepSize) {
|
||||
timePoints.add(i);
|
||||
}
|
||||
|
||||
Competitor competitor = getCompetitorById(race.getRace().getCompetitors(), competitorQuery.getB().id);
|
||||
ArrayList<Triple<String, Date, Double>> markPassingsData = new ArrayList<Triple<String, Date, Double>>();
|
||||
ArrayList<Pair<Date, Double>> raceData = new ArrayList<Pair<Date, Double>>();
|
||||
// Filling the mark passings
|
||||
for (MarkPassing markPassing : race.getMarkPassings(competitor)) {
|
||||
MillisecondsTimePoint time = new MillisecondsTimePoint(markPassing.getTimePoint().asMillis());
|
||||
if (time.asDate().after(competitorQuery.getA())) {
|
||||
markPassingsData.add(new Triple<String, Date, Double>(markPassing.getWaypoint().getName(), time
|
||||
.asDate(), getCompetitorRaceDataEntry(detailType, race, competitor, time)));
|
||||
}
|
||||
markPassingsData.add(new Triple<String, Date, Double>(markPassing.getWaypoint().getName(), time
|
||||
.asDate(), getCompetitorRaceDataEntry(detailType, race, competitor, time)));
|
||||
}
|
||||
// Filling the race data
|
||||
for (Long timePoint : timePoints) {
|
||||
MillisecondsTimePoint time = new MillisecondsTimePoint(timePoint);
|
||||
for (long i = competitorQuery.getA().before(startTime.asDate()) ? startTime.asMillis() : competitorQuery.getA()
|
||||
.getTime(); i <= endTime.asMillis(); i += stepSize) {
|
||||
MillisecondsTimePoint time = new MillisecondsTimePoint(i);
|
||||
raceData.add(new Pair<Date, Double>(time.asDate(), getCompetitorRaceDataEntry(detailType, race, competitor,
|
||||
time)));
|
||||
}
|
||||
// Adding fetched data to the container
|
||||
data.setCompetitorRaceData(competitorQuery.getB(), new CompetitorRaceDataDTO(competitorQuery.getB(),
|
||||
data.setCompetitorData(competitorQuery.getB(), new CompetitorRaceDataDTO(competitorQuery.getB(),
|
||||
detailType, markPassingsData, raceData));
|
||||
}
|
||||
return data;
|
||||
|
||||
+78
-16
@@ -3,6 +3,7 @@ package com.sap.sailing.gwt.ui.shared;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@@ -15,13 +16,13 @@ public class CompetitorRaceDataDTO implements IsSerializable {
|
||||
|
||||
private CompetitorDTO competitor;
|
||||
private DetailType detailType;
|
||||
private Date dateOfNewestData; //TODO Javadoc
|
||||
|
||||
/**
|
||||
* A: Bouy-Name; B: Data-Date; C: Data
|
||||
* A: Bouy-Name; B: mark passing time; C: data as defined by {@link #detailType} for {@link #competitor} for time point B
|
||||
*/
|
||||
private List<Triple<String, Date, Double>> markPassingsData;
|
||||
/**
|
||||
* A: Data-Date; B: Data
|
||||
* A: time for B; B: data as defined by {@link #detailType} for {@link #competitor} for time point A
|
||||
*/
|
||||
private List<Pair<Date, Double>> raceData;
|
||||
|
||||
@@ -45,48 +46,86 @@ public class CompetitorRaceDataDTO implements IsSerializable {
|
||||
return detailType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the {@link Date} of the last elements in {@link #raceData} and {@link #markPassingsData} and returns the newer date.
|
||||
*/
|
||||
public Date getDateOfNewestData() {
|
||||
return dateOfNewestData;
|
||||
Date dateOfNewestRaceData = raceData.get(raceData.size() - 1).getA();
|
||||
Date dateOfNewestMarkPassing = markPassingsData.get(markPassingsData.size() - 1).getB();
|
||||
return dateOfNewestRaceData.after(dateOfNewestMarkPassing) ? dateOfNewestRaceData : dateOfNewestMarkPassing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the old {@link #markPassingsData} and {@link #addAllMarkPassingsData(Collection) adds} the data in <code>markPassingsData</code> afterwards.
|
||||
* @param markPassingsData
|
||||
*/
|
||||
public void setMarkPassingsData(List<Triple<String, Date, Double>> markPassingsData) {
|
||||
this.markPassingsData = new ArrayList<Triple<String,Date,Double>>();
|
||||
addAllMarkPassingsData(markPassingsData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An unmodifiable list of the {@link #markPassingsData}.
|
||||
*/
|
||||
public List<Triple<String, Date, Double>> getMarkPassingsData() {
|
||||
return Collections.unmodifiableList(markPassingsData);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link #addMarkPassingsData(Triple) Adds} all elements in <code>markPassingsDataToAdd</code>. Just adds the data and doesn't do any
|
||||
* checks, like if the data is already contained or if the detail types fit.
|
||||
*
|
||||
* @param markPassingsDataToAdd
|
||||
*/
|
||||
public void addAllMarkPassingsData(Collection<Triple<String, Date, Double>> markPassingsDataToAdd) {
|
||||
for (Triple<String, Date, Double> data : markPassingsDataToAdd) {
|
||||
addMarkPassingsData(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the data <code>markPassingsDataToAdd</code> at the correct index (via binary search) to {@link #markPassingsData}.
|
||||
* Just adds the data and doesn't do any checks, like if the data is already contained or if the detail types fit.
|
||||
*
|
||||
* @param markPassingsDataToAdd
|
||||
*/
|
||||
public void addMarkPassingsData(Triple<String, Date, Double> markPassingsDataToAdd) {
|
||||
getMarkPassingsData().add(markPassingsDataToAdd);
|
||||
//Updating the timePointOfNewestEvent
|
||||
if (markPassingsDataToAdd.getB().after(dateOfNewestData)) {
|
||||
dateOfNewestData = markPassingsDataToAdd.getB();
|
||||
}
|
||||
markPassingsData.add(Collections.binarySearch(markPassingsData, markPassingsDataToAdd, new MarkPassingsByTime()), markPassingsDataToAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An unmodifiable list of the {@link #raceData}
|
||||
*/
|
||||
public List<Pair<Date, Double>> getRaceData() {
|
||||
return Collections.unmodifiableList(raceData);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link #addRaceData(Pair) Adds} all elements in <code>raceDataToAdd</code>. Just adds the data and doesn't do any
|
||||
* checks, like if the data is already contained or if the detail types fit.
|
||||
*
|
||||
* @param raceDataToAdd
|
||||
*/
|
||||
public void addAllRaceData(Collection<Pair<Date, Double>> raceDataToAdd) {
|
||||
for (Pair<Date, Double> data : raceDataToAdd) {
|
||||
addRaceData(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds the data <code>raceDataToAdd</code> at the correct index (via binary search) to {@link #raceData}.
|
||||
* Just adds the data and doesn't do any checks, like if the data is already contained or if the detail types fit.
|
||||
*
|
||||
* @param raceDataToAdd
|
||||
*/
|
||||
public void addRaceData(Pair<Date, Double> raceDataToAdd) {
|
||||
getRaceData().add(raceDataToAdd);
|
||||
//Updating the timePointOfNewestEvent
|
||||
if (raceDataToAdd.getA().after(dateOfNewestData)) {
|
||||
dateOfNewestData = raceDataToAdd.getA();
|
||||
}
|
||||
raceData.add(Collections.binarySearch(raceData, raceDataToAdd, new RaceDataByTime()), raceDataToAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all data, if the detailTypes fit.
|
||||
* Adds all data with {@link #addAllMarkPassingsData(Collection)} and {@link #addAllRaceData(Collection)}, if the
|
||||
* detailTypes fit. Just adds the data and doesn't do any checks, like if the data is already contained.
|
||||
*
|
||||
* @param dataToAdd
|
||||
*/
|
||||
public void addAllData(CompetitorRaceDataDTO dataToAdd) {
|
||||
@@ -96,4 +135,27 @@ public class CompetitorRaceDataDTO implements IsSerializable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param after The date, exclusive, from where the data should be returned
|
||||
* @return An unmodifiable sublist of {@link #raceData}
|
||||
*/
|
||||
public List<Pair<Date, Double>> getRaceDataAfterDate(Date after) {
|
||||
int from = Collections.binarySearch(raceData, new Pair<Date, Double>(after, 0.0), new RaceDataByTime());
|
||||
return Collections.unmodifiableList(raceData.subList(from + 1, raceData.size()));
|
||||
}
|
||||
|
||||
public class RaceDataByTime implements Comparator<Pair<Date, Double>> {
|
||||
@Override
|
||||
public int compare(Pair<Date, Double> d1, Pair<Date, Double> d2) {
|
||||
return d1.getA().compareTo(d2.getA());
|
||||
}
|
||||
}
|
||||
|
||||
public class MarkPassingsByTime implements Comparator<Triple<String, Date, Double>> {
|
||||
@Override
|
||||
public int compare(Triple<String, Date, Double> m1, Triple<String, Date, Double> m2) {
|
||||
return m1.getB().compareTo(m2.getB());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+48
-36
@@ -11,69 +11,68 @@ import com.sap.sailing.domain.common.DetailType;
|
||||
public class MultiCompetitorRaceDataDTO implements IsSerializable {
|
||||
|
||||
private DetailType detailType;
|
||||
private HashMap<CompetitorDTO, CompetitorRaceDataDTO> raceData;
|
||||
private HashMap<CompetitorDTO, CompetitorRaceDataDTO> competitorsData;
|
||||
|
||||
MultiCompetitorRaceDataDTO() {}
|
||||
|
||||
public MultiCompetitorRaceDataDTO(DetailType detailType) {
|
||||
this.detailType = detailType;
|
||||
this.raceData = new HashMap<CompetitorDTO, CompetitorRaceDataDTO>();
|
||||
this.competitorsData = new HashMap<CompetitorDTO, CompetitorRaceDataDTO>();
|
||||
}
|
||||
|
||||
public MultiCompetitorRaceDataDTO(DetailType detailType, HashMap<CompetitorDTO, CompetitorRaceDataDTO> raceData) {
|
||||
this.detailType = detailType;
|
||||
this.raceData = new HashMap<CompetitorDTO, CompetitorRaceDataDTO>(raceData);
|
||||
this.competitorsData = new HashMap<CompetitorDTO, CompetitorRaceDataDTO>(raceData);
|
||||
}
|
||||
|
||||
public Set<CompetitorDTO> getCompetitors() {
|
||||
return raceData.keySet();
|
||||
return competitorsData.keySet();
|
||||
}
|
||||
|
||||
public CompetitorRaceDataDTO getCompetitorRaceData(CompetitorDTO competitor) {
|
||||
return raceData.get(competitor);
|
||||
public CompetitorRaceDataDTO getCompetitorData(CompetitorDTO competitor) {
|
||||
return competitorsData.get(competitor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data for a competitor, if the <code>detailTypes</code> fit.<br />
|
||||
* If the competitor is already contained, the data will be overwritten.
|
||||
*/
|
||||
public void setCompetitorRaceData(CompetitorDTO competitor, CompetitorRaceDataDTO raceData) {
|
||||
if (detailType == raceData.getDetailType()) {
|
||||
this.raceData.put(competitor, raceData);
|
||||
public void setCompetitorData(CompetitorDTO competitor, CompetitorRaceDataDTO competitorData) {
|
||||
if (detailType == competitorData.getDetailType()) {
|
||||
this.competitorsData.put(competitor, competitorData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all data in <code>raceDataToAdd</code> to the existing data of the <code>competitor</code>, if the <code>detailTypes</code> fit.<br />
|
||||
* If the <code>competitor</code> is not contained, the data will be
|
||||
* {@link MultiCompetitorRaceDataDTO#setCompetitorRaceData(CompetitorDTO, CompetitorRaceDataDTO) set}.
|
||||
* Replaces the {@link CompetitorRaceDataDTO#markPassingsData} from the {@link CompetitorRaceDataDTO data} of the
|
||||
* {@link CompetitorDTO} in <code>competitorData</code> with the markPassingsData in <code>competitorData</code>.<br />
|
||||
* If the competitor is not contained, nothing happens.
|
||||
*
|
||||
* @param competitorData
|
||||
*/
|
||||
public void addCompetitorRaceData(CompetitorDTO competitor, CompetitorRaceDataDTO raceDataToAdd) {
|
||||
if (detailType == raceDataToAdd.getDetailType()) {
|
||||
if (raceData.containsKey(competitor)) {
|
||||
raceData.get(competitor).addAllData(raceDataToAdd);
|
||||
} else {
|
||||
raceData.put(competitor, raceDataToAdd);
|
||||
public void setCompetitorMarkPassingsData(CompetitorRaceDataDTO competitorData) {
|
||||
if (detailType == competitorData.getDetailType()) {
|
||||
if (competitorsData.containsKey(competitorData.getCompetitor())) {
|
||||
competitorsData.get(competitorData.getCompetitor()).setMarkPassingsData(competitorData.getMarkPassingsData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all {@link CompetitorRaceDataDTO#raceData} in <code>competitorDataToAdd</code> to the existing data of the
|
||||
* {@link CompetitorDTO} in <code>competitorDataToAdd</code>, if the {@link DetailType DetailTypes} fit.<br />
|
||||
* If the competitor is not contained, nothing happens.
|
||||
*/
|
||||
public void addCompetitorRaceData(CompetitorRaceDataDTO competitorDataToAdd) {
|
||||
if (detailType == competitorDataToAdd.getDetailType()) {
|
||||
if (competitorsData.containsKey(competitorDataToAdd.getCompetitor())) {
|
||||
competitorsData.get(competitorDataToAdd.getCompetitor()).addAllRaceData(competitorDataToAdd.getRaceData());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<CompetitorRaceDataDTO> getAllRaceData() {
|
||||
return raceData.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all data in <code>dataToAdd</code>, if the <code>detailTypes</code> fit.<br />
|
||||
* The data which are not contained, will be
|
||||
* {@link MultiCompetitorRaceDataDTO#setCompetitorRaceData(CompetitorDTO, CompetitorRaceDataDTO) set}.
|
||||
*
|
||||
* @param dataToAdd
|
||||
*/
|
||||
public void addAllRaceData(MultiCompetitorRaceDataDTO dataToAdd) {
|
||||
//The check if the detailType fits will be done by addCompetitorRaceDataDTO
|
||||
for (CompetitorRaceDataDTO competitorDataToAdd : dataToAdd.getAllRaceData()) {
|
||||
addCompetitorRaceData(competitorDataToAdd.getCompetitor(), competitorDataToAdd);
|
||||
}
|
||||
return competitorsData.values();
|
||||
}
|
||||
|
||||
public DetailType getDetailType() {
|
||||
@@ -82,7 +81,7 @@ public class MultiCompetitorRaceDataDTO implements IsSerializable {
|
||||
|
||||
public Date getDateOfNewestData() {
|
||||
Date dateOfNewestData = null;
|
||||
for (CompetitorRaceDataDTO competitorRaceData : raceData.values()) {
|
||||
for (CompetitorRaceDataDTO competitorRaceData : competitorsData.values()) {
|
||||
Date raceDateOfNewestData = competitorRaceData.getDateOfNewestData();
|
||||
if (dateOfNewestData == null) {
|
||||
dateOfNewestData = raceDateOfNewestData;
|
||||
@@ -93,12 +92,25 @@ public class MultiCompetitorRaceDataDTO implements IsSerializable {
|
||||
return dateOfNewestData;
|
||||
}
|
||||
|
||||
public Date getOldestDateOfNewestData() {
|
||||
Date dateOfNewestData = null;
|
||||
for (CompetitorRaceDataDTO competitorRaceData : competitorsData.values()) {
|
||||
Date raceDateOfNewestData = competitorRaceData.getDateOfNewestData();
|
||||
if (dateOfNewestData == null) {
|
||||
dateOfNewestData = raceDateOfNewestData;
|
||||
} else {
|
||||
dateOfNewestData = dateOfNewestData.before(raceDateOfNewestData) ? dateOfNewestData : raceDateOfNewestData;
|
||||
}
|
||||
}
|
||||
return dateOfNewestData;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return raceData.isEmpty();
|
||||
return competitorsData.isEmpty();
|
||||
}
|
||||
|
||||
public boolean contains(CompetitorDTO competitor) {
|
||||
return raceData.containsKey(competitor);
|
||||
return competitorsData.containsKey(competitor);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user