Client - display converted distance in stats charts

This commit is contained in:
Sam 2021-11-14 12:26:36 +01:00
parent 1c6b70d454
commit c0acff9e3d
6 changed files with 209 additions and 18 deletions

View File

@ -40,6 +40,10 @@
type: Boolean, type: Boolean,
required: true, required: true,
}, },
useImperialUnits: {
type: Boolean,
required: true,
},
}, },
setup(props) { setup(props) {
const { t } = useI18n() const { t } = useI18n()
@ -80,7 +84,12 @@
ticks: { ticks: {
maxTicksLimit: 6, maxTicksLimit: 6,
callback: function (value) { callback: function (value) {
return formatTooltipValue(props.displayedData, +value, false) return formatTooltipValue(
props.displayedData,
+value,
props.useImperialUnits,
false
)
}, },
}, },
afterFit: function (scale: LayoutItem) { afterFit: function (scale: LayoutItem) {
@ -108,7 +117,12 @@
.reduce((total, value) => getSum(total, value), 0) .reduce((total, value) => getSum(total, value), 0)
return context.datasetIndex === return context.datasetIndex ===
props.displayedSportIds.length - 1 && total > 0 props.displayedSportIds.length - 1 && total > 0
? formatTooltipValue(props.displayedData, total, false) ? formatTooltipValue(
props.displayedData,
total,
props.useImperialUnits,
false
)
: null : null
}, },
}, },
@ -132,7 +146,8 @@
if (context.parsed.y !== null) { if (context.parsed.y !== null) {
label += formatTooltipValue( label += formatTooltipValue(
props.displayedData, props.displayedData,
context.parsed.y context.parsed.y,
props.useImperialUnits
) )
} }
return label return label
@ -144,7 +159,11 @@
}) })
return ( return (
`${t('common.TOTAL')}: ` + `${t('common.TOTAL')}: ` +
formatTooltipValue(props.displayedData, sum) formatTooltipValue(
props.displayedData,
sum,
props.useImperialUnits
)
) )
}, },
}, },

View File

@ -58,6 +58,7 @@
:displayedData="displayedData" :displayedData="displayedData"
:displayedSportIds="displayedSportIds" :displayedSportIds="displayedSportIds"
:fullStats="fullStats" :fullStats="fullStats"
:useImperialUnits="user.imperial_units"
/> />
</div> </div>
</div> </div>
@ -134,7 +135,8 @@
props.user.weekm, props.user.weekm,
props.sports, props.sports,
props.displayedSportIds, props.displayedSportIds,
statistics.value statistics.value,
props.user.imperial_units
) )
) )

View File

@ -25,6 +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'
const dateFormats: Record<string, Record<string, string>> = { const dateFormats: Record<string, Record<string, string>> = {
week: { week: {
@ -94,12 +95,35 @@ export const getDatasets = (displayedSports: ISport[]): TStatisticsDatasets => {
return datasets return datasets
} }
export const convertStatsValue = (
datasetKey: TStatisticsDatasetKeys,
value: number,
useImperialUnits: boolean
): number => {
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
}
default:
case 'nb_workouts':
case 'total_duration':
return value
}
}
export const formatStats = ( export const formatStats = (
params: IStatisticsDateParams, params: IStatisticsDateParams,
weekStartingMonday: boolean, weekStartingMonday: boolean,
sports: ISport[], sports: ISport[],
displayedSportsId: number[], displayedSportsId: number[],
apiStats: TStatisticsFromApi apiStats: TStatisticsFromApi,
useImperialUnits: boolean
): IStatisticsChartData => { ): IStatisticsChartData => {
const dayKeys = getDateKeys(params, weekStartingMonday) const dayKeys = getDateKeys(params, weekStartingMonday)
const dateFormat = dateFormats[params.duration] const dateFormat = dateFormats[params.duration]
@ -123,7 +147,11 @@ export const formatStats = (
apiStats !== {} && apiStats !== {} &&
date in apiStats && date in apiStats &&
sportsId[dataset.label] in apiStats[date] sportsId[dataset.label] in apiStats[date]
? apiStats[date][sportsId[dataset.label]][datasetKey] ? convertStatsValue(
datasetKey,
apiStats[date][sportsId[dataset.label]][datasetKey],
useImperialUnits
)
: 0 : 0
) )
}) })

View File

@ -1,19 +1,23 @@
import { TStatisticsDatasetKeys } from '@/types/statistics' import { TStatisticsDatasetKeys } from '@/types/statistics'
import { formatDuration } from '@/utils/duration' import { formatDuration } from '@/utils/duration'
import { units } from '@/utils/units'
export const formatTooltipValue = ( export const formatTooltipValue = (
displayedData: TStatisticsDatasetKeys, displayedData: TStatisticsDatasetKeys,
value: number, value: number,
useImperialUnits: boolean,
formatWithUnits = true formatWithUnits = true
): string => { ): string => {
const unitFrom = 'km'
const unitTo = useImperialUnits ? units[unitFrom].defaultTarget : unitFrom
switch (displayedData) { switch (displayedData) {
case 'total_duration': case 'total_duration':
return formatDuration(value, formatWithUnits) return formatDuration(value, formatWithUnits)
case 'total_distance': case 'total_distance':
return value.toFixed(2) + ' km' return `${value.toFixed(2)} ${unitTo}`
case 'total_ascent': case 'total_ascent':
case 'total_descent': case 'total_descent':
return (value / 1000).toFixed(2) + ' km' return `${(value / 1000).toFixed(2)} ${unitTo}`
default: default:
return value.toString() return value.toString()
} }

View File

@ -316,7 +316,7 @@ describe('formatStats', () => {
}, },
} }
assert.deepEqual( assert.deepEqual(
formatStats(inputParams, false, sports, [], inputStats), formatStats(inputParams, false, sports, [], inputStats, false),
expected expected
) )
}) })
@ -369,7 +369,7 @@ describe('formatStats', () => {
}, },
} }
assert.deepEqual( assert.deepEqual(
formatStats(inputParams, false, sports, [2], inputStats), formatStats(inputParams, false, sports, [2], inputStats, false),
expected expected
) )
}) })
@ -427,7 +427,7 @@ describe('formatStats', () => {
}, },
} }
assert.deepEqual( assert.deepEqual(
formatStats(inputParams, false, sports, [], inputStats), formatStats(inputParams, false, sports, [], inputStats, false),
expected expected
) )
}) })
@ -515,7 +515,7 @@ describe('formatStats', () => {
}, },
} }
assert.deepEqual( assert.deepEqual(
formatStats(inputParams, false, sports, [1], inputStats), formatStats(inputParams, false, sports, [1], inputStats, false),
expected expected
) )
}) })
@ -605,7 +605,7 @@ describe('formatStats (duration)', () => {
}, },
} }
assert.deepEqual( assert.deepEqual(
formatStats(inputParams, false, sports, [1], inputStats), formatStats(inputParams, false, sports, [1], inputStats, false),
expected expected
) )
}) })
@ -692,7 +692,7 @@ describe('formatStats (duration)', () => {
}, },
} }
assert.deepEqual( assert.deepEqual(
formatStats(inputParams, false, sports, [1], inputStats), formatStats(inputParams, false, sports, [1], inputStats, false),
expected expected
) )
}) })
@ -780,7 +780,7 @@ describe('formatStats (duration)', () => {
}, },
} }
assert.deepEqual( assert.deepEqual(
formatStats(inputParams, false, sports, [1], inputStats), formatStats(inputParams, false, sports, [1], inputStats, false),
expected expected
) )
}) })
@ -868,7 +868,95 @@ describe('formatStats (duration)', () => {
}, },
} }
assert.deepEqual( assert.deepEqual(
formatStats(inputParams, true, sports, [1], inputStats), formatStats(inputParams, true, sports, [1], inputStats, false),
expected
)
})
it('returns datasets after conversion to imperial units', () => {
const inputStats: TStatisticsFromApi = {
'2021-10-03': {
1: {
nb_workouts: 1,
total_distance: 10,
total_duration: 3000,
total_ascent: 150,
total_descent: 100,
},
},
'2021-10-10': {
1: {
nb_workouts: 1,
total_distance: 15,
total_duration: 3500,
total_ascent: 250,
total_descent: 150,
},
2: {
nb_workouts: 2,
total_distance: 20,
total_duration: 3000,
total_ascent: 150,
total_descent: 200,
},
},
'2021-10-17': {
3: {
nb_workouts: 2,
total_distance: 20,
total_duration: 3000,
total_ascent: 100,
total_descent: 100,
},
},
}
const inputParams = {
duration: 'week',
start: new Date('October 03, 2021 00:00:00'),
end: new Date('October 23, 2021 23:59:59.999'),
}
const expected: IStatisticsChartData = {
labels: ['03/10/2021', '10/10/2021', '17/10/2021'],
datasets: {
nb_workouts: [
{
label: 'Cycling (Sport)',
backgroundColor: ['#4c9792'],
data: [1, 1, 0],
},
],
total_distance: [
{
label: 'Cycling (Sport)',
backgroundColor: ['#4c9792'],
data: [6.21, 9.32, 0],
},
],
total_duration: [
{
label: 'Cycling (Sport)',
backgroundColor: ['#4c9792'],
data: [3000, 3500, 0],
},
],
total_ascent: [
{
label: 'Cycling (Sport)',
backgroundColor: ['#4c9792'],
data: [492.13, 820.21, 0],
},
],
total_descent: [
{
label: 'Cycling (Sport)',
backgroundColor: ['#4c9792'],
data: [328.08, 492.13, 0],
},
],
},
}
assert.deepEqual(
formatStats(inputParams, false, sports, [1], inputStats, true),
expected expected
) )
}) })

View File

@ -42,7 +42,56 @@ describe('formatTooltipValue', () => {
assert.equal( assert.equal(
formatTooltipValue( formatTooltipValue(
testParams.inputDisplayedData, testParams.inputDisplayedData,
testParams.inputValue testParams.inputValue,
false
),
testParams.expectedResult
)
})
})
})
describe('formatTooltipValue after conversion to imperial units', () => {
const testsParams = [
{
description: 'returns 30 if input is workouts count',
inputDisplayedData: datasetKeys[0], // 'nb_workouts'
inputValue: 30,
expectedResult: '30',
},
{
description: 'returns 00m:03s if input is total duration',
inputDisplayedData: datasetKeys[1], // 'total_duration'
inputValue: 30,
expectedResult: '00m 30s',
},
{
description: 'returns 30 mi if input is total distance',
inputDisplayedData: datasetKeys[2], // 'total_distance'
inputValue: 30,
expectedResult: '30.00 mi',
},
{
description: 'returns 0.03 mi if input is total ascent',
inputDisplayedData: datasetKeys[3], // 'total_distance'
inputValue: 30,
expectedResult: '0.03 mi',
},
{
description: 'returns 0.03 mi if input is total descent',
inputDisplayedData: datasetKeys[4], // 'total_distance'
inputValue: 30,
expectedResult: '0.03 mi',
},
]
testsParams.map((testParams) => {
it(testParams.description, () => {
assert.equal(
formatTooltipValue(
testParams.inputDisplayedData,
testParams.inputValue,
true
), ),
testParams.expectedResult testParams.expectedResult
) )
@ -90,6 +139,7 @@ describe('formatTooltipValue (formatWithUnits = false)', () => {
formatTooltipValue( formatTooltipValue(
testParams.inputDisplayedData, testParams.inputDisplayedData,
testParams.inputValue, testParams.inputValue,
false,
false false
), ),
testParams.expectedResult testParams.expectedResult