otw interactive power plot
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
{% load rowerfilters %}
|
||||
<h1>Workout</h1>
|
||||
<ul class="cd-accordion-menu animated">
|
||||
<li class="has-children" id="workout">
|
||||
@@ -5,10 +6,17 @@
|
||||
<label for="group-workout">Workout</label>
|
||||
<ul>
|
||||
<li id="workout-dashboard">
|
||||
{% if user.is_authenticated and workout|may_edit:request %}
|
||||
<a href="/rowers/workout/{{ workout.id }}/workflow">
|
||||
<i class="fas fa-tachometer-alt fa-fw"></i> View
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="/rowers/workout/{{ workout.id }}/workflow">
|
||||
<i class="fas fa-tachometer-alt fa-fw"></i> View
|
||||
</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
{% if user.is_authenticated and workout|may_edit:request %}
|
||||
<li id="workout-edit">
|
||||
<a href="/rowers/workout/{{ workout.id }}/edit">
|
||||
<i class="fas fa-pencil-alt fa-fw"></i> Edit
|
||||
@@ -19,6 +27,7 @@
|
||||
<i class="fas fa-pause fa-fw"></i> Intervals
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li id="workout-stats">
|
||||
<a href="/rowers/workout/{{ workout.id }}/stats">
|
||||
<i class="fal fa-table fa-fw"></i> Statistics
|
||||
@@ -28,12 +37,14 @@
|
||||
<a href="/rowers/multi-compare">
|
||||
<i class="fas fa-balance-scale fa-fw"></i> Compare
|
||||
</a>
|
||||
</li>
|
||||
</li>
|
||||
{% if user.is_authenticated and workout|may_edit:request %}
|
||||
<li id="workout-delete">
|
||||
<a href="/rowers/workout/{{ workout.id }}/delete">
|
||||
<i class="fas fa-trash-alt fa-fw"></i> Delete
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</li>
|
||||
<li class="has-children" id="flexchart">
|
||||
@@ -45,13 +56,21 @@
|
||||
<i class="fas fa-chart-line fa-fw"></i> Flex Chart
|
||||
</a>
|
||||
</li>
|
||||
{% if workout|water %}
|
||||
<li id="chart-map">
|
||||
<a href="/rowers/workout/{{ workout.id }}/map">
|
||||
<i class="fas fa-map-marked-alt fa-fw"></i> Map
|
||||
</a>
|
||||
</li>
|
||||
<li id="chart-otwpower">
|
||||
<a href="/rowers/workout/{{ workout.id }}/interactiveotwplot">
|
||||
<i class="fal fa-calculator-alt fa-fw"></i> OTW Power
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</li>
|
||||
{% if user.is_authenticated and workout|may_edit:request %}
|
||||
<li class="has-children" id="chart">
|
||||
<input type="checkbox" name="group-chart" id="group-chart">
|
||||
<label for="group-chart">Static Charts</label>
|
||||
@@ -76,11 +95,13 @@
|
||||
<i class="fas fa-heartbeat fa-fw"></i> Heart Rate (Pie)
|
||||
</a>
|
||||
</li>
|
||||
{% if workout|water %}
|
||||
<li id="chart-otwpower">
|
||||
<a href="/rowers/workout/{{ workout.id }}/addotwpowerplot">
|
||||
<i class="fas fa-chart-area fa-fw"></i> OTW Power
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</li>
|
||||
<li class="has-children" id="export">
|
||||
@@ -128,6 +149,7 @@
|
||||
<input type="checkbox" name="group-advanced" id="group-advanced">
|
||||
<label for="group-advanced">Advanced</label>
|
||||
<ul>
|
||||
{% if workout|water %}
|
||||
<li id="advanced-wind">
|
||||
<a href="/rowers/workout/{{ workout.id }}/wind">
|
||||
<i class="fas fa-pennant fa-fw"></i> Wind
|
||||
@@ -143,9 +165,11 @@
|
||||
<i class="fas fa-calculator-alt fa-fw"></i> OTW Power
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li id="advanced-instroke">
|
||||
<a href="/rowers/workout/{{ workout.id }}/instroke">
|
||||
<i class="fas fa-search-plus fa-fw"></i> In-Stroke Metrics</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul><!-- cd-accordion-menu -->
|
||||
|
||||
@@ -1,83 +1,50 @@
|
||||
{% extends "base.html" %}
|
||||
{% extends "newbase.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load rowerfilters %}
|
||||
|
||||
{% block title %}View Workout {% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% block main %}
|
||||
|
||||
<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>
|
||||
<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>
|
||||
|
||||
{{ interactiveplot |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, false, 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>
|
||||
{{ interactiveplot |safe }}
|
||||
|
||||
|
||||
<div id="workouts" class="grid_12 alpha">
|
||||
<h1>Interactive Plot</h1>
|
||||
|
||||
|
||||
<h1>Interactive Plot</h1>
|
||||
|
||||
{% if user.is_authenticated and mayedit %}
|
||||
<div class="grid_2 alpha">
|
||||
<p>
|
||||
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/edit">Edit Workout</a>
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid_2">
|
||||
<p>
|
||||
<a class="button gray small" href="/rowers/workout/{{ workout.id }}/advanced">Advanced Edit</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<div class="grid_2">
|
||||
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/wind">Edit Wind Data</a>
|
||||
</div>
|
||||
<div class="grid_2">
|
||||
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/stream">Edit Stream Data</a>
|
||||
</div>
|
||||
<div class="grid_2">
|
||||
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/otwsetpower">OTW Power</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div id="theplot" class="grid_12 alpha flexplot">
|
||||
<ul class="main-content">
|
||||
<li class="grid_4">
|
||||
|
||||
{{ the_div|safe }}
|
||||
</div>
|
||||
</li>
|
||||
<li class="grid_4">
|
||||
<p>
|
||||
<h2>Notes</h2>
|
||||
<ul>
|
||||
<li>
|
||||
Is your erg pace slower than you expected? This may be a sign of room for improvement regarding your technique. An alternative explanation is that your team mates are fatter than they told you! For example, put 80.0 kg if your four consists of 2 70kg guys and 2 90kg guys.
|
||||
</li>
|
||||
<li>
|
||||
In order to speed up the calculation, we are running the calculation only for every 10th datapoint, using interpolation in between. Some very fine pace shifts may disappear.
|
||||
</li>
|
||||
<li>
|
||||
While the wind and stream correction is fairly reliable, the OTW to OTE conversion sometimes throws errors. Those data points are omitted and replaced by interpolated values. We are sorry if this messed up some of your plots.
|
||||
</li>
|
||||
<li>
|
||||
Read more details about the way we calculate things <a href="/rowers/physics">here</a>.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<div class="grid_12">
|
||||
<p>
|
||||
<h3>Notes</h3>
|
||||
<ul>
|
||||
<li>Is your erg pace slower than you expected? This may be a sign of room for improvement regarding your technique. An alternative explanation is that your team mates are fatter than they told you! For example, put 80.0 kg if your four consists of 2 70kg guys and 2 90kg guys.</li>
|
||||
<li>In order to speed up the calculation, we are running the calculation only for every 10th datapoint, using interpolation in between. Some very fine pace shifts may disappear.</li>
|
||||
<li>While the wind and stream correction is fairly reliable, the OTW to OTE conversion sometimes throws errors. Those data points are omitted and replaced by interpolated values. We are sorry if this messed up some of your plots.</li>
|
||||
<li>Read more details about the way we calculate things <a href="/rowers/physics"</a>here</a>.</li>
|
||||
</ul>
|
||||
</p>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
{% block sidebar %}
|
||||
{% include 'menu_workout.html' %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -13,6 +13,8 @@ from rowers.plannedsessions import (
|
||||
race_can_register, race_can_submit,race_rower_status
|
||||
)
|
||||
|
||||
from rowers.types import otwtypes
|
||||
|
||||
def strfdelta(tdelta):
|
||||
minutes,seconds = divmod(tdelta.seconds,60)
|
||||
tenths = int(tdelta.microseconds/1e5)
|
||||
@@ -48,6 +50,10 @@ def secondstotimestring(tdelta):
|
||||
|
||||
return res
|
||||
|
||||
@register.filter
|
||||
def water(workout):
|
||||
return workout.workouttype in otwtypes
|
||||
|
||||
@register.filter
|
||||
def ddays(ddelta):
|
||||
return ddelta.days+1
|
||||
@@ -120,6 +126,18 @@ def is_session_manager(id,user):
|
||||
|
||||
return ps.manager == user
|
||||
|
||||
from rowers.models import checkworkoutuser
|
||||
|
||||
@register.filter
|
||||
def may_edit(workout,request):
|
||||
mayedit = 0
|
||||
if request.user == workout.user.user:
|
||||
mayedit = True
|
||||
if checkworkoutuser(request.user,workout):
|
||||
mayedit = True
|
||||
|
||||
return mayedit
|
||||
|
||||
@register.filter(name='times')
|
||||
def times(number):
|
||||
return range(number)
|
||||
|
||||
@@ -7132,6 +7132,12 @@ def workout_otwsetpower_view(request,id=0,message="",successmessage=""):
|
||||
w = get_workout(id)
|
||||
r = getrower(request.user)
|
||||
|
||||
mayedit = 0
|
||||
if request.user == w.user.user:
|
||||
mayedit=1
|
||||
if checkworkoutuser(request.user,w):
|
||||
mayedit=1
|
||||
|
||||
if (checkworkoutuser(request.user,w)==False):
|
||||
message = "You are not allowed to edit this workout"
|
||||
messages.error(request,message)
|
||||
@@ -7246,6 +7252,7 @@ def workout_otwsetpower_view(request,id=0,message="",successmessage=""):
|
||||
'otwsetpower.html',
|
||||
{'workout':w,
|
||||
'rower':w,
|
||||
'mayedit':mayedit,
|
||||
'active':'nav-workouts',
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'teams':get_my_teams(request.user),
|
||||
@@ -7255,6 +7262,12 @@ def workout_otwsetpower_view(request,id=0,message="",successmessage=""):
|
||||
@login_required()
|
||||
def instroke_view(request,id=0):
|
||||
w = get_workout(id)
|
||||
r = getrower(request.user)
|
||||
mayedit = 0
|
||||
if request.user == w.user.user:
|
||||
mayedit=1
|
||||
if checkworkoutuser(request.user,w):
|
||||
mayedit=1
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
@@ -7298,6 +7311,7 @@ def instroke_view(request,id=0):
|
||||
'rower':r,
|
||||
'active':'nav-workouts',
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'mayedit':mayedit,
|
||||
'teams':get_my_teams(request.user),
|
||||
'instrokemetrics':instrokemetrics,
|
||||
})
|
||||
@@ -7727,6 +7741,12 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
|
||||
r = getrower(request.user)
|
||||
w = get_workout(id)
|
||||
|
||||
mayedit = 0
|
||||
if request.user == w.user.user:
|
||||
mayedit=1
|
||||
if checkworkoutuser(request.user,w):
|
||||
mayedit=1
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/list-workouts',
|
||||
@@ -7877,6 +7897,7 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
|
||||
'teams':get_my_teams(request.user),
|
||||
'workout':w,
|
||||
'rower':r,
|
||||
'mayedit':mayedit,
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'active':'nav-workouts',
|
||||
'workstrokesonly':workstrokesonly,
|
||||
@@ -8555,14 +8576,31 @@ def workout_biginteractive_view(request,id=0,message="",successmessage=""):
|
||||
|
||||
# The interactive plot with wind corrected pace for OTW outings
|
||||
def workout_otwpowerplot_view(request,id=0,message="",successmessage=""):
|
||||
row = get_workout(id)
|
||||
w = get_workout(id)
|
||||
r = getrower(request.user)
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/list-workouts',
|
||||
'name':'Workouts'
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(w.id)
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_otwpowerplot_view,kwargs={'id':id}),
|
||||
'name': 'Interactive OTW Power Plot'
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
# check if user is owner of this workout
|
||||
|
||||
|
||||
# create interactive plot
|
||||
f1 = row.csvfilename
|
||||
u = row.user.user
|
||||
f1 = w.csvfilename
|
||||
u = w.user.user
|
||||
# r = getrower(u)
|
||||
|
||||
promember=0
|
||||
@@ -8572,7 +8610,7 @@ def workout_otwpowerplot_view(request,id=0,message="",successmessage=""):
|
||||
result = request.user.is_authenticated() and ispromember(request.user)
|
||||
if result:
|
||||
promember=1
|
||||
if request.user == row.user.user:
|
||||
if request.user == w.user.user:
|
||||
mayedit=1
|
||||
|
||||
# create interactive plot
|
||||
@@ -8585,7 +8623,10 @@ def workout_otwpowerplot_view(request,id=0,message="",successmessage=""):
|
||||
|
||||
return render(request,
|
||||
'otwinteractive.html',
|
||||
{'workout':row,
|
||||
{'workout':w,
|
||||
'rower':r,
|
||||
'active':'nav-workouts',
|
||||
'breadcrumbs':breadcrumbs,
|
||||
'teams':get_my_teams(request.user),
|
||||
'interactiveplot':script,
|
||||
'the_div':div,
|
||||
@@ -9354,6 +9395,7 @@ def course_upload_view(request):
|
||||
def workout_add_chart_view(request,id,plotnr=1):
|
||||
|
||||
w = get_workout(id)
|
||||
r = getrower(request.user)
|
||||
|
||||
plotnr = int(plotnr)
|
||||
|
||||
@@ -9378,10 +9420,9 @@ def workout_add_chart_view(request,id,plotnr=1):
|
||||
except KeyError:
|
||||
request.session['async_tasks'] = [(jobid,'make_plot')]
|
||||
|
||||
try:
|
||||
url = request.session['referer']
|
||||
except KeyError:
|
||||
url = "/rowers/workout/"+str(w.id)+"/edit"
|
||||
|
||||
url = reverse(r.defaultlandingpage,kwargs={'id':str(w.id)})
|
||||
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
|
||||
@@ -14617,11 +14658,22 @@ class WorkoutDelete(DeleteView):
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
mayedit=0
|
||||
if not self.request.user.is_anonymous():
|
||||
r = getrower(self.request.user)
|
||||
result = self.request.user.is_authenticated() and ispromember(self.request.user)
|
||||
if result:
|
||||
promember=1
|
||||
if self.request.user == self.object.user.user:
|
||||
mayedit=1
|
||||
|
||||
context['active'] = 'nav-workouts'
|
||||
context['rower'] = getrower(self.request.user)
|
||||
context['breadcrumbs'] = breadcrumbs
|
||||
context['workout'] = self.object
|
||||
context['mayedit'] = mayedit
|
||||
context['promember'] = promember
|
||||
|
||||
return context
|
||||
|
||||
|
||||
Reference in New Issue
Block a user