Fix type conversion in the curveMetrics

Fix the string conversion of the curveMetrics and push the formatting
logic to the consumer that require this (eg. WorkoutRecorder). This
enables other consumers of curveMetrics to use non-rounded, "raw" data
instead of preformatted as well as avoid potential future bugs from the
type conversion.
This commit is contained in:
Abász 2023-03-25 20:21:00 +01:00
parent e7c40873cd
commit a1068cf77f
6 changed files with 25 additions and 18 deletions

View File

@ -39,7 +39,7 @@ export class DashboardForceCurve extends AppElement {
datasets: [ datasets: [
{ {
fill: true, fill: true,
data: this.value?.map((data, index) => ({ y: parseInt(data, 10), x: index })), data: this.value?.map((data, index) => ({ y: data, x: index })),
pointRadius: 1, pointRadius: 1,
borderColor: 'rgb(255,255,255)', borderColor: 'rgb(255,255,255)',
backgroundColor: 'rgb(220,220,220)' backgroundColor: 'rgb(220,220,220)'
@ -113,7 +113,7 @@ export class DashboardForceCurve extends AppElement {
render () { render () {
if (this._chart?.data) { if (this._chart?.data) {
this._chart.data.datasets[0].data = this.value?.map((data, index) => ({ y: parseInt(data, 10), x: index })) this._chart.data.datasets[0].data = this.value?.map((data, index) => ({ y: data, x: index }))
this.forceCurve = this.value this.forceCurve = this.value
this._chart.update() this._chart.update()
} }

View File

@ -22,7 +22,7 @@ export function filterObjectByKeys (object, keys) {
/** /**
* Pipe for converting seconds to pace format 00:00 * Pipe for converting seconds to pace format 00:00
* *
* @param seconds The actual time in seconds. * @param {number} seconds The actual time in seconds.
*/ */
export function secondsToPace (seconds) { export function secondsToPace (seconds) {
const hours = Math.floor((seconds % 86400) / 3600) const hours = Math.floor((seconds % 86400) / 3600)
@ -41,8 +41,8 @@ export function secondsToPace (seconds) {
/** /**
* Pipe for formatting distance in meters with units * Pipe for formatting distance in meters with units
* *
* @param value The distance in meters. * @param {number} value The distance in meters.
* @param showInMiles Boolean whether to use imperial metric (default: false). * @param {boolean} showInMiles Boolean whether to use imperial metric (default: false).
*/ */
export function formatDistance (value, showInMiles = false) { export function formatDistance (value, showInMiles = false) {
if (showInMiles === false) { if (showInMiles === false) {
@ -57,8 +57,8 @@ export function formatDistance (value, showInMiles = false) {
/** /**
* Pipe for formatting numbers to specific decimal * Pipe for formatting numbers to specific decimal
* *
* @param value The number. * @param {number} value The number.
* @param decimalPlaces The number of decimal places to round to (default: 0). * @param {number} decimalPlaces The number of decimal places to round to (default: 0).
*/ */
export function formatNumber (value, decimalPlaces = 0) { export function formatNumber (value, decimalPlaces = 0) {
const decimal = Math.pow(10, decimalPlaces) const decimal = Math.pow(10, decimalPlaces)
@ -67,6 +67,13 @@ export function formatNumber (value, decimalPlaces = 0) {
return Math.round(value * decimal) / decimal return Math.round(value * decimal) / decimal
} }
export function simpleMetricFactory (value, unit, icon) { /**
* Helper function to create a simple metric tile
*
* @param {string | number} value The metric to show
* @param {string} unit The unit of the metric.
* @param {string | import('lit').TemplateResult<2>} icon The number of decimal places to round to (default: 0).
*/
export function simpleMetricFactory (value = '--', unit = '', icon = '') {
return html`<dashboard-metric .icon=${icon} .unit=${unit} .value=${value}></dashboard-metric>` return html`<dashboard-metric .icon=${icon} .unit=${unit} .value=${value}></dashboard-metric>`
} }

View File

@ -20,9 +20,9 @@ const log = loglevel.getLogger('RowingEngine')
function createRower (rowerSettings) { function createRower (rowerSettings) {
const flywheel = createFlywheel(rowerSettings) const flywheel = createFlywheel(rowerSettings)
const sprocketRadius = rowerSettings.sprocketRadius / 100 const sprocketRadius = rowerSettings.sprocketRadius / 100
const driveHandleForce = createCurveMetrics(2) const driveHandleForce = createCurveMetrics()
const driveHandleVelocity = createCurveMetrics(3) const driveHandleVelocity = createCurveMetrics()
const driveHandlePower = createCurveMetrics(1) const driveHandlePower = createCurveMetrics()
let _strokeState = 'WaitingForDrive' let _strokeState = 'WaitingForDrive'
let _totalNumberOfStrokes = -1.0 let _totalNumberOfStrokes = -1.0
let recoveryPhaseStartTime = 0.0 let recoveryPhaseStartTime = 0.0

View File

@ -402,9 +402,9 @@ function createRowingStatistics (config) {
driveDistance: driveDistance.clean() >= 0 && sessionStatus === 'Rowing' ? driveDistance.clean() : NaN, // meters driveDistance: driveDistance.clean() >= 0 && sessionStatus === 'Rowing' ? driveDistance.clean() : NaN, // meters
driveAverageHandleForce: driveAverageHandleForce.clean() > 0 && sessionStatus === 'Rowing' ? driveAverageHandleForce.clean() : NaN, driveAverageHandleForce: driveAverageHandleForce.clean() > 0 && sessionStatus === 'Rowing' ? driveAverageHandleForce.clean() : NaN,
drivePeakHandleForce: drivePeakHandleForce.clean() > 0 && sessionStatus === 'Rowing' ? drivePeakHandleForce.clean() : NaN, drivePeakHandleForce: drivePeakHandleForce.clean() > 0 && sessionStatus === 'Rowing' ? drivePeakHandleForce.clean() : NaN,
driveHandleForceCurve: drivePeakHandleForce.clean() > 0 && sessionStatus === 'Rowing' ? driveHandleForceCurve.lastCompleteCurve() : [NaN], driveHandleForceCurve: drivePeakHandleForce.clean() > 0 && sessionStatus === 'Rowing' ? driveHandleForceCurve.lastCompleteCurve() : [],
driveHandleVelocityCurve: drivePeakHandleForce.clean() > 0 && sessionStatus === 'Rowing' ? driveHandleVelocityCurve.lastCompleteCurve() : [NaN], driveHandleVelocityCurve: drivePeakHandleForce.clean() > 0 && sessionStatus === 'Rowing' ? driveHandleVelocityCurve.lastCompleteCurve() : [],
driveHandlePowerCurve: drivePeakHandleForce.clean() > 0 && sessionStatus === 'Rowing' ? driveHandlePowerCurve.lastCompleteCurve() : [NaN], driveHandlePowerCurve: drivePeakHandleForce.clean() > 0 && sessionStatus === 'Rowing' ? driveHandlePowerCurve.lastCompleteCurve() : [],
recoveryDuration: recoveryDuration.clean() >= config.rowerSettings.minimumRecoveryTime && totalNumberOfStrokes > 0 && sessionStatus === 'Rowing' ? recoveryDuration.clean() : NaN, // seconds recoveryDuration: recoveryDuration.clean() >= config.rowerSettings.minimumRecoveryTime && totalNumberOfStrokes > 0 && sessionStatus === 'Rowing' ? recoveryDuration.clean() : NaN, // seconds
dragFactor: dragFactor > 0 ? dragFactor : config.rowerSettings.dragFactor, // Dragfactor dragFactor: dragFactor > 0 ? dragFactor : config.rowerSettings.dragFactor, // Dragfactor
instantPower: instantPower > 0 && rower.strokeState() === 'Drive' ? instantPower : 0, instantPower: instantPower > 0 && rower.strokeState() === 'Drive' ? instantPower : 0,

View File

@ -83,8 +83,8 @@ function createWorkoutRecorder () {
`${currentstroke.cycleStrokeRate.toFixed(1)},${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.cyclePace.toFixed(2) : NaN)},${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.cyclePower.toFixed(0) : NaN)},` + `${currentstroke.cycleStrokeRate.toFixed(1)},${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.cyclePace.toFixed(2) : NaN)},${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.cyclePower.toFixed(0) : NaN)},` +
`${currentstroke.cycleDistance.toFixed(2)},${(currentstroke.driveDuration * 1000).toFixed(0)},${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.driveLength.toFixed(2) : NaN)},${(currentstroke.recoveryDuration * 1000).toFixed(0)},` + `${currentstroke.cycleDistance.toFixed(2)},${(currentstroke.driveDuration * 1000).toFixed(0)},${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.driveLength.toFixed(2) : NaN)},${(currentstroke.recoveryDuration * 1000).toFixed(0)},` +
`${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.cycleLinearVelocity.toFixed(2) : 0)},${currentstroke.totalLinearDistance.toFixed(1)},${currentstroke.totalCalories.toFixed(1)},${currentstroke.dragFactor.toFixed(1)},` + `${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.cycleLinearVelocity.toFixed(2) : 0)},${currentstroke.totalLinearDistance.toFixed(1)},${currentstroke.totalCalories.toFixed(1)},${currentstroke.dragFactor.toFixed(1)},` +
`${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.drivePeakHandleForce.toFixed(1) : NaN)},${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.driveAverageHandleForce.toFixed(1) : 0)},"${currentstroke.driveHandleForceCurve}",` + `${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.drivePeakHandleForce.toFixed(1) : NaN)},${(currentstroke.totalNumberOfStrokes > 0 ? currentstroke.driveAverageHandleForce.toFixed(1) : 0)},"${currentstroke.driveHandleForceCurve.map(value => value.toFixed(2))}",` +
`"${currentstroke.driveHandleVelocityCurve}","${currentstroke.driveHandlePowerCurve}"\n` `"${currentstroke.driveHandleVelocityCurve.map(value => value.toFixed(3))}","${currentstroke.driveHandlePowerCurve.map(value => value.toFixed(1))}"\n`
i++ i++
} }

View File

@ -6,7 +6,7 @@
*/ */
import { createSeries } from './Series.js' import { createSeries } from './Series.js'
function createCurveMetrics (precission = 0) { function createCurveMetrics () {
const _curve = createSeries() const _curve = createSeries()
let _max = 0 let _max = 0
let totalInputXTime = 0 let totalInputXTime = 0
@ -15,7 +15,7 @@ function createCurveMetrics (precission = 0) {
function push (deltaTime, inputValue) { function push (deltaTime, inputValue) {
// add the new dataPoint to the array, we have to move datapoints starting at the oldst ones // add the new dataPoint to the array, we have to move datapoints starting at the oldst ones
if (inputValue > 0) { if (inputValue > 0) {
_curve.push(inputValue.toFixed(precission)) _curve.push(inputValue)
_max = Math.max(_max, inputValue) _max = Math.max(_max, inputValue)
totalInputXTime += deltaTime * inputValue totalInputXTime += deltaTime * inputValue
totaltime += deltaTime totaltime += deltaTime