Moved loading code to Task (not working)
This commit is contained in:
parent
74cc5a6579
commit
2715b66d5b
8 changed files with 224 additions and 135 deletions
|
@ -24,7 +24,6 @@
|
|||
|
||||
package es.kauron.estraba;
|
||||
|
||||
import es.kauron.estraba.controller.DashboardController;
|
||||
import javafx.application.Application;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.Parent;
|
||||
|
@ -51,7 +50,7 @@ public class App extends Application {
|
|||
@Override
|
||||
public void start(Stage stage) throws Exception {
|
||||
FXMLLoader loader = new FXMLLoader(
|
||||
App.class.getResource("fxml/Dashboard.fxml"), GENERAL_BUNDLE);
|
||||
App.class.getResource("fxml/Splash.fxml"), GENERAL_BUNDLE);
|
||||
Parent root = loader.load();
|
||||
|
||||
stage.getIcons().add(new Image(App.class.getResource("img/icon.png").toString()));
|
||||
|
@ -59,7 +58,11 @@ public class App extends Application {
|
|||
stage.setResizable(false);
|
||||
stage.setScene(new Scene(root));
|
||||
|
||||
// Begin awesomewm code
|
||||
stage.setMinHeight(500);
|
||||
stage.setMinWidth(300);
|
||||
stage.setResizable(false);
|
||||
// End awesomewm code
|
||||
stage.show();
|
||||
loader.<DashboardController>getController().postinit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,14 @@ package es.kauron.estraba.controller;
|
|||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXSnackbar;
|
||||
import com.jfoenix.controls.JFXSpinner;
|
||||
import com.lynden.gmapsfx.GoogleMapView;
|
||||
import com.lynden.gmapsfx.MapComponentInitializedListener;
|
||||
import com.lynden.gmapsfx.javascript.object.*;
|
||||
import com.lynden.gmapsfx.shapes.Polyline;
|
||||
import com.lynden.gmapsfx.shapes.PolylineOptions;
|
||||
import es.kauron.estraba.App;
|
||||
import es.kauron.estraba.model.DataBundle;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
|
@ -15,28 +17,14 @@ import javafx.fxml.Initializable;
|
|||
import javafx.scene.chart.AreaChart;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.PieChart;
|
||||
import javafx.scene.chart.XYChart;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.Tab;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.stage.FileChooser;
|
||||
import jgpx.model.analysis.Chunk;
|
||||
import jgpx.model.analysis.TrackData;
|
||||
import jgpx.model.gpx.Track;
|
||||
import jgpx.model.jaxb.GpxType;
|
||||
import jgpx.model.jaxb.TrackPointExtensionT;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.FormatStyle;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/**
|
||||
|
@ -59,13 +47,15 @@ public class DashboardController implements Initializable, MapComponentInitializ
|
|||
private Label valueHRAvg, valueHRMin, valueHRMax, valueSpeedAvg, valueSpeedMax, valueCadenceAvg, valueCadenceMax,
|
||||
valueDate, valueTime, valueActiveTime, valueTotalTime, valueDistance, valueElevation, labelMotivationUpper,
|
||||
valueAscent, valueDescent, labelMotivatorLower;
|
||||
@FXML
|
||||
private JFXSpinner mapSpinner;
|
||||
|
||||
@FXML
|
||||
private PieChart zoneChart;
|
||||
|
||||
@FXML
|
||||
private GoogleMapView mapView;
|
||||
private TrackData track;
|
||||
private ObservableList<Chunk> chunks;
|
||||
|
||||
@FXML
|
||||
private JFXButton elevationButton, speedButton, hrButton, cadenceButton;
|
||||
|
@ -77,8 +67,6 @@ public class DashboardController implements Initializable, MapComponentInitializ
|
|||
private LineChart<Double, Double> speedChart, hrChart, cadenceChart, mapChart;
|
||||
|
||||
private JFXSnackbar snackbar;
|
||||
private static final double DISTANCE_EPSILON = 1E-6;
|
||||
private static final double KILOMETER_CUTOFF = 10000;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
|
@ -117,123 +105,41 @@ public class DashboardController implements Initializable, MapComponentInitializ
|
|||
}
|
||||
}
|
||||
|
||||
public void postinit() {
|
||||
void postInit(DataBundle bundle) {
|
||||
snackbar.registerSnackbarContainer(root);
|
||||
try {load();} catch (JAXBException e) {e.printStackTrace();}
|
||||
loadTrack(bundle);
|
||||
}
|
||||
|
||||
private void loadTrack(TrackData track) {
|
||||
valueHRAvg.setText(track.getAverageHeartrate()
|
||||
+ App.GENERAL_BUNDLE.getString("unit.bpm"));
|
||||
valueHRMax.setText(track.getMaxHeartrate()
|
||||
+ App.GENERAL_BUNDLE.getString("unit.bpm"));
|
||||
valueHRMin.setText(track.getMinHeartRate()
|
||||
+ App.GENERAL_BUNDLE.getString("unit.bpm"));
|
||||
private void loadTrack(DataBundle bundle) {
|
||||
valueHRAvg.setText(bundle.HRAvg);
|
||||
valueHRMax.setText(bundle.HRMax);
|
||||
valueHRMin.setText(bundle.HRMin);
|
||||
valueSpeedAvg.setText(bundle.speedAvg);
|
||||
valueSpeedMax.setText(bundle.speedMax);
|
||||
valueCadenceAvg.setText(bundle.cadenceAvg);
|
||||
valueCadenceMax.setText(bundle.cadenceMax);
|
||||
valueDate.setText(bundle.date);
|
||||
valueTime.setText(bundle.time);
|
||||
valueActiveTime.setText(bundle.activeTime);
|
||||
valueTotalTime.setText(bundle.totalTime);
|
||||
valueDistance.setText(bundle.distance);
|
||||
valueElevation.setText(bundle.elevation);
|
||||
valueAscent.setText(bundle.ascent);
|
||||
valueDescent.setText(bundle.descent);
|
||||
|
||||
// speed is given as m/s
|
||||
valueSpeedAvg.setText(String.format("%.2f", track.getAverageSpeed() * 3.6)
|
||||
+ App.GENERAL_BUNDLE.getString("unit.kmph"));
|
||||
valueSpeedMax.setText(String.format("%.2f", track.getMaxSpeed() * 3.6)
|
||||
+ App.GENERAL_BUNDLE.getString("unit.kmph"));
|
||||
|
||||
valueCadenceAvg.setText(track.getAverageCadence()
|
||||
+ App.GENERAL_BUNDLE.getString("unit.hz"));
|
||||
valueCadenceMax.setText(track.getMaxCadence()
|
||||
+ App.GENERAL_BUNDLE.getString("unit.hz"));
|
||||
|
||||
valueDate.setText(track.getStartTime().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)));
|
||||
valueTime.setText(track.getStartTime().format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM)));
|
||||
valueActiveTime.setText(LocalTime.MIDNIGHT.plus(track.getMovingTime())
|
||||
.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
||||
valueTotalTime.setText(App.GENERAL_BUNDLE.getString("time.of")
|
||||
+ LocalTime.MIDNIGHT.plus(track.getTotalDuration())
|
||||
.format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
||||
|
||||
if (track.getTotalDistance() > KILOMETER_CUTOFF) {
|
||||
valueDistance.setText(String.format("%.2f", track.getTotalDistance() / 1000)
|
||||
+ App.GENERAL_BUNDLE.getString("unit.km"));
|
||||
} else {
|
||||
valueDistance.setText(String.format("%.2f", track.getTotalDistance())
|
||||
+ App.GENERAL_BUNDLE.getString("unit.m"));
|
||||
}
|
||||
|
||||
valueElevation.setText((int)(track.getTotalAscent() - track.getTotalDescend())
|
||||
+ App.GENERAL_BUNDLE.getString("unit.m"));
|
||||
valueAscent.setText((int)track.getTotalAscent()
|
||||
+ App.GENERAL_BUNDLE.getString("unit.m"));
|
||||
valueDescent.setText((int)track.getTotalDescend()
|
||||
+ App.GENERAL_BUNDLE.getString("unit.m"));
|
||||
|
||||
// create charts data
|
||||
XYChart.Series<Double, Double> elevationChartData = new XYChart.Series<>();
|
||||
XYChart.Series<Double, Double> speedChartData = new XYChart.Series<>();
|
||||
XYChart.Series<Double, Double> hrChartData = new XYChart.Series<>();
|
||||
XYChart.Series<Double, Double> cadenceChartData = new XYChart.Series<>();
|
||||
|
||||
// traverse the chunks
|
||||
ObservableList<Chunk> chunks = track.getChunks();
|
||||
double currentDistance = 0.0;
|
||||
double currentHeight = chunks.get(0).getFirstPoint().getElevation();
|
||||
for (Chunk chunk : chunks) {
|
||||
currentDistance += chunk.getDistance();
|
||||
if (chunk.getDistance() < DISTANCE_EPSILON) continue;
|
||||
currentHeight += chunk.getAscent() - chunk.getDescend();
|
||||
|
||||
elevationChartData.getData().add(new XYChart.Data<>(currentDistance, currentHeight));
|
||||
speedChartData.getData().add(new XYChart.Data<>(currentDistance, chunk.getSpeed()*3.6)); // m/s
|
||||
hrChartData.getData().add(new XYChart.Data<>(currentDistance, chunk.getAvgHeartRate()));
|
||||
cadenceChartData.getData().add(new XYChart.Data<>(currentDistance, chunk.getAvgCadence()));
|
||||
|
||||
String zone;
|
||||
if (chunk.getAvgHeartRate() > 170) zone = App.GENERAL_BUNDLE.getString("zone.anaerobic");
|
||||
else if (chunk.getAvgHeartRate() > 150) zone = App.GENERAL_BUNDLE.getString("zone.threshold");
|
||||
else if (chunk.getAvgHeartRate() > 130) zone = App.GENERAL_BUNDLE.getString("zone.tempo");
|
||||
else if (chunk.getAvgHeartRate() > 110) zone = App.GENERAL_BUNDLE.getString("zone.endurance");
|
||||
else zone = App.GENERAL_BUNDLE.getString("zone.recovery");
|
||||
|
||||
boolean pieFound = false;
|
||||
for (PieChart.Data d : zoneChart.getData()){
|
||||
if (d.getName().equals(zone)) {
|
||||
pieFound = true;
|
||||
d.setPieValue(d.getPieValue() + 1);
|
||||
}
|
||||
}
|
||||
if (!pieFound) zoneChart.getData().add( new PieChart.Data(zone, 1) );
|
||||
}
|
||||
zoneChart.setData(bundle.pieData);
|
||||
|
||||
// populate the charts
|
||||
elevationChart.getData().add(elevationChartData);
|
||||
speedChart.getData().add(speedChartData);
|
||||
hrChart.getData().add(hrChartData);
|
||||
cadenceChart.getData().add(cadenceChartData);
|
||||
elevationChart.getData().add(bundle.elevationSeries);
|
||||
speedChart.getData().add(bundle.speedSeries);
|
||||
hrChart.getData().add(bundle.hrSeries);
|
||||
cadenceChart.getData().add(bundle.cadenceSeries);
|
||||
|
||||
//initialize map
|
||||
chunks = bundle.chunks;
|
||||
mapView.addMapInializedListener(this);
|
||||
}
|
||||
|
||||
private void load() throws JAXBException {
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.getExtensionFilters().add(
|
||||
new FileChooser.ExtensionFilter(App.GENERAL_BUNDLE.getString("app.extension.filter.name"), "*.gpx"));
|
||||
File file = fileChooser.showOpenDialog(root.getScene().getWindow());
|
||||
if (file == null) return;
|
||||
|
||||
String name = file.getName();
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(GpxType.class, TrackPointExtensionT.class);
|
||||
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
|
||||
@SuppressWarnings("unchecked")
|
||||
JAXBElement<Object> jaxbElement = (JAXBElement<Object>) unmarshaller.unmarshal(file);
|
||||
GpxType gpx = (GpxType) jaxbElement.getValue();
|
||||
|
||||
if (gpx != null) {
|
||||
track = new TrackData(new Track(gpx.getTrk().get(0)));
|
||||
loadTrack(track);
|
||||
snackbar.show("GPX file: " + name + "successfully loaded", 3000);
|
||||
} else {
|
||||
snackbar.show("Error loading GPX file: " + name, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mapInitialized() {
|
||||
// When the JS init is done
|
||||
|
@ -260,10 +166,10 @@ public class DashboardController implements Initializable, MapComponentInitializ
|
|||
// Prepare an array with LatLong objects
|
||||
MVCArray pathArray = new MVCArray();
|
||||
pathArray.push(new LatLong( // first step of the route
|
||||
track.getChunks().get(0).getFirstPoint().getLatitude(),
|
||||
track.getChunks().get(0).getFirstPoint().getLongitude()
|
||||
chunks.get(0).getFirstPoint().getLatitude(),
|
||||
chunks.get(0).getFirstPoint().getLongitude()
|
||||
));
|
||||
track.getChunks().forEach(chunk -> {
|
||||
chunks.forEach(chunk -> {
|
||||
double lat = chunk.getLastPoint().getLatitude();
|
||||
double lon = chunk.getLastPoint().getLongitude();
|
||||
coord[N] = Math.max(lat, coord[N]);
|
||||
|
@ -283,9 +189,8 @@ public class DashboardController implements Initializable, MapComponentInitializ
|
|||
new LatLong(coord[N], coord[E])
|
||||
));
|
||||
map.setZoom(getBoundsZoomLevel(coord, mapView.getHeight(), mapView.getWidth()));
|
||||
// Print some debug info
|
||||
System.err.printf("Bound to coords: %.2fN, %.2S, %.2fE, %.2fW\n", coord[N], coord[S], coord[E], coord[W]);
|
||||
System.err.printf("Selected zoom: %d\n", map.getZoom());
|
||||
mapView.setVisible(true);
|
||||
mapSpinner.setVisible(false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,15 +1,27 @@
|
|||
package es.kauron.estraba.controller;
|
||||
|
||||
import com.jfoenix.controls.JFXButton;
|
||||
import com.jfoenix.controls.JFXSnackbar;
|
||||
import com.jfoenix.controls.JFXSpinner;
|
||||
import es.kauron.estraba.App;
|
||||
import es.kauron.estraba.model.DataBundle;
|
||||
import javafx.application.Platform;
|
||||
import javafx.concurrent.Task;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.stage.FileChooser;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
|
@ -20,6 +32,9 @@ import java.util.ResourceBundle;
|
|||
|
||||
public class SplashController implements Initializable{
|
||||
|
||||
@FXML
|
||||
private AnchorPane root;
|
||||
|
||||
@FXML
|
||||
private ImageView imgLogo;
|
||||
|
||||
|
@ -32,17 +47,70 @@ public class SplashController implements Initializable{
|
|||
@FXML
|
||||
private JFXButton buttonLoad;
|
||||
|
||||
private JFXSnackbar snackbar;
|
||||
private File file;
|
||||
|
||||
@FXML
|
||||
void loadGPXFile(ActionEvent event) {
|
||||
private void loadGPXFile(ActionEvent event) {
|
||||
|
||||
buttonLoad.setVisible(false);
|
||||
labelWelcome.setVisible(false);
|
||||
spinner.setVisible(true);
|
||||
snackbar.registerSnackbarContainer(root);
|
||||
snackbar.show("Loading file", 5000);
|
||||
FileChooser fileChooser = new FileChooser();
|
||||
fileChooser.getExtensionFilters().add(
|
||||
new FileChooser.ExtensionFilter(App.GENERAL_BUNDLE.getString("app.extension.filter.name"), "*.gpx"));
|
||||
file = fileChooser.showOpenDialog(root.getScene().getWindow());
|
||||
if (file == null) {
|
||||
errorLoading();
|
||||
return;
|
||||
}
|
||||
Task<Void> task = new Task<Void>() {
|
||||
@Override
|
||||
protected Void call() throws Exception {
|
||||
try {
|
||||
DataBundle bundle = DataBundle.loadFrom(file);
|
||||
FXMLLoader loader = new FXMLLoader(
|
||||
App.class.getResource("fxml/Dashboard.fxml"), App.GENERAL_BUNDLE);
|
||||
Parent root = loader.load();
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.getIcons().add(new Image(App.class.getResource("img/icon.png").toString()));
|
||||
stage.setTitle(App.GENERAL_BUNDLE.getString("app.title"));
|
||||
stage.setResizable(false);
|
||||
stage.setScene(new Scene(root));
|
||||
|
||||
// Begin awesomewm code
|
||||
stage.setMinHeight(500);
|
||||
stage.setMinWidth(800);
|
||||
stage.setResizable(false);
|
||||
// End awesomewm code
|
||||
stage.show();
|
||||
loader.<DashboardController>getController().postInit(bundle);
|
||||
Platform.runLater(() -> ((Stage) root.getScene().getWindow()).close());
|
||||
} catch (IOException e) {
|
||||
errorLoading();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
Thread t = new Thread(task);
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
imgLogo.setImage(new Image(App.class.getResourceAsStream("img/splash.png")));
|
||||
imgLogo.setImage(new Image(App.class.getResourceAsStream("img/strava-transparent.png")));
|
||||
snackbar = new JFXSnackbar();
|
||||
}
|
||||
|
||||
private void errorLoading() {
|
||||
buttonLoad.setVisible(true);
|
||||
labelWelcome.setVisible(true);
|
||||
spinner.setVisible(false);
|
||||
snackbar.show("Error loading file", 3000);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
107
src/main/java/es/kauron/estraba/model/DataBundle.java
Normal file
107
src/main/java/es/kauron/estraba/model/DataBundle.java
Normal file
|
@ -0,0 +1,107 @@
|
|||
package es.kauron.estraba.model;
|
||||
|
||||
import es.kauron.estraba.App;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.scene.chart.PieChart;
|
||||
import javafx.scene.chart.XYChart;
|
||||
import jgpx.model.analysis.Chunk;
|
||||
import jgpx.model.analysis.TrackData;
|
||||
import jgpx.model.gpx.Track;
|
||||
import jgpx.model.jaxb.GpxType;
|
||||
import jgpx.model.jaxb.TrackPointExtensionT;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBElement;
|
||||
import javax.xml.bind.Unmarshaller;
|
||||
import java.io.File;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.FormatStyle;
|
||||
|
||||
public class DataBundle {
|
||||
public static final int N = 0, S = 1, E = 2, W = 3;
|
||||
private static final double DISTANCE_EPSILON = 1E-6;
|
||||
private static final double KILOMETER_CUTOFF = 10000;
|
||||
|
||||
public String HRAvg, HRMax, HRMin, speedAvg, speedMax, cadenceAvg, cadenceMax;
|
||||
public String date, time, activeTime, totalTime, distance, elevation, ascent, descent;
|
||||
public XYChart.Series<Double, Double> elevationSeries = new XYChart.Series<>(),
|
||||
speedSeries = new XYChart.Series<>(),
|
||||
hrSeries = new XYChart.Series<>(),
|
||||
cadenceSeries = new XYChart.Series<>();
|
||||
public ObservableList<PieChart.Data> pieData = FXCollections.emptyObservableList();
|
||||
public ObservableList<Chunk> chunks;
|
||||
|
||||
public static DataBundle loadFrom(File file) throws Exception {
|
||||
String name = file.getName();
|
||||
JAXBElement<Object> jaxbElement;
|
||||
JAXBContext jaxbContext = JAXBContext.newInstance(GpxType.class, TrackPointExtensionT.class);
|
||||
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
|
||||
jaxbElement = (JAXBElement<Object>) unmarshaller.unmarshal(file);
|
||||
GpxType gpx = (GpxType) jaxbElement.getValue();
|
||||
|
||||
if (gpx == null) throw new Exception();
|
||||
return new DataBundle(new TrackData(new Track(gpx.getTrk().get(0))));
|
||||
}
|
||||
|
||||
private DataBundle(TrackData track) {
|
||||
HRAvg = track.getAverageHeartrate() + App.GENERAL_BUNDLE.getString("unit.bpm");
|
||||
HRMax = (track.getMaxHeartrate() + App.GENERAL_BUNDLE.getString("unit.bpm"));
|
||||
HRMin = track.getMinHeartRate() + App.GENERAL_BUNDLE.getString("unit.bpm");
|
||||
|
||||
// speed is given as m/s
|
||||
speedAvg = String.format("%.2f", track.getAverageSpeed() * 3.6) + App.GENERAL_BUNDLE.getString("unit.kmph");
|
||||
speedMax = String.format("%.2f", track.getMaxSpeed() * 3.6) + App.GENERAL_BUNDLE.getString("unit.kmph");
|
||||
|
||||
cadenceAvg = track.getAverageCadence() + App.GENERAL_BUNDLE.getString("unit.hz");
|
||||
cadenceMax = track.getMaxCadence() + App.GENERAL_BUNDLE.getString("unit.hz");
|
||||
|
||||
date = track.getStartTime().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL));
|
||||
time = track.getStartTime().format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM));
|
||||
activeTime = LocalTime.MIDNIGHT.plus(track.getMovingTime()).format(DateTimeFormatter.ofPattern("HH:mm:ss"));
|
||||
totalTime = App.GENERAL_BUNDLE.getString("time.of")
|
||||
+ LocalTime.MIDNIGHT.plus(track.getTotalDuration()).format(DateTimeFormatter.ofPattern("HH:mm:ss"));
|
||||
|
||||
if (track.getTotalDistance() > KILOMETER_CUTOFF) {
|
||||
distance = String.format("%.2f", track.getTotalDistance() / 1000) + App.GENERAL_BUNDLE.getString("unit.km");
|
||||
} else {
|
||||
distance = String.format("%.2f", track.getTotalDistance()) + App.GENERAL_BUNDLE.getString("unit.m");
|
||||
}
|
||||
|
||||
elevation = (int)(track.getTotalAscent() - track.getTotalDescend()) + App.GENERAL_BUNDLE.getString("unit.m");
|
||||
ascent = (int)track.getTotalAscent() + App.GENERAL_BUNDLE.getString("unit.m");
|
||||
descent = (int)track.getTotalDescend() + App.GENERAL_BUNDLE.getString("unit.m");
|
||||
|
||||
// traverse the chunks
|
||||
chunks = track.getChunks();
|
||||
double currentDistance = 0.0;
|
||||
double currentHeight = chunks.get(0).getFirstPoint().getElevation();
|
||||
for (Chunk chunk : chunks) {
|
||||
currentDistance += chunk.getDistance();
|
||||
if (chunk.getDistance() < DISTANCE_EPSILON) continue;
|
||||
currentHeight += chunk.getAscent() - chunk.getDescend();
|
||||
|
||||
elevationSeries.getData().add(new XYChart.Data<>(currentDistance, currentHeight));
|
||||
speedSeries.getData().add(new XYChart.Data<>(currentDistance, chunk.getSpeed()*3.6)); // m/s
|
||||
hrSeries.getData().add(new XYChart.Data<>(currentDistance, chunk.getAvgHeartRate()));
|
||||
cadenceSeries.getData().add(new XYChart.Data<>(currentDistance, chunk.getAvgCadence()));
|
||||
|
||||
String zone;
|
||||
if (chunk.getAvgHeartRate() > 170) zone = App.GENERAL_BUNDLE.getString("zone.anaerobic");
|
||||
else if (chunk.getAvgHeartRate() > 150) zone = App.GENERAL_BUNDLE.getString("zone.threshold");
|
||||
else if (chunk.getAvgHeartRate() > 130) zone = App.GENERAL_BUNDLE.getString("zone.tempo");
|
||||
else if (chunk.getAvgHeartRate() > 110) zone = App.GENERAL_BUNDLE.getString("zone.endurance");
|
||||
else zone = App.GENERAL_BUNDLE.getString("zone.recovery");
|
||||
|
||||
boolean pieFound = false;
|
||||
for (PieChart.Data d : pieData){
|
||||
if (d.getName().equals(zone)) {
|
||||
pieFound = true;
|
||||
d.setPieValue(d.getPieValue() + 1);
|
||||
}
|
||||
}
|
||||
if (!pieFound) pieData.add( new PieChart.Data(zone, 1) );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
|
||||
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="300.0" styleClass="background" stylesheets="@../css/palette.css" xmlns="http://javafx.com/javafx/8.0.76-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="es.kauron.estraba.controller.SplashController">
|
||||
<AnchorPane fx:id="root" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="300.0" styleClass="background" stylesheets="@../css/palette.css" xmlns="http://javafx.com/javafx/8.0.76-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="es.kauron.estraba.controller.SplashController">
|
||||
<ImageView fx:id="imgLogo" fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" AnchorPane.leftAnchor="50.0" AnchorPane.rightAnchor="50.0" AnchorPane.topAnchor="25.0">
|
||||
</ImageView>
|
||||
<JFXSpinner fx:id="spinner" visible="false" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
|
||||
|
|
|
@ -4,8 +4,10 @@ label.cadence=Cadence
|
|||
label.distance=Distance
|
||||
label.elevation=Elevation
|
||||
label.hr=Heart rate
|
||||
label.loadGPX=Load GPX file
|
||||
label.motivation=Welcome!
|
||||
label.speed=Speed
|
||||
label.welcome=Welcome!
|
||||
tab.dashboard=Dashboard
|
||||
tab.graph=Stats
|
||||
tab.map=Your Route
|
||||
|
|
|
@ -4,8 +4,10 @@ label.cadence=Cadencia
|
|||
label.distance=Distancia
|
||||
label.elevation=Elevacion
|
||||
label.hr=YOLO
|
||||
label.loadGPX=Obrir arxiu GPX
|
||||
label.motivation=\u00a1Benvinguts!
|
||||
label.speed=Speed
|
||||
label.welcome=Benvingut!
|
||||
tab.dashboard=Sumari
|
||||
tab.graph=Estad\u00edstiques
|
||||
tab.map=La teva ruta
|
||||
|
|
|
@ -4,8 +4,10 @@ label.cadence=Cadencia
|
|||
label.distance=Distancia
|
||||
label.elevation=Elevacion
|
||||
label.hr=Pulsaci\u00f3nes
|
||||
label.loadGPX=Abrir archivo GPX
|
||||
label.motivation=\u00a1Bienvenido!
|
||||
label.speed=Velocidad
|
||||
label.welcome=¡Bienvenido!
|
||||
tab.dashboard=Res\u00famen
|
||||
tab.graph=Estad\u00edsticas
|
||||
tab.map=Tu ruta
|
||||
|
|
Reference in a new issue