adding first pie chart
This commit is contained in:
@@ -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 = [
|
||||
'<ut2',
|
||||
'ut2',
|
||||
'ut1',
|
||||
'at',
|
||||
'tr',
|
||||
'an',
|
||||
]
|
||||
|
||||
colors = ['gray','yellow','lime','blue','purple','red']
|
||||
|
||||
|
||||
size=220
|
||||
TOOLS = 'save'
|
||||
|
||||
z = figure(title="HR "+title, x_range=(-1,1), y_range=(-1,1), width=size, height=size,
|
||||
tools=TOOLS,
|
||||
)
|
||||
|
||||
for start, end , legend, color in zip(source_starts, source_ends, source_legends, colors[0:len(source_starts)]):
|
||||
z.wedge(x=0, y=0, radius=1, start_angle=start, end_angle=end, color=color, legend=legend)
|
||||
|
||||
|
||||
|
||||
z.toolbar_location = 'right'
|
||||
z.legend.visible = False
|
||||
z.axis.visible = False
|
||||
z.xgrid.grid_line_color = None
|
||||
z.ygrid.grid_line_color = None
|
||||
z.outline_line_color = None
|
||||
|
||||
return components(z)
|
||||
|
||||
|
||||
def interactive_boxchart(datadf,fieldname,extratitle='',
|
||||
spmmin=0,spmmax=0,workmin=0,workmax=0):
|
||||
|
||||
|
||||
@@ -5,12 +5,76 @@
|
||||
{% block title %}Rowsandall {% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<h1>History</h1>
|
||||
<ul class="main-content">
|
||||
<li class="grid_4">
|
||||
<h1>Future Functionality</h1>
|
||||
<script async="true" src="https://cdn.pydata.org/bokeh/release/bokeh-1.0.4.min.js"></script>
|
||||
<li class="grid_1">
|
||||
<h2>All workouts</h2>
|
||||
|
||||
<p>Watch this space</p>
|
||||
<p>
|
||||
<table class="listtable shortpadded">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Total Distance</td><td>{{ totalsdict|lookup:"distance"}} meters</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total Duration</td><td>{{ totalsdict|lookup:"duration"}} hours</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Number of workouts</td><td>{{ totalsdict|lookup:"nrworkouts"}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Average heart rate</td><td>{{ totalsdict|lookup:"hrmean"}} bpm</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Maximum heart rate</td><td>{{ totalsdict|lookup:"hrmax"}} bpm</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Average power</td><td>{{ totalsdict|lookup:"powermean"}} W</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Maximum power</td><td>{{ totalsdict|lookup:"powermax"}} W</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<div>{{ totalscript|safe }}{{ totaldiv|safe }}</div>
|
||||
</li>
|
||||
{% for ddict in typedicts %}
|
||||
<li class="grid_1">
|
||||
<h2>{{ ddict|lookup:"wtype"}}</h2>
|
||||
|
||||
<p>
|
||||
<table class="listtable shortpadded">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Total Distance</td><td>{{ ddict|lookup:"distance"}} meters</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Total Duration</td><td>{{ ddict|lookup:"duration"}} hours</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Number of workouts</td><td>{{ ddict|lookup:"nrworkouts"}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Average heart rate</td><td>{{ ddict|lookup:"hrmean"}} bpm</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Maximum heart rate</td><td>{{ ddict|lookup:"hrmax"}} bpm</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Average power</td><td>{{ ddict|lookup:"powermean"}} W</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Maximum power</td><td>{{ ddict|lookup:"powermax"}} W</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user