Add elevation in stats and dashboard and update translations

This commit is contained in:
antoine 2021-08-20 07:35:50 +02:00 committed by Sam
parent e7708b9ece
commit 660190d368
11 changed files with 112 additions and 13 deletions

View File

@ -67,6 +67,8 @@ def get_workouts(
'nb_workouts': 0, 'nb_workouts': 0,
'total_distance': 0.0, 'total_distance': 0.0,
'total_duration': 0, 'total_duration': 0,
'total_ascent': 0.0,
'total_descent': 0.0,
} }
workouts_list_by_sport[sport_id]['nb_workouts'] += 1 workouts_list_by_sport[sport_id]['nb_workouts'] += 1
workouts_list_by_sport[sport_id]['total_distance'] += float( workouts_list_by_sport[sport_id]['total_distance'] += float(
@ -75,6 +77,12 @@ def get_workouts(
workouts_list_by_sport[sport_id][ workouts_list_by_sport[sport_id][
'total_duration' 'total_duration'
] += convert_timedelta_to_integer(workout.moving) ] += convert_timedelta_to_integer(workout.moving)
workouts_list_by_sport[sport_id]['total_ascent'] += float(
workout.ascent
)
workouts_list_by_sport[sport_id]['total_descent'] += float(
workout.descent
)
# filter_type == 'by_time' # filter_type == 'by_time'
else: else:
@ -110,6 +118,8 @@ def get_workouts(
'nb_workouts': 0, 'nb_workouts': 0,
'total_distance': 0.0, 'total_distance': 0.0,
'total_duration': 0, 'total_duration': 0,
'total_ascent': 0.0,
'total_descent': 0.0,
} }
workouts_list_by_time[time_period][sport_id][ workouts_list_by_time[time_period][sport_id][
'nb_workouts' 'nb_workouts'
@ -120,7 +130,14 @@ def get_workouts(
workouts_list_by_time[time_period][sport_id][ workouts_list_by_time[time_period][sport_id][
'total_duration' 'total_duration'
] += convert_timedelta_to_integer(workout.moving) ] += convert_timedelta_to_integer(workout.moving)
if workout.ascent:
workouts_list_by_time[time_period][sport_id][
'total_ascent'
] += float(workout.ascent / 1000)
if workout.descent:
workouts_list_by_time[time_period][sport_id][
'total_descent'
] += float(workout.descent / 1000)
return { return {
'status': 'success', 'status': 'success',
'data': { 'data': {

View File

@ -53,6 +53,24 @@ export default class StatsCharts extends React.PureComponent {
/> />
{t('statistics:duration')} {t('statistics:duration')}
</label> </label>
<label className="radioLabel col">
<input
type="radio"
name="ascent"
checked={displayedData === 'ascent'}
onChange={e => this.handleRadioChange(e)}
/>
{t('statistics:ascent')}
</label>
<label className="radioLabel col">
<input
type="radio"
name="descent"
checked={displayedData === 'descent'}
onChange={e => this.handleRadioChange(e)}
/>
{t('statistics:descent')}
</label>
<label className="radioLabel col"> <label className="radioLabel col">
<input <input
type="radio" type="radio"

View File

@ -43,7 +43,25 @@ export default function WorkoutCard(props) {
)} )}
<i className="fa fa-road" aria-hidden="true" />{' '} <i className="fa fa-road" aria-hidden="true" />{' '}
{t('workouts:Distance')}: {workout.distance} km {t('workouts:Distance')}: {workout.distance} km
<br />
</p> </p>
{workout.min_alt && workout.max_alt && (
<p>
<i className="fi-mountains custom-fa" />
{t('workouts:Min. altitude')}: {workout.min_alt}m
<br />
{t('workouts:Max. altitude')}: {workout.max_alt}m
<br />
</p>
)}
{workout.ascent && workout.descent && (
<p>
<i className="fa fa-location-arrow custom-fa" />
{t('workouts:Ascent')}: {workout.ascent}m
<br />
{t('workouts:Descent')}: {workout.descent}m
</p>
)}
</div> </div>
</div> </div>
</div> </div>

View File

@ -21,6 +21,8 @@ export default class WorkoutsList extends React.PureComponent {
<th scope="col">{t('workouts:Duration')}</th> <th scope="col">{t('workouts:Duration')}</th>
<th scope="col">{t('workouts:Ave. speed')}</th> <th scope="col">{t('workouts:Ave. speed')}</th>
<th scope="col">{t('workouts:Max. speed')}</th> <th scope="col">{t('workouts:Max. speed')}</th>
<th scope="col">{t('workouts:Ascent')}</th>
<th scope="col">{t('workouts:Descent')}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -85,6 +87,18 @@ export default class WorkoutsList extends React.PureComponent {
</span> </span>
{workout.max_speed} km/h {workout.max_speed} km/h
</td> </td>
<td className="text-right">
<span className="heading-span-absolute">
{t('workouts:Ascent')}
</span>
{workout.ascent} m
</td>
<td className="text-right">
<span className="heading-span-absolute">
{t('workouts:Descent')}
</span>
{workout.descent} m
</td>
</tr> </tr>
))} ))}
</tbody> </tbody>

View File

@ -3,6 +3,11 @@
"Cycling (Transport)": "Cycling (Transport)", "Cycling (Transport)": "Cycling (Transport)",
"Hiking": "Hiking", "Hiking": "Hiking",
"Mountain Biking": "Mountain Biking", "Mountain Biking": "Mountain Biking",
"Mountain Biking (Electric)": "Mountain Biking (Electric)",
"Running": "Running", "Running": "Running",
"Walking": "Walking" "Walking": "Walking",
"Trail" : "Trail",
"Skiing (Alpine)" : "Skiing (Alpine)",
"Skiing (Cross Country)" : "Skiing (Cross Country)",
"Rowing" : "Rowing"
} }

View File

@ -2,6 +2,8 @@
"workouts": "workouts", "workouts": "workouts",
"distance": "distance", "distance": "distance",
"duration": "duration", "duration": "duration",
"ascent": "ascent",
"descent": "descent",
"month": "month", "month": "month",
"Statistics": "Statistics", "Statistics": "Statistics",
"year": "year", "year": "year",

View File

@ -3,6 +3,11 @@
"Cycling (Transport)": "Vélo (Transport)", "Cycling (Transport)": "Vélo (Transport)",
"Hiking": "Randonnée", "Hiking": "Randonnée",
"Mountain Biking": "VTT", "Mountain Biking": "VTT",
"Mountain Biking (Electric)": "VTT (Electrique)",
"Running": "Course", "Running": "Course",
"Walking": "Marche" "Walking": "Marche",
"Trail" : "Trail",
"Skiing (Alpine)" : "Ski (Alpin)",
"Skiing (Cross Country)" : "Ski (Randonnée)",
"Rowing" : "Aviron"
} }

View File

@ -2,6 +2,8 @@
"workouts": "séances", "workouts": "séances",
"distance": "distance", "distance": "distance",
"duration": "durée", "duration": "durée",
"ascent": "dénivelé+",
"descent": "dénivelé-",
"month": "mois", "month": "mois",
"Statistics": "Statistiques", "Statistics": "Statistiques",
"year": "année", "year": "année",

View File

@ -5,13 +5,13 @@
"Add a workout": "Ajouter une séance", "Add a workout": "Ajouter une séance",
"Are you sure you want to delete this workout?": "Etes-vous sûr de vouloir supprimer cette séance ?", "Are you sure you want to delete this workout?": "Etes-vous sûr de vouloir supprimer cette séance ?",
"Ave. speed": "Vitesse moyenne", "Ave. speed": "Vitesse moyenne",
"Ascent": "Dénivelé positif", "Ascent": "Dénivelé +",
"Average speed": "Vitesse moyenne", "Average speed": "Vitesse moyenne",
"Chart": "Analyse", "Chart": "Analyse",
"data from gpx, without any cleaning": "données issues du fichier gpx, sans correction", "data from gpx, without any cleaning": "données issues du fichier gpx, sans correction",
"Date": "Date", "Date": "Date",
"Delete workout": "Supprimer l'séance", "Delete workout": "Supprimer l'séance",
"Descent": "Dénivelé négatif", "Descent": "Dénivelé -",
"Distance": "Distance", "Distance": "Distance",
"distance": "distance", "distance": "distance",
"Duration": "Durée", "Duration": "Durée",

View File

@ -39,6 +39,10 @@ export const formatValue = (displayedData, value) =>
? `${value.toFixed(2)} km` ? `${value.toFixed(2)} km`
: displayedData === 'duration' : displayedData === 'duration'
? formatDuration(value) ? formatDuration(value)
: displayedData === 'ascent'
? `${value.toFixed(2)} km`
: displayedData === 'descent'
? `${value.toFixed(2)} km`
: value : value
const dateIncrement = (duration, day) => { const dateIncrement = (duration, day) => {
@ -69,6 +73,8 @@ export const formatStats = (stats, sports, params, displayedSports, weekm) => {
const nbWorkoutsStats = [] const nbWorkoutsStats = []
const distanceStats = [] const distanceStats = []
const durationStats = [] const durationStats = []
const ascentStats = []
const descentStats = []
for ( for (
let day = startDate(params.duration, params.start, weekm); let day = startDate(params.duration, params.start, weekm);
@ -83,6 +89,8 @@ export const formatStats = (stats, sports, params, displayedSports, weekm) => {
const dataNbWorkouts = { date: xAxis } const dataNbWorkouts = { date: xAxis }
const dataDistance = { date: xAxis } const dataDistance = { date: xAxis }
const dataDuration = { date: xAxis } const dataDuration = { date: xAxis }
const dataAscent = { date: xAxis }
const dataDescent = { date: xAxis }
if (stats[date]) { if (stats[date]) {
Object.keys(stats[date]) Object.keys(stats[date])
@ -94,17 +102,23 @@ export const formatStats = (stats, sports, params, displayedSports, weekm) => {
dataNbWorkouts[sportLabel] = stats[date][sportId].nb_workouts dataNbWorkouts[sportLabel] = stats[date][sportId].nb_workouts
dataDistance[sportLabel] = stats[date][sportId].total_distance dataDistance[sportLabel] = stats[date][sportId].total_distance
dataDuration[sportLabel] = stats[date][sportId].total_duration dataDuration[sportLabel] = stats[date][sportId].total_duration
dataAscent[sportLabel] = stats[date][sportId].total_ascent
dataDescent[sportLabel] = stats[date][sportId].total_descent
return null return null
}) })
} }
nbWorkoutsStats.push(dataNbWorkouts) nbWorkoutsStats.push(dataNbWorkouts)
distanceStats.push(dataDistance) distanceStats.push(dataDistance)
durationStats.push(dataDuration) durationStats.push(dataDuration)
ascentStats.push(dataAscent)
descentStats.push(dataDescent)
} }
return { return {
workouts: nbWorkoutsStats, workouts: nbWorkoutsStats,
distance: distanceStats, distance: distanceStats,
duration: durationStats, duration: durationStats,
ascent: ascentStats,
descent: descentStats,
} }
} }

View File

@ -4,13 +4,17 @@ import togeojson from '@mapbox/togeojson'
import { getDateWithTZ } from './index' import { getDateWithTZ } from './index'
export const workoutColors = [ export const workoutColors = [
'#55a8a3', '#F94144',
'#98C3A9', '#F3722C',
'#D0838A', '#F8961E',
'#ECC77E', '#F9844A',
'#926692', '#F9C74F',
'#929292', '#90BE6D',
'#428bca', '#43AA8B',
'#4D908E',
'#577590',
'#277DA1',
'#272DA1',
] ]
export const recordsLabels = [ export const recordsLabels = [