cumstats
This commit is contained in:
@@ -839,6 +839,7 @@ def interactive_histoall(theworkouts):
|
||||
plot.xaxis.axis_label = "Power (W)"
|
||||
plot.yaxis.axis_label = "% of strokes"
|
||||
plot.y_range = Range1d(0,1.05*max(hist_norm))
|
||||
|
||||
|
||||
hover = plot.select(dict(type=HoverTool))
|
||||
|
||||
@@ -856,6 +857,7 @@ def interactive_histoall(theworkouts):
|
||||
plot.add_layout(LinearAxis(y_range_name="fraction",
|
||||
axis_label="Cumulative % of strokes"),'right')
|
||||
|
||||
plot.sizing_mode = 'scale_width'
|
||||
script, div = components(plot)
|
||||
return [script,div]
|
||||
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
{% extends "base.html" %}
|
||||
{% extends "newbase.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load rowerfilters %}
|
||||
|
||||
{% block title %}Workout Statistics{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% block title %}Rowsandall {% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<script src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
|
||||
<script>
|
||||
$(function() {
|
||||
|
||||
// Get the form fields and hidden div
|
||||
var checkbox = $("#id_water");
|
||||
var modality = $("#id_modality");
|
||||
var hidden = $("#id_waterboattype");
|
||||
|
||||
|
||||
@@ -20,15 +19,20 @@
|
||||
// enabled.
|
||||
|
||||
hidden.hide();
|
||||
|
||||
if (modality.val() == 'water') {
|
||||
hidden.show();
|
||||
}
|
||||
|
||||
|
||||
// Setup an event listener for when the state of the
|
||||
// checkbox changes.
|
||||
checkbox.change(function() {
|
||||
modality.change(function() {
|
||||
// Check to see if the checkbox is checked.
|
||||
// If it is, show the fields and populate the input.
|
||||
// If not, hide the fields.
|
||||
if (checkbox.is(':checked')) {
|
||||
// If not, hide the fields.
|
||||
var Value = modality.val();
|
||||
if (Value=='water') {
|
||||
// Show the hidden fields.
|
||||
hidden.show();
|
||||
} else {
|
||||
@@ -46,168 +50,93 @@
|
||||
// $("#hidden_field").val("");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
|
||||
|
||||
<script async="true" type="text/javascript">
|
||||
Bokeh.set_log_level("info");
|
||||
</script>
|
||||
|
||||
{{ 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 %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
<div id="id_css_res">
|
||||
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
|
||||
</div>
|
||||
<div class="grid_12 alpha">
|
||||
<div id="summary" class="grid_6 alpha">
|
||||
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
|
||||
between {{ startdate|date }} and {{ enddate|date }}</p>
|
||||
|
||||
<p>Direct link for other Pro users:
|
||||
<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>
|
||||
</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 id="id_js_res">
|
||||
<script
|
||||
type="text/javascript" src="/static/js/bokeh-0.12.3.min.js">
|
||||
</script>
|
||||
<script
|
||||
type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js">
|
||||
</script>
|
||||
|
||||
</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">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Metric</th>
|
||||
<th>Value</th>
|
||||
<th>Mean</th>
|
||||
<th>Minimum</th>
|
||||
<th>25%</th>
|
||||
<th>Median</th>
|
||||
<th>75%</th>
|
||||
<th>Maximum</th>
|
||||
<th>Standard Deviation</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, value in stats.items %}
|
||||
<tr>
|
||||
<td>Mean</td><td>{{ value.mean|floatformat:-2 }}</td>
|
||||
</tr><tr>
|
||||
<td>Minimum</td><td>{{ value.min|floatformat:-2 }}</td>
|
||||
</tr><tr>
|
||||
<td>25%</td><td>{{ value.firstq|floatformat:-2 }}</td>
|
||||
</tr><tr>
|
||||
<td>Median</td><td>{{ value.median|floatformat:-2 }}</td>
|
||||
</tr><tr>
|
||||
<td>75%</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>
|
||||
<td>{{ value.verbosename }}</td>
|
||||
<td>{{ value.mean|floatformat:-2 }}</td>
|
||||
<td>{{ value.min|floatformat:-2 }}</td>
|
||||
<td>{{ value.firstq|floatformat:-2 }}</td>
|
||||
<td>{{ value.median|floatformat:-2 }}</td>
|
||||
<td>{{ value.thirdq|floatformat:-2 }}</td>
|
||||
<td>{{ value.max|floatformat:-2 }}</td>
|
||||
<td>{{ value.std|floatformat:-2 }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="grid_8 omega">
|
||||
{% if cordict %}
|
||||
<div class="grid_8">
|
||||
<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.
|
||||
|
||||
{% endif %}
|
||||
</li>
|
||||
<li class="grid_4">
|
||||
{% if cordict %}
|
||||
<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>
|
||||
<table width="90%" class="cortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
{% for key,value in cordict.items %}
|
||||
<th class="rotate"><div><span>{{ key }}</span></div></th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, thedict in cordict.items %}
|
||||
<table width="90%" class="cortable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
{% for key,value in cordict.items %}
|
||||
<th class="rotate"><div><span>{{ key }}</span></div></th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for key, thedict in cordict.items %}
|
||||
<tr>
|
||||
<th> {{ key }}</th>
|
||||
{% for key2,value in thedict.items %}
|
||||
@@ -218,24 +147,43 @@
|
||||
<div class="weakposcor">{{ value|floatformat:-1 }}</div>
|
||||
{% elif value < -0.5 %}
|
||||
<div class="negcor">{{ value|floatformat:-1 }}</div>
|
||||
{% elif value < -0.1 %}
|
||||
<div class="weaknegcor">{{ value|floatformat:-1 }}</div>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
{% elif value < -0.1 %}
|
||||
<div class="weaknegcor">{{ value|floatformat:-1 }}</div>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="grid_8">
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% endif %}
|
||||
|
||||
<div class="grid_8">
|
||||
{{ plotdiv|safe }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
|
||||
<table>
|
||||
{{ 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 %}
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li id="stats-cumstats">
|
||||
<a href="/rowers/cumstates">
|
||||
<a href="/rowers/cumstats">
|
||||
<i class="fal fa-table fa-fw"></i> Statistics
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@@ -185,27 +185,19 @@ urlpatterns = [
|
||||
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'^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/(?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'^(?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'^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/(?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'^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<deltadays>\d+)$',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<deltadays>\d+)$',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/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),
|
||||
@@ -216,18 +208,13 @@ urlpatterns = [
|
||||
url(r'^flexalldata/$',views.cum_flex_data),
|
||||
url(r'^histo/user/(?P<theuser>\d+)$',views.histo),
|
||||
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'^cumstats/u/(?P<theuser>\d+)$',views.cumstats),
|
||||
url(r'^cumstats/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)/p/(?P<plotfield>\w+.*)$',views.cumstats),
|
||||
url(r'^(?P<theuser>\d+)/cumstats/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)/p/(?P<plotfield>\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/user/(?P<theuser>\d+)$',views.cumstats),
|
||||
url(r'^cumstats/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.cumstats),
|
||||
url(r'^cumstats/user/(?P<theuser>\d+)/(?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'^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+)/deleteconfirm$',views.graph_delete_confirm_view),
|
||||
url(r'^graph/(?P<id>\d+)/delete$',views.graph_delete_view),
|
||||
|
||||
382
rowers/views.py
382
rowers/views.py
@@ -2358,95 +2358,6 @@ def rower_process_testcallback(request):
|
||||
|
||||
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):
|
||||
try:
|
||||
@@ -2976,7 +2887,7 @@ def workout_histo_view(request,id=0):
|
||||
|
||||
|
||||
# Histogram for a date/time range
|
||||
@login_required()
|
||||
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
|
||||
def histo(request,theuser=0,
|
||||
startdate=timezone.now()-datetime.timedelta(days=365),
|
||||
enddate=timezone.now(),
|
||||
@@ -7442,14 +7353,13 @@ def instroke_chart(request,id=0,metric=''):
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
# Cumulative stats page
|
||||
@login_required()
|
||||
@user_passes_test(ispromember,login_url="/",redirect_field_name=None)
|
||||
def cumstats(request,theuser=0,
|
||||
startdate=timezone.now()-datetime.timedelta(days=30),
|
||||
enddate=timezone.now(),
|
||||
deltadays=-1,
|
||||
startdatestring="",
|
||||
enddatestring="",
|
||||
plotfield='spm',
|
||||
options={
|
||||
'includereststrokes':False,
|
||||
'workouttypes':['rower','dynamic','slides'],
|
||||
@@ -7457,19 +7367,29 @@ def cumstats(request,theuser=0,
|
||||
'rankingonly':False,
|
||||
}):
|
||||
|
||||
if 'options' in request.session:
|
||||
options = request.session['options']
|
||||
r = getrequestrower(request,userid=theuser)
|
||||
theuser = r.user
|
||||
|
||||
if 'waterboattype' in request.session:
|
||||
waterboattype = request.session['waterboattype']
|
||||
else:
|
||||
waterboattype = types.waterboattype
|
||||
|
||||
|
||||
try:
|
||||
workouttypes = options['workouttypes']
|
||||
except KeyError:
|
||||
workouttypes = ['rower','dynamic','slides']
|
||||
if 'rankingonly' in request.session:
|
||||
rankingonly = request.session['rankingonly']
|
||||
else:
|
||||
rankingonly = False
|
||||
|
||||
try:
|
||||
includereststrokes = options['includereststrokes']
|
||||
except KeyError:
|
||||
includereststrokes = False
|
||||
if 'modalities' in request.session:
|
||||
modalities = request.session['modalities']
|
||||
if len(modalities) > 1:
|
||||
modality = 'all'
|
||||
else:
|
||||
modality = modalities[0]
|
||||
else:
|
||||
modalities = [m[0] for m in types.workouttypes]
|
||||
modality = 'all'
|
||||
|
||||
|
||||
try:
|
||||
@@ -7477,12 +7397,16 @@ def cumstats(request,theuser=0,
|
||||
except KeyError:
|
||||
rankingonly = False
|
||||
|
||||
try:
|
||||
includereststrokes = options['includereststrokes']
|
||||
except KeyError:
|
||||
includereststrokes = False
|
||||
|
||||
|
||||
workstrokesonly = not includereststrokes
|
||||
|
||||
waterboattype = types.waterboattype
|
||||
|
||||
if deltadays>0:
|
||||
startdate = enddate-datetime.timedelta(days=int(deltadays))
|
||||
|
||||
|
||||
if startdatestring != "":
|
||||
startdate = iso8601.parse_date(startdatestring)
|
||||
@@ -7495,33 +7419,13 @@ def cumstats(request,theuser=0,
|
||||
enddate = startdate
|
||||
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
|
||||
|
||||
# process form
|
||||
if request.method == 'POST' and "daterange" in request.POST:
|
||||
if request.method == 'POST':
|
||||
form = DateRangeForm(request.POST)
|
||||
deltaform = DeltaDaysForm(request.POST)
|
||||
optionsform = StatsOptionsForm()
|
||||
modalityform = TrendFlexModalForm(request.POST)
|
||||
if form.is_valid():
|
||||
startdate = form.cleaned_data['startdate']
|
||||
enddate = form.cleaned_data['enddate']
|
||||
@@ -7529,111 +7433,118 @@ def cumstats(request,theuser=0,
|
||||
s = enddate
|
||||
enddate = startdate
|
||||
startdate = s
|
||||
elif request.method == 'POST' and "datedelta" in request.POST:
|
||||
deltaform = DeltaDaysForm(request.POST)
|
||||
if deltaform.is_valid():
|
||||
deltadays = deltaform.cleaned_data['deltadays']
|
||||
if deltadays != 0 and isinstance(deltadays, Number):
|
||||
enddate = timezone.now()
|
||||
startdate = enddate-datetime.timedelta(days=deltadays)
|
||||
if startdate > enddate:
|
||||
s = enddate
|
||||
enddate = startdate
|
||||
startdate = s
|
||||
form = DateRangeForm(initial={
|
||||
'startdate': startdate,
|
||||
'enddate': enddate,
|
||||
})
|
||||
optionsform = StatsOptionsForm()
|
||||
if modalityform.is_valid():
|
||||
modality = modalityform.cleaned_data['modality']
|
||||
waterboattype = modalityform.cleaned_data['waterboattype']
|
||||
rankingonly = modalityform.cleaned_data['rankingonly']
|
||||
if modality == 'all':
|
||||
modalities = [m[0] for m in types.workouttypes]
|
||||
else:
|
||||
form = DateRangeForm()
|
||||
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)
|
||||
modalities = [modality]
|
||||
|
||||
options = {
|
||||
'includereststrokes':includereststrokes,
|
||||
'workouttypes':workouttypes,
|
||||
'waterboattype':waterboattype,
|
||||
'rankingonly':rankingonly,
|
||||
}
|
||||
request.session['options'] = options
|
||||
form = DateRangeForm()
|
||||
deltaform = DeltaDaysForm()
|
||||
else:
|
||||
form = DateRangeForm()
|
||||
deltaform = DeltaDaysForm()
|
||||
if modality != 'water':
|
||||
waterboattype = [b[0] for b in types.boattypes]
|
||||
|
||||
|
||||
request.session['modalities'] = modalities
|
||||
request.session['waterboattype'] = waterboattype
|
||||
request.session['rankingonly'] = rankingonly
|
||||
form = DateRangeForm(initial={
|
||||
'startdate': startdate,
|
||||
'enddate': enddate,
|
||||
})
|
||||
else:
|
||||
form = DateRangeForm(initial={
|
||||
'startdate': startdate,
|
||||
'enddate': enddate,
|
||||
})
|
||||
deltaform = DeltaDaysForm()
|
||||
optionsform = StatsOptionsForm()
|
||||
includereststrokes = False
|
||||
|
||||
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:
|
||||
r2 = getrower(theuser)
|
||||
if rankingonly:
|
||||
rankingpiece = [True]
|
||||
else:
|
||||
rankingpiece = [True,False]
|
||||
enddate = iso8601.parse_date(enddatestring)
|
||||
except ParseError:
|
||||
enddate = timezone.now()
|
||||
|
||||
|
||||
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:
|
||||
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]
|
||||
ids = [int(workout.id) for workout in allworkouts]
|
||||
|
||||
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:
|
||||
stats = {}
|
||||
plotfield = 'spm'
|
||||
cordict = {}
|
||||
div = "No Data found"
|
||||
script = ''
|
||||
|
||||
response = render(request,
|
||||
'cumstats.html',
|
||||
@@ -7660,17 +7568,16 @@ def cumstats(request,theuser=0,
|
||||
'stats':stats,
|
||||
'teams':get_my_teams(request.user),
|
||||
'options':options,
|
||||
'active':'nav-analysis',
|
||||
'rower':r,
|
||||
'id':theuser,
|
||||
'theuser':u,
|
||||
'theuser':theuser,
|
||||
'startdate':startdate,
|
||||
'enddate':enddate,
|
||||
'form':form,
|
||||
'deltaform':deltaform,
|
||||
'optionsform':optionsform,
|
||||
'optionsform':modalityform,
|
||||
'cordict':cordict,
|
||||
'plotscript':script,
|
||||
'plotdiv':div,
|
||||
'plotfield':plotfield,
|
||||
})
|
||||
|
||||
request.session['options'] = options
|
||||
@@ -7715,7 +7622,6 @@ def cumstats(request,theuser=0,
|
||||
datadf['workoutid'].replace(datemapping,inplace=True)
|
||||
datadf.rename(columns={"workoutid":"date"},inplace=True)
|
||||
datadf = datadf.sort_values(['date'])
|
||||
script,div = interactive_boxchart(datadf,plotfield)
|
||||
|
||||
# set options form correctly
|
||||
initial = {}
|
||||
@@ -7723,32 +7629,22 @@ def cumstats(request,theuser=0,
|
||||
initial['waterboattype'] = waterboattype
|
||||
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,
|
||||
'cumstats.html',
|
||||
{
|
||||
'stats':stats,
|
||||
'teams':get_my_teams(request.user),
|
||||
'active':'nav-analysis',
|
||||
'rower':r,
|
||||
'options':options,
|
||||
'id':theuser,
|
||||
'theuser':u,
|
||||
'theuser':theuser,
|
||||
'startdate':startdate,
|
||||
'enddate':enddate,
|
||||
'form':form,
|
||||
'deltaform':deltaform,
|
||||
'optionsform':optionsform,
|
||||
'optionsform':modalityform,
|
||||
'cordict':cordict,
|
||||
'plotscript':script,
|
||||
'plotdiv':div,
|
||||
'plotfield':plotfield,
|
||||
})
|
||||
|
||||
request.session['options'] = options
|
||||
|
||||
Reference in New Issue
Block a user