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")