Merge branch 'develop' into feature/sensorfusion
This commit is contained in:
@@ -8,7 +8,7 @@ from rowers.tasks import handle_sendemail_unrecognized
|
|||||||
from rowingdata import rower as rrower
|
from rowingdata import rower as rrower
|
||||||
from rowingdata import main as rmain
|
from rowingdata import main as rmain
|
||||||
|
|
||||||
from rowingdata import get_file_type
|
from rowingdata import get_file_type,get_empower_rigging
|
||||||
|
|
||||||
from pandas import DataFrame,Series
|
from pandas import DataFrame,Series
|
||||||
from pytz import timezone as tz,utc
|
from pytz import timezone as tz,utc
|
||||||
@@ -31,7 +31,7 @@ import os
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import itertools
|
import itertools
|
||||||
|
import math
|
||||||
from tasks import handle_sendemail_unrecognized
|
from tasks import handle_sendemail_unrecognized
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
@@ -102,6 +102,11 @@ def clean_df_stats(datadf,workstrokesonly=True,ignorehr=True,
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
datadf['hr'] = datadf['hr']+10
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
datadf=datadf.clip(lower=0)
|
datadf=datadf.clip(lower=0)
|
||||||
datadf.replace(to_replace=0,value=np.nan,inplace=True)
|
datadf.replace(to_replace=0,value=np.nan,inplace=True)
|
||||||
|
|
||||||
@@ -116,6 +121,11 @@ def clean_df_stats(datadf,workstrokesonly=True,ignorehr=True,
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
datadf['hr'] = datadf['hr']-10
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
# clean data for useful ranges per column
|
# clean data for useful ranges per column
|
||||||
if not ignorehr:
|
if not ignorehr:
|
||||||
try:
|
try:
|
||||||
@@ -222,11 +232,11 @@ def clean_df_stats(datadf,workstrokesonly=True,ignorehr=True,
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mask = datadf['catch'] > -30.
|
mask = datadf['catch'] > -30.
|
||||||
datadf.loc[mask,'catch'] = np.nan
|
datadf.loc[mask,'catch'] = np.nan
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
workoutstateswork = [1,4,5,8,9,6,7]
|
workoutstateswork = [1,4,5,8,9,6,7]
|
||||||
@@ -326,7 +336,8 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
|
|||||||
dosummary=True,title='Workout',
|
dosummary=True,title='Workout',
|
||||||
notes='',totaldist=0,totaltime=0,
|
notes='',totaldist=0,totaltime=0,
|
||||||
summary='',
|
summary='',
|
||||||
makeprivate=False):
|
makeprivate=False,
|
||||||
|
oarlength=2.89,inboard=0.88):
|
||||||
message = None
|
message = None
|
||||||
powerperc = 100*np.array([r.pw_ut2,
|
powerperc = 100*np.array([r.pw_ut2,
|
||||||
r.pw_ut1,
|
r.pw_ut1,
|
||||||
@@ -432,7 +443,7 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
|
|||||||
privacy = 'visible'
|
privacy = 'visible'
|
||||||
|
|
||||||
# check for duplicate start times
|
# check for duplicate start times
|
||||||
ws = Workout.objects.filter(starttime=workoutstarttime,
|
ws = Workout.objects.filter(startdatetime=workoutstartdatetime,
|
||||||
user=r)
|
user=r)
|
||||||
if (len(ws) != 0):
|
if (len(ws) != 0):
|
||||||
message = "Warning: This workout probably already exists in the database"
|
message = "Warning: This workout probably already exists in the database"
|
||||||
@@ -446,6 +457,7 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
|
|||||||
csvfilename=f2,notes=notes,summary=summary,
|
csvfilename=f2,notes=notes,summary=summary,
|
||||||
maxhr=maxhr,averagehr=averagehr,
|
maxhr=maxhr,averagehr=averagehr,
|
||||||
startdatetime=workoutstartdatetime,
|
startdatetime=workoutstartdatetime,
|
||||||
|
inboard=inboard,oarlength=oarlength,
|
||||||
privacy=privacy)
|
privacy=privacy)
|
||||||
|
|
||||||
|
|
||||||
@@ -458,11 +470,13 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower',
|
|||||||
|
|
||||||
# put stroke data in database
|
# put stroke data in database
|
||||||
res = dataprep(row.df,id=w.id,bands=True,
|
res = dataprep(row.df,id=w.id,bands=True,
|
||||||
barchart=True,otwpower=True,empower=True)
|
barchart=True,otwpower=True,empower=True,inboard=inboard)
|
||||||
|
|
||||||
return (w.id,message)
|
return (w.id,message)
|
||||||
|
|
||||||
def handle_nonpainsled(f2,fileformat,summary=''):
|
def handle_nonpainsled(f2,fileformat,summary=''):
|
||||||
|
oarlength = 2.89
|
||||||
|
inboard = 0.88
|
||||||
# handle RowPro:
|
# handle RowPro:
|
||||||
if (fileformat == 'rp'):
|
if (fileformat == 'rp'):
|
||||||
row = RowProParser(f2)
|
row = RowProParser(f2)
|
||||||
@@ -506,6 +520,7 @@ def handle_nonpainsled(f2,fileformat,summary=''):
|
|||||||
if (fileformat == 'speedcoach2'):
|
if (fileformat == 'speedcoach2'):
|
||||||
row = SpeedCoach2Parser(f2)
|
row = SpeedCoach2Parser(f2)
|
||||||
try:
|
try:
|
||||||
|
oarlength,inboard = get_empower_rigging(f2)
|
||||||
summary = row.allstats()
|
summary = row.allstats()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
@@ -534,7 +549,7 @@ def handle_nonpainsled(f2,fileformat,summary=''):
|
|||||||
except:
|
except:
|
||||||
os.remove(f_to_be_deleted+'.gz')
|
os.remove(f_to_be_deleted+'.gz')
|
||||||
|
|
||||||
return (f2,summary)
|
return (f2,summary,oarlength,inboard)
|
||||||
|
|
||||||
# Create new workout from file and store it in the database
|
# Create new workout from file and store it in the database
|
||||||
# This routine should be used everywhere in views.py and mailprocessing.py
|
# This routine should be used everywhere in views.py and mailprocessing.py
|
||||||
@@ -547,6 +562,8 @@ def new_workout_from_file(r,f2,
|
|||||||
message = None
|
message = None
|
||||||
fileformat = get_file_type(f2)
|
fileformat = get_file_type(f2)
|
||||||
summary = ''
|
summary = ''
|
||||||
|
oarlength = 2.89
|
||||||
|
inboard = 0.88
|
||||||
if len(fileformat)==3 and fileformat[0]=='zip':
|
if len(fileformat)==3 and fileformat[0]=='zip':
|
||||||
f_to_be_deleted = f2
|
f_to_be_deleted = f2
|
||||||
with zipfile.ZipFile(f2) as z:
|
with zipfile.ZipFile(f2) as z:
|
||||||
@@ -590,7 +607,7 @@ def new_workout_from_file(r,f2,
|
|||||||
|
|
||||||
# handle non-Painsled by converting it to painsled compatible CSV
|
# handle non-Painsled by converting it to painsled compatible CSV
|
||||||
if (fileformat != 'csv'):
|
if (fileformat != 'csv'):
|
||||||
f2,summary = handle_nonpainsled(f2,fileformat,summary=summary)
|
f2,summary,oarlength,inboard = handle_nonpainsled(f2,fileformat,summary=summary)
|
||||||
|
|
||||||
|
|
||||||
dosummary = (fileformat != 'fit')
|
dosummary = (fileformat != 'fit')
|
||||||
@@ -599,6 +616,7 @@ def new_workout_from_file(r,f2,
|
|||||||
makeprivate=makeprivate,
|
makeprivate=makeprivate,
|
||||||
dosummary=dosummary,
|
dosummary=dosummary,
|
||||||
summary=summary,
|
summary=summary,
|
||||||
|
inboard=inboard,oarlength=oarlength,
|
||||||
title=title)
|
title=title)
|
||||||
|
|
||||||
return (id,message,f2)
|
return (id,message,f2)
|
||||||
@@ -905,7 +923,7 @@ def datafusion(id1,id2,columns,offset):
|
|||||||
# saves it to the stroke_data table in the database
|
# saves it to the stroke_data table in the database
|
||||||
# Takes a rowingdata object's DataFrame as input
|
# Takes a rowingdata object's DataFrame as input
|
||||||
def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
|
def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
|
||||||
empower=True):
|
empower=True,inboard=0.88):
|
||||||
rowdatadf.set_index([range(len(rowdatadf))],inplace=True)
|
rowdatadf.set_index([range(len(rowdatadf))],inplace=True)
|
||||||
t = rowdatadf.ix[:,'TimeStamp (sec)']
|
t = rowdatadf.ix[:,'TimeStamp (sec)']
|
||||||
t = pd.Series(t-rowdatadf.ix[0,'TimeStamp (sec)'])
|
t = pd.Series(t-rowdatadf.ix[0,'TimeStamp (sec)'])
|
||||||
@@ -1018,8 +1036,15 @@ def dataprep(rowdatadf,id=0,bands=True,barchart=True,otwpower=True,
|
|||||||
finish = rowdatadf.ix[:,'finish']
|
finish = rowdatadf.ix[:,'finish']
|
||||||
peakforceangle = rowdatadf.ix[:,'peakforceangle']
|
peakforceangle = rowdatadf.ix[:,'peakforceangle']
|
||||||
driveenergy = rowdatadf.ix[:,'driveenergy']
|
driveenergy = rowdatadf.ix[:,'driveenergy']
|
||||||
drivelength = driveenergy/(averageforce*4.44822)
|
arclength = (inboard-0.05)*(np.radians(finish)-np.radians(catch))
|
||||||
|
if arclength.mean()>0:
|
||||||
|
drivelength = arclength
|
||||||
|
else:
|
||||||
|
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)
|
||||||
@@ -1028,6 +1053,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
|
||||||
@@ -1035,6 +1062,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
|
||||||
|
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -139,9 +108,10 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
|
|||||||
|
|
||||||
columns = ['catch','slip','wash','finish','averageforce',
|
columns = ['catch','slip','wash','finish','averageforce',
|
||||||
'peakforceangle','peakforce','spm','distance',
|
'peakforceangle','peakforce','spm','distance',
|
||||||
'workoutstate']
|
'workoutstate','driveenergy']
|
||||||
|
|
||||||
rowdata = dataprep.getsmallrowdata_db(columns,ids=ids)
|
rowdata = dataprep.getsmallrowdata_db(columns,ids=ids)
|
||||||
|
rowdata.dropna(axis=1,how='all',inplace=True)
|
||||||
rowdata.dropna(axis=0,how='any',inplace=True)
|
rowdata.dropna(axis=0,how='any',inplace=True)
|
||||||
|
|
||||||
workoutstateswork = [1,4,5,8,9,6,7]
|
workoutstateswork = [1,4,5,8,9,6,7]
|
||||||
@@ -154,6 +124,8 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if rowdata.empty:
|
||||||
|
return "","No Valid Data Available","",""
|
||||||
|
|
||||||
catchav = rowdata['catch'].mean()
|
catchav = rowdata['catch'].mean()
|
||||||
finishav = rowdata['finish'].mean()
|
finishav = rowdata['finish'].mean()
|
||||||
@@ -276,6 +248,7 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
|
|||||||
var y = data['y']
|
var y = data['y']
|
||||||
var spm1 = data2['spm']
|
var spm1 = data2['spm']
|
||||||
var distance1 = data2['distance']
|
var distance1 = data2['distance']
|
||||||
|
var driveenergy1 = data2['driveenergy']
|
||||||
|
|
||||||
var thresholdforce = y[1]
|
var thresholdforce = y[1]
|
||||||
|
|
||||||
@@ -291,6 +264,8 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
|
|||||||
var maxspm = maxspm.value
|
var maxspm = maxspm.value
|
||||||
var mindist = mindist.value
|
var mindist = mindist.value
|
||||||
var maxdist = maxdist.value
|
var maxdist = maxdist.value
|
||||||
|
var minwork = minwork.value
|
||||||
|
var maxwork = maxwork.value
|
||||||
|
|
||||||
var catchav = 0
|
var catchav = 0
|
||||||
var finishav = 0
|
var finishav = 0
|
||||||
@@ -305,14 +280,16 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
|
|||||||
for (i=0; i<c.length; i++) {
|
for (i=0; i<c.length; i++) {
|
||||||
if (spm1[i]>=minspm && spm1[i]<=maxspm) {
|
if (spm1[i]>=minspm && spm1[i]<=maxspm) {
|
||||||
if (distance1[i]>=mindist && distance1[i]<=maxdist) {
|
if (distance1[i]>=mindist && distance1[i]<=maxdist) {
|
||||||
catchav += c[i]
|
if (driveenergy1[i]>=minwork && driveenergy1[i]<=maxwork) {
|
||||||
finishav += finish[i]
|
catchav += c[i]
|
||||||
slipav += slip[i]
|
finishav += finish[i]
|
||||||
washav += wash[i]
|
slipav += slip[i]
|
||||||
peakforceangleav += peakforceangle[i]
|
washav += wash[i]
|
||||||
averageforceav += averageforce[i]
|
peakforceangleav += peakforceangle[i]
|
||||||
peakforceav += peakforce[i]
|
averageforceav += averageforce[i]
|
||||||
count += 1
|
peakforceav += peakforce[i]
|
||||||
|
count += 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -349,6 +326,15 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
|
|||||||
title="Max SPM",callback=callback)
|
title="Max SPM",callback=callback)
|
||||||
callback.args["maxspm"] = slider_spm_max
|
callback.args["maxspm"] = slider_spm_max
|
||||||
|
|
||||||
|
slider_work_min = Slider(start=0, end=1500,value=0, step=10,
|
||||||
|
title="Min Work per Stroke",callback=callback)
|
||||||
|
callback.args["minwork"] = slider_work_min
|
||||||
|
|
||||||
|
|
||||||
|
slider_work_max = Slider(start=0, end=1500,value=1500, step=10,
|
||||||
|
title="Max Work per Stroke",callback=callback)
|
||||||
|
callback.args["maxwork"] = slider_work_max
|
||||||
|
|
||||||
distmax = 100+100*int(rowdata['distance'].max()/100.)
|
distmax = 100+100*int(rowdata['distance'].max()/100.)
|
||||||
|
|
||||||
slider_dist_min = Slider(start=0,end=distmax,value=0,step=1,
|
slider_dist_min = Slider(start=0,end=distmax,value=0,step=1,
|
||||||
@@ -361,9 +347,11 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
|
|||||||
callback.args["maxdist"] = slider_dist_max
|
callback.args["maxdist"] = slider_dist_max
|
||||||
|
|
||||||
layout = layoutrow([layoutcolumn([slider_spm_min,
|
layout = layoutrow([layoutcolumn([slider_spm_min,
|
||||||
slider_spm_max,
|
slider_spm_max,
|
||||||
slider_dist_min,
|
slider_dist_min,
|
||||||
slider_dist_max,
|
slider_dist_max,
|
||||||
|
slider_work_min,
|
||||||
|
slider_work_max,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
plot])
|
plot])
|
||||||
@@ -386,6 +374,9 @@ def interactive_histoall(theworkouts):
|
|||||||
rowdata = dataprep.getsmallrowdata_db(['power'],ids=ids,doclean=True)
|
rowdata = dataprep.getsmallrowdata_db(['power'],ids=ids,doclean=True)
|
||||||
rowdata.dropna(axis=0,how='any',inplace=True)
|
rowdata.dropna(axis=0,how='any',inplace=True)
|
||||||
|
|
||||||
|
if rowdata.empty:
|
||||||
|
return "","No Valid Data Available","",""
|
||||||
|
|
||||||
histopwr = rowdata['power'].values
|
histopwr = rowdata['power'].values
|
||||||
if len(histopwr) == 0:
|
if len(histopwr) == 0:
|
||||||
return "","No valid data available","",""
|
return "","No valid data available","",""
|
||||||
@@ -892,20 +883,21 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
|
|||||||
|
|
||||||
# datadf = dataprep.smalldataprep(theworkouts,xparam,yparam1,yparam2)
|
# datadf = dataprep.smalldataprep(theworkouts,xparam,yparam1,yparam2)
|
||||||
ids = [int(w.id) for w in theworkouts]
|
ids = [int(w.id) for w in theworkouts]
|
||||||
datadf = dataprep.getsmallrowdata_db([xparam,yparam1,yparam2],ids=ids,doclean=False)
|
columns = [xparam,yparam1,yparam2,'spm','driveenergy','distance']
|
||||||
|
datadf = dataprep.getsmallrowdata_db(columns,ids=ids,doclean=False)
|
||||||
|
|
||||||
yparamname1 = axlabels[yparam1]
|
yparamname1 = axlabels[yparam1]
|
||||||
if yparam2 != 'None':
|
if yparam2 != 'None':
|
||||||
yparamname2 = axlabels[yparam2]
|
yparamname2 = axlabels[yparam2]
|
||||||
|
|
||||||
|
|
||||||
datadf = datadf[datadf[yparam1] > 0]
|
#datadf = datadf[datadf[yparam1] > 0]
|
||||||
|
|
||||||
|
|
||||||
datadf = datadf[datadf[xparam] > 0]
|
#datadf = datadf[datadf[xparam] > 0]
|
||||||
|
|
||||||
if yparam2 != 'None':
|
#if yparam2 != 'None':
|
||||||
datadf = datadf[datadf[yparam2] > 0]
|
# datadf = datadf[datadf[yparam2] > 0]
|
||||||
|
|
||||||
# check if dataframe not empty
|
# check if dataframe not empty
|
||||||
if datadf.empty:
|
if datadf.empty:
|
||||||
@@ -973,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',
|
||||||
@@ -985,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',
|
||||||
@@ -1025,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',
|
||||||
)
|
)
|
||||||
@@ -1048,6 +1040,7 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
|
|||||||
var y2 = data['y2']
|
var y2 = data['y2']
|
||||||
var spm1 = data['spm']
|
var spm1 = data['spm']
|
||||||
var distance1 = data['distance']
|
var distance1 = data['distance']
|
||||||
|
var driveenergy1 = data['driveenergy']
|
||||||
var xname = data['xname'][0]
|
var xname = data['xname'][0]
|
||||||
var yname1 = data['yname1'][0]
|
var yname1 = data['yname1'][0]
|
||||||
var yname2 = data['yname2'][0]
|
var yname2 = data['yname2'][0]
|
||||||
@@ -1056,6 +1049,8 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
|
|||||||
var maxspm = maxspm.value
|
var maxspm = maxspm.value
|
||||||
var mindist = mindist.value
|
var mindist = mindist.value
|
||||||
var maxdist = maxdist.value
|
var maxdist = maxdist.value
|
||||||
|
var minwork = minwork.value
|
||||||
|
var maxwork = maxwork.value
|
||||||
var xm = 0
|
var xm = 0
|
||||||
var ym1 = 0
|
var ym1 = 0
|
||||||
var ym2 = 0
|
var ym2 = 0
|
||||||
@@ -1075,16 +1070,17 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
|
|||||||
for (i=0; i<x1.length; i++) {
|
for (i=0; i<x1.length; i++) {
|
||||||
if (spm1[i]>=minspm && spm1[i]<=maxspm) {
|
if (spm1[i]>=minspm && spm1[i]<=maxspm) {
|
||||||
if (distance1[i]>=mindist && distance1[i]<=maxdist) {
|
if (distance1[i]>=mindist && distance1[i]<=maxdist) {
|
||||||
data2['x1'].push(x1[i])
|
if (driveenergy1[i]>=minwork && driveenergy1[i]<=maxwork) {
|
||||||
data2['y1'].push(y1[i])
|
data2['x1'].push(x1[i])
|
||||||
data2['y2'].push(y2[i])
|
data2['y1'].push(y1[i])
|
||||||
data2['spm'].push(spm1[i])
|
data2['y2'].push(y2[i])
|
||||||
data2['distance'].push(distance1[i])
|
data2['spm'].push(spm1[i])
|
||||||
|
data2['distance'].push(distance1[i])
|
||||||
xm += x1[i]
|
|
||||||
ym1 += y1[i]
|
|
||||||
ym2 += y2[i]
|
|
||||||
|
|
||||||
|
xm += x1[i]
|
||||||
|
ym1 += y1[i]
|
||||||
|
ym2 += y2[i]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1099,9 +1095,9 @@ def interactive_cum_flex_chart2(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)
|
y1label.text = yname1+': '+(ym1).toFixed(2)
|
||||||
y2label.text = yname2+': '+ym2.toFixed(2)
|
y2label.text = yname2+': '+(ym2).toFixed(2)
|
||||||
xlabel.text = xname+': '+xm.toFixed(2)
|
xlabel.text = xname+': '+(xm).toFixed(2)
|
||||||
|
|
||||||
source2.trigger('change');
|
source2.trigger('change');
|
||||||
""")
|
""")
|
||||||
@@ -1115,6 +1111,15 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
|
|||||||
title="Max SPM",callback=callback)
|
title="Max SPM",callback=callback)
|
||||||
callback.args["maxspm"] = slider_spm_max
|
callback.args["maxspm"] = slider_spm_max
|
||||||
|
|
||||||
|
slider_work_min = Slider(start=0.0, end=1500,value=0.0, step=10,
|
||||||
|
title="Min Work per Stroke",callback=callback)
|
||||||
|
callback.args["minwork"] = slider_work_min
|
||||||
|
|
||||||
|
|
||||||
|
slider_work_max = Slider(start=0.0, end=1500,value=1500.0, step=10,
|
||||||
|
title="Max Work per Stroke",callback=callback)
|
||||||
|
callback.args["maxwork"] = slider_work_max
|
||||||
|
|
||||||
distmax = 100+100*int(datadf['distance'].max()/100.)
|
distmax = 100+100*int(datadf['distance'].max()/100.)
|
||||||
|
|
||||||
slider_dist_min = Slider(start=0,end=distmax,value=0,step=1,
|
slider_dist_min = Slider(start=0,end=distmax,value=0,step=1,
|
||||||
@@ -1127,9 +1132,11 @@ def interactive_cum_flex_chart2(theworkouts,promember=0,
|
|||||||
callback.args["maxdist"] = slider_dist_max
|
callback.args["maxdist"] = slider_dist_max
|
||||||
|
|
||||||
layout = layoutrow([layoutcolumn([slider_spm_min,
|
layout = layoutrow([layoutcolumn([slider_spm_min,
|
||||||
slider_spm_max,
|
slider_spm_max,
|
||||||
slider_dist_min,
|
slider_dist_min,
|
||||||
slider_dist_max,
|
slider_dist_max,
|
||||||
|
slider_work_min,
|
||||||
|
slider_work_max,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
plot])
|
plot])
|
||||||
@@ -1157,11 +1164,13 @@ def interactive_flex_chart2(id=0,promember=0,
|
|||||||
#rowdata,row = dataprep.getrowdata_db(id=id)
|
#rowdata,row = dataprep.getrowdata_db(id=id)
|
||||||
columns = [xparam,yparam1,yparam2,
|
columns = [xparam,yparam1,yparam2,
|
||||||
'ftime','distance','fpace',
|
'ftime','distance','fpace',
|
||||||
'power','hr','spm',
|
'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)
|
||||||
|
|
||||||
rowdata.dropna(axis=1,how='all',inplace=True)
|
rowdata.dropna(axis=1,how='all',inplace=True)
|
||||||
|
rowdata.dropna(axis=0,how='any',inplace=True)
|
||||||
|
|
||||||
row = Workout.objects.get(id=id)
|
row = Workout.objects.get(id=id)
|
||||||
if rowdata.empty:
|
if rowdata.empty:
|
||||||
@@ -1182,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]
|
||||||
@@ -1211,7 +1220,10 @@ def interactive_flex_chart2(id=0,promember=0,
|
|||||||
|
|
||||||
# average values
|
# average values
|
||||||
if xparam != 'time':
|
if xparam != 'time':
|
||||||
x1mean = rowdata['x1'].mean()
|
try:
|
||||||
|
x1mean = rowdata['x1'].mean()
|
||||||
|
except TypeError:
|
||||||
|
x1mean = 0
|
||||||
else:
|
else:
|
||||||
x1mean = 0
|
x1mean = 0
|
||||||
|
|
||||||
@@ -1277,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',
|
||||||
)
|
)
|
||||||
@@ -1290,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',
|
||||||
)
|
)
|
||||||
@@ -1365,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',
|
||||||
)
|
)
|
||||||
@@ -1400,6 +1412,7 @@ def interactive_flex_chart2(id=0,promember=0,
|
|||||||
var y1 = data['y1']
|
var y1 = data['y1']
|
||||||
var y2 = data['y2']
|
var y2 = data['y2']
|
||||||
var spm1 = data['spm']
|
var spm1 = data['spm']
|
||||||
|
var driveenergy1 = data['driveenergy']
|
||||||
var time1 = data['time']
|
var time1 = data['time']
|
||||||
var pace1 = data['pace']
|
var pace1 = data['pace']
|
||||||
var hr1 = data['hr']
|
var hr1 = data['hr']
|
||||||
@@ -1414,6 +1427,8 @@ def interactive_flex_chart2(id=0,promember=0,
|
|||||||
var maxspm = maxspm.value
|
var maxspm = maxspm.value
|
||||||
var mindist = mindist.value
|
var mindist = mindist.value
|
||||||
var maxdist = maxdist.value
|
var maxdist = maxdist.value
|
||||||
|
var minwork = minwork.value
|
||||||
|
var maxwork = maxwork.value
|
||||||
var xm = 0
|
var xm = 0
|
||||||
var ym1 = 0
|
var ym1 = 0
|
||||||
var ym2 = 0
|
var ym2 = 0
|
||||||
@@ -1438,21 +1453,22 @@ def interactive_flex_chart2(id=0,promember=0,
|
|||||||
for (i=0; i<x1.length; i++) {
|
for (i=0; i<x1.length; i++) {
|
||||||
if (spm1[i]>=minspm && spm1[i]<=maxspm) {
|
if (spm1[i]>=minspm && spm1[i]<=maxspm) {
|
||||||
if (distance1[i]>=mindist && distance1[i]<=maxdist) {
|
if (distance1[i]>=mindist && distance1[i]<=maxdist) {
|
||||||
data2['x1'].push(x1[i])
|
if (driveenergy1[i]>=minwork && driveenergy1[i]<=maxwork) {
|
||||||
data2['y1'].push(y1[i])
|
data2['x1'].push(x1[i])
|
||||||
data2['y2'].push(y2[i])
|
data2['y1'].push(y1[i])
|
||||||
data2['spm'].push(spm1[i])
|
data2['y2'].push(y2[i])
|
||||||
data2['time'].push(time1[i])
|
data2['spm'].push(spm1[i])
|
||||||
data2['fpace'].push(fpace1[i])
|
data2['time'].push(time1[i])
|
||||||
data2['pace'].push(pace1[i])
|
data2['fpace'].push(fpace1[i])
|
||||||
data2['hr'].push(hr1[i])
|
data2['pace'].push(pace1[i])
|
||||||
data2['distance'].push(distance1[i])
|
data2['hr'].push(hr1[i])
|
||||||
data2['power'].push(power1[i])
|
data2['distance'].push(distance1[i])
|
||||||
|
data2['power'].push(power1[i])
|
||||||
xm += x1[i]
|
|
||||||
ym1 += y1[i]
|
|
||||||
ym2 += y2[i]
|
|
||||||
|
|
||||||
|
xm += x1[i]
|
||||||
|
ym1 += y1[i]
|
||||||
|
ym2 += y2[i]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1483,6 +1499,15 @@ def interactive_flex_chart2(id=0,promember=0,
|
|||||||
title="Max SPM",callback=callback)
|
title="Max SPM",callback=callback)
|
||||||
callback.args["maxspm"] = slider_spm_max
|
callback.args["maxspm"] = slider_spm_max
|
||||||
|
|
||||||
|
slider_work_min = Slider(start=0.0, end=1500,value=0.0, step=10,
|
||||||
|
title="Min Work per Stroke",callback=callback)
|
||||||
|
callback.args["minwork"] = slider_work_min
|
||||||
|
|
||||||
|
|
||||||
|
slider_work_max = Slider(start=0.0, end=1500,value=1500.0, step=10,
|
||||||
|
title="Max Work per Stroke",callback=callback)
|
||||||
|
callback.args["maxwork"] = slider_work_max
|
||||||
|
|
||||||
distmax = 100+100*int(rowdata['distance'].max()/100.)
|
distmax = 100+100*int(rowdata['distance'].max()/100.)
|
||||||
|
|
||||||
slider_dist_min = Slider(start=0,end=distmax,value=0,step=1,
|
slider_dist_min = Slider(start=0,end=distmax,value=0,step=1,
|
||||||
@@ -1495,9 +1520,11 @@ def interactive_flex_chart2(id=0,promember=0,
|
|||||||
callback.args["maxdist"] = slider_dist_max
|
callback.args["maxdist"] = slider_dist_max
|
||||||
|
|
||||||
layout = layoutrow([layoutcolumn([slider_spm_min,
|
layout = layoutrow([layoutcolumn([slider_spm_min,
|
||||||
slider_spm_max,
|
slider_spm_max,
|
||||||
slider_dist_min,
|
slider_dist_min,
|
||||||
slider_dist_max,
|
slider_dist_max,
|
||||||
|
slider_work_min,
|
||||||
|
slider_work_max,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
plot])
|
plot])
|
||||||
@@ -1512,7 +1539,9 @@ def interactive_flex_chart2(id=0,promember=0,
|
|||||||
def interactive_bar_chart(id=0,promember=0):
|
def interactive_bar_chart(id=0,promember=0):
|
||||||
# check if valid ID exists (workout exists)
|
# check if valid ID exists (workout exists)
|
||||||
rowdata,row = dataprep.getrowdata_db(id=id)
|
rowdata,row = dataprep.getrowdata_db(id=id)
|
||||||
|
rowdata.dropna(axis=1,how='all',inplace=True)
|
||||||
rowdata.dropna(axis=0,how='any',inplace=True)
|
rowdata.dropna(axis=0,how='any',inplace=True)
|
||||||
|
|
||||||
if rowdata.empty:
|
if rowdata.empty:
|
||||||
return "","No Valid Data Available"
|
return "","No Valid Data Available"
|
||||||
|
|
||||||
@@ -1610,7 +1639,9 @@ def interactive_multiple_compare_chart(ids,xparam,yparam,plottype='line',
|
|||||||
'workoutid']
|
'workoutid']
|
||||||
|
|
||||||
datadf = dataprep.getsmallrowdata_db(columns,ids=ids)
|
datadf = dataprep.getsmallrowdata_db(columns,ids=ids)
|
||||||
|
datadf.dropna(axis=1,how='all',inplace=True)
|
||||||
datadf.dropna(axis=0,how='any',inplace=True)
|
datadf.dropna(axis=0,how='any',inplace=True)
|
||||||
|
|
||||||
tseconds = datadf.ix[:,'time']
|
tseconds = datadf.ix[:,'time']
|
||||||
|
|
||||||
yparamname = axlabels[yparam]
|
yparamname = axlabels[yparam]
|
||||||
@@ -1672,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]
|
||||||
group['y'] = group[yparam]
|
try:
|
||||||
|
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,
|
||||||
)
|
)
|
||||||
@@ -1772,8 +1806,11 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
|
|||||||
rowdata1[n].fillna(value=0,inplace=True)
|
rowdata1[n].fillna(value=0,inplace=True)
|
||||||
rowdata2[n].fillna(value=0,inplace=True)
|
rowdata2[n].fillna(value=0,inplace=True)
|
||||||
|
|
||||||
|
rowdata1.dropna(axis=1,how='all',inplace=True)
|
||||||
rowdata1.dropna(axis=0,how='any',inplace=True)
|
rowdata1.dropna(axis=0,how='any',inplace=True)
|
||||||
|
rowdata2.dropna(axis=1,how='all',inplace=True)
|
||||||
rowdata2.dropna(axis=0,how='any',inplace=True)
|
rowdata2.dropna(axis=0,how='any',inplace=True)
|
||||||
|
|
||||||
row1 = Workout.objects.get(id=id1)
|
row1 = Workout.objects.get(id=id1)
|
||||||
row2 = Workout.objects.get(id=id2)
|
row2 = Workout.objects.get(id=id2)
|
||||||
|
|
||||||
@@ -1787,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)
|
||||||
|
|
||||||
x1 = rowdata1.ix[:,xparam]
|
try:
|
||||||
x2 = rowdata2.ix[:,xparam]
|
x1 = rowdata1.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'
|
||||||
@@ -1914,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(
|
||||||
@@ -1943,7 +1983,9 @@ def interactive_comparison_chart(id1=0,id2=0,xparam='distance',yparam='spm',
|
|||||||
def interactive_otw_advanced_pace_chart(id=0,promember=0):
|
def interactive_otw_advanced_pace_chart(id=0,promember=0):
|
||||||
# check if valid ID exists (workout exists)
|
# check if valid ID exists (workout exists)
|
||||||
rowdata,row = dataprep.getrowdata_db(id=id)
|
rowdata,row = dataprep.getrowdata_db(id=id)
|
||||||
|
rowdata.dropna(axis=1,how='all',inplace=True)
|
||||||
rowdata.dropna(axis=0,how='any',inplace=True)
|
rowdata.dropna(axis=0,how='any',inplace=True)
|
||||||
|
|
||||||
if rowdata.empty:
|
if rowdata.empty:
|
||||||
return "","No Valid Data Available"
|
return "","No Valid Data Available"
|
||||||
|
|
||||||
|
|||||||
@@ -393,6 +393,12 @@ class Workout(models.Model):
|
|||||||
maxhr = models.IntegerField(blank=True,null=True)
|
maxhr = models.IntegerField(blank=True,null=True)
|
||||||
uploadedtostrava = models.IntegerField(default=0)
|
uploadedtostrava = models.IntegerField(default=0)
|
||||||
uploadedtosporttracks = models.IntegerField(default=0)
|
uploadedtosporttracks = models.IntegerField(default=0)
|
||||||
|
|
||||||
|
# empower stuff
|
||||||
|
inboard = models.FloatField(default=0.88)
|
||||||
|
oarlength = models.FloatField(default=2.89)
|
||||||
|
|
||||||
|
|
||||||
notes = models.CharField(blank=True,null=True,max_length=1000)
|
notes = models.CharField(blank=True,null=True,max_length=1000)
|
||||||
summary = models.TextField(blank=True)
|
summary = models.TextField(blank=True)
|
||||||
privacy = models.CharField(default='visible',max_length=30,
|
privacy = models.CharField(default='visible',max_length=30,
|
||||||
@@ -492,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):
|
||||||
|
|||||||
@@ -6,144 +6,134 @@
|
|||||||
|
|
||||||
{% 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 () {
|
||||||
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
|
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
|
||||||
var plot = Bokeh.index[plotid];
|
var plot = Bokeh.index[plotid];
|
||||||
var plotresizer = function() {
|
var plotresizer = function() {
|
||||||
// arguments: use width, use height, maintain aspect ratio
|
// arguments: use width, use height, maintain aspect ratio
|
||||||
plot.resize_width_height(true, true, false);
|
plot.resize_width_height(true, true, false);
|
||||||
};
|
};
|
||||||
window.addEventListener('resize', plotresizer);
|
window.addEventListener('resize', plotresizer);
|
||||||
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 %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div id="other" class="grid_12 alpha">
|
<div id="other" class="grid_12 alpha">
|
||||||
<div class="grid_2 alpha">
|
<div class="grid_2 alpha">
|
||||||
<a class="button blue small"
|
<a class="button blue small"
|
||||||
href="/rowers/workout/compare/{{ id2 }}/{{ id1 }}/{{ xparam }}/{{ yparam }}/{{ plottype }}">Swap Workouts</a>
|
href="/rowers/workout/compare/{{ id2 }}/{{ id1 }}/{{ xparam }}/{{ yparam }}/{{ plottype }}">Swap Workouts</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid_2">
|
<div class="grid_2">
|
||||||
<a class="button blue small"
|
<a class="button blue small"
|
||||||
href="/rowers/workout/{{ id1 }}/edit">Edit Workout</a>
|
href="/rowers/workout/{{ id1 }}/edit">Edit Workout</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid_2 suffix_6 omega">
|
<div class="grid_2 suffix_6 omega">
|
||||||
<a class="button blue small"
|
<a class="button blue small"
|
||||||
href="/rowers/workout/{{ id1 }}/advanced">Advanced Edit</a>
|
href="/rowers/workout/{{ id1 }}/advanced">Advanced Edit</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p> </p>
|
<p> </p>
|
||||||
|
|
||||||
<div id="plotbuttons" class="grid_12 alpha">
|
<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 suffix_2 omega dropdown">
|
||||||
<div class="grid_2 alpha dropdown">
|
<button class="grid_2 alpha button blue small dropbtn">Y-axis</button>
|
||||||
<button class="grid_2 alpha button blue small dropbtn">X-axis</button>
|
<div class="dropdown-content">
|
||||||
<div class="dropdown-content">
|
{% for key, value in axchoicesbasic.items %}
|
||||||
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/time/{{ yparam }}/{{ plottype }}">Time</a>
|
{% if key not in noylist and key != 'None' %}
|
||||||
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/distance/{{ yparam }}/{{ plottype }}">Distance</a>
|
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ key }}/{{ plottype }}">{{ value }}</a>
|
||||||
{% if promember %}
|
{% endif %}
|
||||||
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/power/{{ yparam }}/scatter">Power</a>
|
{% endfor %}
|
||||||
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/hr/{{ yparam }}/scatter">HR</a>
|
{% if promember %}
|
||||||
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/spm/{{ yparam }}/scatter">SPM</a>
|
{% for key, value in axchoicespro.items %}
|
||||||
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/peakforce/{{ yparam }}/scatter">Peak Force</a>
|
{% if key not in noylist %}
|
||||||
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/averageforce/{{ yparam }}/scatter">Average Force</a>
|
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ key }}/{{ plottype }}">{{ value }}</a>
|
||||||
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/forceratio/{{ yparam }}/scatter">Average/Peak Force Ratio</a>
|
{% endif %}
|
||||||
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/drivelength/{{ yparam }}/scatter">Drive Length</a>
|
{% endfor %}
|
||||||
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/driveenergy/{{ yparam }}/scatter">Work per Stroke</a>
|
{% else %}
|
||||||
<a class="button blue small alpha" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/drivespeed/{{ yparam }}/scatter">Drive Speed</a>
|
{% for key, value in axchoicespro.items %}
|
||||||
{% else %}
|
{% if key not in noylist %}
|
||||||
<a class="button rosy small" href="/rowers/promembership">Power (Pro)</a>
|
<a class="button rosy small" href="/rowers/promembership">{{ value }} (Pro)</a>
|
||||||
<a class="button rosy small" href="/rowers/promembership">HR (Pro)</a>
|
{% endif %}
|
||||||
<a class="button rosy small" href="/rowers/promembership">SPM (Pro)</a>
|
{% endfor %}
|
||||||
<a class="button rosy small" href="/rowers/promembership">Peak Force (Pro)</a>
|
{% endif %}
|
||||||
<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>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="y-axis" class="grid_6 omega">
|
|
||||||
<div class="grid_2 prefix_2 alpha">
|
</div>
|
||||||
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ yparam }}/line">Line Plot</a>
|
|
||||||
</div>
|
<div id="y-axis" class="grid_6 omega">
|
||||||
<div class="grid_2 omega">
|
<div class="grid_2 prefix_2 alpha">
|
||||||
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ yparam }}/scatter">Scatter Plot</a>
|
<a class="button blue small" href="/rowers/workout/compare/{{ id1 }}/{{ id2 }}/{{ xparam }}/{{ yparam }}/line">Line Plot</a>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
|
|
||||||
<div id="theplot" class="grid_12 alpha flexplot">
|
<div id="theplot" class="grid_12 alpha flexplot">
|
||||||
|
|
||||||
|
|
||||||
{{ the_div|safe }}
|
{{ the_div|safe }}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -51,122 +51,70 @@
|
|||||||
<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>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
{% if promember %}
|
{% if promember %}
|
||||||
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/peakforce/{{ plottype }}">Peak Force</a>
|
{% for key, value in axchoicespro.items %}
|
||||||
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/averageforce/{{ plottype }}">Average Force</a>
|
{% if key not in noylist %}
|
||||||
<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 }}/{{ key }}/{{ plottype }}">{{ value }}</a>
|
||||||
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/drivelength/{{ plottype }}">Drive Length</a>
|
{% endif %}
|
||||||
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/driveenergy/{{ plottype }}">Work per Stroke</a>
|
{% endfor %}
|
||||||
<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>
|
|
||||||
{% 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">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>
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,21 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{{ workout.name }}</h1>
|
<h1>{{ workout.name }}</h1>
|
||||||
|
|
||||||
<div class="grid_2 suffix_10 alpha">
|
<div class="grid_2 alpha">
|
||||||
|
{% if user.is_authenticated and user == rower.user %}
|
||||||
|
<p>
|
||||||
|
<a class="button gray small" href="/rowers/workout/{{ graph.workout.id }}/edit">Edit Workout</a>
|
||||||
|
</p>
|
||||||
|
{% else %}
|
||||||
|
<p>
|
||||||
|
<a class="button gray small" href="/rowers/workout/{{ graph.workout.id }}">See Workout</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="grid_2 suffix_8 omega">
|
||||||
{% if user.is_authenticated and user == rower.user %}
|
{% if user.is_authenticated and user == rower.user %}
|
||||||
<p>
|
<p>
|
||||||
<a class="button red small" href="/rowers/graph/{{ graph.id }}/deleteconfirm">Delete</a>
|
<a class="button red small" href="/rowers/graph/{{ graph.id }}/deleteconfirm">Delete Chart</a>
|
||||||
</p>
|
</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
<p> </p>
|
<p> </p>
|
||||||
|
|||||||
@@ -231,7 +231,6 @@ def rower_register_view(request):
|
|||||||
theuser.email = email
|
theuser.email = email
|
||||||
theuser.save()
|
theuser.save()
|
||||||
|
|
||||||
|
|
||||||
therower = Rower(user=theuser)
|
therower = Rower(user=theuser)
|
||||||
|
|
||||||
therower.save()
|
therower.save()
|
||||||
@@ -3154,10 +3153,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 +3252,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 +3263,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 +3289,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 +3456,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 +3476,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 +3504,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 +3737,26 @@ def workout_comment_view(request,id=0):
|
|||||||
return HttpResponseRedirect(url)
|
return HttpResponseRedirect(url)
|
||||||
|
|
||||||
form = WorkoutCommentForm()
|
form = WorkoutCommentForm()
|
||||||
|
|
||||||
return render(request,
|
g = GraphImage.objects.filter(workout=row).order_by("-creationdatetime")
|
||||||
'workout_comments.html',
|
|
||||||
{'workout':w,
|
if (len(g)<=3):
|
||||||
'comments':comments,
|
return render(request,
|
||||||
'form':form,
|
'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
|
# The basic edit page
|
||||||
|
|||||||
Reference in New Issue
Block a user