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

View File

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

View File

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

View File

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

View File

@ -13,6 +13,7 @@ describe('getDatasets', () => {
inputParams: {
charData: [],
locale: 'fr',
useImperialUnits: false,
},
expected: {
distance_labels: [],
@ -72,6 +73,7 @@ describe('getDatasets', () => {
},
],
locale: 'en',
useImperialUnits: false,
},
expected: {
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) => {
it(testParams.description, () => {
locale.value = testParams.inputParams.locale
assert.deepEqual(
getDatasets(testParams.inputParams.charData, t),
getDatasets(
testParams.inputParams.charData,
t,
testParams.inputParams.useImperialUnits
),
testParams.expected
)
})