diff --git a/App.js b/App.js index ad7ed66..6d12ee2 100644 --- a/App.js +++ b/App.js @@ -13,7 +13,7 @@ import ThemedStackNavigation from './components/ThemedStackNavigation'; const store = createStore(swimtrackerReducer); -const deviceReduxCoupling = new DeviceReduxCoupling(store); +//const deviceReduxCoupling = new DeviceReduxCoupling(store); export default class App extends React.Component { @@ -31,6 +31,7 @@ export default class App extends React.Component { ...Ionicons.font, }); this.setState({ isReady: true }); + this.device = new DeviceReduxCoupling(store); } render() { diff --git a/components/Graph.js b/components/Graph.js index 3013780..cdbfc31 100644 --- a/components/Graph.js +++ b/components/Graph.js @@ -1,34 +1,83 @@ import React from 'react'; -import {View, StyleSheet, Text} from 'react-native'; +import { View, StyleSheet } from 'react-native'; //import Svg, {Polyline, Polygon, Rect, G} from 'react-native-svg-web'; -import Svg, {Polyline, Polygon, Rect, G} from 'react-native-svg'; +import Svg, { Polyline, Polygon, Rect, G, Text } from 'react-native-svg'; +import { connect } from 'react-redux'; +function computeTickMark(largest, mostTicks) { + const minimum = largest / mostTicks + const magnitude = 10 ** Math.floor(Math.log10(minimum)) + const residual = minimum / magnitude + if (residual > 5) + return 10 * magnitude + else if (residual > 2) + return 5 * magnitude + else if (residual > 1) + return 2 * magnitude + else + return magnitude +} + const Graph = props => { const graphHeight = 100; - const data = props.data.slice(-600); - - const coordStr = data.map((element, i) => `${i}, ${element / 2}`); + const data = props.data.slice(-300); + const maxElement = data.reduce((running, x) => Math.max(x, running), 2 / props.kgFactor); + + const coordStr = data.map((element, i) => `${i}, ${100 - (element * 100 / maxElement)}`); + + const tick = computeTickMark(maxElement * props.kgFactor * 0.6, 4); + let ticks = []; + let nextTick = tick; + while (nextTick < maxElement * props.kgFactor) { + ticks.push(nextTick); + nextTick += tick; + } return ( - - - + + - + {ticks.map(tick => ( + + + {tick} kg + + ) + )} ); }; -export default Graph; +const mapStateToProps = (state) => { + return { + data: state.deviceState.measurements, + kgFactor: state.settings.analysis.kgFactor + }; +}; + + +export default connect(mapStateToProps)(Graph); diff --git a/components/HomeView.js b/components/HomeView.js index d1e1dc3..427edba 100644 --- a/components/HomeView.js +++ b/components/HomeView.js @@ -50,7 +50,7 @@ function HomeView(props) { } const mapStateToProps = (state) => { - return { running: state.deviceState.connState == ConnState.CONNECTED_STARTING }; + return { running: state.deviceState.connState === ConnState.CONNECTED_RUNNING }; }; export default connect(mapStateToProps)(HomeView); diff --git a/components/LiveTrainingView.js b/components/LiveTrainingView.js index b525635..cde8a66 100644 --- a/components/LiveTrainingView.js +++ b/components/LiveTrainingView.js @@ -31,6 +31,7 @@ function LiveTrainingView(props) { + {/* diff --git a/state/ActionCreators.js b/state/ActionCreators.js deleted file mode 100644 index baa5294..0000000 --- a/state/ActionCreators.js +++ /dev/null @@ -1,30 +0,0 @@ - - -export const CHANGE_USER_NAME = "SET_USERNAME"; -export const CHANGE_THEME = "CHANGE_THEME"; -export const RESET_DEVICE_DATA = "RESET_DEVICE_DATA"; - - - - -export const changeUsername = newUsername => ({ - type: CHANGE_USER_NAME, - newUserName: newUsername, -}); - -export const changeTheme = newThemeName => ({ - type: CHANGE_THEME, - newThemeName: newThemeName -}); - -export const startSession = () => ({ - type: START_SESSION -}); - -export const stopSession = () => ({ - type: STOP_SESSION -}); - -// --------------------- - - diff --git a/state/DeviceReduxCoupling.js b/state/DeviceReduxCoupling.js index 7ab407b..c62cadf 100644 --- a/state/DeviceReduxCoupling.js +++ b/state/DeviceReduxCoupling.js @@ -126,12 +126,18 @@ export const deviceStateReducer = (state = INITIAL_DEVICE_STATE, action) => { case DEVICE_DISCONNECT: return { ...INITIAL_DEVICE_STATE, connState: ConnState.DISCONNECTED }; case SESSION_STARTED: + console.log("session started"); return { ...INITIAL_DEVICE_STATE, connState: ConnState.CONNECTED_RUNNING, sessionId: action.sessionId }; case SESSION_STOPPED: + console.log("session stopped"); return { ...INITIAL_DEVICE_STATE, connState: ConnState.CONNECTED_STOPPED }; case START_SESSION: + if(state.connState === ConnState.SESSION_STARTED) + return state; return { ...INITIAL_DEVICE_STATE, connState: ConnState.CONNECTED_STARTING }; case STOP_SESSION: + if(state.connState === ConnState.SESSION_STOPPED) + return state; return { ...INITIAL_DEVICE_STATE, connState: ConnState.CONNECTED_STOPPING }; default: console.log("Unhandled state in deviceStateReducer", action.type); @@ -140,4 +146,4 @@ export const deviceStateReducer = (state = INITIAL_DEVICE_STATE, action) => { }; - + diff --git a/state/Reducer.js b/state/Reducer.js index 46af712..f0cbd06 100644 --- a/state/Reducer.js +++ b/state/Reducer.js @@ -1,7 +1,29 @@ import { combineReducers } from 'redux'; -import { CHANGE_THEME, CHANGE_USER_NAME, NEW_DEVICE_DATA, START_SESSION, STOP_SESSION, RESET_DEVICE_DATA } from './ActionCreators'; import { deviceStateReducer } from "./DeviceReduxCoupling"; +export const CHANGE_USER_NAME = "SET_USERNAME"; +export const CHANGE_THEME = "CHANGE_THEME"; +export const RESET_DEVICE_DATA = "RESET_DEVICE_DATA"; + + +export const changeUsername = newUsername => ({ + type: CHANGE_USER_NAME, + newUserName: newUsername, +}); + +export const changeTheme = newThemeName => ({ + type: CHANGE_THEME, + newThemeName: newThemeName +}); + +export const startSession = () => ({ + type: START_SESSION +}); + +export const stopSession = () => ({ + type: STOP_SESSION +}); + const INITIAL_SETTINGS = { theme: "hot", username: "", @@ -12,6 +34,8 @@ const INITIAL_SETTINGS = { windowSizeInSecs: 5, numMeasurementsPerSec: 10, + kgFactor: 1.0 / 1100.0, + peakDetector: 'SIMPLE', // either 'SIMPLE' or 'ZSCORE' peakDetectorSimpleThreshold: 2500,