Add title to user overview graphs
This commit is contained in:
39
app.py
39
app.py
@@ -239,7 +239,10 @@ def graph_user_workouts(user_id):
|
|||||||
|
|
||||||
period = request.args.get('period', default='day', type=str)
|
period = request.args.get('period', default='day', type=str)
|
||||||
|
|
||||||
return plot_averaged_attributes(workouts, start_date, end_date, period, attributes)
|
user_data = generate_user_data(user)
|
||||||
|
title = f'{format_key_values(user_data["attributes"], attributes)} over {get_value_from_key(user_data["periods"], period)}'
|
||||||
|
|
||||||
|
return plot_averaged_attributes(workouts, start_date, end_date, period, attributes, title)
|
||||||
|
|
||||||
|
|
||||||
def daterange(start_date, end_date, delta=timedelta(days=1)):
|
def daterange(start_date, end_date, delta=timedelta(days=1)):
|
||||||
@@ -299,7 +302,7 @@ def average_workout_attributes_per_period(workouts, start_date, end_date, period
|
|||||||
return dict(results)
|
return dict(results)
|
||||||
|
|
||||||
|
|
||||||
def create_user_graph(x_values, y_data, filename, x_label='Time'):
|
def create_user_graph(x_values, y_data, filename, x_label='Time', title=None):
|
||||||
"""Create a graph for given x-values and y-values.
|
"""Create a graph for given x-values and y-values.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
@@ -307,12 +310,17 @@ def create_user_graph(x_values, y_data, filename, x_label='Time'):
|
|||||||
- y_data: A dictionary where key is y_label and value is list of y-values.
|
- y_data: A dictionary where key is y_label and value is list of y-values.
|
||||||
- filename: Name for the generated file.
|
- filename: Name for the generated file.
|
||||||
- x_label: Label for x-axis.
|
- x_label: Label for x-axis.
|
||||||
|
- title: Title for the plot.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
- Flask Response object containing the image of the graph.
|
- Flask Response object containing the image of the graph.
|
||||||
"""
|
"""
|
||||||
fig, ax = plt.subplots()
|
fig, ax = plt.subplots()
|
||||||
|
|
||||||
|
# Set the title if provided
|
||||||
|
if title:
|
||||||
|
ax.set_title(title)
|
||||||
|
|
||||||
# Plotting multiple lines
|
# Plotting multiple lines
|
||||||
for y_label, y_values in y_data.items():
|
for y_label, y_values in y_data.items():
|
||||||
ax.plot(x_values, y_values, label=y_label)
|
ax.plot(x_values, y_values, label=y_label)
|
||||||
@@ -335,7 +343,7 @@ def create_user_graph(x_values, y_data, filename, x_label='Time'):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def plot_averaged_attributes(workouts_list, start_date, end_date, period, attributes):
|
def plot_averaged_attributes(workouts_list, start_date, end_date, period, attributes, title):
|
||||||
"""Creates a graph for averaged attributes over a period.
|
"""Creates a graph for averaged attributes over a period.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
@@ -359,7 +367,7 @@ def plot_averaged_attributes(workouts_list, start_date, end_date, period, attrib
|
|||||||
for date in x_values]
|
for date in x_values]
|
||||||
|
|
||||||
# Creating the graph
|
# Creating the graph
|
||||||
return create_user_graph(x_values, y_data, filename=f"average_attributes_over_{period}")
|
return create_user_graph(x_values, y_data, filename=f"average_attributes_over_{period}", title=title)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/user/<int:user_id>/workout/<int:workout_id>/<string:graph_type>', methods=['GET'])
|
@app.route('/user/<int:user_id>/workout/<int:workout_id>/<string:graph_type>', methods=['GET'])
|
||||||
@@ -471,7 +479,7 @@ def generate_user_data(user, workouts=[]):
|
|||||||
'daily_duration_sparkline': generate_daily_duration_sparkline(workouts),
|
'daily_duration_sparkline': generate_daily_duration_sparkline(workouts),
|
||||||
'calendar_month': generate_calendar_monthly_view(workouts, datetime.now().date()),
|
'calendar_month': generate_calendar_monthly_view(workouts, datetime.now().date()),
|
||||||
'attributes': [('workout_count', 'Workout count'), ('duration', 'Duration'), ('average_rpm', 'Average RPM'), ('average_bpm', 'Average BPM'), ('distance', 'Distance'), ('calories', 'Calories')],
|
'attributes': [('workout_count', 'Workout count'), ('duration', 'Duration'), ('average_rpm', 'Average RPM'), ('average_bpm', 'Average BPM'), ('distance', 'Distance'), ('calories', 'Calories')],
|
||||||
'periods': ['day', 'week', 'month'],
|
'periods': [('day', 'Day'), ('week', 'Week'), ('month', 'Month')],
|
||||||
'first_workout_date': workouts[-1]['start_time_date'] if workouts else None,
|
'first_workout_date': workouts[-1]['start_time_date'] if workouts else None,
|
||||||
'last_workout_date': workouts[0]['start_time_date'] if workouts else None,
|
'last_workout_date': workouts[0]['start_time_date'] if workouts else None,
|
||||||
}
|
}
|
||||||
@@ -622,8 +630,7 @@ def generate_calendar_monthly_view(workouts, selected_date):
|
|||||||
start_date, end_date = get_month_bounds(selected_date)
|
start_date, end_date = get_month_bounds(selected_date)
|
||||||
|
|
||||||
# Build a lookup dictionary for faster access
|
# Build a lookup dictionary for faster access
|
||||||
workout_lookup = {w['start_time_date']
|
workout_lookup = {w['start_time_date'] : w for w in workouts if start_date <= w['start_time_date'] <= end_date}
|
||||||
: w for w in workouts if start_date <= w['start_time_date'] <= end_date}
|
|
||||||
|
|
||||||
current_date = datetime.now().date()
|
current_date = datetime.now().date()
|
||||||
days_of_month = [
|
days_of_month = [
|
||||||
@@ -684,6 +691,24 @@ def toDate(dateString):
|
|||||||
return datetime.strptime(dateString, "%Y-%m-%d").date()
|
return datetime.strptime(dateString, "%Y-%m-%d").date()
|
||||||
|
|
||||||
|
|
||||||
|
def get_value_from_key(tuples_list, key):
|
||||||
|
for k, v in tuples_list:
|
||||||
|
if k == key:
|
||||||
|
return v
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def format_key_values(tuples_list, keys_list):
|
||||||
|
values = [get_value_from_key(tuples_list, key) for key in keys_list]
|
||||||
|
|
||||||
|
if len(values) == 1:
|
||||||
|
return values[0]
|
||||||
|
elif len(values) == 2:
|
||||||
|
return f"{values[0]} & {values[1]}"
|
||||||
|
else:
|
||||||
|
return ', '.join(values[:-1]) + f" & {values[-1]}"
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Bind to PORT if defined, otherwise default to 5000.
|
# Bind to PORT if defined, otherwise default to 5000.
|
||||||
port = int(os.environ.get('PORT', 5000))
|
port = int(os.environ.get('PORT', 5000))
|
||||||
|
|||||||
@@ -72,8 +72,8 @@
|
|||||||
te.Select.getOrCreateInstance(me).setValue({{ ['week'] }})
|
te.Select.getOrCreateInstance(me).setValue({{ ['week'] }})
|
||||||
end">
|
end">
|
||||||
|
|
||||||
{% for p in user.periods %}
|
{% for val,name in user.periods %}
|
||||||
<option value="{{ p }}">{{ p }}</option>
|
<option value="{{ val }}">{{ name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user