Private
Public Access
1
0

Merge branch 'feature/effectivedrivelength' into develop

This commit is contained in:
Sander Roosendaal
2017-03-04 20:28:39 +01:00
8 changed files with 291 additions and 307 deletions

View File

@@ -1020,7 +1020,10 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
drivelength = arclength
else:
drivelength = driveenergy/(averageforce*4.44822)
slip = rowdatadf.ix[:,'slip']
totalangle = finish-catch
effectiveangle = finish-wash-catch-slip
if windowsize > 3 and windowsize<len(slip):
wash = savgol_filter(wash,windowsize,3)
slip = savgol_filter(slip,windowsize,3)
@@ -1029,6 +1032,8 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
peakforceangle = savgol_filter(peakforceangle,windowsize,3)
driveenergy = savgol_filter(driveenergy,windowsize,3)
drivelength = savgol_filter(drivelength,windowsize,3)
totalangle = savgol_filter(totalangle,windowsize,3)
effectiveangle = savgol_filter(effectiveangle,windowsize,3)
data['wash'] = wash
data['catch'] = catch
data['slip'] = slip
@@ -1036,6 +1041,8 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
data['peakforceangle'] = peakforceangle
data['driveenergy'] = driveenergy
data['drivelength'] = drivelength
data['totalangle'] = totalangle
data['effectiveangle'] = effectiveangle
except KeyError:
pass

View File

@@ -260,7 +260,7 @@ class WorkoutMultipleCompareForm(forms.Form):
from rowers.interactiveplots import axlabels
axlabels.pop('None')
axlabels = list(axlabels.items())
axlabels = list(sorted(axlabels.items(), key = lambda x:x[1]))
class ChartParamChoiceForm(forms.Form):

View File

@@ -1,4 +1,3 @@
from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage
from rowingdata import rower as rrower
from rowingdata import main as rmain
@@ -51,66 +50,36 @@ import stravastuff
from rowers.dataprep import rdata
import rowers.dataprep as dataprep
axlabels = {
'time': 'Time',
'distance': 'Distance (m)',
'cumdist': 'Cumulative Distance (m)',
'hr': 'Heart Rate (bpm)',
'spm': 'Stroke Rate (spm)',
'pace': 'Pace (/500m)',
'power': 'Power (Watt)',
'averageforce': 'Average Drive Force (lbs)',
'drivelength': 'Drive Length (m)',
'peakforce': 'Peak Drive Force (lbs)',
'forceratio': 'Average/Peak Drive Force Ratio',
'driveenergy': 'Work per Stroke (J)',
'drivespeed': 'Drive Speed (m/s)',
'slip': 'Slip (degrees)',
'catch': 'Catch (degrees)',
'finish': 'Finish (degrees)',
'wash': 'Wash (degrees)',
'peakforceangle': 'Peak Force Angle (degrees)',
'rhythm': 'Stroke Rhythm (%)',
'None': '',
}
axes = (
('time','Time',0,1e5,'basic'),
('distance', 'Distance (m)',0,1e5,'basic'),
('cumdist', 'Cumulative Distance (m)',0,1e5,'basic'),
('hr','Heart Rate (bpm)',100,200,'basic'),
('spm', 'Stroke Rate (spm)',15,45,'basic'),
('pace', 'Pace (/500m)',1.0e3*210,1.0e3*75,'basic'),
('power', 'Power (Watt)',0,600,'basic'),
('averageforce', 'Average Drive Force (lbs)',0,200,'pro'),
('drivelength', 'Drive Length (m)',0.5,2.0,'pro'),
('peakforce', 'Peak Drive Force (lbs)',0,400,'pro'),
('forceratio', 'Average/Peak Force Ratio',0,1,'pro'),
('driveenergy', 'Work per Stroke (J)',0,1000,'pro'),
('drivespeed', 'Drive Speed (m/s)',0,4,'pro'),
('slip', 'Slip (degrees)',0,20,'pro'),
('catch', 'Catch (degrees)',-40,-75,'pro'),
('finish', 'Finish (degrees)',20,55,'pro'),
('wash', 'Wash (degrees)',0,30,'pro'),
('peakforceangle', 'Peak Force Angle (degrees)',-20,20,'pro'),
('totalangle', 'Drive Length (deg)',40,140,'pro'),
('effectiveangle', 'Effective Drive Length (deg)',40,140,'pro'),
('rhythm', 'Stroke Rhythm (%)',20,55,'pro'),
('None', 'None',0,1,'basic'),
)
yaxminima = {
'hr':100,
'spm':15,
'pace': 1.0e3*210,
'power': 0,
'averageforce': 0,
'peakforce': 0,
'forceratio':0,
'drivelength':0.5,
'driveenergy': 0,
'drivespeed': 0,
'slip': 0,
'catch': -40,
'finish': 20,
'wash': 0,
'peakforceangle': -20,
'rhythm':20,
}
axlabels = {ax[0]:ax[1] for ax in axes}
yaxmaxima = {
'hr':200,
'spm':45,
'pace': 1.0e3*75,
'power': 600,
'averageforce':200,
'peakforce':400,
'forceratio':1,
'drivelength':2.0,
'driveenergy': 1000,
'drivespeed':4,
'slip': 15,
'catch': -75,
'finish': 55,
'wash': 30,
'peakforceangle': 20,
'rhythm':55,
}
yaxminima = {ax[0]:ax[2] for ax in axes}
yaxmaxima = {ax[0]:ax[3] for ax in axes}
def tailwind(bearing,vwind,winddir):
""" Calculates head-on head/tailwind in direction of rowing
@@ -996,7 +965,7 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
line_dash=[6,6],line_width=2)
y2means = y1means
xlabel = Label(x=370,y=130,x_units='screen',y_units='screen',
xlabel = Label(x=100,y=130,x_units='screen',y_units='screen',
text=xparam+": {x1mean:6.2f}".format(x1mean=x1mean),
background_fill_alpha=.7,
text_color='green',
@@ -1008,7 +977,7 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
plot.add_layout(y1means)
y1label = Label(x=370,y=100,x_units='screen',y_units='screen',
y1label = Label(x=100,y=100,x_units='screen',y_units='screen',
text=yparam1+": {y1mean:6.2f}".format(y1mean=y1mean),
background_fill_alpha=.7,
text_color='blue',
@@ -1048,8 +1017,8 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
plot.add_layout(y2means)
y2label = Label(x=370,y=70,x_units='screen',y_units='screen',
text=yparam2+": {y2mean:6.2f}".format(y2mean=y2mean),
y2label = Label(x=100,y=70,x_units='screen',y_units='screen',
text=axlabels[yparam2]+": {y2mean:6.2f}".format(y2mean=y2mean),
background_fill_alpha=.7,
text_color='red',
)
@@ -1196,7 +1165,7 @@ def interactive_flex_chart2(id=0,promember=0,
columns = [xparam,yparam1,yparam2,
'ftime','distance','fpace',
'power','hr','spm','driveenergy',
'time','pace','workoutstate']
'time','pace','workoutstate','time']
rowdata = dataprep.getsmallrowdata_db(columns,ids=[id],doclean=True)
@@ -1222,7 +1191,7 @@ def interactive_flex_chart2(id=0,promember=0,
try:
rowdata['x1'] = rowdata.ix[:,xparam]
except KeyError:
rowdata['x1'] = 0*rowdata.ix[:'time']
rowdata['x1'] = 0*rowdata.ix[:,1]
try:
rowdata['y1'] = rowdata.ix[:,yparam1]
@@ -1251,7 +1220,10 @@ def interactive_flex_chart2(id=0,promember=0,
# average values
if xparam != 'time':
x1mean = rowdata['x1'].mean()
try:
x1mean = rowdata['x1'].mean()
except TypeError:
x1mean = 0
else:
x1mean = 0
@@ -1317,8 +1289,8 @@ def interactive_flex_chart2(id=0,promember=0,
line_dash=[6,6],line_width=2)
y2means = y1means
xlabel = Label(x=370,y=130,x_units='screen',y_units='screen',
text=xparam+": {x1mean:6.2f}".format(x1mean=x1mean),
xlabel = Label(x=100,y=130,x_units='screen',y_units='screen',
text=axlabels[xparam]+": {x1mean:6.2f}".format(x1mean=x1mean),
background_fill_alpha=.7,
text_color='green',
)
@@ -1330,8 +1302,8 @@ def interactive_flex_chart2(id=0,promember=0,
plot.add_layout(y1means)
y1label = Label(x=370,y=100,x_units='screen',y_units='screen',
text=yparam1+": {y1mean:6.2f}".format(y1mean=y1mean),
y1label = Label(x=100,y=100,x_units='screen',y_units='screen',
text=axlabels[yparam1]+": {y1mean:6.2f}".format(y1mean=y1mean),
background_fill_alpha=.7,
text_color='blue',
)
@@ -1405,8 +1377,8 @@ def interactive_flex_chart2(id=0,promember=0,
plot.add_layout(y2means)
y2label = Label(x=370,y=70,x_units='screen',y_units='screen',
text=yparam2+": {y2mean:6.2f}".format(y2mean=y2mean),
y2label = Label(x=100,y=70,x_units='screen',y_units='screen',
text=axlabels[yparam2]+": {y2mean:6.2f}".format(y2mean=y2mean),
background_fill_alpha=.7,
text_color='red',
)
@@ -1731,12 +1703,15 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line',
group = datadf[datadf['workoutid']==int(id)].copy()
group.sort_values(by='time',ascending=True,inplace=True)
group['x'] = group[xparam]
group['y'] = group[yparam]
try:
group['y'] = group[yparam]
except KeyError:
group['y'] = 0.0*group['x']
ymean = group['y'].mean()
ylabel = Label(x=100,y=70+20*cntr,
x_units='screen',y_units='screen',
text=yparam+": {ymean:6.2f}".format(ymean=ymean),
text=axlabels[yparam]+": {ymean:6.2f}".format(ymean=ymean),
background_fill_alpha=.7,
text_color=color,
)
@@ -1849,11 +1824,14 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
else:
rowdata2.sort_values(by='time',ascending=True,inplace=True)
x1 = rowdata1.ix[:,xparam]
x2 = rowdata2.ix[:,xparam]
try:
x1 = rowdata1.ix[:,xparam]
x2 = rowdata2.ix[:,xparam]
y1 = rowdata1.ix[:,yparam]
y2 = rowdata2.ix[:,yparam]
y1 = rowdata1.ix[:,yparam]
y2 = rowdata2.ix[:,yparam]
except KeyError:
return "","No valid Data Available"
x_axis_type = 'linear'
y_axis_type = 'linear'
@@ -1976,7 +1954,7 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
plot.title.text = row1.name+' vs '+row2.name
plot.title.text_font_size=value("1.2em")
plot.xaxis.axis_label = axlabels[xparam]
plot.yaxis.axis_label = axlabels[yparam]
if xparam == 'time':
plot.xaxis[0].formatter = DatetimeTickFormatter(

View File

@@ -498,6 +498,8 @@ class StrokeData(models.Model):
wash = models.FloatField(default=0,null=True,verbose_name='Wash')
peakforceangle = models.FloatField(default=0,null=True,verbose_name='Peak Force Angle')
rhythm = models.FloatField(default=1.0,null=True,verbose_name='Rhythm')
totalangle = models.FloatField(default=0.0,null=True,verbose_name='Total Stroke Length (deg)')
effectiveangle = models.FloatField(default=0.0,null=True,verbose_name='Effective Stroke Length (deg)')
# A wrapper around the png files
class GraphImage(models.Model):

View File

@@ -6,144 +6,134 @@
{% block content %}
<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 }}
{{ 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, 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>
<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, 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>
<div id="navigation" class="grid_12 alpha">
{% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2 suffix_8 omega">
<p>
<a class="button gray small" href="/rowers/workout/compare/{{ id }}/advanced">Advanced Edit</a>
</p>
{% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha">
<p>
<a class="button gray small" href="/rowers/workout/{{ id }}/edit">Edit Workout</a>
</p>
</div>
<div class="grid_2 suffix_8 omega">
<p>
<a class="button gray small" href="/rowers/workout/compare/{{ id }}/advanced">Advanced Edit</a>
</p>
</div>
{% endif %}
</div>
{% endif %}
</div>
<div id="other" class="grid_12 alpha">
<div class="grid_2 alpha">
<a class="button blue small"
href="/rowers/workout/compare/{{ id2 }}/{{ id1 }}/{{ xparam }}/{{ yparam }}/{{ plottype }}">Swap Workouts</a>
</div>
<div class="grid_2">
<a class="button blue small"
href="/rowers/workout/{{ id1 }}/edit">Edit Workout</a>
</div>
<div class="grid_2 suffix_6 omega">
<a class="button blue small"
href="/rowers/workout/{{ id1 }}/advanced">Advanced Edit</a>
</div>
<div class="grid_2 alpha">
<a class="button blue small"
href="/rowers/workout/compare/{{ id2 }}/{{ id1 }}/{{ xparam }}/{{ yparam }}/{{ plottype }}">Swap Workouts</a>
</div>
<div class="grid_2">
<a class="button blue small"
href="/rowers/workout/{{ id1 }}/edit">Edit Workout</a>
</div>
<div class="grid_2 suffix_6 omega">
<a class="button blue small"
href="/rowers/workout/{{ id1 }}/advanced">Advanced Edit</a>
</div>
</div>
<p>&nbsp;</p>
<div id="plotbuttons" class="grid_12 alpha">
<div id="x-axis" class="grid_6 alpha">
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button blue small dropbtn">X-axis</button>
<div class="dropdown-content">
{% for key, value in axchoicesbasic.items %}
{% if key != 'None' %}
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1}}/{{ id2 }}/{{ key }}/{{ yparam }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
{% for key, value in axchoicespro.items %}
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ key }}/{{ yparam }}/{{ plottype }}">{{ value }}</a>
{% endfor %}
{% else %}
{% for key, value in axchoicespro.items %}
<a class="button rosy small" href="/rowers/promembership">{{ value }}</a>
{% endfor %}
{% endif %}
</div>
</div>
<div id="x-axis" class="grid_6 alpha">
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button blue small dropbtn">X-axis</button>
<div class="dropdown-content">
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/time/{{ yparam }}/{{ plottype }}">Time</a>
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/distance/{{ yparam }}/{{ plottype }}">Distance</a>
{% if promember %}
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/power/{{ yparam }}/scatter">Power</a>
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/hr/{{ yparam }}/scatter">HR</a>
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/spm/{{ yparam }}/scatter">SPM</a>
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/peakforce/{{ yparam }}/scatter">Peak Force</a>
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/averageforce/{{ yparam }}/scatter">Average Force</a>
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/forceratio/{{ yparam }}/scatter">Average/Peak Force Ratio</a>
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/drivelength/{{ yparam }}/scatter">Drive Length</a>
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/driveenergy/{{ yparam }}/scatter">Work per Stroke</a>
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/drivespeed/{{ yparam }}/scatter">Drive Speed</a>
{% else %}
<a class="button rosy small" href="/rowers/promembership">Power (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">HR (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">SPM (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Peak Force (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Average Force (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Average/Peak Force Ratio (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Length (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Work per Stroke (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Speed (Pro)</a>
{% endif %}
</div>
</div>
<div class="grid_2 suffix_2 omega dropdown">
<button class="grid_2 alpha button blue small dropbtn">Y-axis</button>
<div class="dropdown-content">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/pace/{{ plottype }}">Pace</a>
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/hr/{{ plottype }}">HR</a>
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/spm/{{ plottype }}">SPM</a>
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/power/{{ plottype }}">Power</a>
{% if promember %}
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/peakforce/{{ plottype }}">Peak Force</a>
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/averageforce/{{ plottype }}">Average Force</a>
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/forceratio/{{ plottype }}">Average/Peak Force Ratio</a>
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/drivelength/{{ plottype }}">Drive Length</a>
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/driveenergy/{{ plottype }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/drivespeed/{{ plottype }}">Drive Speed</a>
{% else %}
<a class="button rosy small" href="/rowers/promembership">Peak Force (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Average Force (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Average/Peak Force Ratio (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Length (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Work per Stroke (Pro)</a>
{% endif %}
</div>
</div>
<div class="grid_2 suffix_2 omega dropdown">
<button class="grid_2 alpha button blue small dropbtn">Y-axis</button>
<div class="dropdown-content">
{% for key, value in axchoicesbasic.items %}
{% if key not in noylist and key != 'None' %}
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ key }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ key }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% else %}
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endif %}
{% endfor %}
{% endif %}
</div>
</div>
</div>
<div id="y-axis" class="grid_6 omega">
<div class="grid_2 prefix_2 alpha">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ yparam }}/line">Line Plot</a>
</div>
<div class="grid_2 omega">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ yparam }}/scatter">Scatter Plot</a>
</div>
</div>
</div>
<div id="y-axis" class="grid_6 omega">
<div class="grid_2 prefix_2 alpha">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ yparam }}/line">Line Plot</a>
</div>
<div class="grid_2 omega">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ yparam }}/scatter">Scatter Plot</a>
</div>
</div>
</div>
<div id="theplot" class="grid_12 alpha flexplot">
{{ the_div|safe }}
{{ the_div|safe }}
</div>

View File

@@ -47,13 +47,13 @@
<ul>
<li>Advantages
<ul>
<li>It may take up to five minutes for the workout to show up
on the site.</li>
<li>It's a simple process, which can be automated.</li>
</ul>
</li>
<li>Disadvantages
<ul>
<li>It's a simple process, which can be automated.</li>
<li>It may take up to five minutes for the workout to show up
on the site.</li>
</ul>
</li>
</ul>
@@ -86,7 +86,7 @@
<li>The API is not stable and not fully tested yet.</li>
<li>You need to register your app with us. We can revoke your
permissions if you misuse them.</li>
<li>The first time user must grant permissions to your app.</li>
<li>The user user must grant permissions to your app.</li>
<li>You need to manage authorization tokens.</li>
</ul>
</li>

View File

@@ -51,122 +51,70 @@
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button blue small dropbtn">X-axis</button>
<div class="dropdown-content">
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/time/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">Time</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/distance/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">Distance</a>
{% for key, value in axchoicesbasic.items %}
{% if key != 'None' %}
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/{{ key }}/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/power/{{ yparam1 }}/{{ yparam2 }}/scatter">Power</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/hr/{{ yparam1 }}/{{ yparam2 }}/scatter">HR</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/spm/{{ yparam1 }}/{{ yparam2 }}/scatter">SPM</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/peakforce/{{ yparam1 }}/{{ yparam2 }}/scatter">Peak Force</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/averageforce/{{ yparam1 }}/{{ yparam2 }}/scatter">Average Force</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/forceratio/{{ yparam1 }}/{{ yparam2 }}/scatter">Average/Peak force ratio</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/drivelength/{{ yparam1 }}/{{ yparam2 }}/scatter">Drive Length</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/driveenergy/{{ yparam1 }}/{{ yparam2 }}/scatter">Work per Stroke</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/drivespeed/{{ yparam1 }}/{{ yparam2 }}/scatter">Drive Speed</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/catch/{{ yparam1 }}/{{ yparam2 }}/scatter">Catch Angle</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/finish/{{ yparam1 }}/{{ yparam2 }}/scatter">Finish Angle</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/slip/{{ yparam1 }}/{{ yparam2 }}/scatter">Slip</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/wash/{{ yparam1 }}/{{ yparam2 }}/scatter">Wash</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/peakforceangle/{{ yparam1 }}/{{ yparam2 }}/scatter">Peak Force Angle</a>
{% for key, value in axchoicespro.items %}
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/{{ key }}/{{ yparam1 }}/{{ yparam2 }}/scatter">{{ value }}</a>
{% endfor %}
{% else %}
<a class="button rosy small" href="/rowers/promembership">Power (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">HR (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">SPM (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Peak Force (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Average Force (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Average/Peak Force Ratio (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Length (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Work per Stroke (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Speed (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Catch Angle (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Finish Angle (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Slip (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Wash (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Peak Force Angle (Pro)</a>
{% for key, value in axchoicespro.items %}
<a class="button rosy small" href="/rowers/promembership">{{ value }}</a>
{% endfor %}
{% endif %}
</div>
</div>
<div class="grid_2 dropdown">
<div id="left-y" class="grid_2 dropdown">
<button class="grid_2 alpha button blue small dropbtn">Left</button>
<div class="dropdown-content">
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/pace/{{ yparam2 }}/{{ plottype }}">Pace</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/hr/{{ yparam2 }}/{{ plottype }}">HR</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/spm/{{ yparam2 }}/{{ plottype }}">SPM</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/power/{{ yparam2 }}/{{ plottype }}">Power</a>
{% for key, value in axchoicesbasic.items %}
{% if key not in noylist and key != 'None' %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/peakforce/{{ yparam2 }}/{{ plottype }}">Peak Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/averageforce/{{ yparam2 }}/{{ plottype }}">Average Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/forceratio/{{ yparam2 }}/{{ plottype }}">Average/Peak Force Ratio</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/drivelength/{{ yparam2 }}/{{ plottype }}">Drive Length</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/driveenergy/{{ yparam2 }}/{{ plottype }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/drivespeed/{{ yparam2 }}/{{ plottype }}">Drive Speed</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/rhythm/{{ yparam2 }}/{{ plottype }}">Drive Rhythm</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/catch/{{ yparam2 }}/{{ plottype }}">Catch Angle</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/finish/{{ yparam2 }}/{{ plottype }}">Finish Angle</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/slip/{{ yparam2 }}/{{ plottype }}">Slip</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/wash/{{ yparam2 }}/{{ plottype }}">Wash</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/peakforceangle/{{ yparam2 }}/{{ plottype }}">Peak Force Angle</a>
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ key }}/{{ yparam2 }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% else %}
<a class="button rosy small" href="/rowers/promembership">Peak Force (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Average Force (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Average/Peak Force Ratio (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Length (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Work per Stroke (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Speed (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Rhythm (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Catch Angle (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Finish Angle(Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Wash (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Slip (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Peak Force Angle (Pro)</a>
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endif %}
{% endfor %}
{% endif %}
</div>
</div>
<div class="grid_2 dropdown omega">
<div id="right-y" class="grid_2 dropdown omega">
<button class="grid_2 alpha button blue small dropbtn">Right</button>
<div class="dropdown-content">
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/hr/{{ plottype }}">HR</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/spm/{{ plottype }}">SPM</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/power/{{ plottype }}">Power</a>
{% for key, value in axchoicesbasic.items %}
{% if key not in noylist %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/peakforce/{{ plottype }}">Peak Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/averageforce/{{ plottype }}">Average Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/forceratio/{{ plottype }}">Average/Peak Force Ratio</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/drivelength/{{ plottype }}">Drive Length</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/driveenergy/{{ plottype }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/drivespeed/{{ plottype }}">Drive Speed</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/rhythm/{{ plottype }}">Drive Rhythm</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/catch/{{ plottype }}">Catch Angle</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/finish/{{ plottype }}">Finish Angle</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/slip/{{ plottype }}">Slip</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/wash/{{ plottype }}">Wash</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/peakforceangle/{{ plottype }}">Peak Force Angle</a>
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% else %}
<a class="button rosy small" href="/rowers/promembership">Peak Force (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Average Force (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Average/Peak Force Ratio (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Length (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Work per Stroke (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Speed (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Rhythm (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Catch Angle (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Finish Angle (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Slip (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Wash (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Peak Force Angle (Pro)</a>
{% for key, value in axchoicespro.items %}
{% if key not in noylist %}
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
{% endif %}
{% endfor %}
{% endif %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/None/{{ plottype }}">None</a>
</div>
</div>

View File

@@ -3154,10 +3154,6 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
fieldlist,fielddict = dataprep.getstatsfields()
fielddict.pop('workoutstate')
print "aap"
print datadf['catch'].mean()
print "noot"
for field,verbosename in fielddict.iteritems():
thedict = {
@@ -3257,6 +3253,10 @@ def workout_comparison_view(request,id1=0,id2=0,xparam='distance',yparam='spm'):
promember=promember)
script = res[0]
div = res[1]
axchoicesbasic = {ax[0]:ax[1] for ax in axes if ax[4]=='basic'}
axchoicespro = {ax[0]:ax[1] for ax in axes if ax[4]=='pro'}
noylist = ["time","distance"]
axchoicesbasic.pop("cumdist")
return render(request,
@@ -3264,6 +3264,9 @@ def workout_comparison_view(request,id1=0,id2=0,xparam='distance',yparam='spm'):
{'interactiveplot':script,
'the_div':div,
'id1':id1,
'id2':id2,
'axchoicesbasic':axchoicesbasic,
'axchoicespro':axchoicespro,
'noylist':noylist,
'xparam':xparam,
'yparam':yparam,
@@ -3287,12 +3290,33 @@ def workout_comparison_view2(request,id1=0,id2=0,xparam='distance',
promember=promember,plottype=plottype)
script = res[0]
div = res[1]
axchoicesbasic = {ax[0]:ax[1] for ax in axes if ax[4]=='basic'}
axchoicespro = {ax[0]:ax[1] for ax in axes if ax[4]=='pro'}
noylist = ["time","distance"]
axchoicesbasic.pop("cumdist")
row1 = Workout.objects.get(id=id1)
row2 = Workout.objects.get(id=id2)
if row1.workouttype != 'water' or row2.workouttype != 'water':
axchoicespro.pop('slip')
axchoicespro.pop('wash')
axchoicespro.pop('catch')
axchoicespro.pop('finish')
axchoicespro.pop('totalangle')
axchoicespro.pop('effectiveangle')
axchoicespro.pop('peakforceangle')
return render(request,
'comparisonchart2.html',
{'interactiveplot':script,
'the_div':div,
'id1':id1,
'id2':id2,
'axchoicesbasic':axchoicesbasic,
'axchoicespro':axchoicespro,
'noylist':noylist,
'xparam':xparam,
'yparam':yparam,
@@ -3433,6 +3457,12 @@ def workout_flexchart3_view(request,*args,**kwargs):
# div = res[1]
# js_resources = res[2]
# css_resources = res[3]
axchoicesbasic = {ax[0]:ax[1] for ax in axes if ax[4]=='basic'}
axchoicespro = {ax[0]:ax[1] for ax in axes if ax[4]=='pro'}
noylist = ["time","distance"]
axchoicesbasic.pop("cumdist")
if row.workouttype == 'water':
return render(request,
@@ -3447,13 +3477,25 @@ def workout_flexchart3_view(request,*args,**kwargs):
'yparam2':yparam2,
'plottype':plottype,
'mayedit':mayedit,
'promember':promember,
'axchoicesbasic':axchoicesbasic,
'axchoicespro':axchoicespro,
'noylist':noylist,
'workstrokesonly': not workstrokesonly,
'favoritenr':favoritenr,
'maxfav':maxfav,
})
else:
axchoicespro.pop('slip')
axchoicespro.pop('wash')
axchoicespro.pop('catch')
axchoicespro.pop('finish')
axchoicespro.pop('totalangle')
axchoicespro.pop('effectiveangle')
axchoicespro.pop('peakforceangle')
return render(request,
return render(request,
'flexchart3otw.html',
{'the_script':script,
'the_div':div,
@@ -3463,6 +3505,9 @@ def workout_flexchart3_view(request,*args,**kwargs):
'xparam':xparam,
'yparam1':yparam1,
'yparam2':yparam2,
'plottype':plottype,
'axchoicesbasic':axchoicesbasic,
'axchoicespro':axchoicespro,
'noylist':noylist,
'mayedit':mayedit,
'promember':promember,
@@ -3693,12 +3738,26 @@ def workout_comment_view(request,id=0):
return HttpResponseRedirect(url)
form = WorkoutCommentForm()
return render(request,
'workout_comments.html',
{'workout':w,
'comments':comments,
'form':form,
g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
if (len(g)<=3):
return render(request,
'workout_comments.html',
{'workout':w,
'graphs1':g[0:3],
'comments':comments,
'form':form,
})
else:
return render(request,
'workout_comments.html',
{'workout':w,
'graphs1':g[0:3],
'graphs1':g[3:6],
'comments':comments,
'form':form,
})
# The basic edit page