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

View File

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

View File

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

View File

@@ -6,14 +6,14 @@
{% block content %} {% block content %}
<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> <script>
// Set things up to resize the plot on a window resize. You can play with // 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. // the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () { var plot_resize_setup = function () {
@@ -27,23 +27,23 @@
plotresizer(); plotresizer();
}; };
window.addEventListener('load', plot_resize_setup); window.addEventListener('load', plot_resize_setup);
</script> </script>
<style> <style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/ /* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;} html, body {height: 100%; margin:5px;}
</style> </style>
<div id="navigation" class="grid_12 alpha"> <div id="navigation" class="grid_12 alpha">
{% if user.is_authenticated and mayedit %} {% if user.is_authenticated and mayedit %}
<div class="grid_2 alpha"> <div class="grid_2 alpha">
<p> <p>
<a class="button gray small" href="/rowers/workout/{{ id }}/edit">Edit Workout</a> <a class="button gray small" href="/rowers/workout/{{ id }}/edit">Edit Workout</a>
</p> </p>
</div> </div>
<div class="grid_2 suffix_8 omega"> <div class="grid_2 suffix_8 omega">
<p> <p>
<a class="button gray small" href="/rowers/workout/compare/{{ id }}/advanced">Advanced Edit</a> <a class="button gray small" href="/rowers/workout/compare/{{ id }}/advanced">Advanced Edit</a>
</p> </p>
</div> </div>
{% endif %} {% endif %}
@@ -68,60 +68,50 @@
<p>&nbsp;</p> <p>&nbsp;</p>
<div id="plotbuttons" class="grid_12 alpha"> <div id="plotbuttons" class="grid_12 alpha">
<div id="x-axis" class="grid_6 alpha"> <div id="x-axis" class="grid_6 alpha">
<div class="grid_2 alpha dropdown"> <div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button blue small dropbtn">X-axis</button> <button class="grid_2 alpha button blue small dropbtn">X-axis</button>
<div class="dropdown-content"> <div class="dropdown-content">
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/time/{{ yparam }}/{{ plottype }}">Time</a> {% for key, value in axchoicesbasic.items %}
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/distance/{{ yparam }}/{{ plottype }}">Distance</a> {% if key != 'None' %}
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1}}/{{ id2 }}/{{ key }}/{{ yparam }}/{{ plottype }}">{{ value }}</a>
{% endif %}
{% endfor %}
{% if promember %} {% if promember %}
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/power/{{ yparam }}/scatter">Power</a> {% for key, value in axchoicespro.items %}
<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 }}/{{ key }}/{{ yparam }}/{{ plottype }}">{{ value }}</a>
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/spm/{{ yparam }}/scatter">SPM</a> {% endfor %}
<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 %} {% else %}
<a class="button rosy small" href="/rowers/promembership">Power (Pro)</a> {% for key, value in axchoicespro.items %}
<a class="button rosy small" href="/rowers/promembership">HR (Pro)</a> <a class="button rosy small" href="/rowers/promembership">{{ value }}</a>
<a class="button rosy small" href="/rowers/promembership">SPM (Pro)</a> {% endfor %}
<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 %} {% endif %}
</div> </div>
</div> </div>
<div class="grid_2 suffix_2 omega dropdown"> <div class="grid_2 suffix_2 omega dropdown">
<button class="grid_2 alpha button blue small dropbtn">Y-axis</button> <button class="grid_2 alpha button blue small dropbtn">Y-axis</button>
<div class="dropdown-content"> <div class="dropdown-content">
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/pace/{{ plottype }}">Pace</a> {% for key, value in axchoicesbasic.items %}
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/hr/{{ plottype }}">HR</a> {% if key not in noylist and key != 'None' %}
<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 }}/{{ key }}/{{ plottype }}">{{ value }}</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 %} {% 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>

View File

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

View File

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

View File

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