Client - display converted speed/elevation in workout chart

This commit is contained in:
Sam 2021-11-14 13:33:07 +01:00
parent c0acff9e3d
commit 9b7f685992
6 changed files with 114 additions and 20 deletions

View File

@ -55,12 +55,14 @@
import { LineChart, useLineChart } from 'vue-chart-3' import { LineChart, useLineChart } from 'vue-chart-3'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { TUnit } from '@/types/units'
import { IUserProfile } from '@/types/user' import { IUserProfile } from '@/types/user'
import { import {
IWorkoutChartData, IWorkoutChartData,
IWorkoutData, IWorkoutData,
TCoordinates, TCoordinates,
} from '@/types/workouts' } from '@/types/workouts'
import { units } from '@/utils/units'
import { getDatasets } from '@/utils/workouts' import { getDatasets } from '@/utils/workouts'
interface Props { interface Props {
@ -76,8 +78,10 @@
let displayDistance = ref(true) let displayDistance = ref(true)
let beginElevationAtZero = ref(true) let beginElevationAtZero = ref(true)
const datasets: ComputedRef<IWorkoutChartData> = computed(() => const datasets: ComputedRef<IWorkoutChartData> = computed(() =>
getDatasets(props.workoutData.chartData, t) getDatasets(props.workoutData.chartData, t, props.authUser.imperial_units)
) )
const fromKmUnit = getUnitTo('km')
const fromMUnit = getUnitTo('m')
let chartData: ComputedRef<ChartData<'line'>> = computed(() => ({ let chartData: ComputedRef<ChartData<'line'>> = computed(() => ({
labels: displayDistance.value labels: displayDistance.value
? datasets.value.distance_labels ? datasets.value.distance_labels
@ -119,7 +123,7 @@
title: { title: {
display: true, display: true,
text: displayDistance.value text: displayDistance.value
? t('workouts.DISTANCE') + ' (km)' ? t('workouts.DISTANCE') + ` (${fromKmUnit})`
: t('workouts.DURATION'), : t('workouts.DURATION'),
}, },
}, },
@ -130,7 +134,7 @@
position: 'left', position: 'left',
title: { title: {
display: true, display: true,
text: t('workouts.SPEED') + ' (km/h)', text: t('workouts.SPEED') + ` (${fromKmUnit}/h)`,
}, },
}, },
yElevation: { yElevation: {
@ -141,7 +145,7 @@
position: 'right', position: 'right',
title: { title: {
display: true, display: true,
text: t('workouts.ELEVATION') + ' (m)', text: t('workouts.ELEVATION') + ` (${fromMUnit})`,
}, },
}, },
}, },
@ -164,8 +168,8 @@
label: function (context) { label: function (context) {
const label = ` ${context.dataset.label}: ${context.formattedValue}` const label = ` ${context.dataset.label}: ${context.formattedValue}`
return context.dataset.yAxisID === 'yElevation' return context.dataset.yAxisID === 'yElevation'
? label + ' m' ? label + ` ${fromMUnit}`
: label + ' km/h' : label + ` ${fromKmUnit}/h`
}, },
title: function (tooltipItems) { title: function (tooltipItems) {
if (tooltipItems.length > 0) { if (tooltipItems.length > 0) {
@ -174,7 +178,9 @@
return tooltipItems.length === 0 return tooltipItems.length === 0
? '' ? ''
: displayDistance.value : displayDistance.value
? `${t('workouts.DISTANCE')}: ${tooltipItems[0].label} km` ? `${t('workouts.DISTANCE')}: ${
tooltipItems[0].label
} ${fromKmUnit}`
: `${t('workouts.DURATION')}: ${formatDuration( : `${t('workouts.DURATION')}: ${formatDuration(
tooltipItems[0].label.replace(',', '') tooltipItems[0].label.replace(',', '')
)}` )}`
@ -200,6 +206,11 @@
function emitEmptyCoordinates() { function emitEmptyCoordinates() {
emitCoordinates({ latitude: null, longitude: null }) emitCoordinates({ latitude: null, longitude: null })
} }
function getUnitTo(unitFrom: TUnit): TUnit {
return props.authUser.imperial_units
? units[unitFrom].defaultTarget
: unitFrom
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -19,7 +19,6 @@
<Distance <Distance
:distance="segment.distance" :distance="segment.distance"
unitFrom="km" unitFrom="km"
:strong="true"
:useImperialUnits="useImperialUnits" :useImperialUnits="useImperialUnits"
/>, {{ $t('workouts.DURATION') }}: {{ segment.duration }}) />, {{ $t('workouts.DURATION') }}: {{ segment.duration }})
</li> </li>

View File

@ -25,7 +25,7 @@ import {
} from '@/types/statistics' } from '@/types/statistics'
import { incrementDate, getStartDate } from '@/utils/dates' import { incrementDate, getStartDate } from '@/utils/dates'
import { sportColors } from '@/utils/sports' import { sportColors } from '@/utils/sports'
import { convertDistance, units } from '@/utils/units' import { convertStatsDistance } from '@/utils/units'
const dateFormats: Record<string, Record<string, string>> = { const dateFormats: Record<string, Record<string, string>> = {
week: { week: {
@ -103,13 +103,12 @@ export const convertStatsValue = (
switch (datasetKey) { switch (datasetKey) {
case 'total_distance': case 'total_distance':
case 'total_ascent': case 'total_ascent':
case 'total_descent': { case 'total_descent':
const unitFrom = datasetKey === 'total_distance' ? 'km' : 'm' return convertStatsDistance(
const unitTo = useImperialUnits ? units[unitFrom].defaultTarget : unitFrom datasetKey === 'total_distance' ? 'km' : 'm',
return useImperialUnits value,
? convertDistance(value, unitFrom, unitTo, 2) useImperialUnits
: value )
}
default: default:
case 'nb_workouts': case 'nb_workouts':
case 'total_duration': case 'total_duration':

View File

@ -54,3 +54,12 @@ export const convertDistance = (
} }
return convertedDistance return convertedDistance
} }
export const convertStatsDistance = (
unitFrom: TUnit,
value: number,
useImperialUnits: boolean
): number => {
const unitTo = useImperialUnits ? units[unitFrom].defaultTarget : unitFrom
return useImperialUnits ? convertDistance(value, unitFrom, unitTo, 2) : value
}

View File

@ -5,10 +5,12 @@ import {
TCoordinates, TCoordinates,
TWorkoutDatasets, TWorkoutDatasets,
} from '@/types/workouts' } from '@/types/workouts'
import { convertStatsDistance } from '@/utils/units'
export const getDatasets = ( export const getDatasets = (
chartData: IWorkoutApiChartData[], chartData: IWorkoutApiChartData[],
t: CallableFunction t: CallableFunction,
useImperialUnits: boolean
): IWorkoutChartData => { ): IWorkoutChartData => {
const datasets: TWorkoutDatasets = { const datasets: TWorkoutDatasets = {
speed: { speed: {
@ -36,8 +38,12 @@ export const getDatasets = (
chartData.map((data) => { chartData.map((data) => {
distance_labels.push(data.distance) distance_labels.push(data.distance)
duration_labels.push(data.duration) duration_labels.push(data.duration)
datasets.speed.data.push(data.speed) datasets.speed.data.push(
datasets.elevation.data.push(data.elevation) convertStatsDistance('km', data.speed, useImperialUnits)
)
datasets.elevation.data.push(
convertStatsDistance('m', data.elevation, useImperialUnits)
)
coordinates.push({ latitude: data.latitude, longitude: data.longitude }) coordinates.push({ latitude: data.latitude, longitude: data.longitude })
}) })

View File

@ -13,6 +13,7 @@ describe('getDatasets', () => {
inputParams: { inputParams: {
charData: [], charData: [],
locale: 'fr', locale: 'fr',
useImperialUnits: false,
}, },
expected: { expected: {
distance_labels: [], distance_labels: [],
@ -72,6 +73,7 @@ describe('getDatasets', () => {
}, },
], ],
locale: 'en', locale: 'en',
useImperialUnits: false,
}, },
expected: { expected: {
distance_labels: [0, 0, 0.01], distance_labels: [0, 0, 0.01],
@ -102,12 +104,80 @@ describe('getDatasets', () => {
], ],
}, },
}, },
{
description: 'returns datasets w/ units conversion',
inputParams: {
charData: [
{
distance: 0,
duration: 0,
elevation: 83.6,
latitude: 48.845574,
longitude: 2.373723,
speed: 2.89,
time: 'Sun, 12 Sep 2021 13:29:24 GMT',
},
{
distance: 0,
duration: 1,
elevation: 83.7,
latitude: 48.845578,
longitude: 2.373732,
speed: 1.56,
time: 'Sun, 12 Sep 2021 13:29:25 GMT',
},
{
distance: 0.01,
duration: 96,
elevation: 84.3,
latitude: 48.845591,
longitude: 2.373811,
speed: 14.73,
time: 'Sun, 12 Sep 2021 13:31:00 GMT',
},
],
locale: 'en',
useImperialUnits: true,
},
expected: {
distance_labels: [0, 0, 0.01],
duration_labels: [0, 1, 96],
datasets: {
speed: {
label: 'speed',
backgroundColor: ['#FFFFFF'],
borderColor: ['#8884d8'],
borderWidth: 2,
data: [1.8, 0.97, 9.15],
yAxisID: 'ySpeed',
},
elevation: {
label: 'elevation',
backgroundColor: ['#e5e5e5'],
borderColor: ['#cccccc'],
borderWidth: 1,
fill: true,
data: [274.28, 274.61, 276.57],
yAxisID: 'yElevation',
},
},
coordinates: [
{ latitude: 48.845574, longitude: 2.373723 },
{ latitude: 48.845578, longitude: 2.373732 },
{ latitude: 48.845591, longitude: 2.373811 },
],
},
},
] ]
testparams.map((testParams) => { testparams.map((testParams) => {
it(testParams.description, () => { it(testParams.description, () => {
locale.value = testParams.inputParams.locale locale.value = testParams.inputParams.locale
assert.deepEqual( assert.deepEqual(
getDatasets(testParams.inputParams.charData, t), getDatasets(
testParams.inputParams.charData,
t,
testParams.inputParams.useImperialUnits
),
testParams.expected testParams.expected
) )
}) })