diff --git a/features/person_overview.py b/features/person_overview.py index 9851cee..afc955f 100644 --- a/features/person_overview.py +++ b/features/person_overview.py @@ -1,4 +1,7 @@ +from utils import calculate_estimated_1rm, get_exercise_graph_model + + class PersonOverview: def __init__(self, db_connection_method): self.execute = db_connection_method @@ -111,7 +114,7 @@ class PersonOverview: result = self.execute(sql_query, params) if not result: - return {"person_id": person_id, "person_name": None, "workouts": [], "selected_exercises": []} + return {"person_id": person_id, "person_name": None, "workouts": [], "selected_exercises": [], "exercise_progress_graphs": []} # Extract person info from the first row person_info = {"person_id": result[0]["person_id"], "person_name": result[0]["person_name"]} @@ -131,6 +134,9 @@ class PersonOverview: workouts = [] workout_map = {} # Map to track workouts + # Initialize the exercise sets dictionary + exercise_sets = {exercise["id"]: {"exercise_id": exercise["id"], "name": exercise["name"], "sets": []} for exercise in exercises} + for row in result: workout_id = row["workout_id"] @@ -145,16 +151,77 @@ class PersonOverview: # Add topset to the corresponding exercise if row["exercise_id"] and row["topset_id"]: + # Add to workout exercises workout_map[workout_id]["exercises"][row["exercise_id"]].append({ "repetitions": row["repetitions"], "weight": row["weight"] }) + # Add to the exercise sets dictionary with workout start date + exercise_sets[row["exercise_id"]]["sets"].append({ + "repetitions": row["repetitions"], + "weight": row["weight"], + "estimated_1rm": calculate_estimated_1rm(row["weight"], row["repetitions"]), + "workout_start_date": row["start_date"], + "exercise_name": row["exercise_name"] + }) + # Transform into a list of rows for workout_id, workout in workout_map.items(): workouts.append(workout) + + exercise_progress_graphs = self.generate_exercise_progress_graphs(person_info["person_id"], exercise_sets) + + return { + **person_info, + "workouts": workouts, + "selected_exercises": exercises, + "exercise_progress_graphs": exercise_progress_graphs + } + + def generate_exercise_progress_graphs(self, person_id, exercise_sets): + exercise_progress_graphs = [] + + for exercise_id, exercise_data in exercise_sets.items(): + # Sort the sets by start date in descending order + sorted_exercise_sets = sorted(exercise_data["sets"], key=lambda t: t["workout_start_date"], reverse=True) + + # Extract the required data + estimated_1rm = [t["estimated_1rm"] for t in sorted_exercise_sets] + repetitions = [t["repetitions"] for t in sorted_exercise_sets] + weight = [t["weight"] for t in sorted_exercise_sets] + start_dates = [t["workout_start_date"] for t in sorted_exercise_sets] + messages = [ + f'{t["repetitions"]} x {t["weight"]}kg ({t["estimated_1rm"]}kg E1RM) on {t["workout_start_date"].strftime("%d %b %y")}' + for t in sorted_exercise_sets + ] + epoch = "All" + exercise_name = sorted_exercise_sets[0]["exercise_name"] + + # Check for valid data before generating the graph + if exercise_name and estimated_1rm and repetitions and weight and start_dates and messages: + exercise_progress = get_exercise_graph_model( + title=exercise_name, + estimated_1rm=estimated_1rm, + repetitions=repetitions, + weight=weight, + start_dates=start_dates, + messages=messages, + epoch=epoch, + person_id=person_id, + exercise_id=exercise_id, + ) + + # Append the generated graph model to the list + exercise_progress_graphs.append({ + "exercise_id": exercise_id, + "exercise_name": exercise_name, + "progress_graph": exercise_progress + }) + + return exercise_progress_graphs + - return {**person_info, "workouts": workouts, "selected_exercises": exercises} diff --git a/templates/person_overview.html b/templates/person_overview.html index af1d9fd..8fd729c 100644 --- a/templates/person_overview.html +++ b/templates/person_overview.html @@ -94,6 +94,12 @@ {{ render_partial('partials/tags.html',person_id=person_id, tags=tags) }} +
+ {% for graph in exercise_progress_graphs %} + {{ render_partial('partials/sparkline.html', **graph.progress_graph) }} + {% endfor %} +
+
diff --git a/utils.py b/utils.py index fd98032..83c1d60 100644 --- a/utils.py +++ b/utils.py @@ -469,3 +469,10 @@ def generate_plot(df, title): # Convert Plotly figure to HTML div plot_div = pio.to_html(fig, full_html=False) return plot_div + +def calculate_estimated_1rm(weight, repetitions): + # Ensure the inputs are numeric + if repetitions == 0: # Avoid division by zero + return 0 + estimated_1rm = round((100 * int(weight)) / (101.3 - 2.67123 * repetitions), 0) + return int(estimated_1rm) \ No newline at end of file