oterankings
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "newbase.html" %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load rowerfilters %}
|
{% load rowerfilters %}
|
||||||
|
|
||||||
@@ -8,175 +8,109 @@
|
|||||||
|
|
||||||
{% block title %}Workouts{% endblock %}
|
{% block title %}Workouts{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block main %}
|
||||||
|
|
||||||
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
|
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
|
||||||
<script async="true" type="text/javascript">
|
<script async="true" type="text/javascript">
|
||||||
Bokeh.set_log_level("info");
|
Bokeh.set_log_level("info");
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{{ interactiveplot |safe }}
|
{{ interactiveplot |safe }}
|
||||||
|
|
||||||
<script>
|
{% if theuser %}
|
||||||
// Set things up to resize the plot on a window resize. You can play with
|
<h1>{{ theuser.first_name }}'s Ranking Pieces</h1>
|
||||||
// the arguments of resize_width_height() to change the plot's behavior.
|
{% else %}
|
||||||
var plot_resize_setup = function () {
|
<h1>{{ user.first_name }}'s Ranking Pieces</h1>
|
||||||
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
|
{% endif %}
|
||||||
var plot = Bokeh.index[plotid];
|
|
||||||
var plotresizer = function() {
|
|
||||||
// arguments: use width, use height, maintain aspect ratio
|
|
||||||
plot.resize_width_height(true, true, false);
|
|
||||||
};
|
|
||||||
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>
|
|
||||||
|
|
||||||
|
<ul class="main-content">
|
||||||
|
<li class="grid_2">
|
||||||
|
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
|
||||||
|
between {{ startdate|date }} and {{ enddate|date }}</p>
|
||||||
|
|
||||||
<div id="title" class="grid_12 alpha">
|
<p>The table gives the efforts you marked as Ranking Piece.
|
||||||
<div class="grid_10 alpha">
|
The graph shows the best segments from those pieces, plotted as
|
||||||
{% if theuser %}
|
average power (over the segment) vs the duration of the segment/
|
||||||
<h3>{{ theuser.first_name }}'s Ranking Pieces</h3>
|
In other words: How long you can hold that power.
|
||||||
{% else %}
|
</p>
|
||||||
<h3>{{ user.first_name }}'s Ranking Pieces</h3>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="grid_2 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 %}
|
|
||||||
{% if workouttype == 'water' %}
|
|
||||||
<a class="button green small" href="/rowers/{{ member.id }}/otw-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a>
|
|
||||||
{% else %}
|
|
||||||
<a class="button green small" href="/rowers/{{ member.id }}/ote-ranking/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">{{ member.first_name }} {{ member.last_name }}</a>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="summary" class="grid_6 alpha">
|
<p>Whenever you load or reload the page, a new calculation is started
|
||||||
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
|
as a background process. The page will reload automatically when the
|
||||||
between {{ startdate|date }} and {{ enddate|date }}</p>
|
calculation is ready.
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>Direct link for other users:
|
<p>At the bottom of the page, you will find predictions derived from the model.</p>
|
||||||
{% if workouttype == 'water' %}
|
</li>
|
||||||
<a href="/rowers/{{ id }}/otw-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">https://rowsandall.com/rowers/{{ id }}/otw-bests/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}</a>
|
<li class="grid_2">
|
||||||
{% else %}
|
<p>Use this form to select a different date range:</p>
|
||||||
<a href="/rowers/{{ id }}/ote-ranking/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}">https://rowsandall.com/rowers/{{ id }}/ote-ranking/{{ startdate|date:"Y-m-d" }}/{{ enddate|date:"Y-m-d" }}</a>
|
<p>
|
||||||
{% endif %}
|
Select start and end date for a date range:
|
||||||
</p>
|
<form enctype="multipart/form-data" action="" method="post">
|
||||||
|
|
||||||
<p>The table gives the efforts you marked as Ranking Piece.
|
<table>
|
||||||
The graph shows the best segments from those pieces, plotted as
|
{{ dateform.as_table }}
|
||||||
average power (over the segment) vs the duration of the segment/
|
</table>
|
||||||
In other words: How long you can hold that power.
|
{% csrf_token %}
|
||||||
</p>
|
<input name='daterange' class="button green" type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
</li>
|
||||||
|
<li class="grid_4">
|
||||||
|
|
||||||
<p>Whenever you load or reload the page, a new calculation is started
|
<h2>Critical Power Plot</h2>
|
||||||
as a background process. The page will reload automatically when
|
|
||||||
calculation is ready.</p>
|
|
||||||
<p>At the bottom of the page, you will find predictions derived from the model.</p>
|
|
||||||
</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>
|
|
||||||
{{ dateform.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 id="theplot" class="grid_12 alpha">
|
|
||||||
|
|
||||||
<h2>Critical Power Plot</h2>
|
|
||||||
|
|
||||||
{{ the_div|safe }}
|
{{ the_div|safe }}
|
||||||
|
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
<div class="grid_12 alpha">
|
<li class="grid_2">
|
||||||
|
|
||||||
<h2>Ranking Piece Results</h2>
|
<h2>Ranking Piece Results</h2>
|
||||||
|
|
||||||
{% if rankingworkouts %}
|
{% if rankingworkouts %}
|
||||||
|
|
||||||
<table width="70%" class="listtable">
|
<table width="100%" class="listtable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th> Distance</th>
|
<th> Distance</th>
|
||||||
<th> Duration</th>
|
<th> Duration</th>
|
||||||
<th> Avg Power</th>
|
<th> Avg Power</th>
|
||||||
<th> Date</th>
|
<th> Date</th>
|
||||||
<th> Avg HR </th>
|
<th> Avg HR </th>
|
||||||
<th> Max HR </th>
|
<th> Max HR </th>
|
||||||
<th> Edit</th>
|
<th> Edit</th>
|
||||||
<tr>
|
<tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for workout in rankingworkouts %}
|
{% for workout in rankingworkouts %}
|
||||||
<tr>
|
<tr>
|
||||||
<td> {{ workout.distance }} m</td>
|
<td> {{ workout.distance }} m</td>
|
||||||
<td> {{ workout.duration |durationprint:"%H:%M:%S.%f" }} </td>
|
<td> {{ workout.duration |durationprint:"%H:%M:%S.%f" }} </td>
|
||||||
<td> {{ avgpower|lookup:workout.id }} W</td>
|
<td> {{ avgpower|lookup:workout.id }} W</td>
|
||||||
<td> {{ workout.date }} </td>
|
<td> {{ workout.date }} </td>
|
||||||
<td> {{ workout.averagehr }} </td>
|
<td> {{ workout.averagehr }} </td>
|
||||||
<td> {{ workout.maxhr }} </td>
|
<td> {{ workout.maxhr }} </td>
|
||||||
<td>
|
<td>
|
||||||
<a href="/rowers/workout/{{ workout.id }}/edit">{{ workout.name }}</a> </td>
|
<a href="/rowers/workout/{{ workout.id }}/edit">{{ workout.name }}</a> </td>
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p> No ranking workouts found </p>
|
<p> No ranking workouts found </p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
<div id="predictions" class="grid_12 alpha">
|
<li class="grid_2">
|
||||||
<h2>Pace predictions for Ranking Pieces</h2>
|
<h2>Pace predictions for Ranking Pieces</h2>
|
||||||
|
|
||||||
<p>Add non-ranking piece using the form. The piece will be added in the prediction tables below. </p>
|
<p>Add non-ranking piece using the form. The piece will be added in the prediction tables below. </p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div id="cpmodel" class="grid_6 alpha">
|
<table width="100%" class="listtable">
|
||||||
<table width="90%" class="listtable">
|
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th> Duration</th>
|
<th> Duration</th>
|
||||||
@@ -208,25 +142,25 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
</div>
|
</li>
|
||||||
|
|
||||||
<div class="grid_3">
|
<li class="grid_2">
|
||||||
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
|
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
|
||||||
{{ form.value }} {{ form.pieceunit }}
|
{{ form.value }} {{ form.pieceunit }}
|
||||||
|
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
</div>
|
|
||||||
<div class="grid_1">
|
|
||||||
minutes
|
minutes
|
||||||
</div>
|
<input name="piece" class="button green"
|
||||||
<div class="grid_2 omega">
|
action=""
|
||||||
<input name="piece" class="button green"
|
type="submit" value="Add">
|
||||||
action=""
|
</form>
|
||||||
type="submit" value="Add">
|
</li>
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</ul>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block sidebar %}
|
||||||
|
{% include 'menu_analytics.html' %}
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
@@ -286,7 +286,6 @@ def is_not_past_due(self):
|
|||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def userurl(path,member):
|
def userurl(path,member):
|
||||||
print path
|
|
||||||
pattern = re.compile('user\/\d+')
|
pattern = re.compile('user\/\d+')
|
||||||
userstring = 'user/%s' % member.id
|
userstring = 'user/%s' % member.id
|
||||||
if pattern.search(path) is not None:
|
if pattern.search(path) is not None:
|
||||||
|
|||||||
@@ -202,12 +202,12 @@ urlpatterns = [
|
|||||||
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/(?P<deltadays>\d+)$',views.otwrankings_view),
|
||||||
url(r'^otw-bests/$',views.otwrankings_view),
|
url(r'^otw-bests/$',views.otwrankings_view),
|
||||||
url(r'^(?P<theuser>\d+)/ote-ranking/(?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'^(?P<theuser>\d+)/ote-ranking/(?P<deltadays>\d+)$',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/(?P<deltadays>\d+)$',views.oterankings_view),
|
||||||
url(r'^ote-ranking/$',views.oterankings_view),
|
url(r'^ote-ranking/$',views.oterankings_view),
|
||||||
url(r'^(?P<theuser>\d+)/ote-ranking/$',views.oterankings_view),
|
url(r'^ote-ranking/user/(?P<theuser>\d+)/$',views.oterankings_view),
|
||||||
url(r'^(?P<theuser>\d+)/flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.cum_flex),
|
url(r'^(?P<theuser>\d+)/flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.cum_flex),
|
||||||
url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.cum_flex),
|
url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<startdatestring>\w+.*)/(?P<enddatestring>\w+.*)$',views.cum_flex),
|
||||||
url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)$',views.cum_flex),
|
url(r'^flexall/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)$',views.cum_flex),
|
||||||
|
|||||||
@@ -4798,6 +4798,8 @@ def oterankings_view(request,theuser=0,
|
|||||||
{'rankingworkouts':theworkouts,
|
{'rankingworkouts':theworkouts,
|
||||||
'interactiveplot':script,
|
'interactiveplot':script,
|
||||||
'the_div':div,
|
'the_div':div,
|
||||||
|
'rower':r,
|
||||||
|
'active':'nav-analysis',
|
||||||
'cpredictions':cpredictions,
|
'cpredictions':cpredictions,
|
||||||
'avgpower':avgpower,
|
'avgpower':avgpower,
|
||||||
'form':form,
|
'form':form,
|
||||||
|
|||||||
Reference in New Issue
Block a user