From 68d238b9625fba2964075825b1932acfb27281ef Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Tue, 5 May 2020 16:08:58 +0200
Subject: [PATCH] adding first pie chart
---
rowers/interactiveplots.py | 74 +++++++++++++++++++++++++++++++++++
rowers/templates/history.html | 70 +++++++++++++++++++++++++++++++--
rowers/views/analysisviews.py | 68 +++++++++++++++++++++++++++++++-
rowers/views/workoutviews.py | 2 +-
4 files changed, 209 insertions(+), 5 deletions(-)
diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py
index ad8e6ba7..a714f4d5 100644
--- a/rowers/interactiveplots.py
+++ b/rowers/interactiveplots.py
@@ -169,6 +169,80 @@ def tailwind(bearing,vwind,winddir):
from rowers.dataprep import nicepaceformat,niceformat
from rowers.dataprep import timedeltaconv
+from math import pi
+
+def interactive_hr_piechart(df,rower,title):
+
+ df.sort_values(by='hr',inplace=True)
+ qry = 'hr < {ut2}'.format(ut2=rower.ut2)
+ frac_lut2 = len(df.query(qry))/len(df)
+
+ qry = 'hr < {ut1}'.format(ut1=rower.ut1,ut2=rower.ut2)
+ frac_ut2 = len(df.query(qry))/len(df)
+
+ qry = 'hr < {at}'.format(ut1=rower.ut1,at=rower.at)
+ frac_ut1 = len(df.query(qry))/len(df)
+
+ qry = 'hr < {tr}'.format(at=rower.at,tr=rower.tr)
+ frac_at = len(df.query(qry))/len(df)
+
+ qry = 'hr < {an}'.format(tr=rower.tr,an=rower.an)
+ frac_tr = len(df.query(qry))/len(df)
+
+ frac_an = 1.
+
+ source_starts = 2*pi*pd.Series([
+ 0,
+ frac_lut2,
+ frac_ut2,
+ frac_ut1,
+ frac_at,
+ frac_tr,
+ ])
+
+ source_ends = 2*pi*pd.Series([
+ frac_lut2,
+ frac_ut2,
+ frac_ut1,
+ frac_at,
+ frac_tr,
+ frac_an,
+ ])
+
+ source_legends = [
+ 'History
- -
-
Future Functionality
+
+ -
+
All workouts
- Watch this space
+
+
+
+
+ | Total Distance | {{ totalsdict|lookup:"distance"}} meters |
+
+
+ | Total Duration | {{ totalsdict|lookup:"duration"}} hours |
+
+
+ | Number of workouts | {{ totalsdict|lookup:"nrworkouts"}} |
+
+
+ | Average heart rate | {{ totalsdict|lookup:"hrmean"}} bpm |
+
+
+ | Maximum heart rate | {{ totalsdict|lookup:"hrmax"}} bpm |
+
+
+ | Average power | {{ totalsdict|lookup:"powermean"}} W |
+
+
+ | Maximum power | {{ totalsdict|lookup:"powermax"}} W |
+
+
+
+
+
+ {{ totalscript|safe }}{{ totaldiv|safe }}
+
+ {% for ddict in typedicts %}
+
+ {{ ddict|lookup:"wtype"}}
+
+
+
+
+
+ | Total Distance | {{ ddict|lookup:"distance"}} meters |
+
+
+ | Total Duration | {{ ddict|lookup:"duration"}} hours |
+
+
+ | Number of workouts | {{ ddict|lookup:"nrworkouts"}} |
+
+
+ | Average heart rate | {{ ddict|lookup:"hrmean"}} bpm |
+
+
+ | Maximum heart rate | {{ ddict|lookup:"hrmax"}} bpm |
+
+
+ | Average power | {{ ddict|lookup:"powermean"}} W |
+
+
+ | Maximum power | {{ ddict|lookup:"powermax"}} W |
+
+
+
+
+
+ {% endfor %}
{% endblock %}
diff --git a/rowers/views/analysisviews.py b/rowers/views/analysisviews.py
index 2a70d01d..c21ca7b1 100644
--- a/rowers/views/analysisviews.py
+++ b/rowers/views/analysisviews.py
@@ -4654,6 +4654,68 @@ class AlertDelete(DeleteView):
@login_required()
def history_view(request,userid=0):
r = getrequestrower(request,userid=userid)
+ usertimezone = pytz.timezone(r.defaulttimezone)
+
+ activity_enddate = timezone.now()
+ activity_enddate = activity_enddate.replace(hour=23,minute=59,second=59).astimezone(usertimezone)
+ activity_startdate = activity_enddate-datetime.timedelta(days=15)
+ activity_startdate = activity_startdate.replace(hour=0,minute=0,second=0)
+
+ g_workouts = Workout.objects.filter(
+ user=r,
+ startdatetime__gte=activity_startdate,
+ startdatetime__lte=activity_enddate,
+ duplicate=False,
+ privacy='visible'
+ ).order_by("-startdatetime")
+
+ ids = [w.id for w in g_workouts]
+
+ columns = ['hr','power']
+
+ df = getsmallrowdata_db(columns,ids=ids)
+
+ totalmeters,totalhours, totalminutes = get_totals(g_workouts)
+
+ # meters, duration per workout type
+ wtypes = list(set([w.workouttype for w in g_workouts]))
+ listofdicts = []
+
+ for wtype in wtypes:
+ a_workouts = g_workouts.filter(workouttype=wtype)
+ wmeters, whours, wminutes = get_totals(a_workouts)
+ ddict = {}
+ ddict['wtype'] = mytypes.workouttypes_ordered[wtype]
+ ddict['distance'] = wmeters
+ ddict['duration'] = "{whours}:{wminutes:02d}".format(
+ whours=whours,
+ wminutes=wminutes
+ )
+ ddf = getsmallrowdata_db(columns,ids=[w.id for w in a_workouts])
+ ddict['hrmean'] = ddf['hr'].mean().astype(int)
+ ddict['hrmax'] = ddf['hr'].max().astype(int)
+ ddict['powermean'] = ddf['power'].mean().astype(int)
+ ddict['powermax'] = ddf['power'].max().astype(int)
+ ddict['nrworkouts'] = a_workouts.count()
+ listofdicts.append(ddict)
+
+ # interactive hr pie chart
+ totalscript,totaldiv = interactive_hr_piechart(df,r,'All Workouts')
+
+ # interactive power pie chart
+
+ totalsdict = {}
+ totalsdict['duration'] = "{totalhours}:{totalminutes}".format(
+ totalhours=totalhours,
+ totalminutes=totalminutes
+ )
+
+ totalsdict['distance'] = totalmeters
+ totalsdict['powermean'] = df['power'].mean().astype(int)
+ totalsdict['powermax'] = df['power'].max().astype(int)
+ totalsdict['hrmean'] = df['hr'].mean().astype(int)
+ totalsdict['hrmax'] = df['hr'].max().astype(int)
+ totalsdict['nrworkouts'] = g_workouts.count()
breadcrumbs = [
{
@@ -4670,5 +4732,9 @@ def history_view(request,userid=0):
{
'rower':r,
'breadcrumbs':breadcrumbs,
- 'active':'nav-analysis'
+ 'active':'nav-analysis',
+ 'totalsdict':totalsdict,
+ 'typedicts':listofdicts,
+ 'totalscript':totalscript,
+ 'totaldiv':totaldiv,
})
diff --git a/rowers/views/workoutviews.py b/rowers/views/workoutviews.py
index 105c069b..0163840d 100644
--- a/rowers/views/workoutviews.py
+++ b/rowers/views/workoutviews.py
@@ -1918,7 +1918,7 @@ def workouts_view(request,message='',successmessage='',
g_workouts = Workout.objects.filter(
team=theteam,user=r,
startdatetime__gte=activity_startdate,
- enddatetime__lte=activity_enddate,
+ startdatetime__lte=activity_enddate,
duplicate=False,
privacy='visible').order_by("-startdatetime")