kauron/estraba
Archived
1
0
Fork 0

Added load button and max HR dialog

This commit is contained in:
Carlos Galindo 2016-05-24 14:37:47 +02:00
parent 05d052fb00
commit 414c3c3ee9
Signed by: kauron
GPG key ID: 83E68706DEE119A3
4 changed files with 96 additions and 42 deletions

View file

@ -37,7 +37,10 @@ import es.kauron.estraba.model.DataBundle;
import javafx.collections.ObservableList;
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.chart.AreaChart;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.PieChart;
@ -46,8 +49,10 @@ import javafx.scene.control.Tab;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import jgpx.model.analysis.Chunk;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
@ -62,7 +67,7 @@ public class DashboardController implements Initializable, MapComponentInitializ
private AnchorPane root;
@FXML
private Tab tabDashboard, tabMap, tabGraph, tabSettings;
private Tab tabDashboard, tabMap, tabGraph;
@FXML
private ImageView imgHR, imgSpeed, imgCadence, imgDate, imgDistance, imgElevation;
@ -92,6 +97,7 @@ public class DashboardController implements Initializable, MapComponentInitializ
@Override
public void initialize(URL location, ResourceBundle resources) {
mapView.setVisible(false);
// populate map icons
((ImageView)elevationButton.getGraphic()).setImage(new Image(App.class.getResourceAsStream("img/elevation.png")));
((ImageView)speedButton.getGraphic()).setImage(new Image(App.class.getResourceAsStream("img/speed.png")));
@ -107,6 +113,19 @@ public class DashboardController implements Initializable, MapComponentInitializ
imgElevation.setImage(new Image(App.class.getResourceAsStream("img/elevation.png")));
}
@FXML
private void loadFile() {
FXMLLoader loader = new FXMLLoader(
App.class.getResource("fxml/Splash.fxml"), App.GENERAL_BUNDLE);
Parent parent;
try {
parent = loader.load();
((Stage) root.getScene().getWindow()).setScene(new Scene(parent));
} catch (IOException e) {
e.printStackTrace();
}
}
@FXML
private void onMapButton(ActionEvent event){
switch (((JFXButton)event.getSource()).getId()) {
@ -196,16 +215,12 @@ public class DashboardController implements Initializable, MapComponentInitializ
coord[W] = Math.min(lon, coord[W]);
pathArray.push(new LatLong(lat, lon));
});
// Create and add the polyline using the array
// This polyline displays instantly with no problem
// TODO: add color with PolylineOptions.strokeColor("#ffff00") to match the color schemes of the app
// When using that method, the line does not load properly, it needs an update to the zoom to show up.
map.addMarker(new Marker(new MarkerOptions()
.position(new LatLong(
chunks.get(0).getFirstPoint().getLatitude(),
chunks.get(0).getFirstPoint().getLongitude()))
.title("label.begin")));
map.addMapShape(new Polyline(new PolylineOptions().path(pathArray)));
map.addMapShape(new Polyline(new PolylineOptions().path(pathArray).strokeColor("#fc4c02")));
map.addMarker(new Marker(new MarkerOptions()
.position(new LatLong(
chunks.get(chunks.size() - 1).getLastPoint().getLatitude(),

View file

@ -38,12 +38,17 @@ import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Text;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
@ -78,6 +83,7 @@ public class SplashController implements Initializable{
private JFXSnackbar snackbar;
private File file;
private int maxHR;
@FXML
private void loadGPXFile(ActionEvent event) throws Exception {
@ -93,15 +99,16 @@ public class SplashController implements Initializable{
}
public void loadGPXFile(File file) {
maxHR = showHRDialog();
if (maxHR < 0) errorLoading();
buttonLoad.setVisible(false);
labelWelcome.setVisible(false);
spinner.setVisible(true);
snackbar.registerSnackbarContainer(root);
snackbar.show("Loading file", 5000);
Thread th = new Thread(new Task<DataBundle>() {
@Override
protected DataBundle call() throws Exception {
return DataBundle.loadFrom(file);
return DataBundle.loadFrom(file, maxHR);
}
@Override
@ -169,6 +176,7 @@ public class SplashController implements Initializable{
e.setDropCompleted(success);
e.consume();
}));
snackbar.registerSnackbarContainer(root);
}
private void errorLoading() {
@ -177,5 +185,36 @@ public class SplashController implements Initializable{
spinner.setVisible(false);
snackbar.show("Error loading file", 3000);
}
private int showHRDialog() {
Dialog<Integer> dialog = new Dialog<>();
dialog.setTitle("Input your maximum heart rate or age");
GridPane grid = new GridPane();
grid.setHgap(5);
grid.setVgap(2);
grid.addColumn(0, new Text("Heart rate:"), new Text("Age:"));
Spinner<Integer> spinnerAge = new Spinner<>(18, 99, 25, 1);
Spinner<Integer> spinnerHR = new Spinner<>(60, 202, 180, 5);
spinnerAge.valueProperty().addListener((obs, oldV, newV) ->
spinnerHR.setValueFactory(new SpinnerValueFactory
.IntegerSpinnerValueFactory(60, 202, 220 - newV, 5)));
spinnerHR.valueProperty().addListener((obs, old, newV) ->
spinnerAge.setValueFactory(new SpinnerValueFactory
.IntegerSpinnerValueFactory(18, 99, 220 - newV, 1)));
grid.addColumn(1, spinnerHR, spinnerAge);
Button buttonOk = new Button("Ok");
buttonOk.setDefaultButton(true);
buttonOk.setOnAction(event -> {
dialog.setResult(spinnerHR.getValue());
dialog.close();
});
grid.add(buttonOk, 1, 2);
dialog.getDialogPane().setContent(grid);
dialog.showAndWait();
if (dialog.getResult() != null)
return dialog.getResult();
else
return -1;
}
}

View file

@ -55,7 +55,7 @@ public class DataBundle {
public ObservableList<PieChart.Data> pieData;
public ObservableList<Chunk> chunks;
private DataBundle(TrackData track) {
private DataBundle(TrackData track, int maxHR) {
HRAvg = track.getAverageHeartrate() + App.GENERAL_BUNDLE.getString("unit.bpm");
HRMax = track.getMaxHeartrate() + App.GENERAL_BUNDLE.getString("unit.bpm");
@ -106,10 +106,10 @@ public class DataBundle {
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");
if (chunk.getAvgHeartRate() > maxHR * .9) zone = App.GENERAL_BUNDLE.getString("zone.anaerobic");
else if (chunk.getAvgHeartRate() > maxHR * .8) zone = App.GENERAL_BUNDLE.getString("zone.threshold");
else if (chunk.getAvgHeartRate() > maxHR * .7) zone = App.GENERAL_BUNDLE.getString("zone.tempo");
else if (chunk.getAvgHeartRate() > maxHR * .6) zone = App.GENERAL_BUNDLE.getString("zone.endurance");
else zone = App.GENERAL_BUNDLE.getString("zone.recovery");
boolean pieFound = false;
@ -117,13 +117,14 @@ public class DataBundle {
if (d.getName().equals(zone)) {
pieFound = true;
d.setPieValue(d.getPieValue() + 1);
break;
}
}
if (!pieFound) pieData.add( new PieChart.Data(zone, 1) );
}
}
public static DataBundle loadFrom(File file) throws Exception {
public static DataBundle loadFrom(File file, int maxHR) throws Exception {
JAXBElement<Object> jaxbElement;
JAXBContext jaxbContext = JAXBContext.newInstance(GpxType.class, TrackPointExtensionT.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
@ -131,6 +132,6 @@ public class DataBundle {
GpxType gpx = (GpxType) jaxbElement.getValue();
if (gpx == null) throw new Exception();
return new DataBundle(new TrackData(new Track(gpx.getTrk().get(0))));
return new DataBundle(new TrackData(new Track(gpx.getTrk().get(0))), maxHR);
}
}

View file

@ -25,17 +25,26 @@
~
-->
<?import com.jfoenix.controls.*?>
<?import com.jfoenix.controls.JFXButton?>
<?import com.jfoenix.controls.JFXSpinner?>
<?import com.jfoenix.controls.JFXTabPane?>
<?import com.lynden.gmapsfx.GoogleMapView?>
<?import javafx.geometry.*?>
<?import javafx.scene.chart.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" fx:id="root" xmlns="http://javafx.com/javafx/8.0.76-ea"
fx:controller="es.kauron.estraba.controller.DashboardController">
<?import java.lang.String?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.chart.AreaChart?>
<?import javafx.scene.chart.LineChart?>
<?import javafx.scene.chart.NumberAxis?>
<?import javafx.scene.chart.PieChart?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<AnchorPane fx:id="root" xmlns="http://javafx.com/javafx/8.0.76-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="es.kauron.estraba.controller.DashboardController">
<JFXTabPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="1000.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<Tab fx:id="tabDashboard" styleClass=".estraba.dashboard" text="%tab.dashboard">
<VBox prefHeight="200.0" prefWidth="100.0">
@ -201,7 +210,7 @@
</VBox>
</HBox>
</VBox>
<PieChart fx:id="zoneChart" labelsVisible="false" legendVisible="true" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="360.0" startAngle="90" HBox.hgrow="ALWAYS">
<PieChart fx:id="zoneChart" labelsVisible="false" legendVisible="true" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="360.0" startAngle="90">
</PieChart>
<VBox layoutX="15.0" layoutY="15.0" minHeight="360.0" minWidth="300.0" prefHeight="300.0">
<HBox alignment="CENTER" layoutX="10.0" layoutY="10.0" minHeight="-Infinity" minWidth="-Infinity" prefHeight="90.0" prefWidth="200.0" HBox.hgrow="ALWAYS" VBox.vgrow="ALWAYS">
@ -346,18 +355,11 @@
</HBox>
</VBox>
</HBox>
<Label fx:id="labelMotivationLower" alignment="CENTER" focusTraversable="false" maxWidth="1.7976931348623157E308" text="%label.motivation">
<font>
<Font name="Roboto" size="56.0" />
</font>
<VBox.margin>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</VBox.margin>
<styleClass>
<String fx:value=".estraba.dashboard.motivation" />
<String fx:value=".estraba.dashboard.motivation.lower" />
</styleClass>
</Label>
<HBox alignment="CENTER" spacing="10.0">
<children>
<JFXButton minWidth="70.0" onAction="#loadFile" style="-fx-background-color: #fc4c02;" text="Load another file" textAlignment="CENTER" textFill="WHITE" />
</children>
</HBox>
</VBox>
</Tab>
<Tab fx:id="tabMap" text="%tab.map">
@ -365,7 +367,7 @@
<padding>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</padding>
<StackPane prefHeight="150.0" prefWidth="200.0" VBox.vgrow="ALWAYS" >
<StackPane prefHeight="150.0" prefWidth="200.0" VBox.vgrow="ALWAYS">
<children>
<GoogleMapView fx:id="mapView" />
<JFXSpinner fx:id="mapSpinner" />
@ -456,8 +458,5 @@
</LineChart>
</VBox>
</Tab>
<Tab fx:id="tabSettings" text="%tab.settings">
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</Tab>
</JFXTabPane>
</AnchorPane>