mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-30 17:36:40 +00:00
Reorganizing the AbstractChartPanel
This commit is contained in:
1 parent
1e8d5dfabc
commit
38446a3ad2
6 files changed
+101
-100
No files matched your search
+84
-56
@@ -1,12 +1,11 @@
|
||||
package com.sap.sailing.gwt.ui.leaderboard;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.moxieapps.gwt.highcharts.client.Axis;
|
||||
import org.moxieapps.gwt.highcharts.client.Chart;
|
||||
@@ -75,12 +74,11 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
protected Chart chart;
|
||||
protected final AbsolutePanel busyIndicatorPanel;
|
||||
protected final Label noCompetitorsSelectedLabel;
|
||||
protected final Map<CompetitorDTO, Series> seriesByCompetitor;
|
||||
protected final Map<CompetitorDTO, Series> dataSeriesByCompetitor;
|
||||
protected final Map<CompetitorDTO, Series> markPassingSeriesByCompetitor;
|
||||
protected final RaceSelectionProvider raceSelectionProvider;
|
||||
protected long stepSize = 5000;
|
||||
protected final StringMessages stringMessages;
|
||||
protected final Set<Series> seriesIsUsed;
|
||||
protected final Timer timer;
|
||||
protected final DateTimeFormat dateFormat = DateTimeFormat.getFormat("HH:mm:ss");
|
||||
protected DetailType dataToShow;
|
||||
@@ -90,7 +88,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
CompetitorSelectionProvider competitorSelectionProvider, RaceSelectionProvider raceSelectionProvider,
|
||||
Timer timer, final StringMessages stringMessages, ErrorReporter errorReporter, DetailType dataToShow) {
|
||||
this.stringMessages = stringMessages;
|
||||
seriesByCompetitor = new HashMap<CompetitorDTO, Series>();
|
||||
dataSeriesByCompetitor = new HashMap<CompetitorDTO, Series>();
|
||||
markPassingSeriesByCompetitor = new HashMap<CompetitorDTO, Series>();
|
||||
this.timer = timer;
|
||||
this.timer.addTimeListener(this);
|
||||
@@ -99,7 +97,6 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
this.errorReporter = errorReporter;
|
||||
this.dataToShow = dataToShow;
|
||||
chartData = null;
|
||||
seriesIsUsed = new HashSet<Series>();
|
||||
this.sailingService = sailingService;
|
||||
this.raceSelectionProvider = raceSelectionProvider;
|
||||
raceSelectionProvider.addRaceSelectionChangeListener(this);
|
||||
@@ -130,6 +127,12 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
protected void selectRace(final RaceIdentifier selectedRace) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new chart for the given {@link DetailType} <code>dataToShow</code> and also
|
||||
* clears the {@link #chartData}, the {@link #dataSeriesByCompetitor} and the {@link #markPassingSeriesByCompetitor}.
|
||||
* @param dataToShow The detail type for the new chart.
|
||||
* @return A chart for the given detail Type
|
||||
*/
|
||||
private Chart createChart(DetailType dataToShow) {
|
||||
Chart chart = new Chart().setZoomType(Chart.ZoomType.X)
|
||||
.setSpacingRight(20)
|
||||
@@ -164,6 +167,10 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
numberFormat.format(toolTipData.getYAsDouble()) + unit;
|
||||
}
|
||||
}));
|
||||
|
||||
setChartData(null);
|
||||
dataSeriesByCompetitor.clear();
|
||||
markPassingSeriesByCompetitor.clear();
|
||||
return chart;
|
||||
}
|
||||
|
||||
@@ -201,7 +208,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
if (result != null) {
|
||||
chartData.addAllRaceData(result);
|
||||
}
|
||||
updateTableData(competitorSelectionProvider.getSelectedCompetitors());
|
||||
drawChartData();
|
||||
setWidget(chart);
|
||||
}
|
||||
});
|
||||
@@ -239,43 +246,56 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void updateTableData(Iterable<CompetitorDTO> competitors) {
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private synchronized void drawChartData() {
|
||||
//Make sure the busy indicator is removed at this point, or plotting the data results in an exception
|
||||
setWidget(chart);
|
||||
Iterable<CompetitorDTO> competitors = competitorSelectionProvider.getAllCompetitors();
|
||||
if (chartData != null && competitors != null && competitors.iterator().hasNext()) {
|
||||
//Clearing the series to keep the chart clean
|
||||
chart.removeAllSeries();
|
||||
List<Series> chartSeries = Arrays.asList(chart.getSeries());
|
||||
for (CompetitorDTO competitor : competitors) {
|
||||
Series compSeries = getCompetitorSeries(competitor);
|
||||
seriesIsUsed.add(compSeries);
|
||||
Series markSeries = getCompetitorMarkPassingSeries(competitor);
|
||||
seriesIsUsed.add(markSeries);
|
||||
CompetitorRaceDataDTO competitorData = chartData.getCompetitorRaceData(competitor);
|
||||
if (isCompetitorVisible(competitor) && competitorData != null) {
|
||||
List<Triple<String, Long, Double>> markPassingsData = competitorData.getMarkPassingsData();
|
||||
List<Point> markPassingPoints = new ArrayList<Point>();
|
||||
for (Triple<String, Long, Double> markPassingData : markPassingsData) {
|
||||
if (markPassingData.getB() != null && markPassingData.getC() != null) {
|
||||
Point markPassingPoint = new Point(markPassingData.getB(), markPassingData.getC());
|
||||
markPassingPoint.setName(markPassingData.getA());
|
||||
markPassingPoints.add(markPassingPoint);
|
||||
}
|
||||
}
|
||||
markSeries.setPoints(markPassingPoints.toArray(new Point[0]));
|
||||
|
||||
List<Pair<Long, Double>> raceData = competitorData.getRaceData();
|
||||
List<Point> competitorPoints = new ArrayList<Point>();
|
||||
for (Pair<Long, Double> data : raceData) {
|
||||
if (data.getA() != null && data.getB() != null) {
|
||||
Point competitorPoint = new Point(data.getA(), data.getB());
|
||||
competitorPoints.add(competitorPoint);
|
||||
}
|
||||
}
|
||||
compSeries.setPoints(competitorPoints.toArray(new Point[0]));
|
||||
}
|
||||
if (isCompetitorVisible(competitor)) {
|
||||
chart.addSeries(compSeries);
|
||||
chart.addSeries(markSeries);
|
||||
CompetitorRaceDataDTO competitorData = chartData.getCompetitorRaceData(competitor);
|
||||
if (competitorData != null) { //TODO Exception?
|
||||
List<Triple<String, Long, Double>> markPassingsData = competitorData.getMarkPassingsData();
|
||||
List<Point> markPassingPoints = new ArrayList<Point>();
|
||||
for (Triple<String, Long, Double> markPassingData : markPassingsData) {
|
||||
if (markPassingData.getB() != null && markPassingData.getC() != null) {
|
||||
Point markPassingPoint = new Point(markPassingData.getB(), markPassingData.getC());
|
||||
markPassingPoint.setName(markPassingData.getA());
|
||||
markPassingPoints.add(markPassingPoint);
|
||||
}
|
||||
}
|
||||
|
||||
markSeries.setPoints(markPassingPoints.toArray(new Point[0]));
|
||||
List<Pair<Long, Double>> raceData = competitorData.getRaceData();
|
||||
List<Point> competitorPoints = new ArrayList<Point>();
|
||||
for (Pair<Long, Double> data : raceData) {
|
||||
if (data.getA() != null && data.getB() != null) {
|
||||
Point competitorPoint = new Point(data.getA(), data.getB());
|
||||
competitorPoints.add(competitorPoint);
|
||||
}
|
||||
}
|
||||
compSeries.setPoints(competitorPoints.toArray(new Point[0]));
|
||||
|
||||
//Adding the series if chart doesn't contain it
|
||||
if (!chartSeries.contains(compSeries)) {
|
||||
chart.addSeries(compSeries);
|
||||
chart.addSeries(markSeries);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//Removing the series if chart contains it
|
||||
if (chartSeries.contains(compSeries)) {
|
||||
chart.removeSeries(compSeries);
|
||||
chart.removeSeries(markSeries);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -318,7 +338,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
* @return A series in the chart, that can be used to show the data of a specific competitor.
|
||||
*/
|
||||
private Series getCompetitorSeries(final CompetitorDTO competitor){
|
||||
Series result = seriesByCompetitor.get(competitor);
|
||||
Series result = dataSeriesByCompetitor.get(competitor);
|
||||
if (result == null) {
|
||||
result = chart.createSeries().setType(Series.Type.LINE).setName(competitor.name);
|
||||
result.setPlotOptions(new LinePlotOptions()
|
||||
@@ -326,7 +346,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
.setMarker(new Marker().setEnabled(false).setHoverState(new Marker().setEnabled(true).setRadius(4)))
|
||||
.setShadow(false).setHoverStateLineWidth(LINE_WIDTH)
|
||||
.setColor(competitorSelectionProvider.getColor(competitor)));
|
||||
seriesByCompetitor.put(competitor, result);
|
||||
dataSeriesByCompetitor.put(competitor, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -369,14 +389,10 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
|
||||
/**
|
||||
* Clears the whole chart and empties cached data.
|
||||
*
|
||||
* @param clearCheckBoxes Declares whether the checkboxes for the visibility of the competitors should be cleared too. Should be true, when you change the race to show.
|
||||
*/
|
||||
protected void clearChart(boolean clearCheckBoxes) {
|
||||
if (clearCheckBoxes) {
|
||||
seriesIsUsed.clear();
|
||||
}
|
||||
seriesByCompetitor.clear();
|
||||
protected void clearChart() {
|
||||
setChartData(null);
|
||||
dataSeriesByCompetitor.clear();
|
||||
markPassingSeriesByCompetitor.clear();
|
||||
chart.removeAllSeries();
|
||||
}
|
||||
@@ -399,12 +415,17 @@ 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(boolean)} and {@link #loadData()} after
|
||||
* updating all settings.
|
||||
* by subclasses thereof. Subclasses also need to call {@link #clearChart()} and {@link #loadData()}, if this method returns <code>true</code>;
|
||||
*
|
||||
* @return <code>true</code> if the settings had been changed and a clearing and loading is needed.
|
||||
*/
|
||||
protected void updateSettingsOnly(ChartSettings newSettings) {
|
||||
setStepSize(newSettings.getStepSize());
|
||||
setChartData(null);
|
||||
protected boolean updateSettingsOnly(ChartSettings newSettings) {
|
||||
boolean settingsChanged = false;
|
||||
if (getStepSize() != newSettings.getStepSize()) {
|
||||
setStepSize(newSettings.getStepSize());
|
||||
settingsChanged = true;
|
||||
}
|
||||
return settingsChanged;
|
||||
}
|
||||
|
||||
protected StringMessages getStringMessages() {
|
||||
@@ -424,14 +445,21 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the {@link #dataToShow} field but does not yet {@link #clearChart(boolean) clear the chart} nor
|
||||
* {@link #loadData load the data}.
|
||||
* 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}.
|
||||
*
|
||||
* @return <code>true</code> if the data to show changed
|
||||
*/
|
||||
protected void setDataToShow(DetailType dataToShow) {
|
||||
protected boolean setDataToShow(DetailType dataToShow) {
|
||||
if (dataToShow != this.dataToShow) {
|
||||
this.dataToShow = dataToShow;
|
||||
setChartData(null);
|
||||
chart = createChart(dataToShow);
|
||||
this.setWidget(chart);
|
||||
setWidget(chart);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,7 +474,7 @@ implements CompetitorSelectionChangeListener, RaceSelectionChangeListener, TimeL
|
||||
@Override
|
||||
public void onRaceSelectionChange(List<RaceIdentifier> selectedRaces) {
|
||||
setChartData(null);
|
||||
clearChart(true);
|
||||
clearChart();
|
||||
loadData();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public class ChartPanel extends AbstractChartPanel<ChartSettings> implements Com
|
||||
@Override
|
||||
public void updateSettings(ChartSettings newSettings) {
|
||||
updateSettingsOnly(newSettings);
|
||||
clearChart(true);
|
||||
clearChart();
|
||||
loadData();
|
||||
}
|
||||
|
||||
|
||||
+6
-4
@@ -36,10 +36,12 @@ public class MultiChartPanel extends AbstractChartPanel<MultiChartSettings> impl
|
||||
|
||||
@Override
|
||||
public void updateSettings(MultiChartSettings newSettings) {
|
||||
updateSettingsOnly(newSettings);
|
||||
setDataToShow(newSettings.getDataToShow());
|
||||
clearChart(true);
|
||||
loadData();
|
||||
boolean settingsChanged = updateSettingsOnly(newSettings);
|
||||
boolean dataToShowChanged = setDataToShow(newSettings.getDataToShow());
|
||||
if (dataToShowChanged || settingsChanged) {
|
||||
clearChart();
|
||||
loadData();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -1383,7 +1383,7 @@ public class SailingServiceImpl extends RemoteServiceServlet implements SailingS
|
||||
}
|
||||
// Adding fetched data to the container
|
||||
data.setCompetitorRaceData(competitorQuery.getB(), new CompetitorRaceDataDTO(competitorQuery.getB(),
|
||||
detailType, startTime, markPassingsData, raceData));
|
||||
detailType, markPassingsData, raceData));
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
+9
-29
@@ -2,6 +2,7 @@ package com.sap.sailing.gwt.ui.shared;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gwt.user.client.rpc.IsSerializable;
|
||||
@@ -13,8 +14,7 @@ public class CompetitorRaceDataDTO implements IsSerializable {
|
||||
|
||||
private CompetitorDTO competitor;
|
||||
private DetailType detailType;
|
||||
private long timePointOfNewestEvent;
|
||||
private long startTime;
|
||||
private long timePointOfNewestEvent; //TODO Javadoc
|
||||
/**
|
||||
* A: Bouy-Name; B: Timepoint; C: Data
|
||||
*/
|
||||
@@ -26,24 +26,20 @@ public class CompetitorRaceDataDTO implements IsSerializable {
|
||||
|
||||
CompetitorRaceDataDTO() {}
|
||||
|
||||
public CompetitorRaceDataDTO(CompetitorDTO competitor, DetailType detailType, long startTime,
|
||||
public CompetitorRaceDataDTO(CompetitorDTO competitor, DetailType detailType,
|
||||
Collection<Triple<String, Long, Double>> markPassingsData, Collection<Pair<Long, Double>> raceData) {
|
||||
this.competitor = competitor;
|
||||
this.detailType = detailType;
|
||||
this.startTime = startTime;
|
||||
this.timePointOfNewestEvent = 0;
|
||||
this.markPassingsData = new ArrayList<Triple<String, Long, Double>>(markPassingsData);
|
||||
this.raceData = new ArrayList<Pair<Long, Double>>(raceData);
|
||||
this.markPassingsData = new ArrayList<Triple<String, Long, Double>>();
|
||||
addAllMarkPassingsData(markPassingsData);
|
||||
this.raceData = new ArrayList<Pair<Long, Double>>();
|
||||
addAllRaceData(raceData);
|
||||
}
|
||||
|
||||
public CompetitorDTO getCompetitor() {
|
||||
return competitor;
|
||||
}
|
||||
|
||||
public void setCompetitor(CompetitorDTO competitor) {
|
||||
this.competitor = competitor;
|
||||
}
|
||||
|
||||
public DetailType getDetailType() {
|
||||
return detailType;
|
||||
}
|
||||
@@ -51,21 +47,9 @@ public class CompetitorRaceDataDTO implements IsSerializable {
|
||||
public long getTimePointOfNewestEvent() {
|
||||
return timePointOfNewestEvent;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public void setStartTime(long startTime) {
|
||||
this.startTime = startTime;
|
||||
}
|
||||
|
||||
public List<Triple<String, Long, Double>> getMarkPassingsData() {
|
||||
return markPassingsData;
|
||||
}
|
||||
|
||||
public void setMarkPassingsData(Collection<Triple<String, Long, Double>> markPassingsData) {
|
||||
this.markPassingsData = new ArrayList<Triple<String, Long, Double>>(markPassingsData);
|
||||
return Collections.unmodifiableList(markPassingsData);
|
||||
}
|
||||
|
||||
public void addAllMarkPassingsData(Collection<Triple<String, Long, Double>> markPassingsDataToAdd) {
|
||||
@@ -83,11 +67,7 @@ public class CompetitorRaceDataDTO implements IsSerializable {
|
||||
}
|
||||
|
||||
public List<Pair<Long, Double>> getRaceData() {
|
||||
return raceData;
|
||||
}
|
||||
|
||||
public void setRaceData(Collection<Pair<Long, Double>> raceData) {
|
||||
this.raceData = new ArrayList<Pair<Long, Double>>(raceData);
|
||||
return Collections.unmodifiableList(raceData);
|
||||
}
|
||||
|
||||
public void addAllRaceData(Collection<Pair<Long, Double>> raceDataToAdd) {
|
||||
|
||||
-9
@@ -87,15 +87,6 @@ public class MultiCompetitorRaceDataDTO implements IsSerializable {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
long result = -1;
|
||||
for (CompetitorRaceDataDTO competitorRaceData : raceData.values()) {
|
||||
long raceDataNewestEvent = competitorRaceData.getStartTime();
|
||||
result = result <= raceDataNewestEvent ? result : raceDataNewestEvent;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return raceData.isEmpty();
|
||||
|
||||
Reference in new issue
Block a user