Fixed sparkline not updating.
#story[1095]
This commit is contained in:
@@ -2,6 +2,8 @@ package shared.model;
|
||||
|
||||
import javafx.beans.property.Property;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import network.Messages.Enums.RaceStatusEnum;
|
||||
import network.Messages.Enums.RaceTypeEnum;
|
||||
import shared.dataInput.BoatDataSource;
|
||||
@@ -37,6 +39,12 @@ public abstract class RaceState {
|
||||
*/
|
||||
private RegattaDataSource regattaDataSource;
|
||||
|
||||
/**
|
||||
* Legs in the race.
|
||||
* We have this in a separate list so that it can be observed.
|
||||
*/
|
||||
private ObservableList<Leg> legs;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -65,6 +73,9 @@ public abstract class RaceState {
|
||||
*/
|
||||
public RaceState() {
|
||||
|
||||
//Legs.
|
||||
this.legs = FXCollections.observableArrayList();
|
||||
|
||||
//Race clock.
|
||||
this.raceClock = new RaceClock(ZonedDateTime.now());
|
||||
|
||||
@@ -90,8 +101,9 @@ public abstract class RaceState {
|
||||
* @param legs The new list of legs to use.
|
||||
*/
|
||||
protected void useLegsList(List<Leg> legs) {
|
||||
this.legs.setAll(legs);
|
||||
//We add a "dummy" leg at the end of the race.
|
||||
if (legs.size() > 0) {
|
||||
if (getLegs().size() > 0) {
|
||||
getLegs().add(new Leg("Finish", getLegs().size()));
|
||||
}
|
||||
}
|
||||
@@ -126,6 +138,7 @@ public abstract class RaceState {
|
||||
public void setRaceDataSource(RaceDataSource raceDataSource) {
|
||||
this.raceDataSource = raceDataSource;
|
||||
this.getRaceClock().setStartingTime(raceDataSource.getStartDateTime());
|
||||
useLegsList(raceDataSource.getLegs());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -309,8 +322,8 @@ public abstract class RaceState {
|
||||
* Returns the legs of the race.
|
||||
* @return Legs of the race.
|
||||
*/
|
||||
public List<Leg> getLegs() {
|
||||
return raceDataSource.getLegs();
|
||||
public ObservableList<Leg> getLegs() {
|
||||
return legs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -531,6 +531,7 @@ public class ResizableRaceCanvas extends ResizableCanvas {
|
||||
* draws the line leg by leg
|
||||
* @param legs the legs of a race
|
||||
* @param index the index of the current leg to use
|
||||
* @param legStartPoint The position the current leg.
|
||||
* @return the end point of the current leg that has been drawn
|
||||
*/
|
||||
private GPSCoordinate drawLineRounding(List<Leg> legs, int index, GPSCoordinate legStartPoint){
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package visualiser.model;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
import javafx.scene.chart.XYChart;
|
||||
import javafx.scene.paint.Color;
|
||||
import shared.model.Leg;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
@@ -32,10 +36,10 @@ public class Sparkline {
|
||||
private ObservableList<VisualiserBoat> boats;
|
||||
|
||||
/**
|
||||
* The number of legs in the race.
|
||||
* Used to correctly scale the linechart.
|
||||
* Race legs to observe.
|
||||
* We need to observe legs as they may be added after the sparkline is created if race.xml is received after this is created.
|
||||
*/
|
||||
private Integer legNum;
|
||||
private ObservableList<Leg> legs;
|
||||
|
||||
|
||||
/**
|
||||
@@ -53,6 +57,14 @@ public class Sparkline {
|
||||
*/
|
||||
private NumberAxis yAxis;
|
||||
|
||||
/**
|
||||
* A map between a boat and its data series in the sparkline.
|
||||
* This is used so that we can remove a series when (or if) a boat is removed from the race.
|
||||
*/
|
||||
private Map<VisualiserBoat, XYChart.Series<Number, Number>> boatSeriesMap;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor to set up initial sparkline (LineChart) object
|
||||
@@ -62,12 +74,14 @@ public class Sparkline {
|
||||
public Sparkline(VisualiserRaceState race, LineChart<Number,Number> sparklineChart) {
|
||||
this.race = race;
|
||||
this.boats = new SortedList<>(race.getBoats());
|
||||
this.legNum = race.getLegCount();
|
||||
this.legs = race.getLegs();
|
||||
|
||||
this.sparklineChart = sparklineChart;
|
||||
this.yAxis = (NumberAxis) sparklineChart.getYAxis();
|
||||
this.xAxis = (NumberAxis) sparklineChart.getXAxis();
|
||||
|
||||
this.boatSeriesMap = new HashMap<>();
|
||||
|
||||
createSparkline();
|
||||
|
||||
}
|
||||
@@ -79,12 +93,88 @@ public class Sparkline {
|
||||
* Position numbers are displayed.
|
||||
*/
|
||||
private void createSparkline() {
|
||||
// NOTE: Y axis is in negatives to display correct positions
|
||||
|
||||
//For each boat...
|
||||
for (VisualiserBoat boat : this.boats) {
|
||||
//We need to dynamically update the sparkline when boats are added/removed.
|
||||
boats.addListener((ListChangeListener.Change<? extends VisualiserBoat> c) -> {
|
||||
|
||||
//Create data series for each boat.
|
||||
Platform.runLater(() -> {
|
||||
|
||||
while (c.next()) {
|
||||
|
||||
if (c.wasAdded()) {
|
||||
for (VisualiserBoat boat : c.getAddedSubList()) {
|
||||
addBoatSeries(boat);
|
||||
}
|
||||
|
||||
} else if (c.wasRemoved()) {
|
||||
for (VisualiserBoat boat : c.getRemoved()) {
|
||||
removeBoatSeries(boat);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Update height of y axis.
|
||||
yAxis.setLowerBound(boats.size());
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
legs.addListener((ListChangeListener.Change<? extends Leg> c) -> {
|
||||
Platform.runLater(() -> xAxis.setUpperBound(race.getLegCount()));
|
||||
});
|
||||
|
||||
|
||||
//Initialise chart for existing boats.
|
||||
for (VisualiserBoat boat : boats) {
|
||||
addBoatSeries(boat);
|
||||
}
|
||||
|
||||
|
||||
sparklineChart.setCreateSymbols(false);
|
||||
|
||||
//Set x axis details
|
||||
xAxis.setAutoRanging(false);
|
||||
xAxis.setTickMarkVisible(false);
|
||||
xAxis.setTickLabelsVisible(false);
|
||||
xAxis.setMinorTickVisible(false);
|
||||
xAxis.setLowerBound(0);
|
||||
xAxis.setUpperBound(race.getLegCount());
|
||||
xAxis.setTickUnit(1);
|
||||
|
||||
//Set y axis details
|
||||
yAxis.setLowerBound(boats.size());
|
||||
yAxis.setUpperBound(1);
|
||||
yAxis.setAutoRanging(false);
|
||||
yAxis.setLabel("Position in Race");
|
||||
yAxis.setTickUnit(-1);//Negative tick reverses the y axis.
|
||||
|
||||
yAxis.setTickMarkVisible(true);
|
||||
yAxis.setTickLabelsVisible(true);
|
||||
yAxis.setTickMarkVisible(true);
|
||||
yAxis.setMinorTickVisible(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Removes the data series for a given boat from the sparkline.
|
||||
* @param boat Boat to remove series for.
|
||||
*/
|
||||
private void removeBoatSeries(VisualiserBoat boat) {
|
||||
sparklineChart.getData().remove(boatSeriesMap.get(boat));
|
||||
boatSeriesMap.remove(boat);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a data series for a boat, and adds it to the sparkline.
|
||||
* @param boat Boat to add series for.
|
||||
*/
|
||||
private void addBoatSeries(VisualiserBoat boat) {
|
||||
|
||||
//Create data series for boat.
|
||||
XYChart.Series<Number, Number> series = new XYChart.Series<>();
|
||||
|
||||
|
||||
@@ -121,30 +211,8 @@ public class Sparkline {
|
||||
series.getNode().setStyle("-fx-stroke: " + colourToHex(boat.getColor()) + ";");
|
||||
|
||||
|
||||
}
|
||||
boatSeriesMap.put(boat, series);
|
||||
|
||||
sparklineChart.setCreateSymbols(false);
|
||||
|
||||
//Set x axis details
|
||||
xAxis.setAutoRanging(false);
|
||||
xAxis.setTickMarkVisible(false);
|
||||
xAxis.setTickLabelsVisible(false);
|
||||
xAxis.setMinorTickVisible(false);
|
||||
xAxis.setLowerBound(0);
|
||||
xAxis.setUpperBound(legNum + 2);
|
||||
xAxis.setTickUnit(1);
|
||||
|
||||
//Set y axis details
|
||||
yAxis.setLowerBound(boats.size());
|
||||
yAxis.setUpperBound(1);
|
||||
yAxis.setAutoRanging(false);
|
||||
yAxis.setLabel("Position in Race");
|
||||
yAxis.setTickUnit(-1);//Negative tick reverses the y axis.
|
||||
|
||||
yAxis.setTickMarkVisible(true);
|
||||
yAxis.setTickLabelsVisible(true);
|
||||
yAxis.setTickMarkVisible(true);
|
||||
yAxis.setMinorTickVisible(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ public class VisualiserRaceState extends RaceState {
|
||||
this.generateVisualiserBoats(this.boats, getBoatDataSource().getBoats(), raceDataSource.getParticipants(), unassignedColors);
|
||||
}
|
||||
|
||||
useLegsList(raceDataSource.getLegs());
|
||||
initialiseLegCompletionOrder();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,14 +125,9 @@ public class VisualiserRaceState extends RaceState {
|
||||
|
||||
|
||||
/**
|
||||
* See {@link RaceState#useLegsList(List)}.
|
||||
* Also initialises the {@link #legCompletionOrder} map.
|
||||
* @param legs The new list of legs to use.
|
||||
* Initialises the {@link #legCompletionOrder} map.
|
||||
*/
|
||||
@Override
|
||||
public void useLegsList(List<Leg> legs) {
|
||||
super.useLegsList(legs);
|
||||
|
||||
public void initialiseLegCompletionOrder() {
|
||||
//Initialise the leg completion order map.
|
||||
for (Leg leg : getLegs()) {
|
||||
this.legCompletionOrder.put(leg, new ArrayList<>(this.boats.size()));
|
||||
|
||||
Reference in New Issue
Block a user