[Client] statistics - display average speed in chart

This commit is contained in:
Sam
2021-11-24 18:01:38 +01:00
parent fb127b22c4
commit bd0d79f575
8 changed files with 244 additions and 35 deletions

View File

@ -77,7 +77,7 @@
},
},
y: {
stacked: true,
stacked: props.displayedData !== 'average_speed',
grid: {
drawOnChartArea: false,
},
@ -101,29 +101,50 @@
datalabels: {
anchor: 'end',
align: 'end',
color: function (context) {
return props.displayedData === 'average_speed' &&
context.dataset.backgroundColor
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
context.dataset.backgroundColor[0]
: '#666666'
},
rotation: function (context) {
return props.fullStats && context.chart.chartArea.width < 580
? 310
: 0
},
display: function (context) {
return !(props.fullStats && context.chart.chartArea.width < 300)
return props.fullStats && context.chart.chartArea.width < 300
? false
: props.displayedData === 'average_speed'
? 'auto'
: true
},
formatter: function (value, context) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const total: number = context.chart.data.datasets
.map((d) => d.data[context.dataIndex])
.reduce((total, value) => getSum(total, value), 0)
return context.datasetIndex ===
props.displayedSportIds.length - 1 && total > 0
? formatTooltipValue(
props.displayedData,
total,
props.useImperialUnits,
false
)
: null
if (props.displayedData === 'average_speed') {
return formatTooltipValue(
props.displayedData,
value,
props.useImperialUnits,
false
)
} else {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const total: number = context.chart.data.datasets
.map((d) => d.data[context.dataIndex])
.reduce((total, value) => getSum(total, value), 0)
return context.datasetIndex ===
props.displayedSportIds.length - 1 && total > 0
? formatTooltipValue(
props.displayedData,
total,
props.useImperialUnits,
false
)
: null
}
},
},
legend: {
@ -133,6 +154,8 @@
interaction: {
intersect: true,
mode: 'index',
position:
props.displayedData === 'average_speed' ? 'nearest' : 'average',
},
filter: function (tooltipItem) {
return tooltipItem.formattedValue !== '0'
@ -153,6 +176,9 @@
return label
},
footer: function (tooltipItems) {
if (props.displayedData === 'average_speed') {
return ''
}
let sum = 0
tooltipItems.map((tooltipItem) => {
sum += tooltipItem.parsed.y

View File

@ -32,6 +32,15 @@
/>
{{ $t('workouts.WORKOUT', 2) }}
</label>
<label v-if="fullStats">
<input
type="radio"
name="average_speed"
:checked="displayedData === 'average_speed'"
@click="updateDisplayData"
/>
{{ $t('workouts.AVERAGE_SPEED') }}
</label>
<label v-if="fullStats">
<input
type="radio"

View File

@ -4,6 +4,8 @@ export interface IChartDataset {
borderColor?: string[]
borderWidth?: number
fill?: boolean
data: number[]
data: (number | null)[]
yAxisID?: string
type?: string
spanGaps?: boolean
}

View File

@ -19,6 +19,7 @@ export interface IStatisticsDateParams {
}
export type TStatisticsDatasetKeys =
| 'average_speed'
| 'nb_workouts'
| 'total_duration'
| 'total_distance'

View File

@ -43,6 +43,7 @@ const dateFormats: Record<string, Record<string, string>> = {
}
export const datasetKeys: TStatisticsDatasetKeys[] = [
'average_speed',
'nb_workouts',
'total_duration',
'total_distance',
@ -67,17 +68,25 @@ export const getDateKeys = (
const getStatisticsChartDataset = (
sportLabel: string,
color: string
color: string,
isLineChart = false
): IChartDataset => {
return {
const dataset: IChartDataset = {
label: sportLabel,
backgroundColor: [color],
data: [],
}
if (isLineChart) {
dataset.type = 'line'
dataset.borderColor = [color]
dataset.spanGaps = true
}
return dataset
}
export const getDatasets = (displayedSports: ISport[]): TStatisticsDatasets => {
const datasets: TStatisticsDatasets = {
average_speed: [],
nb_workouts: [],
total_distance: [],
total_duration: [],
@ -86,6 +95,9 @@ export const getDatasets = (displayedSports: ISport[]): TStatisticsDatasets => {
}
displayedSports.map((sport) => {
const color = sport.color ? sport.color : sportColors[sport.label]
datasets.average_speed.push(
getStatisticsChartDataset(sport.label, color, true)
)
datasets.nb_workouts.push(getStatisticsChartDataset(sport.label, color))
datasets.total_distance.push(getStatisticsChartDataset(sport.label, color))
datasets.total_duration.push(getStatisticsChartDataset(sport.label, color))
@ -101,11 +113,12 @@ export const convertStatsValue = (
useImperialUnits: boolean
): number => {
switch (datasetKey) {
case 'average_speed':
case 'total_distance':
case 'total_ascent':
case 'total_descent':
return convertStatsDistance(
datasetKey === 'total_distance' ? 'km' : 'm',
['average_speed', 'total_distance'].includes(datasetKey) ? 'km' : 'm',
value,
useImperialUnits
)
@ -151,6 +164,8 @@ export const formatStats = (
apiStats[date][sportsId[dataset.label]][datasetKey],
useImperialUnits
)
: datasetKey === 'average_speed'
? null
: 0
)
})

View File

@ -11,6 +11,8 @@ export const formatTooltipValue = (
const unitFrom = 'km'
const unitTo = useImperialUnits ? units[unitFrom].defaultTarget : unitFrom
switch (displayedData) {
case 'average_speed':
return `${value.toFixed(2)} ${unitTo}/h`
case 'total_duration':
return formatDuration(value, formatWithUnits)
case 'total_distance':