WIP: Add graphs to workouts list view that show reps/weight, still need to refactor logic and dont display unless plot button(Need to add) is checked
This commit is contained in:
28
app.py
28
app.py
@@ -5,7 +5,7 @@ from flask import Flask, render_template, redirect, request, url_for
|
||||
import jinja_partials
|
||||
from decorators import validate_person, validate_topset, validate_workout
|
||||
from db import DataBase
|
||||
from utils import get_people_and_exercise_rep_maxes, convert_str_to_date, get_earliest_and_latest_workout_date, filter_workout_topsets, get_exercise_ids_from_workouts, first_and_last_visible_days_in_month
|
||||
from utils import flatten, get_people_and_exercise_rep_maxes, convert_str_to_date, get_earliest_and_latest_workout_date, filter_workout_topsets, get_exercise_ids_from_workouts, first_and_last_visible_days_in_month
|
||||
from flask_htmx import HTMX
|
||||
import minify_html
|
||||
from urllib.parse import urlparse, unquote, quote
|
||||
@@ -100,6 +100,32 @@ def get_person(person_id):
|
||||
filtered_exercises = filter(
|
||||
lambda e: e['ExerciseId'] in active_exercise_ids, person['Exercises'])
|
||||
person['FilteredExercises'] = list(filtered_exercises)
|
||||
|
||||
# New feature to plot reps and weights over time
|
||||
topsets_with_start_date = flatten([(p['StartDate'], p['TopSets'])
|
||||
for p in person['Workouts']])
|
||||
topsets = flatten([[{**t, 'StartDate': start_date} for t in topsets]
|
||||
for (start_date, topsets) in topsets_with_start_date])
|
||||
|
||||
exercise_graph_view_models = []
|
||||
for exercise_id in active_exercise_ids:
|
||||
topsets_for_exercise = [
|
||||
t for t in topsets if t['ExerciseId'] == exercise_id]
|
||||
if topsets_for_exercise:
|
||||
repitions = [t['Repetitions'] for t in topsets_for_exercise]
|
||||
weights = [t['Weight'] for t in topsets_for_exercise]
|
||||
start_dates = [t['StartDate'].strftime(
|
||||
"%Y-%m-%d") for t in topsets_for_exercise]
|
||||
exercise_view_model = {
|
||||
'ExerciseId': exercise_id,
|
||||
'ExerciseName': topsets_for_exercise[0]['ExerciseName'],
|
||||
'Repititions': repitions[::-1],
|
||||
'Weights': weights[::-1],
|
||||
'StartDates': start_dates[::-1]
|
||||
}
|
||||
exercise_graph_view_models.append(exercise_view_model)
|
||||
person['ExerciseGraphs'] = exercise_graph_view_models
|
||||
|
||||
if htmx:
|
||||
return render_template('partials/page/person.html',
|
||||
person=person, selected_exercise_ids=active_exercise_ids, max_date=max_date, min_date=min_date, tags=tags), 200, {"HX-Trigger": "updatedPeople"}
|
||||
|
||||
@@ -162,9 +162,52 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 mb-4 w-full grid grid-cols-1 2xl:grid-cols-2 gap-4">
|
||||
{% for exercise_graph in person['ExerciseGraphs'] %}
|
||||
<div class="bg-white shadow rounded-lg p-4 sm:p-6 xl:p-8 ">
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="flex-shrink-0">
|
||||
<span class="text-2xl sm:text-3xl leading-none font-bold text-gray-900">{{
|
||||
exercise_graph['ExerciseName'] }}</span>
|
||||
</div>
|
||||
<div id="e-{{ exercise_graph['ExerciseId'] }}"></div>
|
||||
<script>
|
||||
Plotly.newPlot("e-{{ exercise_graph['ExerciseId'] }}", [
|
||||
{
|
||||
x: {{ exercise_graph['StartDates'] | replace('"', "'") | safe }},
|
||||
y: {{ exercise_graph['Repititions'] | replace('"', "'") | safe }},
|
||||
name: 'Reps',
|
||||
type: 'scatter'
|
||||
},
|
||||
{
|
||||
x: {{ exercise_graph['StartDates'] | replace('"', "'") | safe }},
|
||||
y: {{ exercise_graph['Weights'] | replace('"', "'") | safe }},
|
||||
name: 'Weight',
|
||||
yaxis: 'y2',
|
||||
type: 'scatter'
|
||||
}
|
||||
],
|
||||
{
|
||||
title: '{{ exercise_graph['ExerciseName'] }}}',
|
||||
margin: { t: 0 },
|
||||
xaxis: { type: 'date', showgrid: false },
|
||||
yaxis: { title: 'Reps', showgrid: false },
|
||||
yaxis2: {
|
||||
title: 'Weight',
|
||||
overlaying: 'y',
|
||||
side: 'right', showgrid: false
|
||||
}
|
||||
}, config);
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{{ render_partial('partials/stats.html', stats=person['Stats']) }}
|
||||
|
||||
<button
|
||||
|
||||
13
utils.py
13
utils.py
@@ -170,3 +170,16 @@ def first_and_last_visible_days_in_month(first_day_of_month, last_day_of_month):
|
||||
end_date = last_day_of_month + \
|
||||
timedelta(days=end[last_day_of_month.weekday()])
|
||||
return (start_date, end_date)
|
||||
|
||||
|
||||
def flatten(lst):
|
||||
"""
|
||||
Flatten a list of lists.
|
||||
"""
|
||||
result = []
|
||||
for item in lst:
|
||||
if isinstance(item, list):
|
||||
result.extend(flatten(item))
|
||||
else:
|
||||
result.append(item)
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user