diff --git a/pom.xml b/pom.xml index e77cdb3..82b5741 100644 --- a/pom.xml +++ b/pom.xml @@ -58,11 +58,6 @@ controlsfx 8.40.10 - - jfree - jfreechart - 1.0.13 - com.github.rterp GMapsFX diff --git a/src/main/java/es/kauron/estraba/App.java b/src/main/java/es/kauron/estraba/App.java index 24ed1d5..f837507 100644 --- a/src/main/java/es/kauron/estraba/App.java +++ b/src/main/java/es/kauron/estraba/App.java @@ -61,6 +61,7 @@ public class App extends Application { stage.setResizable(false); stage.setScene(new Scene(root)); + if (getParameters().getUnnamed().size() == 1) { loader.getController().loadGPXFile(new File(getParameters().getUnnamed().get(0))); } diff --git a/src/main/java/es/kauron/estraba/controller/DashboardController.java b/src/main/java/es/kauron/estraba/controller/DashboardController.java index de85431..3a1e2e1 100644 --- a/src/main/java/es/kauron/estraba/controller/DashboardController.java +++ b/src/main/java/es/kauron/estraba/controller/DashboardController.java @@ -39,6 +39,7 @@ import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.fxml.Initializable; +import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.chart.AreaChart; @@ -48,6 +49,7 @@ import javafx.scene.control.Label; import javafx.scene.control.Tab; import javafx.scene.image.Image; import javafx.scene.image.ImageView; +import javafx.scene.input.MouseEvent; import javafx.scene.layout.AnchorPane; import javafx.stage.Stage; import jgpx.model.analysis.Chunk; @@ -63,38 +65,41 @@ import java.util.ResourceBundle; public class DashboardController implements Initializable, MapComponentInitializedListener { + final int N = 0, S = 1, E = 2, W = 3; + final double[] coord = new double[4]; @FXML private AnchorPane root; - @FXML private Tab tabDashboard, tabMap, tabGraph; @FXML private ImageView imgHR, imgSpeed, imgCadence, imgDate, imgDistance, imgElevation; - @FXML 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 ObservableList chunks; - @FXML private JFXButton elevationButton, speedButton, hrButton, cadenceButton; @FXML private AreaChart elevationChart; + @FXML + private AreaChart elevationTChart; + @FXML private LineChart speedChart, hrChart, cadenceChart, mapChart; + @FXML + private LineChart speedTChart, hrTChart, cadenceTChart; + @Override public void initialize(URL location, ResourceBundle resources) { mapView.setVisible(false); @@ -111,6 +116,15 @@ public class DashboardController implements Initializable, MapComponentInitializ imgDate.setImage(new Image(App.class.getResourceAsStream("img/date.png"))); imgDistance.setImage(new Image(App.class.getResourceAsStream("img/distance.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 @@ -168,9 +182,13 @@ public class DashboardController implements Initializable, MapComponentInitializ // populate the charts elevationChart.getData().add(bundle.elevationSeries); + elevationTChart.getData().add(bundle.elevationTSeries); speedChart.getData().add(bundle.speedSeries); + speedTChart.getData().add(bundle.speedTSeries); hrChart.getData().add(bundle.hrSeries); + hrTChart.getData().add(bundle.hrTSeries); cadenceChart.getData().add(bundle.cadenceSeries); + cadenceTChart.getData().add(bundle.cadenceTSeries); //initialize map chunks = bundle.chunks; @@ -180,8 +198,6 @@ public class DashboardController implements Initializable, MapComponentInitializ @Override public void mapInitialized() { // 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[1] = Double.MAX_VALUE; coord[2] = Double.MIN_VALUE; @@ -227,13 +243,20 @@ public class DashboardController implements Initializable, MapComponentInitializ chunks.get(chunks.size() - 1).getLastPoint().getLongitude())) .title("label.end"))); // 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[N], coord[E]) )); - map.setZoom(getBoundsZoomLevel(coord, mapView.getHeight(), mapView.getWidth())); - mapView.setVisible(true); - mapSpinner.setVisible(false); } /** diff --git a/src/main/java/es/kauron/estraba/controller/SplashController.java b/src/main/java/es/kauron/estraba/controller/SplashController.java index 9dc1600..e09e97f 100644 --- a/src/main/java/es/kauron/estraba/controller/SplashController.java +++ b/src/main/java/es/kauron/estraba/controller/SplashController.java @@ -30,7 +30,6 @@ 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; @@ -108,7 +107,13 @@ public class SplashController implements Initializable{ Thread th = new Thread(new Task() { @Override 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 @@ -124,6 +129,7 @@ public class SplashController implements Initializable{ loader.getController().load(bundle); ((Stage) root.getScene().getWindow()).setScene(new Scene(parent)); } catch (IOException e) { + e.printStackTrace(); 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(); if (db.hasFiles()) { e.acceptTransferModes(TransferMode.COPY); @@ -162,16 +168,12 @@ public class SplashController implements Initializable{ })); // Dropping over surface - Platform.runLater(() -> root.getScene().setOnDragDropped(e -> { + Platform.runLater(() -> root.setOnDragDropped(e -> { Dragboard db = e.getDragboard(); boolean success = false; if (db.hasFiles()) { success = true; - String filePath = null; - for (File file : db.getFiles()) { - filePath = file.getAbsolutePath(); - System.out.println(filePath); - } + loadGPXFile(db.getFiles().get(0).getAbsoluteFile()); } e.setDropCompleted(success); e.consume(); @@ -183,7 +185,7 @@ public class SplashController implements Initializable{ buttonLoad.setVisible(true); labelWelcome.setVisible(true); spinner.setVisible(false); - snackbar.show("Error loading file", 3000); + snackbar.show(App.GENERAL_BUNDLE.getString("error.file"), 3000); } private int showHRDialog() { diff --git a/src/main/java/es/kauron/estraba/model/DataBundle.java b/src/main/java/es/kauron/estraba/model/DataBundle.java index bb27f1c..457375b 100644 --- a/src/main/java/es/kauron/estraba/model/DataBundle.java +++ b/src/main/java/es/kauron/estraba/model/DataBundle.java @@ -40,18 +40,20 @@ import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.Unmarshaller; import java.io.File; +import java.time.Duration; 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 elevationSeries, speedSeries, hrSeries, cadenceSeries; + public XYChart.Series elevationTSeries, speedTSeries, hrTSeries, cadenceTSeries; public ObservableList pieData; public ObservableList chunks; @@ -87,23 +89,34 @@ public class DataBundle { // traverse the chunks chunks = track.getChunks(); double currentDistance = 0.0; + Duration currentTime = Duration.ZERO; double currentHeight = chunks.get(0).getFirstPoint().getElevation(); elevationSeries = new XYChart.Series<>(); + elevationTSeries = new XYChart.Series<>(); cadenceSeries = new XYChart.Series<>(); + cadenceTSeries = new XYChart.Series<>(); hrSeries = new XYChart.Series<>(); + hrTSeries = new XYChart.Series<>(); speedSeries = new XYChart.Series<>(); + speedTSeries = new XYChart.Series<>(); pieData = FXCollections.observableArrayList(); for (Chunk chunk : chunks) { 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(); 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 + speedTSeries.getData().add(new XYChart.Data<>(currentTime.toMinutes(), chunk.getSpeed() * 3.6)); // m/s 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())); + cadenceTSeries.getData().add(new XYChart.Data<>(currentTime.toMinutes(), chunk.getAvgCadence())); String zone; if (chunk.getAvgHeartRate() > maxHR * .9) zone = App.GENERAL_BUNDLE.getString("zone.anaerobic"); diff --git a/src/main/resources/es/kauron/estraba/fxml/Dashboard.fxml b/src/main/resources/es/kauron/estraba/fxml/Dashboard.fxml index 959399c..c8599c5 100644 --- a/src/main/resources/es/kauron/estraba/fxml/Dashboard.fxml +++ b/src/main/resources/es/kauron/estraba/fxml/Dashboard.fxml @@ -424,38 +424,94 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/general.properties b/src/main/resources/general.properties index 39341a7..4156188 100644 --- a/src/main/resources/general.properties +++ b/src/main/resources/general.properties @@ -25,6 +25,7 @@ app.extension=GPX data files app.title=ESTRABA +error.file=Error loading file label.begin=Salida label.cadence=Cadence label.distance=Distance diff --git a/src/main/resources/general_ca.properties b/src/main/resources/general_ca.properties index 7e4699a..5cb615a 100644 --- a/src/main/resources/general_ca.properties +++ b/src/main/resources/general_ca.properties @@ -25,6 +25,7 @@ app.extension=Arxius GPX app.title=ESTRABA +error.file=Error label.begin=Salida label.cadence=Cadencia label.distance=Distancia diff --git a/src/main/resources/general_es.properties b/src/main/resources/general_es.properties index 20b3b56..c072112 100644 --- a/src/main/resources/general_es.properties +++ b/src/main/resources/general_es.properties @@ -25,6 +25,7 @@ app.extension=Archivos de datos GPX app.title=ESTRABA +error.file=Error al cargar el archivo label.begin=Salida label.cadence=Cadencia label.distance=Distancia