Private
Public Access
1
0
This commit is contained in:
Sander Roosendaal
2018-10-08 15:20:11 +02:00
parent b0748831ad
commit 9025a0d8dc
5 changed files with 258 additions and 425 deletions

View File

@@ -839,6 +839,7 @@ def interactive_histoall(theworkouts):
plot.xaxis.axis_label = "Power (W)" plot.xaxis.axis_label = "Power (W)"
plot.yaxis.axis_label = "% of strokes" plot.yaxis.axis_label = "% of strokes"
plot.y_range = Range1d(0,1.05*max(hist_norm)) plot.y_range = Range1d(0,1.05*max(hist_norm))
hover = plot.select(dict(type=HoverTool)) hover = plot.select(dict(type=HoverTool))
@@ -856,6 +857,7 @@ def interactive_histoall(theworkouts):
plot.add_layout(LinearAxis(y_range_name="fraction", plot.add_layout(LinearAxis(y_range_name="fraction",
axis_label="Cumulative % of strokes"),'right') axis_label="Cumulative % of strokes"),'right')
plot.sizing_mode = 'scale_width'
script, div = components(plot) script, div = components(plot)
return [script,div] return [script,div]

View File

@@ -1,17 +1,16 @@
{% extends "base.html" %} {% extends "newbase.html" %}
{% load staticfiles %} {% load staticfiles %}
{% load rowerfilters %} {% load rowerfilters %}
{% block title %}Workout Statistics{% endblock %} {% block title %}Rowsandall {% endblock %}
{% block content %}
{% block main %}
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<script> <script>
$(function() { $(function() {
// Get the form fields and hidden div // Get the form fields and hidden div
var checkbox = $("#id_water"); var modality = $("#id_modality");
var hidden = $("#id_waterboattype"); var hidden = $("#id_waterboattype");
@@ -20,15 +19,20 @@
// enabled. // enabled.
hidden.hide(); hidden.hide();
if (modality.val() == 'water') {
hidden.show();
}
// Setup an event listener for when the state of the // Setup an event listener for when the state of the
// checkbox changes. // checkbox changes.
checkbox.change(function() { modality.change(function() {
// Check to see if the checkbox is checked. // Check to see if the checkbox is checked.
// If it is, show the fields and populate the input. // If it is, show the fields and populate the input.
// If not, hide the fields. // If not, hide the fields.
if (checkbox.is(':checked')) { var Value = modality.val();
if (Value=='water') {
// Show the hidden fields. // Show the hidden fields.
hidden.show(); hidden.show();
} else { } else {
@@ -46,168 +50,93 @@
// $("#hidden_field").val(""); // $("#hidden_field").val("");
} }
}); });
});
});
</script> </script>
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript"> <div id="id_css_res">
Bokeh.set_log_level("info"); <link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
</script> <link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
{{ plotscript |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, true, true);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div class="grid_12 alpha">
<div class="grid_4 alpha">
{% if theuser %}
<h3>{{ theuser.first_name }}'s Workout Statistics</h3>
{% else %}
<h3>{{ user.first_name }}'s Workout Statistics</h3>
{% endif %}
</div>
<div class="grid_2 suffix_6 omega">
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button green small dropbtn">
{{ theuser.first_name }} {{ theuser.last_name }}
</button>
<div class="dropdown-content">
{% for member in user|team_members %}
<a class="button green small" href="/rowers/{{ member.id }}/cumstats/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/p/{{ plotfield }}">{{ member.first_name }} {{ member.last_name }}</a>
{% endfor %}
</div>
{% else %}
&nbsp;
{% endif %}
</div>
</div> </div>
<div class="grid_12 alpha"> <div id="id_js_res">
<div id="summary" class="grid_6 alpha"> <script
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }} type="text/javascript" src="/static/js/bokeh-0.12.3.min.js">
between {{ startdate|date }} and {{ enddate|date }}</p> </script>
<script
<p>Direct link for other Pro users: type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js">
<a href="/rowers/{{ id }}/cumstats/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/p/{{ plotfield }}">https://rowsandall.com/rowers/{{ id }}/cumstats/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/p/{{ plotfield }}</a> </script>
</p>
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% csrf_token %}
<div class="grid_2 alpha">
<table>
{{ optionsform.as_table }}
</table>
</div>
<div class="grid_2 suffix_2 omega">
<input type="hidden" name="options" value="options">
<input class="grid_1 alpha button green small" value="Submit" type="Submit">
</div>
</form>
</div> </div>
<div id="form" class="grid_6 omega">
<p>Use this form to select a different date range:</p>
<p>
Select start and end date for a date range:
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
<table>
{{ form.as_table }}
</table>
{% csrf_token %}
</div>
<div class="grid_2 omega">
<input name='daterange' class="button green" type="submit" value="Submit"> </form>
</div>
<div class="grid_4 alpha">
<form enctype="multipart/form-data" action="" method="post">
Or use the last {{ deltaform }} days.
</div>
<div class="grid_2 omega">
{% csrf_token %}
<input name='datedelta' class="button green" type="submit" value="Submit">
</form>
</div>
</div>
</div>
<div class="grid_12 alpha">
<div class="grid_4 alpha">
{% if stats %}
{% for key, value in stats.items %}
<h2>{{ value.verbosename }}</h2>
<div class="grid_1">
<p>
<a class="button blue small" href="/rowers/{{ id }}/cumstats/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}/p/{{ key }}">Plot</a>
</p>
</div>
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
<div id="id_script">
</div>
<ul class="main-content">
<li class="grid_4">
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
between {{ startdate|date }} and {{ enddate|date }}</p>
</li>
<li class="grid_4">
{% if stats %}
<h2>Statistics</h2>
<table width="100%" class="listtable"> <table width="100%" class="listtable">
<thead> <thead>
<tr> <tr>
<th>Metric</th> <th>Metric</th>
<th>Value</th> <th>Mean</th>
<th>Minimum</th>
<th>25&#37;</th>
<th>Median</th>
<th>75&#37;</th>
<th>Maximum</th>
<th>Standard Deviation</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for key, value in stats.items %}
<tr> <tr>
<td>Mean</td><td>{{ value.mean|floatformat:-2 }}</td> <td>{{ value.verbosename }}</td>
</tr><tr> <td>{{ value.mean|floatformat:-2 }}</td>
<td>Minimum</td><td>{{ value.min|floatformat:-2 }}</td> <td>{{ value.min|floatformat:-2 }}</td>
</tr><tr> <td>{{ value.firstq|floatformat:-2 }}</td>
<td>25&#37;</td><td>{{ value.firstq|floatformat:-2 }}</td> <td>{{ value.median|floatformat:-2 }}</td>
</tr><tr> <td>{{ value.thirdq|floatformat:-2 }}</td>
<td>Median</td><td>{{ value.median|floatformat:-2 }}</td> <td>{{ value.max|floatformat:-2 }}</td>
</tr><tr> <td>{{ value.std|floatformat:-2 }}</td>
<td>75&#37;</td><td>{{ value.thirdq|floatformat:-2 }}</td>
</tr><tr>
<td>Maximum</td><td>{{ value.max|floatformat:-2 }}</td>
</tr><tr>
<td>Standard Deviation</td><td>{{ value.std|floatformat:-2 }}</td>
</tr> </tr>
{% endfor %}
</tbody> </tbody>
</table> </table>
{% endfor %}
{% endif %} {% endif %}
</div> </li>
<div class="grid_8 omega"> <li class="grid_4">
{% if cordict %} {% if cordict %}
<div class="grid_8"> <h2> Correlation matrix</h2>
<h2> Correlation Matrix</h2> <p>This matrix indicates a positive (+) or negative (-) correlation between two parameters. The Spearman correlation coefficient has values between +1 and -1. Positive correlation between two metrics means that if one metric increases, the other value is also likely to increase. Negative is the opposite. The further from zero, the higher the likelyhood.
<p>This matrix indicates a positive (+) or negative (-) correlation between two parameters. The Spearman correlation coefficient has values between +1 and -1. Positive correlation between two metrics means that if one metric increases, the other value is also likely to increase. Negative is the opposite. The further from zero, the higher the likelyhood.
</p> </p>
<table width="90%" class="cortable"> <table width="90%" class="cortable">
<thead> <thead>
<tr> <tr>
<th>&nbsp;</th> <th>&nbsp;</th>
{% for key,value in cordict.items %} {% for key,value in cordict.items %}
<th class="rotate"><div><span>{{ key }}</span></div></th> <th class="rotate"><div><span>{{ key }}</span></div></th>
{% endfor %} {% endfor %}
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for key, thedict in cordict.items %} {% for key, thedict in cordict.items %}
<tr> <tr>
<th> {{ key }}</th> <th> {{ key }}</th>
{% for key2,value in thedict.items %} {% for key2,value in thedict.items %}
@@ -218,24 +147,43 @@
<div class="weakposcor">{{ value|floatformat:-1 }}</div> <div class="weakposcor">{{ value|floatformat:-1 }}</div>
{% elif value < -0.5 %} {% elif value < -0.5 %}
<div class="negcor">{{ value|floatformat:-1 }}</div> <div class="negcor">{{ value|floatformat:-1 }}</div>
{% elif value < -0.1 %} {% elif value < -0.1 %}
<div class="weaknegcor">{{ value|floatformat:-1 }}</div> <div class="weaknegcor">{{ value|floatformat:-1 }}</div>
{% else %} {% else %}
&nbsp; &nbsp;
{% endif %} {% endif %}
</td> </td>
{% endfor %} {% endfor %}
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
<div class="grid_8">
{% endif %} {% endif %}
<div class="grid_8"> </li>
{{ plotdiv|safe }} <li>
</div> <form enctype="multipart/form-data" action="{{ formloc }}" method="post">
</div> <table>
</div> {{ optionsform.as_table }}
</table>
<input type="hidden" name="options" value="options">
</li>
<li>
<table>
{{ form.as_table }}
</table>
</li>
<li>
{% csrf_token %}
<input class="button green small" value="Submit" type="Submit">
</form>
</li>
</ul>
{% endblock %}
{% block sidebar %}
{% include 'menu_analytics.html' %}
{% endblock %} {% endblock %}

View File

@@ -46,7 +46,7 @@
</a> </a>
</li> </li>
<li id="stats-cumstats"> <li id="stats-cumstats">
<a href="/rowers/cumstates"> <a href="/rowers/cumstats">
<i class="fal fa-table fa-fw"></i>&nbsp;Statistics <i class="fal fa-table fa-fw"></i>&nbsp;Statistics
</a> </a>
</li> </li>

View File

@@ -185,27 +185,19 @@ urlpatterns = [
url(r'^fitness-progress/user/(?P<id>\d+)$',views.fitnessmetric_view), url(r'^fitness-progress/user/(?P<id>\d+)$',views.fitnessmetric_view),
url(r'^fitness-progress/user/(?P<id>\d+)/(?P<mode>\w+.*)$',views.fitnessmetric_view), url(r'^fitness-progress/user/(?P<id>\d+)/(?P<mode>\w+.*)$',views.fitnessmetric_view),
url(r'^ote-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.rankings_view), url(r'^ote-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.rankings_view),
url(r'^ote-bests/user/(?P<theuser>\d+)/(?P<deltadays>\d+)$',views.rankings_view),
url(r'^ote-bests/user/(?P<theuser>\d+)$',views.rankings_view), url(r'^ote-bests/user/(?P<theuser>\d+)$',views.rankings_view),
url(r'^ote-bests/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.rankings_view), url(r'^ote-bests/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.rankings_view),
url(r'^ote-bests/(?P<deltadays>\d+)$',views.rankings_view),
url(r'^ote-bests/$',views.rankings_view), url(r'^ote-bests/$',views.rankings_view),
url(r'^(?P<theuser>\d+)/ote-bests/$',views.rankings_view), url(r'^(?P<theuser>\d+)/ote-bests/$',views.rankings_view),
url(r'^(?P<theuser>\d+)/ote-bests2/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.rankings_view2), url(r'^(?P<theuser>\d+)/ote-bests2/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.rankings_view2),
url(r'^ote-bests2/user/(?P<theuser>\d+)/(?P<deltadays>\d+)$',views.rankings_view2),
url(r'^ote-bests2/user/(?P<theuser>\d+)$',views.rankings_view2), url(r'^ote-bests2/user/(?P<theuser>\d+)$',views.rankings_view2),
url(r'^ote-bests2/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.rankings_view2), url(r'^ote-bests2/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.rankings_view2),
url(r'^ote-bests2/(?P<deltadays>\d+)$',views.rankings_view2),
url(r'^ote-bests2/$',views.rankings_view2), url(r'^ote-bests2/$',views.rankings_view2),
url(r'^otw-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.otwrankings_view), url(r'^otw-bests/user/(?P<theuser>\d+)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.otwrankings_view),
url(r'^otw-bests/user/(?P<theuser>\d+)/(?P<deltadays>\d+)$',views.otwrankings_view),
url(r'^otw-bests/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.otwrankings_view), url(r'^otw-bests/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.otwrankings_view),
url(r'^otw-bests/(?P<deltadays>\d+)$',views.otwrankings_view),
url(r'^otw-bests/$',views.otwrankings_view), url(r'^otw-bests/$',views.otwrankings_view),
url(r'^ote-ranking/user/(?P<theuser>\d+)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.oterankings_view), url(r'^ote-ranking/user/(?P<theuser>\d+)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.oterankings_view),
url(r'^ote-ranking/user/(?P<theuser>\d+)/(?P<deltadays>\d+)$',views.oterankings_view),
url(r'^ote-ranking/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.oterankings_view), url(r'^ote-ranking/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.oterankings_view),
url(r'^ote-ranking/(?P<deltadays>\d+)$',views.oterankings_view),
url(r'^ote-ranking/$',views.oterankings_view), url(r'^ote-ranking/$',views.oterankings_view),
url(r'^ote-ranking/user/(?P<theuser>\d+)/$',views.oterankings_view), url(r'^ote-ranking/user/(?P<theuser>\d+)/$',views.oterankings_view),
url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)/user/(?P<theuser>\d+)$',views.cum_flex), url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)/user/(?P<theuser>\d+)$',views.cum_flex),
@@ -216,18 +208,13 @@ urlpatterns = [
url(r'^flexalldata/$',views.cum_flex_data), url(r'^flexalldata/$',views.cum_flex_data),
url(r'^histo/user/(?P<theuser>\d+)$',views.histo), url(r'^histo/user/(?P<theuser>\d+)$',views.histo),
url(r'^histodata$',views.histo_data), url(r'^histodata$',views.histo_data),
url(r'^(?P<theuser>\d+)/histo/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.histo), url(r'^histo/user/(?P<theuser>\d+)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.histo),
url(r'^histo/$',views.histo), url(r'^histo/$',views.histo),
url(r'^cumstats/u/(?P<theuser>\d+)$',views.cumstats), url(r'^cumstats/user/(?P<theuser>\d+)$',views.cumstats),
url(r'^cumstats/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)/p/(?P<plotfield>\w+.*)$',views.cumstats), url(r'^cumstats/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.cumstats),
url(r'^(?P<theuser>\d+)/cumstats/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)/p/(?P<plotfield>\w+.*)$',views.cumstats), url(r'^cumstats/user/(?P<theuser>\d+)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.cumstats),
url(r'^(?P<theuser>\d+)/cumstats/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.cumstats),
url(r'^(?P<theuser>\d+)/cumstats/(?P<deltadays>\d+)$',views.cumstats),
url(r'^cumstats/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.cumstats), url(r'^cumstats/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.cumstats),
url(r'^cumstats/(?P<deltadays>\d+)$',views.cumstats),
url(r'^cumstats/$',views.cumstats), url(r'^cumstats/$',views.cumstats),
url(r'^histo-all/$',views.histo_all),
url(r'^(?P<theuser>\d+)/histo-all/$',views.histo_all),
url(r'^graph/(?P<id>\d+)/$',views.graph_show_view), url(r'^graph/(?P<id>\d+)/$',views.graph_show_view),
url(r'^graph/(?P<id>\d+)/deleteconfirm$',views.graph_delete_confirm_view), url(r'^graph/(?P<id>\d+)/deleteconfirm$',views.graph_delete_confirm_view),
url(r'^graph/(?P<id>\d+)/delete$',views.graph_delete_view), url(r'^graph/(?P<id>\d+)/delete$',views.graph_delete_view),

View File

@@ -2358,95 +2358,6 @@ def rower_process_testcallback(request):
return HttpResponse(text) return HttpResponse(text)
# View around the Histogram of all strokes. Not implemented in UI
@login_required()
def histo_all(request,theuser=0,
startdate=timezone.now()-datetime.timedelta(days=10),
enddate=timezone.now(),
deltadays=-1,
startdatestring="",
enddatestring="",
options={
'includereststrokes':False,
'workouttypes':[i[0] for i in types.workouttypes],
'waterboattype':types.waterboattype
}):
if 'options' in request.session:
options = request.session['options']
workouttypes = options['workouttypes']
includereststrokes = options['includereststrokes']
waterboattype = options['waterboattype']
workstrokesonly = not includereststrokes
# checktypes = ['water','rower','dynamic','slides','skierg',
# 'paddle','snow','coastal','other']
if deltadays>0:
startdate = enddate-datetime.timedelta(days=int(deltadays))
if startdatestring != "":
startdate = iso8601.parse_date(startdatestring)
if enddatestring != "":
enddate = iso8601.parse_date(enddatestring)
startdate = datetime.datetime.combine(startdate,datetime.time())
enddate = datetime.datetime.combine(enddate,datetime.time(23,59,59))
if enddate < startdate:
s = enddate
enddate = startdate
startdate = s
promember=0
if theuser == 0:
theuser = request.user.id
if not request.user.is_anonymous():
r = getrower(request.user)
result = request.user.is_authenticated() and ispromember(request.user)
if result:
promember=1
if not promember:
return HttpResponseRedirect("/rowers/about/")
# get all indoor rows of past 12 months
ayearago = timezone.now()-datetime.timedelta(days=365)
try:
r2 = getrower(theuser)
allergworkouts = Workout.objects.filter(user=r2,
workouttype__in=['rower','dynamic','slides'],
startdatetime__gte=ayearago)
except Rower.DoesNotExist:
allergworkouts = []
r2=0
try:
u = User.objects.get(id=theuser)
except User.DoesNotExist:
u = ''
if allergworkouts:
res = interactive_histoall(allergworkouts)
script = res[0]
div = res[1]
else:
script = ''
div = '<p>No erg pieces uploaded yet.</p>'
return render(request, 'histoall.html',
{'interactiveplot':script,
'the_div':div,
'id':theuser,
'theuser':u,
'teams':get_my_teams(request.user),
})
def keyvalue_get_default(key,options,def_options): def keyvalue_get_default(key,options,def_options):
try: try:
@@ -2976,7 +2887,7 @@ def workout_histo_view(request,id=0):
# Histogram for a date/time range # Histogram for a date/time range
@login_required() @user_passes_test(ispromember,login_url="/",redirect_field_name=None)
def histo(request,theuser=0, def histo(request,theuser=0,
startdate=timezone.now()-datetime.timedelta(days=365), startdate=timezone.now()-datetime.timedelta(days=365),
enddate=timezone.now(), enddate=timezone.now(),
@@ -7442,14 +7353,13 @@ def instroke_chart(request,id=0,metric=''):
return HttpResponseRedirect(url) return HttpResponseRedirect(url)
# Cumulative stats page # Cumulative stats page
@login_required() @user_passes_test(ispromember,login_url="/",redirect_field_name=None)
def cumstats(request,theuser=0, def cumstats(request,theuser=0,
startdate=timezone.now()-datetime.timedelta(days=30), startdate=timezone.now()-datetime.timedelta(days=30),
enddate=timezone.now(), enddate=timezone.now(),
deltadays=-1, deltadays=-1,
startdatestring="", startdatestring="",
enddatestring="", enddatestring="",
plotfield='spm',
options={ options={
'includereststrokes':False, 'includereststrokes':False,
'workouttypes':['rower','dynamic','slides'], 'workouttypes':['rower','dynamic','slides'],
@@ -7457,19 +7367,29 @@ def cumstats(request,theuser=0,
'rankingonly':False, 'rankingonly':False,
}): }):
if 'options' in request.session: r = getrequestrower(request,userid=theuser)
options = request.session['options'] theuser = r.user
if 'waterboattype' in request.session:
waterboattype = request.session['waterboattype']
else:
waterboattype = types.waterboattype
try: if 'rankingonly' in request.session:
workouttypes = options['workouttypes'] rankingonly = request.session['rankingonly']
except KeyError: else:
workouttypes = ['rower','dynamic','slides'] rankingonly = False
try: if 'modalities' in request.session:
includereststrokes = options['includereststrokes'] modalities = request.session['modalities']
except KeyError: if len(modalities) > 1:
includereststrokes = False modality = 'all'
else:
modality = modalities[0]
else:
modalities = [m[0] for m in types.workouttypes]
modality = 'all'
try: try:
@@ -7477,12 +7397,16 @@ def cumstats(request,theuser=0,
except KeyError: except KeyError:
rankingonly = False rankingonly = False
try:
includereststrokes = options['includereststrokes']
except KeyError:
includereststrokes = False
workstrokesonly = not includereststrokes workstrokesonly = not includereststrokes
waterboattype = types.waterboattype waterboattype = types.waterboattype
if deltadays>0:
startdate = enddate-datetime.timedelta(days=int(deltadays))
if startdatestring != "": if startdatestring != "":
startdate = iso8601.parse_date(startdatestring) startdate = iso8601.parse_date(startdatestring)
@@ -7495,33 +7419,13 @@ def cumstats(request,theuser=0,
enddate = startdate enddate = startdate
startdate = s startdate = s
promember=0
if theuser == 0:
if 'rowerid' in request.session:
try:
r = Rower.objects.get(id=request.session['rowerid'])
theuser = r.user.id
except Rower.DoesNotExist:
theuser = request.user.id
else:
theuser = request.user.id
if not request.user.is_anonymous():
r = getrower(request.user)
result = request.user.is_authenticated() and ispromember(request.user)
if result:
promember=1
if not promember:
return HttpResponseRedirect("/rowers/promembership/")
# get all indoor rows of in date range # get all indoor rows of in date range
# process form # process form
if request.method == 'POST' and "daterange" in request.POST: if request.method == 'POST':
form = DateRangeForm(request.POST) form = DateRangeForm(request.POST)
deltaform = DeltaDaysForm(request.POST) modalityform = TrendFlexModalForm(request.POST)
optionsform = StatsOptionsForm()
if form.is_valid(): if form.is_valid():
startdate = form.cleaned_data['startdate'] startdate = form.cleaned_data['startdate']
enddate = form.cleaned_data['enddate'] enddate = form.cleaned_data['enddate']
@@ -7529,111 +7433,118 @@ def cumstats(request,theuser=0,
s = enddate s = enddate
enddate = startdate enddate = startdate
startdate = s startdate = s
elif request.method == 'POST' and "datedelta" in request.POST: if modalityform.is_valid():
deltaform = DeltaDaysForm(request.POST) modality = modalityform.cleaned_data['modality']
if deltaform.is_valid(): waterboattype = modalityform.cleaned_data['waterboattype']
deltadays = deltaform.cleaned_data['deltadays'] rankingonly = modalityform.cleaned_data['rankingonly']
if deltadays != 0 and isinstance(deltadays, Number): if modality == 'all':
enddate = timezone.now() modalities = [m[0] for m in types.workouttypes]
startdate = enddate-datetime.timedelta(days=deltadays)
if startdate > enddate:
s = enddate
enddate = startdate
startdate = s
form = DateRangeForm(initial={
'startdate': startdate,
'enddate': enddate,
})
optionsform = StatsOptionsForm()
else: else:
form = DateRangeForm() modalities = [modality]
optionsform = StatsOptionsForm()
elif request.method == 'POST' and 'options' in request.POST:
optionsform = StatsOptionsForm(request.POST)
if optionsform.is_valid():
includereststrokes = optionsform.cleaned_data['includereststrokes']
workstrokesonly = not includereststrokes
workouttypes = []
rankingonly = optionsform.cleaned_data['rankingonly']
waterboattype = optionsform.cleaned_data['waterboattype']
for type in types.checktypes:
if optionsform.cleaned_data[type]:
workouttypes.append(type)
options = { if modality != 'water':
'includereststrokes':includereststrokes, waterboattype = [b[0] for b in types.boattypes]
'workouttypes':workouttypes,
'waterboattype':waterboattype,
'rankingonly':rankingonly, request.session['modalities'] = modalities
} request.session['waterboattype'] = waterboattype
request.session['options'] = options request.session['rankingonly'] = rankingonly
form = DateRangeForm() form = DateRangeForm(initial={
deltaform = DeltaDaysForm() 'startdate': startdate,
else: 'enddate': enddate,
form = DateRangeForm() })
deltaform = DeltaDaysForm()
else: else:
form = DateRangeForm(initial={ form = DateRangeForm(initial={
'startdate': startdate, 'startdate': startdate,
'enddate': enddate, 'enddate': enddate,
}) })
deltaform = DeltaDaysForm() includereststrokes = False
optionsform = StatsOptionsForm()
workstrokesonly = not includereststrokes
modalityform = TrendFlexModalForm(
initial={
'modality':modality,
'waterboattype':waterboattype,
'rankingonly':rankingonly,
}
)
negtypes = []
for b in types.boattypes:
if b[0] not in waterboattype:
negtypes.append(b[0])
script = ''
div = get_call()
js_resources = ''
css_resources = ''
options = {
'modality': modality,
'theuser': theuser.id,
'waterboattype':waterboattype,
'startdatestring':startdatestring,
'enddatestring':enddatestring,
'rankingonly':rankingonly,
'includereststrokes':includereststrokes,
}
request.session['options'] = options
if modality == 'all':
modalities = [m[0] for m in types.workouttypes]
else:
modalities = [modality]
try:
startdate = iso8601.parse_date(startdatestring)
except ParseError:
startdate = timezone.now()-datetime.timedelta(days=7)
try: try:
r2 = getrower(theuser) enddate = iso8601.parse_date(enddatestring)
if rankingonly: except ParseError:
rankingpiece = [True] enddate = timezone.now()
else:
rankingpiece = [True,False]
if enddate < startdate:
s = enddate
enddate = startdate
startdate = s
promember=0
if theuser == 0:
theuser = request.user.id
if not request.user.is_anonymous():
r = getrower(request.user)
result = request.user.is_authenticated() and ispromember(request.user)
if result:
promember=1
r2 = getrower(theuser)
if rankingonly:
rankingpiece = [True,]
else:
rankingpiece = [True,False]
waterinclude = False allworkouts = Workout.objects.filter(
user=r2,
workouttype__in=modalities,
boattype__in=waterboattype,
startdatetime__gte=startdate,
startdatetime__lte=enddate,
rankingpiece__in=rankingpiece
).order_by("-date", "-starttime")
for ttype in types.otwtypes: ids = [int(workout.id) for workout in allworkouts]
if ttype in workouttypes:
waterinclude = True
if waterinclude:
workoutsw = Workout.objects.filter(user=r2,
startdatetime__gte=startdate,
startdatetime__lte=enddate,
workouttype='water',
boattype__in='waterboattype',
rankingpiece__in=rankingpiece,
)
workouttypes = [w for w in workouttypes if w != 'water']
workoutse = Workout.objects.filter(user=r2,
startdatetime__gte=startdate,
startdatetime__lte=enddate,
workouttype__in=workouttypes,
rankingpiece__in=rankingpiece)
if waterinclude:
allergworkouts = workoutse | workoutsw
allergworkouts = allergworkouts.distinct().order_by("-date", "-starttime")
else:
allergworkouts = workoutse.order_by("-date","-starttime")
if waterinclude:
for ttype in types.otwtypes:
workouttypes.append(ttype)
except Rower.DoesNotExist:
allergworkouts = []
r2=0
try:
u = User.objects.get(id=theuser)
except User.DoesNotExist:
u = ''
ids = [int(workout.id) for workout in allergworkouts]
datemapping = { datemapping = {
w.id:w.date for w in allergworkouts w.id:w.date for w in allworkouts
} }
@@ -7649,10 +7560,7 @@ def cumstats(request,theuser=0,
if datadf.empty: if datadf.empty:
stats = {} stats = {}
plotfield = 'spm'
cordict = {} cordict = {}
div = "No Data found"
script = ''
response = render(request, response = render(request,
'cumstats.html', 'cumstats.html',
@@ -7660,17 +7568,16 @@ def cumstats(request,theuser=0,
'stats':stats, 'stats':stats,
'teams':get_my_teams(request.user), 'teams':get_my_teams(request.user),
'options':options, 'options':options,
'active':'nav-analysis',
'rower':r,
'id':theuser, 'id':theuser,
'theuser':u, 'theuser':theuser,
'startdate':startdate, 'startdate':startdate,
'enddate':enddate, 'enddate':enddate,
'form':form, 'form':form,
'deltaform':deltaform, 'deltaform':deltaform,
'optionsform':optionsform, 'optionsform':modalityform,
'cordict':cordict, 'cordict':cordict,
'plotscript':script,
'plotdiv':div,
'plotfield':plotfield,
}) })
request.session['options'] = options request.session['options'] = options
@@ -7715,7 +7622,6 @@ def cumstats(request,theuser=0,
datadf['workoutid'].replace(datemapping,inplace=True) datadf['workoutid'].replace(datemapping,inplace=True)
datadf.rename(columns={"workoutid":"date"},inplace=True) datadf.rename(columns={"workoutid":"date"},inplace=True)
datadf = datadf.sort_values(['date']) datadf = datadf.sort_values(['date'])
script,div = interactive_boxchart(datadf,plotfield)
# set options form correctly # set options form correctly
initial = {} initial = {}
@@ -7723,32 +7629,22 @@ def cumstats(request,theuser=0,
initial['waterboattype'] = waterboattype initial['waterboattype'] = waterboattype
initial['rankingonly'] = rankingonly initial['rankingonly'] = rankingonly
for wtype in types.checktypes:
if wtype in workouttypes:
initial[wtype] = True
else:
initial[wtype] = False
optionsform = StatsOptionsForm(initial=initial)
response = render(request, response = render(request,
'cumstats.html', 'cumstats.html',
{ {
'stats':stats, 'stats':stats,
'teams':get_my_teams(request.user), 'teams':get_my_teams(request.user),
'active':'nav-analysis',
'rower':r,
'options':options, 'options':options,
'id':theuser, 'id':theuser,
'theuser':u, 'theuser':theuser,
'startdate':startdate, 'startdate':startdate,
'enddate':enddate, 'enddate':enddate,
'form':form, 'form':form,
'deltaform':deltaform, 'optionsform':modalityform,
'optionsform':optionsform,
'cordict':cordict, 'cordict':cordict,
'plotscript':script,
'plotdiv':div,
'plotfield':plotfield,
}) })
request.session['options'] = options request.session['options'] = options