Private
Public Access
1
0

Merge branch 'release/annotations'

This commit is contained in:
Sander Roosendaal
2016-11-18 19:10:55 +01:00
19 changed files with 242 additions and 14 deletions
+9 -1
View File
@@ -99,7 +99,9 @@ def dataprep(rowdatadf,bands=False,barchart=False,otwpower=False):
peakforce = rowdatadf.ix[:,' PeakDriveForce (lbs)'] peakforce = rowdatadf.ix[:,' PeakDriveForce (lbs)']
forceratio = averageforce/peakforce
forceratio = forceratio.fillna(value=0)
f = rowdatadf['TimeStamp (sec)'].diff().mean() f = rowdatadf['TimeStamp (sec)'].diff().mean()
windowsize = 2*(int(10./(f)))+1 windowsize = 2*(int(10./(f)))+1
if windowsize <= 3: if windowsize <= 3:
@@ -109,6 +111,7 @@ def dataprep(rowdatadf,bands=False,barchart=False,otwpower=False):
spm = savgol_filter(spm,windowsize,3) spm = savgol_filter(spm,windowsize,3)
hr = savgol_filter(hr,windowsize,3) hr = savgol_filter(hr,windowsize,3)
drivelength = savgol_filter(drivelength,windowsize,3) drivelength = savgol_filter(drivelength,windowsize,3)
forceratio = savgol_filter(forceratio,windowsize,3)
t2 = t.fillna(method='ffill').apply(lambda x: timedeltaconv(x)) t2 = t.fillna(method='ffill').apply(lambda x: timedeltaconv(x))
@@ -117,6 +120,7 @@ def dataprep(rowdatadf,bands=False,barchart=False,otwpower=False):
drivespeed = drivelength/rowdatadf[' DriveTime (ms)']*1.0e3 drivespeed = drivelength/rowdatadf[' DriveTime (ms)']*1.0e3
drivespeed = drivespeed.fillna(value=0)
driveenergy = drivelength*averageforce*4.44822 driveenergy = drivelength*averageforce*4.44822
distance = rowdatadf.ix[:,'cum_dist'] distance = rowdatadf.ix[:,'cum_dist']
@@ -139,6 +143,7 @@ def dataprep(rowdatadf,bands=False,barchart=False,otwpower=False):
averageforce=averageforce, averageforce=averageforce,
drivelength=drivelength, drivelength=drivelength,
peakforce=peakforce, peakforce=peakforce,
forceratio=forceratio,
distance=distance, distance=distance,
drivespeed=drivespeed, drivespeed=drivespeed,
) )
@@ -186,4 +191,7 @@ def dataprep(rowdatadf,bands=False,barchart=False,otwpower=False):
data['fergpace'] = nicepaceformat(ergpace) data['fergpace'] = nicepaceformat(ergpace)
data['fnowindpace'] = nicepaceformat(nowindpace) data['fnowindpace'] = nicepaceformat(nowindpace)
data = data.replace([-np.inf,np.inf],np.nan)
data = data.fillna(method='ffill')
return data return data
+85 -3
View File
@@ -19,7 +19,7 @@ from bokeh.models import (
GMapPlot, GMapOptions, ColumnDataSource, Circle, GMapPlot, GMapOptions, ColumnDataSource, Circle,
DataRange1d, PanTool, WheelZoomTool, BoxSelectTool, DataRange1d, PanTool, WheelZoomTool, BoxSelectTool,
SaveTool, ResizeTool, ResetTool, TapTool,CrosshairTool,BoxZoomTool, SaveTool, ResizeTool, ResetTool, TapTool,CrosshairTool,BoxZoomTool,
Span, Span, Label
) )
#from bokeh.models.widgets import Slider, Select, TextInput #from bokeh.models.widgets import Slider, Select, TextInput
from bokeh.core.properties import value from bokeh.core.properties import value
@@ -590,6 +590,7 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
'averageforce': 'Average Drive Force (lbs)', 'averageforce': 'Average Drive Force (lbs)',
'drivelength': 'Drive Length (m)', 'drivelength': 'Drive Length (m)',
'peakforce': 'Peak Drive Force (lbs)', 'peakforce': 'Peak Drive Force (lbs)',
'forceratio': 'Average/Peak Drive Force Ratio',
'driveenergy': 'Work per Stroke (J)', 'driveenergy': 'Work per Stroke (J)',
'drivespeed': 'Drive Speed (m/s)', 'drivespeed': 'Drive Speed (m/s)',
'None': '', 'None': '',
@@ -605,6 +606,7 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
'power': 0, 'power': 0,
'averageforce': 0, 'averageforce': 0,
'peakforce': 0, 'peakforce': 0,
'forceratio':0,
'drivelength':0.5, 'drivelength':0.5,
'driveenergy': 0, 'driveenergy': 0,
'drivespeed': 0, 'drivespeed': 0,
@@ -617,6 +619,7 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
'power': 600, 'power': 600,
'averageforce':200, 'averageforce':200,
'peakforce':400, 'peakforce':400,
'forceratio':1,
'drivelength':2.0, 'drivelength':2.0,
'driveenergy': 1000, 'driveenergy': 1000,
'drivespeed':4, 'drivespeed':4,
@@ -693,6 +696,12 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
y_axis_type = 'datetime' y_axis_type = 'datetime'
y1mean = datadf.ix[:,'pseconds'].mean() y1mean = datadf.ix[:,'pseconds'].mean()
datadf['xname'] = xparam
datadf['yname1'] = yparam1
if yparam2 != 'None':
datadf['yname2'] = yparam2
else:
datadf['yname2'] = yparam1
source = ColumnDataSource( source = ColumnDataSource(
datadf datadf
@@ -720,12 +729,27 @@ def interactive_cum_flex_chart(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',
text=xparam+": {x1mean:6.2f}".format(x1mean=x1mean),
background_fill_alpha=.7,
text_color='green',
)
if (xparam != 'time') and (xparam != 'distance'): if (xparam != 'time') and (xparam != 'distance'):
plot.add_layout(x1means) plot.add_layout(x1means)
plot.add_layout(xlabel)
plot.add_layout(y1means) plot.add_layout(y1means)
y1label = Label(x=370,y=100,x_units='screen',y_units='screen',
text=yparam1+": {y1mean:6.2f}".format(y1mean=y1mean),
background_fill_alpha=.7,
text_color='blue',
)
if yparam1 != 'time' and yparam1 != 'pace':
plot.add_layout(y1label)
y2label = y1label
plot.circle('x1','y1',source=source2,fill_alpha=0.3,line_color=None, plot.circle('x1','y1',source=source2,fill_alpha=0.3,line_color=None,
legend=yparamname1, legend=yparamname1,
) )
@@ -777,6 +801,13 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
plot.add_layout(y2means) plot.add_layout(y2means)
y2label = Label(x=370,y=70,x_units='screen',y_units='screen',
text=yparam2+": {y2mean:6.2f}".format(y2mean=y2mean),
background_fill_alpha=.7,
text_color='red',
)
if yparam2 != 'pace' and yparam2 != 'time':
plot.add_layout(y2label)
hover = plot.select(dict(type=HoverTool)) hover = plot.select(dict(type=HoverTool))
@@ -794,6 +825,9 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
callback = CustomJS(args = dict(source=source,source2=source2, callback = CustomJS(args = dict(source=source,source2=source2,
x1means=x1means, x1means=x1means,
y1means=y1means, y1means=y1means,
y1label=y1label,
y2label=y2label,
xlabel=xlabel,
y2means=y2means), code=""" y2means=y2means), code="""
var data = source.data var data = source.data
var data2 = source2.data var data2 = source2.data
@@ -806,6 +840,9 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
var hr1 = data['hr'] var hr1 = data['hr']
var distance1 = data['distance'] var distance1 = data['distance']
var power1 = data['power'] var power1 = data['power']
var xname = data['xname'][0]
var yname1 = data['yname1'][0]
var yname2 = data['yname2'][0]
var minspm = minspm.value var minspm = minspm.value
var maxspm = maxspm.value var maxspm = maxspm.value
@@ -862,6 +899,9 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
x1means.location = xm x1means.location = xm
y1means.location = ym1 y1means.location = ym1
y2means.location = ym2 y2means.location = ym2
y1label.text = yname1+': '+ym1.toFixed(2)
y2label.text = yname2+': '+ym2.toFixed(2)
xlabel.text = xname+': '+xm.toFixed(2)
source2.trigger('change'); source2.trigger('change');
""") """)
@@ -922,6 +962,7 @@ def interactive_flex_chart2(id=0,promember=0,
'averageforce': 'Average Drive Force (lbs)', 'averageforce': 'Average Drive Force (lbs)',
'drivelength': 'Drive Length (m)', 'drivelength': 'Drive Length (m)',
'peakforce': 'Peak Drive Force (lbs)', 'peakforce': 'Peak Drive Force (lbs)',
'forceratio': 'Average/Peak Drive Force Ratio',
'driveenergy': 'Work per Stroke (J)', 'driveenergy': 'Work per Stroke (J)',
'drivespeed': 'Drive Speed (m/s)', 'drivespeed': 'Drive Speed (m/s)',
'None': '', 'None': '',
@@ -934,6 +975,7 @@ def interactive_flex_chart2(id=0,promember=0,
'power': 0, 'power': 0,
'averageforce': 0, 'averageforce': 0,
'peakforce': 0, 'peakforce': 0,
'forceratio':0,
'drivelength':0.5, 'drivelength':0.5,
'driveenergy': 0, 'driveenergy': 0,
'drivespeed': 0, 'drivespeed': 0,
@@ -946,6 +988,7 @@ def interactive_flex_chart2(id=0,promember=0,
'power': 600, 'power': 600,
'averageforce':200, 'averageforce':200,
'peakforce':400, 'peakforce':400,
'forceratio':1,
'drivelength':2.0, 'drivelength':2.0,
'driveenergy': 1000, 'driveenergy': 1000,
'drivespeed':4, 'drivespeed':4,
@@ -1020,7 +1063,14 @@ def interactive_flex_chart2(id=0,promember=0,
y_axis_type = 'datetime' y_axis_type = 'datetime'
y1mean = rowdata.ix[:,'pseconds'].mean() y1mean = rowdata.ix[:,'pseconds'].mean()
rowdata['xname'] = xparam
rowdata['yname1'] = yparam1
if yparam2 != 'None':
rowdata['yname2'] = yparam2
else:
rowdata['yname2'] = yparam1
# prepare data # prepare data
source = ColumnDataSource( source = ColumnDataSource(
rowdata rowdata
@@ -1053,12 +1103,27 @@ 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',
text=xparam+": {x1mean:6.2f}".format(x1mean=x1mean),
background_fill_alpha=.7,
text_color='green',
)
if (xparam != 'time') and (xparam != 'distance'): if (xparam != 'time') and (xparam != 'distance'):
plot.add_layout(x1means) plot.add_layout(x1means)
plot.add_layout(xlabel)
plot.add_layout(y1means) plot.add_layout(y1means)
y1label = Label(x=370,y=100,x_units='screen',y_units='screen',
text=yparam1+": {y1mean:6.2f}".format(y1mean=y1mean),
background_fill_alpha=.7,
text_color='blue',
)
if yparam1 != 'time' and yparam1 != 'pace':
plot.add_layout(y1label)
y2label = y1label
# average values # average values
if yparam1 == 'driveenergy': if yparam1 == 'driveenergy':
@@ -1126,6 +1191,13 @@ 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',
text=yparam2+": {y2mean:6.2f}".format(y2mean=y2mean),
background_fill_alpha=.7,
text_color='red',
)
if yparam2 != 'pace' and yparam2 != 'time':
plot.add_layout(y2label)
hover = plot.select(dict(type=HoverTool)) hover = plot.select(dict(type=HoverTool))
@@ -1144,6 +1216,9 @@ def interactive_flex_chart2(id=0,promember=0,
callback = CustomJS(args = dict(source=source,source2=source2, callback = CustomJS(args = dict(source=source,source2=source2,
x1means=x1means, x1means=x1means,
y1means=y1means, y1means=y1means,
y1label=y1label,
y2label=y2label,
xlabel=xlabel,
y2means=y2means), code=""" y2means=y2means), code="""
var data = source.data var data = source.data
var data2 = source2.data var data2 = source2.data
@@ -1156,6 +1231,9 @@ def interactive_flex_chart2(id=0,promember=0,
var hr1 = data['hr'] var hr1 = data['hr']
var distance1 = data['distance'] var distance1 = data['distance']
var power1 = data['power'] var power1 = data['power']
var xname = data['xname'][0]
var yname1 = data['yname1'][0]
var yname2 = data['yname2'][0]
var minspm = minspm.value var minspm = minspm.value
var maxspm = maxspm.value var maxspm = maxspm.value
@@ -1212,6 +1290,9 @@ def interactive_flex_chart2(id=0,promember=0,
x1means.location = xm x1means.location = xm
y1means.location = ym1 y1means.location = ym1
y2means.location = ym2 y2means.location = ym2
y1label.text = yname1+': '+ym1.toFixed(2)
y2label.text = yname2+': '+ym2.toFixed(2)
xlabel.text = xname+': '+xm.toFixed(2)
source2.trigger('change'); source2.trigger('change');
""") """)
@@ -1365,6 +1446,7 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
'averageforce': 'Average Drive Force (lbs)', 'averageforce': 'Average Drive Force (lbs)',
'drivelength': 'Drive Length (m)', 'drivelength': 'Drive Length (m)',
'peakforce': 'Peak Drive Force (lbs)', 'peakforce': 'Peak Drive Force (lbs)',
'forceratio': 'Average/Peak Drive Force Ratio',
'driveenergy': 'Work per Stroke (J)', 'driveenergy': 'Work per Stroke (J)',
'drivespeed': 'Drive Speed (m/s)', 'drivespeed': 'Drive Speed (m/s)',
} }
+23 -3
View File
@@ -4,7 +4,7 @@ from rowers.tasks import handle_sendemail_unrecognized
from django_mailbox.models import Mailbox,Message,MessageAttachment from django_mailbox.models import Mailbox,Message,MessageAttachment
from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage,AdvancedWorkoutForm from rowers.models import Workout, User, Rower, WorkoutForm,RowerForm,GraphImage,AdvancedWorkoutForm
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.mail import send_mail, BadHeaderError,EmailMessage
from rowsandall_app.settings import BASE_DIR from rowsandall_app.settings import BASE_DIR
from rowingdata import rower as rrower from rowingdata import rower as rrower
@@ -19,6 +19,22 @@ from rowingdata import summarydata,get_file_type
from scipy.signal import savgol_filter from scipy.signal import savgol_filter
def send_confirm(u,name,link):
fullemail = u.email
subject = 'Workout added: '+name
message = 'Dear '+u.first_name+',\n\n'
message += "Your workout has been added to Rowsandall.com.\n"
message += "Link to workout: "+link+"\n\n"
message += "Best Regards, the Rowsandall Team"
email = EmailMessage(subject,message,
'Rowsandall <info@rowsandall.com>',
[fullemail])
res = email.send()
return 1
def rdata(file,rower=rrower()): def rdata(file,rower=rrower()):
try: try:
res = rrdata(file,rower=rower) res = rrdata(file,rower=rower)
@@ -49,7 +65,11 @@ def processattachments():
rr = Rower.objects.get(user=u.id) rr = Rower.objects.get(user=u.id)
# move attachment and make workout # move attachment and make workout
try: try:
res += [make_new_workout_from_email(rr,a.document,name)] wid = [make_new_workout_from_email(rr,a.document,name)]
res += wid
print wid
link = 'http://rowsandall.com/rowers/workout/'+str(wid[0])+'/edit'
dd = send_confirm(u,name,link)
except: except:
# replace with code to process error # replace with code to process error
res += ['fail: '+name] res += ['fail: '+name]
@@ -221,7 +241,7 @@ def make_new_workout_from_email(rr,f2,name,cntr=0):
startdatetime=row.rowdatetime) startdatetime=row.rowdatetime)
w.save() w.save()
return 1 return w.id
+6 -2
View File
@@ -30,7 +30,7 @@ from rowingdata import make_cumvalues
from rowingdata import summarydata,get_file_type from rowingdata import summarydata,get_file_type
from scipy.signal import savgol_filter from scipy.signal import savgol_filter
from rowers.mailprocessing import make_new_workout_from_email from rowers.mailprocessing import make_new_workout_from_email,send_confirm
def rdata(file,rower=rrower()): def rdata(file,rower=rrower()):
try: try:
@@ -60,7 +60,11 @@ class Command(BaseCommand):
rr = Rower.objects.get(user=u.id) rr = Rower.objects.get(user=u.id)
# move attachment and make workout # move attachment and make workout
try: try:
res += [make_new_workout_from_email(rr,a.document,name,cntr=cntr)] wid = [make_new_workout_from_email(rr,a.document,name)]
res += wid
link = 'http://rowsandall.com/rowers/workout/'+str(wid[0])+'/edit'
dd = send_confirm(u,name,link)
except: except:
# replace with code to process error # replace with code to process error
res += ['fail: '+name] res += ['fail: '+name]
+5 -1
View File
@@ -82,6 +82,7 @@
<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 }}/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 }}/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 }}/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 }}/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 }}/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> <a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/drivespeed/{{ yparam }}/scatter">Drive Speed</a>
@@ -91,6 +92,7 @@
<a class="button rosy small" href="/rowers/promembership">SPM (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">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 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">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">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 Speed (Pro)</a>
@@ -109,12 +111,14 @@
{% if promember %} {% 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 }}/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 }}/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 }}/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 }}/driveenergy/{{ plottype }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/drivespeed/{{ plottype }}">Drive Speed</a> <a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/drivespeed/{{ plottype }}">Drive Speed</a>
{% else %} {% else %}
<a class="button rosy small" href="/rowers/promembership">Peak Force (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 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">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">Work per Stroke (Pro)</a>
{% endif %} {% endif %}
@@ -143,4 +147,4 @@
</div> </div>
{% endblock %} {% endblock %}
+1
View File
@@ -22,6 +22,7 @@
<ul> <ul>
<li> Painsled (CSV)</li> <li> Painsled (CSV)</li>
<li> ErgData (CSV export from Concept2 logbook)</li> <li> ErgData (CSV export from Concept2 logbook)</li>
<li> RowPro (CSV)</li>
<li> ErgStick (CSV)</li></ul></p> <li> ErgStick (CSV)</li></ul></p>
+7 -1
View File
@@ -47,6 +47,7 @@
<a class="button blue small alpha" href="/rowers/flexall/spm/{{ yparam1 }}/{{ yparam2 }}">SPM</a> <a class="button blue small alpha" href="/rowers/flexall/spm/{{ yparam1 }}/{{ yparam2 }}">SPM</a>
<a class="button blue small alpha" href="/rowers/flexall/peakforce/{{ yparam1 }}/{{ yparam2 }}">Peak Force</a> <a class="button blue small alpha" href="/rowers/flexall/peakforce/{{ yparam1 }}/{{ yparam2 }}">Peak Force</a>
<a class="button blue small alpha" href="/rowers/flexall/averageforce/{{ yparam1 }}/{{ yparam2 }}">Average Force</a> <a class="button blue small alpha" href="/rowers/flexall/averageforce/{{ yparam1 }}/{{ yparam2 }}">Average Force</a>
<a class="button blue small alpha" href="/rowers/flexall/forceratio/{{ yparam1 }}/{{ yparam2 }}">Average/Peak Force Ratio</a>
<a class="button blue small alpha" href="/rowers/flexall/drivelength/{{ yparam1 }}/{{ yparam2 }}">Drive Length</a> <a class="button blue small alpha" href="/rowers/flexall/drivelength/{{ yparam1 }}/{{ yparam2 }}">Drive Length</a>
<a class="button blue small alpha" href="/rowers/flexall/driveenergy/{{ yparam1 }}/{{ yparam2 }}">Work per Stroke</a> <a class="button blue small alpha" href="/rowers/flexall/driveenergy/{{ yparam1 }}/{{ yparam2 }}">Work per Stroke</a>
<a class="button blue small alpha" href="/rowers/flexall/drivespeed/{{ yparam1 }}/{{ yparam2 }}">Drive Speed</a> <a class="button blue small alpha" href="/rowers/flexall/drivespeed/{{ yparam1 }}/{{ yparam2 }}">Drive Speed</a>
@@ -56,6 +57,7 @@
<a class="button rosy small" href="/rowers/promembership">SPM (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">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 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">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">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 Speed (Pro)</a>
@@ -74,12 +76,14 @@
{% if promember %} {% if promember %}
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/peakforce/{{ yparam2 }}">Peak Force</a> <a class="button blue small" href="/rowers/flexall/{{ xparam }}/peakforce/{{ yparam2 }}">Peak Force</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/averageforce/{{ yparam2 }}">Average Force</a> <a class="button blue small" href="/rowers/flexall/{{ xparam }}/averageforce/{{ yparam2 }}">Average Force</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/forceratio/{{ yparam2 }}">Average/Peak Force Ratio</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/drivelength/{{ yparam2 }}">Drive Length</a> <a class="button blue small" href="/rowers/flexall/{{ xparam }}/drivelength/{{ yparam2 }}">Drive Length</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/driveenergy/{{ yparam2 }}">Work per Stroke</a> <a class="button blue small" href="/rowers/flexall/{{ xparam }}/driveenergy/{{ yparam2 }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/drivespeed/{{ yparam2 }}">Drive Speed</a> <a class="button blue small" href="/rowers/flexall/{{ xparam }}/drivespeed/{{ yparam2 }}">Drive Speed</a>
{% else %} {% else %}
<a class="button rosy small" href="/rowers/promembership">Peak Force (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 Force (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Avxerage/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">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">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 Speed (Pro)</a>
@@ -97,12 +101,14 @@
{% if promember %} {% if promember %}
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/peakforce">Peak Force</a> <a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/peakforce">Peak Force</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/averageforce">Average Force</a> <a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/averageforce">Average Force</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/forceratio">Average/Peak Force Ratio</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/drivelength">Drive Length</a> <a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/drivelength">Drive Length</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/driveenergy">Work per Stroke</a> <a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/driveenergy">Work per Stroke</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/drivespeed">Drive Speed</a> <a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/drivespeed">Drive Speed</a>
{% else %} {% else %}
<a class="button rosy small" href="/rowers/promembership">Peak Force (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 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">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">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 Speed (Pro)</a>
@@ -159,4 +165,4 @@
</div> </div>
{% endblock %} {% endblock %}
+6
View File
@@ -59,6 +59,7 @@
<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/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/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/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/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/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/drivespeed/{{ yparam1 }}/{{ yparam2 }}/scatter">Drive Speed</a>
@@ -68,6 +69,7 @@
<a class="button rosy small" href="/rowers/promembership">SPM (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">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 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">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">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 Speed (Pro)</a>
@@ -86,12 +88,14 @@
{% if promember %} {% 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 }}/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 }}/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 }}/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 }}/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 }}/drivespeed/{{ yparam2 }}/{{ plottype }}">Drive Speed</a>
{% else %} {% else %}
<a class="button rosy small" href="/rowers/promembership">Peak Force (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 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">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">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 Speed (Pro)</a>
@@ -109,12 +113,14 @@
{% if promember %} {% 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 }}/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 }}/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 }}/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 }}/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 }}/drivespeed/{{ plottype }}">Drive Speed</a>
{% else %} {% else %}
<a class="button rosy small" href="/rowers/promembership">Peak Force (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 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">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">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 Speed (Pro)</a>
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
[{"data": [12.0, 22.0, 31.0, 40.0, 53.0, 62.0, 71.0, 80.0, 93.0, 101.0, 116.0, 125.0, 130.0, 142.0, 151.0, 165.0, 174.0, 182.0, 197.0, 205.0, 214.0, 227.0, 236.0, 246.0, 259.0, 268.0, 276.0, 286.0, 299.0, 312.0, 317.0, 334.0, 349.0, 365.0, 370.0, 384.0, 397.0, 406.0, 412.0, 422.0, 432.0, 443.0, 455.0, 464.0, 478.0, 485.0, 500.0, 509.0, 517.0, 531.0, 538.0, 554.0, 559.0, 572.0, 585.0, 594.0, 601.0, 611.0, 622.0, 632.0, 643.0, 653.0, 664.0, 679.0, 685.0, 702.0, 717.0, 728.0, 742.0, 751.0, 758.0, 774.0, 779.0, 790.0, 800.0, 811.0, 821.0, 832.0, 842.0, 853.0, 867.0, 874.0, 884.0, 899.0, 905.0, 916.0, 926.0, 937.0, 953.0, 962.0, 971.0, 979.0, 989.0, 1000.0, 1012.0, 1021.0, 1031.0, 1042.0, 1052.0, 1069.0, 1073.0, 1088.0, 1094.0, 1104.0, 1115.0, 1125.0, 1136.0, 1146.0, 1156.0, 1167.0, 1177.0, 1191.0, 1200.0, 1213.0, 1222.0, 1229.0, 1239.0, 1250.0, 1260.0, 1271.0, 1281.0, 1292.0, 1302.0, 1313.0, 1329.0, 1334.0, 1344.0, 1355.0, 1365.0, 1375.0, 1386.0, 1396.0, 1407.0, 1418.0, 1427.0, 1442.0, 1448.0, 1458.0, 1469.0, 1479.0, 1495.0, 1500.0, 1510.0, 1527.0, 1536.0, 1541.0, 1558.0, 1562.0, 1572.0, 1585.0, 1592.0, 1603.0, 1613.0, 1623.0, 1633.0, 1643.0, 1654.0, 1669.0, 1679.0, 1685.0, 1695.0, 1705.0, 1715.0, 1725.0, 1741.0, 1751.0, 1760.0, 1765.0, 1782.0, 1791.0, 1799.0, 1807.0, 1817.0, 1827.0, 1838.0, 1848.0, 1858.0, 1872.0, 1885.0, 1889.0, 1899.0, 1909.0, 1919.0, 1929.0, 1940.0, 1950.0, 1965.0, 1975.0, 1984.0, 1993.0, 1999.0, 2002.0, 2015.0, 2023.0, 2033.0, 2044.0, 2054.0, 2064.0, 2074.0, 2084.0, 2095.0, 2105.0, 2115.0, 2125.0, 2135.0, 2145.0, 2155.0, 2165.0, 2175.0, 2185.0, 2196.0, 2206.0, 2222.0, 2231.0, 2240.0, 2247.0, 2257.0, 2268.0, 2278.0, 2294.0, 2303.0, 2308.0, 2321.0, 2329.0, 2344.0, 2353.0, 2360.0, 2370.0, 2380.0, 2390.0, 2401.0, 2411.0, 2421.0, 2431.0, 2447.0, 2452.0, 2462.0, 2472.0, 2482.0, 2496.0, 2499.0, 2502.0, 2519.0, 2536.0, 2545.0, 2553.0, 2568.0, 2577.0, 2584.0, 2594.0, 2608.0, 2617.0, 2626.0, 2635.0, 2648.0, 2656.0, 2670.0, 2680.0, 2686.0, 2696.0, 2706.0, 2717.0, 2727.0, 2737.0, 2747.0, 2757.0, 2767.0, 2777.0, 2788.0, 2798.0, 2810.0, 2823.0, 2832.0, 2841.0, 2849.0, 2858.0, 2873.0, 2879.0, 2889.0, 2899.0, 2910.0, 2920.0, 2930.0, 2940.0, 2950.0, 2963.0, 2970.0, 2981.0, 2991.0, 2997.0, 3011.0, 3021.0, 3035.0, 3042.0, 3052.0, 3062.0, 3076.0, 3082.0, 3092.0, 3102.0, 3113.0, 3123.0, 3133.0, 3143.0, 3157.0, 3163.0, 3172.0, 3183.0, 3192.0, 3202.0, 3212.0, 3223.0, 3237.0, 3242.0, 3252.0, 3268.0, 3272.0, 3286.0, 3291.0, 3301.0, 3311.0, 3327.0, 3331.0, 3344.0, 3351.0, 3362.0, 3376.0, 3382.0, 3392.0, 3403.0, 3413.0, 3426.0, 3433.0, 3443.0, 3453.0, 3464.0, 3474.0, 3484.0, 3500.0, 3505.0, 3515.0, 3525.0, 3535.0, 3551.0, 3560.0, 3565.0, 3576.0, 3585.0, 3596.0, 3609.0, 3619.0, 3632.0, 3641.0, 3647.0, 3657.0, 3669.0, 3682.0, 3690.0, 3700.0, 3709.0, 3722.0, 3728.0, 3738.0, 3748.0, 3758.0, 3768.0, 3778.0, 3794.0, 3803.0, 3808.0, 3818.0, 3828.0, 3844.0, 3853.0, 3858.0, 3868.0, 3880.0, 3888.0, 3898.0, 3911.0, 3919.0, 3929.0, 3939.0, 3949.0, 3959.0, 3969.0, 3979.0, 3989.0, 4000.0, 4009.0, 4019.0, 4029.0, 4040.0, 4050.0, 4065.0, 4070.0, 4080.0, 4090.0, 4101.0, 4111.0, 4121.0, 4131.0, 4141.0, 4151.0, 4161.0, 4171.0, 4183.0, 4191.0, 4200.0, 4210.0, 4220.0, 4230.0, 4240.0, 4254.0, 4260.0, 4270.0, 4280.0, 4290.0, 4300.0, 4310.0, 4320.0, 4330.0, 4340.0, 4353.0, 4362.0, 4375.0, 4384.0, 4390.0, 4400.0, 4410.0, 4420.0, 4429.0, 4439.0, 4452.0, 4459.0, 4470.0, 4478.0, 4488.0, 4500.0, 4510.0, 4520.0, 4533.0, 4538.0, 4551.0, 4560.0, 4568.0, 4577.0, 4591.0, 4598.0, 4607.0, 4617.0, 4627.0, 4637.0, 4647.0, 4657.0, 4672.0, 4677.0, 4687.0, 4696.0, 4706.0, 4721.0, 4726.0, 4739.0, 4745.0, 4761.0, 4770.0, 4779.0, 4785.0, 4795.0, 4805.0, 4815.0, 4825.0, 4835.0, 4845.0, 4859.0, 4865.0, 4875.0, 4885.0, 4899.0, 4905.0, 4917.0, 4929.0, 4938.0, 4947.0, 4954.0, 4970.0, 4978.0, 4983.0, 4997.0, 4999.0, 5005.0, 5013.0, 5027.0, 5032.0, 5046.0, 5051.0, 5061.0, 5072.0, 5086.0, 5091.0, 5103.0, 5111.0, 5120.0, 5130.0, 5140.0, 5153.0, 5162.0, 5169.0, 5178.0, 5188.0, 5202.0, 5211.0, 5217.0, 5230.0, 5237.0, 5246.0, 5256.0, 5266.0, 5276.0, 5285.0, 5295.0, 5305.0, 5314.0, 5323.0, 5333.0, 5346.0, 5352.0, 5368.0, 5372.0, 5381.0, 5396.0, 5401.0, 5413.0, 5426.0, 5431.0, 5445.0, 5449.0, 5462.0, 5471.0, 5480.0, 5493.0, 5500.0, 5511.0, 5516.0, 5526.0, 5538.0, 5545.0, 5554.0, 5564.0, 5574.0, 5584.0, 5594.0, 5603.0, 5617.0, 5622.0, 5635.0, 5643.0, 5656.0, 5665.0, 5670.0, 5682.0, 5689.0, 5699.0, 5708.0, 5718.0, 5728.0, 5738.0, 5747.0, 5756.0, 5769.0, 5778.0, 5784.0, 5794.0, 5808.0, 5812.0, 5826.0, 5831.0, 5843.0, 5850.0, 5861.0, 5874.0, 5882.0, 5887.0, 5899.0, 5905.0, 5915.0, 5924.0, 5933.0, 5943.0, 5952.0, 5962.0, 5974.0, 5981.0, 5992.0, 5999.0], "type": "distance", "resolution": "high", "original_size": 595, "series_type": "distance"}]
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
[{"data": [12.0, 22.0, 31.0, 40.0, 53.0, 62.0, 71.0, 80.0, 93.0, 101.0, 116.0, 125.0, 130.0, 142.0, 151.0, 165.0, 174.0, 182.0, 197.0, 205.0, 214.0, 227.0, 236.0, 246.0, 259.0, 268.0, 276.0, 286.0, 299.0, 312.0, 317.0, 334.0, 349.0, 365.0, 370.0, 384.0, 397.0, 406.0, 412.0, 422.0, 432.0, 443.0, 455.0, 464.0, 478.0, 485.0, 500.0, 509.0, 517.0, 531.0, 538.0, 554.0, 559.0, 572.0, 585.0, 594.0, 601.0, 611.0, 622.0, 632.0, 643.0, 653.0, 664.0, 679.0, 685.0, 702.0, 717.0, 728.0, 742.0, 751.0, 758.0, 774.0, 779.0, 790.0, 800.0, 811.0, 821.0, 832.0, 842.0, 853.0, 867.0, 874.0, 884.0, 899.0, 905.0, 916.0, 926.0, 937.0, 953.0, 962.0, 971.0, 979.0, 989.0, 1000.0, 1012.0, 1021.0, 1031.0, 1042.0, 1052.0, 1069.0, 1073.0, 1088.0, 1094.0, 1104.0, 1115.0, 1125.0, 1136.0, 1146.0, 1156.0, 1167.0, 1177.0, 1191.0, 1200.0, 1213.0, 1222.0, 1229.0, 1239.0, 1250.0, 1260.0, 1271.0, 1281.0, 1292.0, 1302.0, 1313.0, 1329.0, 1334.0, 1344.0, 1355.0, 1365.0, 1375.0, 1386.0, 1396.0, 1407.0, 1418.0, 1427.0, 1442.0, 1448.0, 1458.0, 1469.0, 1479.0, 1495.0, 1500.0, 1510.0, 1527.0, 1536.0, 1541.0, 1558.0, 1562.0, 1572.0, 1585.0, 1592.0, 1603.0, 1613.0, 1623.0, 1633.0, 1643.0, 1654.0, 1669.0, 1679.0, 1685.0, 1695.0, 1705.0, 1715.0, 1725.0, 1741.0, 1751.0, 1760.0, 1765.0, 1782.0, 1791.0, 1799.0, 1807.0, 1817.0, 1827.0, 1838.0, 1848.0, 1858.0, 1872.0, 1885.0, 1889.0, 1899.0, 1909.0, 1919.0, 1929.0, 1940.0, 1950.0, 1965.0, 1975.0, 1984.0, 1993.0, 1999.0, 2002.0, 2015.0, 2023.0, 2033.0, 2044.0, 2054.0, 2064.0, 2074.0, 2084.0, 2095.0, 2105.0, 2115.0, 2125.0, 2135.0, 2145.0, 2155.0, 2165.0, 2175.0, 2185.0, 2196.0, 2206.0, 2222.0, 2231.0, 2240.0, 2247.0, 2257.0, 2268.0, 2278.0, 2294.0, 2303.0, 2308.0, 2321.0, 2329.0, 2344.0, 2353.0, 2360.0, 2370.0, 2380.0, 2390.0, 2401.0, 2411.0, 2421.0, 2431.0, 2447.0, 2452.0, 2462.0, 2472.0, 2482.0, 2496.0, 2499.0, 2502.0, 2519.0, 2536.0, 2545.0, 2553.0, 2568.0, 2577.0, 2584.0, 2594.0, 2608.0, 2617.0, 2626.0, 2635.0, 2648.0, 2656.0, 2670.0, 2680.0, 2686.0, 2696.0, 2706.0, 2717.0, 2727.0, 2737.0, 2747.0, 2757.0, 2767.0, 2777.0, 2788.0, 2798.0, 2810.0, 2823.0, 2832.0, 2841.0, 2849.0, 2858.0, 2873.0, 2879.0, 2889.0, 2899.0, 2910.0, 2920.0, 2930.0, 2940.0, 2950.0, 2963.0, 2970.0, 2981.0, 2991.0, 2997.0, 3011.0, 3021.0, 3035.0, 3042.0, 3052.0, 3062.0, 3076.0, 3082.0, 3092.0, 3102.0, 3113.0, 3123.0, 3133.0, 3143.0, 3157.0, 3163.0, 3172.0, 3183.0, 3192.0, 3202.0, 3212.0, 3223.0, 3237.0, 3242.0, 3252.0, 3268.0, 3272.0, 3286.0, 3291.0, 3301.0, 3311.0, 3327.0, 3331.0, 3344.0, 3351.0, 3362.0, 3376.0, 3382.0, 3392.0, 3403.0, 3413.0, 3426.0, 3433.0, 3443.0, 3453.0, 3464.0, 3474.0, 3484.0, 3500.0, 3505.0, 3515.0, 3525.0, 3535.0, 3551.0, 3560.0, 3565.0, 3576.0, 3585.0, 3596.0, 3609.0, 3619.0, 3632.0, 3641.0, 3647.0, 3657.0, 3669.0, 3682.0, 3690.0, 3700.0, 3709.0, 3722.0, 3728.0, 3738.0, 3748.0, 3758.0, 3768.0, 3778.0, 3794.0, 3803.0, 3808.0, 3818.0, 3828.0, 3844.0, 3853.0, 3858.0, 3868.0, 3880.0, 3888.0, 3898.0, 3911.0, 3919.0, 3929.0, 3939.0, 3949.0, 3959.0, 3969.0, 3979.0, 3989.0, 4000.0, 4009.0, 4019.0, 4029.0, 4040.0, 4050.0, 4065.0, 4070.0, 4080.0, 4090.0, 4101.0, 4111.0, 4121.0, 4131.0, 4141.0, 4151.0, 4161.0, 4171.0, 4183.0, 4191.0, 4200.0, 4210.0, 4220.0, 4230.0, 4240.0, 4254.0, 4260.0, 4270.0, 4280.0, 4290.0, 4300.0, 4310.0, 4320.0, 4330.0, 4340.0, 4353.0, 4362.0, 4375.0, 4384.0, 4390.0, 4400.0, 4410.0, 4420.0, 4429.0, 4439.0, 4452.0, 4459.0, 4470.0, 4478.0, 4488.0, 4500.0, 4510.0, 4520.0, 4533.0, 4538.0, 4551.0, 4560.0, 4568.0, 4577.0, 4591.0, 4598.0, 4607.0, 4617.0, 4627.0, 4637.0, 4647.0, 4657.0, 4672.0, 4677.0, 4687.0, 4696.0, 4706.0, 4721.0, 4726.0, 4739.0, 4745.0, 4761.0, 4770.0, 4779.0, 4785.0, 4795.0, 4805.0, 4815.0, 4825.0, 4835.0, 4845.0, 4859.0, 4865.0, 4875.0, 4885.0, 4899.0, 4905.0, 4917.0, 4929.0, 4938.0, 4947.0, 4954.0, 4970.0, 4978.0, 4983.0, 4997.0, 4999.0, 5005.0, 5013.0, 5027.0, 5032.0, 5046.0, 5051.0, 5061.0, 5072.0, 5086.0, 5091.0, 5103.0, 5111.0, 5120.0, 5130.0, 5140.0, 5153.0, 5162.0, 5169.0, 5178.0, 5188.0, 5202.0, 5211.0, 5217.0, 5230.0, 5237.0, 5246.0, 5256.0, 5266.0, 5276.0, 5285.0, 5295.0, 5305.0, 5314.0, 5323.0, 5333.0, 5346.0, 5352.0, 5368.0, 5372.0, 5381.0, 5396.0, 5401.0, 5413.0, 5426.0, 5431.0, 5445.0, 5449.0, 5462.0, 5471.0, 5480.0, 5493.0, 5500.0, 5511.0, 5516.0, 5526.0, 5538.0, 5545.0, 5554.0, 5564.0, 5574.0, 5584.0, 5594.0, 5603.0, 5617.0, 5622.0, 5635.0, 5643.0, 5656.0, 5665.0, 5670.0, 5682.0, 5689.0, 5699.0, 5708.0, 5718.0, 5728.0, 5738.0, 5747.0, 5756.0, 5769.0, 5778.0, 5784.0, 5794.0, 5808.0, 5812.0, 5826.0, 5831.0, 5843.0, 5850.0, 5861.0, 5874.0, 5882.0, 5887.0, 5899.0, 5905.0, 5915.0, 5924.0, 5933.0, 5943.0, 5952.0, 5962.0, 5974.0, 5981.0, 5992.0, 5999.0], "type": "distance", "resolution": "high", "original_size": 595, "series_type": "distance"}]
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"athlete_count": 1, "trainer": true, "start_date_local": "2016-11-11T08:29:41Z", "calories": 373.8, "private": false, "partner_logo_url": null, "commute": false, "timezone": "(GMT-08:00) America/Los_Angeles", "segment_efforts": [], "id": 772462862, "location_city": null, "location_country": "Czech Republic", "kudos_count": 1, "gear_id": null, "average_speed": 4.478, "has_heartrate": true, "elapsed_time": 1337, "start_longitude": null, "comment_count": 0, "type": "Rowing", "start_date": "2016-11-11T16:29:41Z", "map": {"resource_state": 3, "polyline": "", "id": "a772462862"}, "photo_count": 0, "description": "imported through email", "location_state": null, "moving_time": 1337, "start_latlng": null, "photos": {"count": 0, "primary": null}, "max_watts": 309, "max_speed": 5.4, "end_latlng": null, "has_kudoed": false, "max_heartrate": 184.0, "distance": 5987.0, "name": "6km", "total_elevation_gain": 0.0, "athlete": {"resource_state": 1, "id": 1754726}, "manual": false, "total_photo_count": 0, "flagged": false, "average_heartrate": 178.1, "upload_id": 854556931, "embed_token": "498b459b7d08aedb02e56837396770711233cb97", "resource_state": 3, "achievement_count": 0, "external_id": "tap-sync-476bccea758138bb911e2358e767a571-7393-5603b4eacbe97e241e653122.fit", "start_latitude": null, "average_cadence": 26.7}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+92 -3
View File
@@ -19,6 +19,7 @@ from minimocktest import MockTestCase
import pandas as pd import pandas as pd
import json import json
import numpy as np
from rowers import urls from rowers import urls
from rowers.views import error500_view,error404_view,error400_view,error403_view from rowers.views import error500_view,error404_view,error400_view,error403_view
@@ -37,12 +38,12 @@ class DjangoTestCase(TestCase, MockTestCase):
class C2Objects(DjangoTestCase): class C2Objects(DjangoTestCase):
def test_strokedata(self): def test_strokedata(self):
with open('c2stroketestdata.txt','r') as infile: with open('rowers/testdata/c2stroketestdata.txt','r') as infile:
res = json.load(infile) res = json.load(infile)
strokedata = pd.DataFrame.from_dict(res['data']) strokedata = pd.DataFrame.from_dict(res['data'])
with open('c2testdata.txt','r') as infile: with open('rowers/testdata/c2testdata.txt','r') as infile:
res = json.load(infile) res = json.load(infile)
data = res['data'] data = res['data']
@@ -56,8 +57,96 @@ class C2Objects(DjangoTestCase):
res = add_workout_from_strokedata(u,1,data,strokedata,source='c2') res = add_workout_from_strokedata(u,1,data,strokedata,source='c2')
class StravaObjects(DjangoTestCase):
def test_strokedata(self):
timejson = json.load(open('rowers/testdata/stravatimetestdata.txt','r'))
velojson = json.load(open('rowers/testdata/stravavelotestdata.txt','r'))
distancejson = json.load(open('rowers/testdata/stravadistancetestdata.txt','r'))
latlongjson = json.load(open('rowers/testdata/stravalatlongtestdata.txt','r'))
hrjson = json.load(open('rowers/testdata/stravahrtestdata.txt','r'))
spmjson = json.load(open('rowers/testdata/stravaspmtestdata.txt','r'))
workoutsummary = json.load(open('rowers/testdata/stravasummarytestdata.txt','r'))
workoutsummary['timezone'] = "Etc/UTC"
startdatetime = workoutsummary['start_date']
t = np.array(timejson[0]['data'])
d = np.array(distancejson[0]['data'])
nr_rows = len(t)
try:
spm = np.array( spmjson[1]['data'])
except IndexError:
spm = np.zeros(nr_rows)
try:
hr = np.array(hrjson[1]['data'])
except IndexError:
hr = np.zeros(nr_rows)
try:
velo = np.array(velojson[1]['data'])
except IndexError:
velo = np.zeros(nr_rows)
dt = np.diff(t).mean()
wsize = round(5./dt)
from stravastuff import ewmovingaverage
velo2 = ewmovingaverage(velo,wsize)
coords = np.array(latlongjson[0]['data'])
try:
lat = coords[:,0]
lon = coords[:,1]
except IndexError:
lat = np.zeros(len(t))
lon = np.zeros(len(t))
strokelength = velo*60./(spm)
strokelength[np.isinf(strokelength)] = 0.0
pace = 500./(1.0*velo2)
pace[np.isinf(pace)] = 0.0
strokedata = pd.DataFrame({'t':10*t,
'd':10*d,
'p':10*pace,
'spm':spm,
'hr':hr,
'lat':lat,
'lon':lon,
'strokelength':strokelength,
})
from rowers.views import add_workout_from_strokedata
u = User.objects.create_user('john',
'sander@ds.ds',
'koeinsloot')
r = Rower.objects.create(user=u)
res = add_workout_from_strokedata(u,1,workoutsummary,strokedata,
source='strava')
class STObjects(DjangoTestCase):
def test_strokedata(self):
with open('rowers/testdata/sporttrackstestdata.txt','r') as infile:
data = json.load(infile)
from rowers.views import add_workout_from_stdata
u = User.objects.create_user('john',
'sander@ds.ds',
'koeinsloot')
r = Rower.objects.create(user=u)
res = add_workout_from_stdata(u,1,data)
class TestErrorPages(TestCase): class TestErrorPages(TestCase):
def test_error_handlers(self): def test_error_handlers(self):
self.assertTrue(urls.handler404.endswith('.error404_view')) self.assertTrue(urls.handler404.endswith('.error404_view'))