diff --git a/app.py b/app.py index f85c3f3..5ba25fe 100644 --- a/app.py +++ b/app.py @@ -404,11 +404,12 @@ def get_exercise_progress_for_user(person_id, exercise_id): max_date = convert_str_to_date(request.args.get( 'max_date'), '%Y-%m-%d') epoch = request.args.get('epoch', default='All') + degree = request.args.get('degree', type=int, default=1) if epoch == 'Custom' and (min_date is None or max_date is None): (min_date, max_date) = db.get_exercise_earliest_and_latest_dates(person_id, exercise_id) - exercise_progress = db.get_exercise_progress_for_user(person_id, exercise_id, min_date, max_date, epoch) + exercise_progress = db.get_exercise_progress_for_user(person_id, exercise_id, min_date, max_date, epoch, degree=degree) if not exercise_progress: abort(404) diff --git a/db.py b/db.py index e3c3777..4e8f8ac 100644 --- a/db.py +++ b/db.py @@ -481,7 +481,7 @@ class DataBase(): 'SELECT exercise_id, name FROM exercise') return exercises - def get_exercise_progress_for_user(self, person_id, exercise_id, min_date=None, max_date=None, epoch='all'): + def get_exercise_progress_for_user(self, person_id, exercise_id, min_date=None, max_date=None, epoch='all', degree=1): today = datetime.now() if epoch == '1M': min_date = today - relativedelta(months=1) @@ -489,6 +489,7 @@ class DataBase(): min_date = today - relativedelta(months=3) elif epoch == '6M': min_date = today - relativedelta(months=6) + # Execute SQL query to fetch topset data for a specific person and exercise topsets = self.execute(""" SELECT @@ -516,13 +517,26 @@ class DataBase(): return None # Extracting values and calculating value ranges for SVG dimensions + exercise_name = topsets[0]['exercise_name'] estimated_1rm = [t['estimated_1rm'] for t in topsets] repetitions = [t['repetitions'] for t in topsets] weight = [t['weight'] for t in topsets] start_dates = [t['start_date'] for t in topsets] messages = [f'{t["repetitions"]} x {t["weight"]}kg ({t["estimated_1rm"]}kg E1RM) on {t["start_date"].strftime("%d %b %y")}' for t in topsets] - exercise_progress = get_exercise_graph_model(topsets[0]['exercise_name'], estimated_1rm, repetitions, weight, start_dates, messages, epoch, person_id, exercise_id, min_date, max_date) + exercise_progress = get_exercise_graph_model( + exercise_name, + estimated_1rm, + repetitions, + weight, + start_dates, + messages, + epoch, + person_id, + exercise_id, + min_date, + max_date, + degree) return exercise_progress diff --git a/templates/partials/sparkline.html b/templates/partials/sparkline.html index e831c3f..c4da7fb 100644 --- a/templates/partials/sparkline.html +++ b/templates/partials/sparkline.html @@ -72,53 +72,129 @@ {% endfor %} {% if selected_epoch == 'Custom' %} -
-
-
- -
-
- -
- -
+
+ +
+ +
+
+
-
- -
-
- -
- -
+
+ + +
+ +
+
+ +
+ +
+
+ + +
+ +
+
+ + + + + +
+ +
+
+
+ {% endif %} {% for plot in plots %} diff --git a/utils.py b/utils.py index 1d5c339..51a026b 100644 --- a/utils.py +++ b/utils.py @@ -13,7 +13,7 @@ def convert_str_to_date(date_str, format='%Y-%m-%d'): except TypeError: return None -def get_exercise_graph_model(title, estimated_1rm, repetitions, weight, start_dates, messages, epoch, person_id, exercise_id, min_date=None, max_date=None): +def get_exercise_graph_model(title, estimated_1rm, repetitions, weight, start_dates, messages, epoch, person_id, exercise_id, min_date=None, max_date=None, degree=1): # Precompute ranges min_date, max_date = min(start_dates), max(start_dates) total_span = (max_date - min_date).days or 1 @@ -47,9 +47,10 @@ def get_exercise_graph_model(title, estimated_1rm, repetitions, weight, start_da best_fit_points = [] try: if len(relative_positions) > 1: # Ensure there are enough points for polyfit - # Calculate line of best fit using NumPy - m, b = np.polyfit(relative_positions, estimated_1rm_scaled, 1) - y_best_fit = m * relative_positions + b + # Fit a polynomial of the given degree + coeffs = np.polyfit(relative_positions, estimated_1rm_scaled, degree) + poly_fit = np.poly1d(coeffs) + y_best_fit = poly_fit(relative_positions) best_fit_points = list(zip(y_best_fit.tolist(), relative_positions.tolist())) else: raise ValueError("Not enough data points for polyfit") @@ -92,7 +93,8 @@ def get_exercise_graph_model(title, estimated_1rm, repetitions, weight, start_da 'person_id': person_id, 'exercise_id': exercise_id, 'min_date': min_date, - 'max_date': max_date + 'max_date': max_date, + 'degree': degree } def get_distinct_colors(n):