Client - display converted distance in stats charts
This commit is contained in:
parent
1c6b70d454
commit
c0acff9e3d
@ -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
|
||||||
|
)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user