kauron/estraba
Archived
1
0
Fork 0

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/main/java/es/kauron/estraba/controller/DashboardController.java
#	src/main/java/es/kauron/estraba/controller/SplashController.java
#	src/main/java/es/kauron/estraba/model/DataBundle.java
This commit is contained in:
Carlos Galindo 2016-05-24 14:40:47 +02:00
commit cd465af904
Signed by: kauron
GPG key ID: 83E68706DEE119A3
9 changed files with 153 additions and 60 deletions

View file

@ -58,11 +58,6 @@
<artifactId>controlsfx</artifactId> <artifactId>controlsfx</artifactId>
<version>8.40.10</version> <version>8.40.10</version>
</dependency> </dependency>
<dependency>
<groupId>jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.13</version>
</dependency>
<dependency> <dependency>
<groupId>com.github.rterp</groupId> <groupId>com.github.rterp</groupId>
<artifactId>GMapsFX</artifactId> <artifactId>GMapsFX</artifactId>

View file

@ -61,6 +61,7 @@ public class App extends Application {
stage.setResizable(false); stage.setResizable(false);
stage.setScene(new Scene(root)); stage.setScene(new Scene(root));
if (getParameters().getUnnamed().size() == 1) { if (getParameters().getUnnamed().size() == 1) {
loader.<SplashController>getController().loadGPXFile(new File(getParameters().getUnnamed().get(0))); loader.<SplashController>getController().loadGPXFile(new File(getParameters().getUnnamed().get(0)));
} }

View file

@ -39,6 +39,7 @@ import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable; import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent; import javafx.scene.Parent;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.chart.AreaChart; import javafx.scene.chart.AreaChart;
@ -48,6 +49,7 @@ import javafx.scene.control.Label;
import javafx.scene.control.Tab; import javafx.scene.control.Tab;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage; import javafx.stage.Stage;
import jgpx.model.analysis.Chunk; import jgpx.model.analysis.Chunk;
@ -63,38 +65,41 @@ import java.util.ResourceBundle;
public class DashboardController implements Initializable, MapComponentInitializedListener { public class DashboardController implements Initializable, MapComponentInitializedListener {
final int N = 0, S = 1, E = 2, W = 3;
final double[] coord = new double[4];
@FXML @FXML
private AnchorPane root; private AnchorPane root;
@FXML @FXML
private Tab tabDashboard, tabMap, tabGraph; private Tab tabDashboard, tabMap, tabGraph;
@FXML @FXML
private ImageView imgHR, imgSpeed, imgCadence, imgDate, imgDistance, imgElevation; private ImageView imgHR, imgSpeed, imgCadence, imgDate, imgDistance, imgElevation;
@FXML @FXML
private Label valueHRAvg, valueHRMin, valueHRMax, valueSpeedAvg, valueSpeedMax, valueCadenceAvg, valueCadenceMax, private Label valueHRAvg, valueHRMin, valueHRMax, valueSpeedAvg, valueSpeedMax, valueCadenceAvg, valueCadenceMax,
valueDate, valueTime, valueActiveTime, valueTotalTime, valueDistance, valueElevation, labelMotivationUpper, valueDate, valueTime, valueActiveTime, valueTotalTime, valueDistance, valueElevation, labelMotivationUpper,
valueAscent, valueDescent, labelMotivatorLower; valueAscent, valueDescent, labelMotivatorLower;
@FXML @FXML
private JFXSpinner mapSpinner; private JFXSpinner mapSpinner;
@FXML @FXML
private PieChart zoneChart; private PieChart zoneChart;
@FXML @FXML
private GoogleMapView mapView; private GoogleMapView mapView;
private ObservableList<Chunk> chunks; private ObservableList<Chunk> chunks;
@FXML @FXML
private JFXButton elevationButton, speedButton, hrButton, cadenceButton; private JFXButton elevationButton, speedButton, hrButton, cadenceButton;
@FXML @FXML
private AreaChart<Double, Double> elevationChart; private AreaChart<Double, Double> elevationChart;
@FXML
private AreaChart<Long, Double> elevationTChart;
@FXML @FXML
private LineChart<Double, Double> speedChart, hrChart, cadenceChart, mapChart; private LineChart<Double, Double> speedChart, hrChart, cadenceChart, mapChart;
@FXML
private LineChart<Long, Double> speedTChart, hrTChart, cadenceTChart;
@Override @Override
public void initialize(URL location, ResourceBundle resources) { public void initialize(URL location, ResourceBundle resources) {
mapView.setVisible(false); mapView.setVisible(false);
@ -111,6 +116,15 @@ public class DashboardController implements Initializable, MapComponentInitializ
imgDate.setImage(new Image(App.class.getResourceAsStream("img/date.png"))); imgDate.setImage(new Image(App.class.getResourceAsStream("img/date.png")));
imgDistance.setImage(new Image(App.class.getResourceAsStream("img/distance.png"))); imgDistance.setImage(new Image(App.class.getResourceAsStream("img/distance.png")));
imgElevation.setImage(new Image(App.class.getResourceAsStream("img/elevation.png"))); imgElevation.setImage(new Image(App.class.getResourceAsStream("img/elevation.png")));
}
@FXML
private void toggleChart(MouseEvent e) {
System.out.println("hi");
for (Node n : ((Node) e.getSource()).getParent().getChildrenUnmodifiable())
n.setVisible(!n.isVisible());
} }
@FXML @FXML
@ -168,9 +182,13 @@ public class DashboardController implements Initializable, MapComponentInitializ
// populate the charts // populate the charts
elevationChart.getData().add(bundle.elevationSeries); elevationChart.getData().add(bundle.elevationSeries);
elevationTChart.getData().add(bundle.elevationTSeries);
speedChart.getData().add(bundle.speedSeries); speedChart.getData().add(bundle.speedSeries);
speedTChart.getData().add(bundle.speedTSeries);
hrChart.getData().add(bundle.hrSeries); hrChart.getData().add(bundle.hrSeries);
hrTChart.getData().add(bundle.hrTSeries);
cadenceChart.getData().add(bundle.cadenceSeries); cadenceChart.getData().add(bundle.cadenceSeries);
cadenceTChart.getData().add(bundle.cadenceTSeries);
//initialize map //initialize map
chunks = bundle.chunks; chunks = bundle.chunks;
@ -180,8 +198,6 @@ public class DashboardController implements Initializable, MapComponentInitializ
@Override @Override
public void mapInitialized() { public void mapInitialized() {
// When the JS init is done // When the JS init is done
final int N = 0, S = 1, E = 2, W = 3;
final double[] coord = new double[4];
coord[0] = Double.MIN_VALUE; coord[0] = Double.MIN_VALUE;
coord[1] = Double.MAX_VALUE; coord[1] = Double.MAX_VALUE;
coord[2] = Double.MIN_VALUE; coord[2] = Double.MIN_VALUE;
@ -227,13 +243,20 @@ public class DashboardController implements Initializable, MapComponentInitializ
chunks.get(chunks.size() - 1).getLastPoint().getLongitude())) chunks.get(chunks.size() - 1).getLastPoint().getLongitude()))
.title("label.end"))); .title("label.end")));
// Adjust the map to the correct center and zoom // Adjust the map to the correct center and zoom
map.fitBounds(new LatLongBounds( mapView.setVisible(true);
mapSpinner.setVisible(false);
mapView.heightProperty().addListener(e -> centerMap());
mapView.widthProperty().addListener(e -> centerMap());
centerMap();
}
private void centerMap() {
mapView.getMap().setZoom(getBoundsZoomLevel(coord, mapView.getHeight(), mapView.getWidth()));
mapView.getMap().fitBounds(new LatLongBounds(
new LatLong(coord[S], coord[W]), new LatLong(coord[S], coord[W]),
new LatLong(coord[N], coord[E]) new LatLong(coord[N], coord[E])
)); ));
map.setZoom(getBoundsZoomLevel(coord, mapView.getHeight(), mapView.getWidth()));
mapView.setVisible(true);
mapSpinner.setVisible(false);
} }
/** /**

View file

@ -30,7 +30,6 @@ import com.jfoenix.controls.JFXSnackbar;
import com.jfoenix.controls.JFXSpinner; import com.jfoenix.controls.JFXSpinner;
import es.kauron.estraba.App; import es.kauron.estraba.App;
import es.kauron.estraba.model.DataBundle; import es.kauron.estraba.model.DataBundle;
import javafx.application.Platform;
import javafx.concurrent.Task; import javafx.concurrent.Task;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
@ -108,7 +107,13 @@ public class SplashController implements Initializable{
Thread th = new Thread(new Task<DataBundle>() { Thread th = new Thread(new Task<DataBundle>() {
@Override @Override
protected DataBundle call() throws Exception { protected DataBundle call() throws Exception {
return DataBundle.loadFrom(file, maxHR); DataBundle db = null;
try {
db = DataBundle.loadFrom(file, maxHR);
} catch (Exception e) {
e.printStackTrace();
}
return db;
} }
@Override @Override
@ -124,6 +129,7 @@ public class SplashController implements Initializable{
loader.<DashboardController>getController().load(bundle); loader.<DashboardController>getController().load(bundle);
((Stage) root.getScene().getWindow()).setScene(new Scene(parent)); ((Stage) root.getScene().getWindow()).setScene(new Scene(parent));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace();
errorLoading(); errorLoading();
} }
} }
@ -152,7 +158,7 @@ public class SplashController implements Initializable{
} }
}); });
Platform.runLater(() -> root.getScene().setOnDragOver(e -> { Platform.runLater(() -> root.setOnDragOver(e -> {
Dragboard db = e.getDragboard(); Dragboard db = e.getDragboard();
if (db.hasFiles()) { if (db.hasFiles()) {
e.acceptTransferModes(TransferMode.COPY); e.acceptTransferModes(TransferMode.COPY);
@ -162,16 +168,12 @@ public class SplashController implements Initializable{
})); }));
// Dropping over surface // Dropping over surface
Platform.runLater(() -> root.getScene().setOnDragDropped(e -> { Platform.runLater(() -> root.setOnDragDropped(e -> {
Dragboard db = e.getDragboard(); Dragboard db = e.getDragboard();
boolean success = false; boolean success = false;
if (db.hasFiles()) { if (db.hasFiles()) {
success = true; success = true;
String filePath = null; loadGPXFile(db.getFiles().get(0).getAbsoluteFile());
for (File file : db.getFiles()) {
filePath = file.getAbsolutePath();
System.out.println(filePath);
}
} }
e.setDropCompleted(success); e.setDropCompleted(success);
e.consume(); e.consume();
@ -183,7 +185,7 @@ public class SplashController implements Initializable{
buttonLoad.setVisible(true); buttonLoad.setVisible(true);
labelWelcome.setVisible(true); labelWelcome.setVisible(true);
spinner.setVisible(false); spinner.setVisible(false);
snackbar.show("Error loading file", 3000); snackbar.show(App.GENERAL_BUNDLE.getString("error.file"), 3000);
} }
private int showHRDialog() { private int showHRDialog() {

View file

@ -40,18 +40,20 @@ import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller; import javax.xml.bind.Unmarshaller;
import java.io.File; import java.io.File;
import java.time.Duration;
import java.time.LocalTime; import java.time.LocalTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle; import java.time.format.FormatStyle;
public class DataBundle { 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 DISTANCE_EPSILON = 1E-6;
private static final double KILOMETER_CUTOFF = 10000; private static final double KILOMETER_CUTOFF = 10000;
public String HRAvg, HRMax, HRMin, speedAvg, speedMax, cadenceAvg, cadenceMax; public String HRAvg, HRMax, HRMin, speedAvg, speedMax, cadenceAvg, cadenceMax;
public String date, time, activeTime, totalTime, distance, elevation, ascent, descent; public String date, time, activeTime, totalTime, distance, elevation, ascent, descent;
public XYChart.Series<Double, Double> elevationSeries, speedSeries, hrSeries, cadenceSeries; public XYChart.Series<Double, Double> elevationSeries, speedSeries, hrSeries, cadenceSeries;
public XYChart.Series<Long, Double> elevationTSeries, speedTSeries, hrTSeries, cadenceTSeries;
public ObservableList<PieChart.Data> pieData; public ObservableList<PieChart.Data> pieData;
public ObservableList<Chunk> chunks; public ObservableList<Chunk> chunks;
@ -87,23 +89,34 @@ public class DataBundle {
// traverse the chunks // traverse the chunks
chunks = track.getChunks(); chunks = track.getChunks();
double currentDistance = 0.0; double currentDistance = 0.0;
Duration currentTime = Duration.ZERO;
double currentHeight = chunks.get(0).getFirstPoint().getElevation(); double currentHeight = chunks.get(0).getFirstPoint().getElevation();
elevationSeries = new XYChart.Series<>(); elevationSeries = new XYChart.Series<>();
elevationTSeries = new XYChart.Series<>();
cadenceSeries = new XYChart.Series<>(); cadenceSeries = new XYChart.Series<>();
cadenceTSeries = new XYChart.Series<>();
hrSeries = new XYChart.Series<>(); hrSeries = new XYChart.Series<>();
hrTSeries = new XYChart.Series<>();
speedSeries = new XYChart.Series<>(); speedSeries = new XYChart.Series<>();
speedTSeries = new XYChart.Series<>();
pieData = FXCollections.observableArrayList(); pieData = FXCollections.observableArrayList();
for (Chunk chunk : chunks) { for (Chunk chunk : chunks) {
currentDistance += chunk.getDistance(); currentDistance += chunk.getDistance();
if (chunk.getDistance() < DISTANCE_EPSILON) continue; currentTime = currentTime.plus(chunk.getMovingTime());
if (chunk.getDistance() < DISTANCE_EPSILON ||
chunk.getMovingTime().getSeconds() < 1) continue;
currentHeight += chunk.getAscent() - chunk.getDescend(); currentHeight += chunk.getAscent() - chunk.getDescend();
elevationSeries.getData().add(new XYChart.Data<>(currentDistance, currentHeight)); elevationSeries.getData().add(new XYChart.Data<>(currentDistance, currentHeight));
elevationTSeries.getData().add(new XYChart.Data<>(currentTime.toMinutes(), currentHeight));
speedSeries.getData().add(new XYChart.Data<>(currentDistance, chunk.getSpeed()*3.6)); // m/s speedSeries.getData().add(new XYChart.Data<>(currentDistance, chunk.getSpeed()*3.6)); // m/s
speedTSeries.getData().add(new XYChart.Data<>(currentTime.toMinutes(), chunk.getSpeed() * 3.6)); // m/s
hrSeries.getData().add(new XYChart.Data<>(currentDistance, chunk.getAvgHeartRate())); hrSeries.getData().add(new XYChart.Data<>(currentDistance, chunk.getAvgHeartRate()));
hrTSeries.getData().add(new XYChart.Data<>(currentTime.toMinutes(), chunk.getAvgHeartRate()));
cadenceSeries.getData().add(new XYChart.Data<>(currentDistance, chunk.getAvgCadence())); cadenceSeries.getData().add(new XYChart.Data<>(currentDistance, chunk.getAvgCadence()));
cadenceTSeries.getData().add(new XYChart.Data<>(currentTime.toMinutes(), chunk.getAvgCadence()));
String zone; String zone;
if (chunk.getAvgHeartRate() > maxHR * .9) zone = App.GENERAL_BUNDLE.getString("zone.anaerobic"); if (chunk.getAvgHeartRate() > maxHR * .9) zone = App.GENERAL_BUNDLE.getString("zone.anaerobic");

View file

@ -424,38 +424,94 @@
<padding> <padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding> </padding>
<AreaChart fx:id="elevationChart" createSymbols="false" legendVisible="false" minHeight="100.0"> <StackPane>
<children>
<AreaChart fx:id="elevationChart" createSymbols="false" legendVisible="false" minHeight="100.0"
onMouseClicked="#toggleChart">
<xAxis> <xAxis>
<NumberAxis side="BOTTOM" /> <NumberAxis side="BOTTOM"/>
</xAxis> </xAxis>
<yAxis> <yAxis>
<NumberAxis side="LEFT" /> <NumberAxis side="LEFT"/>
</yAxis> </yAxis>
</AreaChart> </AreaChart>
<LineChart fx:id="speedChart" createSymbols="false" legendVisible="false" minHeight="100.0"> <AreaChart fx:id="elevationTChart" createSymbols="false" layoutX="10.0" layoutY="10.0"
legendVisible="false" minHeight="100.0" onMouseClicked="#toggleChart" visible="false">
<xAxis> <xAxis>
<NumberAxis /> <NumberAxis/>
</xAxis> </xAxis>
<yAxis> <yAxis>
<NumberAxis side="LEFT" /> <NumberAxis side="LEFT"/>
</yAxis> </yAxis>
</LineChart> </AreaChart>
<LineChart fx:id="hrChart" createSymbols="false" legendVisible="false" minHeight="100.0"> </children>
</StackPane>
<StackPane>
<children>
<LineChart fx:id="speedChart" createSymbols="false" legendVisible="false" minHeight="100.0"
onMouseClicked="#toggleChart">
<xAxis> <xAxis>
<NumberAxis side="BOTTOM" /> <NumberAxis/>
</xAxis> </xAxis>
<yAxis> <yAxis>
<NumberAxis side="LEFT" /> <NumberAxis side="LEFT"/>
</yAxis> </yAxis>
</LineChart> </LineChart>
<LineChart fx:id="cadenceChart" createSymbols="false" legendVisible="false" minHeight="100.0"> <LineChart fx:id="speedTChart" createSymbols="false" layoutX="10.0" layoutY="10.0"
legendVisible="false" minHeight="100.0" onMouseClicked="#toggleChart" visible="false">
<xAxis> <xAxis>
<NumberAxis side="BOTTOM" /> <NumberAxis/>
</xAxis> </xAxis>
<yAxis> <yAxis>
<NumberAxis side="LEFT" /> <NumberAxis side="LEFT"/>
</yAxis> </yAxis>
</LineChart> </LineChart>
</children>
</StackPane>
<StackPane>
<children>
<LineChart fx:id="hrChart" createSymbols="false" legendVisible="false" minHeight="100.0"
onMouseClicked="#toggleChart">
<xAxis>
<NumberAxis side="BOTTOM"/>
</xAxis>
<yAxis>
<NumberAxis side="LEFT"/>
</yAxis>
</LineChart>
<LineChart fx:id="hrTChart" createSymbols="false" layoutX="10.0" layoutY="10.0" legendVisible="false"
minHeight="100.0" onMouseClicked="#toggleChart" visible="false">
<xAxis>
<NumberAxis/>
</xAxis>
<yAxis>
<NumberAxis side="LEFT"/>
</yAxis>
</LineChart>
</children>
</StackPane>
<StackPane>
<children>
<LineChart fx:id="cadenceChart" createSymbols="false" legendVisible="false" minHeight="100.0"
onMouseClicked="#toggleChart">
<xAxis>
<NumberAxis side="BOTTOM"/>
</xAxis>
<yAxis>
<NumberAxis side="LEFT"/>
</yAxis>
</LineChart>
<LineChart fx:id="cadenceTChart" createSymbols="false" layoutX="10.0" layoutY="10.0"
legendVisible="false" minHeight="100.0" onMouseClicked="#toggleChart" visible="false">
<xAxis>
<NumberAxis/>
</xAxis>
<yAxis>
<NumberAxis side="LEFT"/>
</yAxis>
</LineChart>
</children>
</StackPane>
</VBox> </VBox>
</Tab> </Tab>
</JFXTabPane> </JFXTabPane>

View file

@ -25,6 +25,7 @@
app.extension=GPX data files app.extension=GPX data files
app.title=ESTRABA app.title=ESTRABA
error.file=Error loading file
label.begin=Salida label.begin=Salida
label.cadence=Cadence label.cadence=Cadence
label.distance=Distance label.distance=Distance

View file

@ -25,6 +25,7 @@
app.extension=Arxius GPX app.extension=Arxius GPX
app.title=ESTRABA app.title=ESTRABA
error.file=Error
label.begin=Salida label.begin=Salida
label.cadence=Cadencia label.cadence=Cadencia
label.distance=Distancia label.distance=Distancia

View file

@ -25,6 +25,7 @@
app.extension=Archivos de datos GPX app.extension=Archivos de datos GPX
app.title=ESTRABA app.title=ESTRABA
error.file=Error al cargar el archivo
label.begin=Salida label.begin=Salida
label.cadence=Cadencia label.cadence=Cadencia
label.distance=Distancia label.distance=Distancia