made metrics and strokedata model dynamic
This commit is contained in:
@@ -1,32 +1,236 @@
|
|||||||
from utils import lbstoN
|
from utils import lbstoN
|
||||||
|
|
||||||
axes = (
|
rowingmetrics = (
|
||||||
('time','Time',0,1e5,'basic'),
|
('time',{
|
||||||
('distance', 'Distance (m)',0,1e5,'basic'),
|
'numtype':'float',
|
||||||
('cumdist', 'Cumulative Distance (m)',0,1e5,'basic'),
|
'null':True,
|
||||||
('hr','Heart Rate (bpm)',100,200,'basic'),
|
'verbose_name': 'Time',
|
||||||
('spm', 'Stroke Rate (spm)',15,45,'basic'),
|
'ax_min': 0,
|
||||||
('pace', 'Pace (/500m)',1.0e3*210,1.0e3*75,'basic'),
|
'ax_max': 1e5,
|
||||||
('power', 'Power (Watt)',0,600,'basic'),
|
'mode':'both',
|
||||||
('averageforce', 'Average Drive Force (N)',0,900,'pro'),
|
'type': 'basic'}),
|
||||||
('drivelength', 'Drive Length (m)',0.5,2.0,'pro'),
|
|
||||||
('peakforce', 'Peak Drive Force (N)',0,900,'pro'),
|
('hr',{
|
||||||
('forceratio', 'Average/Peak Force Ratio',0,1,'pro'),
|
'numtype':'integer',
|
||||||
('driveenergy', 'Work per Stroke (J)',0,1000,'pro'),
|
'null':True,
|
||||||
('drivespeed', 'Drive Speed (m/s)',0,4,'pro'),
|
'verbose_name': 'Heart Rate (bpm)',
|
||||||
('slip', 'Slip (degrees)',0,20,'pro'),
|
'ax_min': 100,
|
||||||
('catch', 'Catch (degrees)',-40,-75,'pro'),
|
'ax_max': 200,
|
||||||
('finish', 'Finish (degrees)',20,55,'pro'),
|
'mode':'both',
|
||||||
('wash', 'Wash (degrees)',0,30,'pro'),
|
'type': 'basic'}),
|
||||||
('peakforceangle', 'Peak Force Angle (degrees)',-20,20,'pro'),
|
|
||||||
('totalangle', 'Drive Length (deg)',40,140,'pro'),
|
('pace',{
|
||||||
('effectiveangle', 'Effective Drive Length (deg)',40,140,'pro'),
|
'numtype':'float',
|
||||||
('rhythm', 'Stroke Rhythm (%)',20,55,'pro'),
|
'null':True,
|
||||||
('efficiency', 'OTW efficiency (%)',0,110,'pro'),
|
'verbose_name': 'Pace (/500m)',
|
||||||
('distanceperstroke','Distance per Stroke (m)',0,15,'pro'),
|
'ax_min': 1.0e3*210,
|
||||||
('None', 'None',0,1,'basic'),
|
'ax_max': 1.0e3*75,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'basic'}),
|
||||||
|
|
||||||
|
('spm',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Stroke Rate (spm)',
|
||||||
|
'ax_min': 15,
|
||||||
|
'ax_max': 45,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'basic'}),
|
||||||
|
|
||||||
|
('driveenergy',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Work Per Stroke (J)',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 1000,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('power',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Power (W)',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 600,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'basic'}),
|
||||||
|
|
||||||
|
('averageforce',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Average Drive Force (N)',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 900,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('peakforce',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Peak Drive Force (N)',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 900,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('drivelength',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Drive Length (m)',
|
||||||
|
'ax_min': 15,
|
||||||
|
'ax_max': 45,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('forceratio',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Average/Peak Force Ratio',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 1,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('distance',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Distance (m)',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 1e5,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'basic'}),
|
||||||
|
|
||||||
|
('cumdist',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Cumulative Distance (m)',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 1e5,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'basic'}),
|
||||||
|
|
||||||
|
('drivespeed',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Drive Speed (m/s)',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 4,
|
||||||
|
'default': 0,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('catch',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Catch Angle (degrees)',
|
||||||
|
'ax_min': -40,
|
||||||
|
'ax_max': -75,
|
||||||
|
'default': 0,
|
||||||
|
'mode':'water',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('slip',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Slip (degrees)',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 20,
|
||||||
|
'default': 0,
|
||||||
|
'mode':'water',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('finish',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Finish Angle (degrees)',
|
||||||
|
'ax_min': 20,
|
||||||
|
'ax_max': 55,
|
||||||
|
'default': 0,
|
||||||
|
'mode':'water',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('wash',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Wash (degrees)',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 30,
|
||||||
|
'default': 0,
|
||||||
|
'mode':'water',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('peakforceangle',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Peak Force Angle',
|
||||||
|
'ax_min': -20,
|
||||||
|
'ax_max': 20,
|
||||||
|
'default': 0,
|
||||||
|
'mode':'water',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
|
||||||
|
('totalangle',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Drive Length (deg)',
|
||||||
|
'ax_min': 40,
|
||||||
|
'ax_max': 140,
|
||||||
|
'default': 0,
|
||||||
|
'mode':'water',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
|
||||||
|
('effectiveangle',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Effective Drive Length (deg)',
|
||||||
|
'ax_min': 40,
|
||||||
|
'ax_max': 140,
|
||||||
|
'default': 0,
|
||||||
|
'mode':'water',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('rhythm',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Stroke Rhythm',
|
||||||
|
'ax_min': 20,
|
||||||
|
'ax_max': 55,
|
||||||
|
'default': 1.0,
|
||||||
|
'mode':'erg',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('efficiency',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'OTW Efficiency (%)',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 110,
|
||||||
|
'default': 0,
|
||||||
|
'mode':'water',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
|
('distanceperstroke',{
|
||||||
|
'numtype':'float',
|
||||||
|
'null':True,
|
||||||
|
'verbose_name': 'Distance per Stroke (m)',
|
||||||
|
'ax_min': 0,
|
||||||
|
'ax_max': 15,
|
||||||
|
'default': 0,
|
||||||
|
'mode':'both',
|
||||||
|
'type': 'pro'}),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
axesnew = [
|
||||||
|
(name,d['verbose_name'],d['ax_min'],d['ax_max'],d['type']) for name,d in rowingmetrics
|
||||||
|
]
|
||||||
|
|
||||||
|
axes = tuple(axesnew+[('None','None',0,1,'basic')])
|
||||||
|
|
||||||
axlabels = {ax[0]:ax[1] for ax in axes}
|
axlabels = {ax[0]:ax[1] for ax in axes}
|
||||||
|
|
||||||
yaxminima = {ax[0]:ax[2] for ax in axes}
|
yaxminima = {ax[0]:ax[2] for ax in axes}
|
||||||
|
|||||||
100
rowers/models.py
100
rowers/models.py
@@ -519,57 +519,65 @@ def auto_delete_strokedata_on_delete(sender, instance, **kwargs):
|
|||||||
conn.close()
|
conn.close()
|
||||||
engine.dispose()
|
engine.dispose()
|
||||||
|
|
||||||
|
from rowers.metrics import rowingmetrics
|
||||||
|
|
||||||
|
strokedatafields = {
|
||||||
|
'workoutid':models.IntegerField(null=True),
|
||||||
|
'workoutstate':models.IntegerField(null=True,default=1),
|
||||||
|
'ftime':models.CharField(max_length=30),
|
||||||
|
'fpace':models.CharField(max_length=30),
|
||||||
|
'hr_ut2':models.IntegerField(null=True),
|
||||||
|
'hr_ut1':models.IntegerField(null=True),
|
||||||
|
'hr_at':models.IntegerField(null=True),
|
||||||
|
'hr_tr':models.IntegerField(null=True),
|
||||||
|
'hr_an':models.IntegerField(null=True),
|
||||||
|
'hr_max':models.IntegerField(null=True),
|
||||||
|
'hr_bottom':models.IntegerField(null=True),
|
||||||
|
'x_right':models.FloatField(null=True),
|
||||||
|
'ergpace':models.FloatField(null=True),
|
||||||
|
'nowindpace':models.FloatField(null=True),
|
||||||
|
'equivergpower':models.FloatField(null=True),
|
||||||
|
'fergpace':models.CharField(max_length=30),
|
||||||
|
'fnowindpace':models.CharField(max_length=30),
|
||||||
|
}
|
||||||
|
|
||||||
|
for name,d in rowingmetrics:
|
||||||
|
if d['numtype'] == 'float':
|
||||||
|
try:
|
||||||
|
strokedatafields[name] = models.FloatField(
|
||||||
|
null=d['null'],
|
||||||
|
default=d['default'],
|
||||||
|
verbose_name=d['verbose_name'])
|
||||||
|
except KeyError:
|
||||||
|
strokedatafields[name] = models.FloatField(
|
||||||
|
null=d['null'],
|
||||||
|
verbose_name=d['verbose_name'])
|
||||||
|
elif d['numtype'] == 'integer':
|
||||||
|
try:
|
||||||
|
strokedatafields[name] = models.IntegerField(
|
||||||
|
null=d['null'],
|
||||||
|
default=d['default'],
|
||||||
|
verbose_name=d['verbose_name'])
|
||||||
|
except KeyError:
|
||||||
|
strokedatafields[name] = models.IntegerField(
|
||||||
|
null=d['null'],
|
||||||
|
verbose_name=d['verbose_name'])
|
||||||
|
class Meta:
|
||||||
|
db_table = 'strokedata'
|
||||||
|
index_together = ['workoutid']
|
||||||
|
app_label = 'rowers'
|
||||||
|
|
||||||
|
attrs = {'__module__': '', 'Meta': Meta}
|
||||||
|
attrs.update(strokedatafields)
|
||||||
|
|
||||||
# Model of StrokeData table
|
# Model of StrokeData table
|
||||||
# the definition here is used only to enable easy Django migration
|
# the definition here is used only to enable easy Django migration
|
||||||
# when the StrokeData are expanded.
|
# when the StrokeData are expanded.
|
||||||
# No Django Instances of this model are managed. Strokedata table is
|
# No Django Instances of this model are managed. Strokedata table is
|
||||||
# accesssed directly with SQL commands
|
# accesssed directly with SQL commands
|
||||||
class StrokeData(models.Model):
|
StrokeData = type(str('StrokeData'), (models.Model,),
|
||||||
class Meta:
|
attrs
|
||||||
db_table = 'strokedata'
|
)
|
||||||
index_together = ['workoutid']
|
|
||||||
|
|
||||||
workoutid = models.IntegerField(null=True)
|
|
||||||
time = models.FloatField(null=True,verbose_name='Time')
|
|
||||||
hr = models.IntegerField(null=True,verbose_name='Heart Rate')
|
|
||||||
pace = models.FloatField(null=True,verbose_name='Pace')
|
|
||||||
workoutstate = models.IntegerField(null=True,default=1)
|
|
||||||
spm = models.FloatField(null=True,verbose_name='Stroke Rate')
|
|
||||||
cumdist = models.FloatField(null=True,verbose_name='Cumulative Distance')
|
|
||||||
ftime = models.CharField(max_length=30)
|
|
||||||
fpace = models.CharField(max_length=30)
|
|
||||||
driveenergy = models.FloatField(null=True,verbose_name='Work per Stroke')
|
|
||||||
power = models.FloatField(null=True,verbose_name='Power')
|
|
||||||
averageforce = models.FloatField(null=True,verbose_name='Average Force')
|
|
||||||
drivelength = models.FloatField(null=True,verbose_name='Drive Length')
|
|
||||||
peakforce = models.FloatField(null=True,verbose_name='Peak Force')
|
|
||||||
forceratio = models.FloatField(null=True,verbose_name='Average/Peak Force Ratio')
|
|
||||||
distance = models.FloatField(null=True,verbose_name='Distance')
|
|
||||||
drivespeed = models.FloatField(null=True,verbose_name='Drive Speed',
|
|
||||||
default=0)
|
|
||||||
hr_ut2 = models.IntegerField(null=True)
|
|
||||||
hr_ut1 = models.IntegerField(null=True)
|
|
||||||
hr_at = models.IntegerField(null=True)
|
|
||||||
hr_tr = models.IntegerField(null=True)
|
|
||||||
hr_an = models.IntegerField(null=True)
|
|
||||||
hr_max = models.IntegerField(null=True)
|
|
||||||
hr_bottom = models.IntegerField(null=True)
|
|
||||||
x_right = models.FloatField(null=True)
|
|
||||||
ergpace = models.FloatField(null=True)
|
|
||||||
nowindpace = models.FloatField(null=True)
|
|
||||||
equivergpower = models.FloatField(null=True)
|
|
||||||
fergpace = models.CharField(max_length=30)
|
|
||||||
fnowindpace = models.CharField(max_length=30)
|
|
||||||
catch = models.FloatField(default=0,null=True,verbose_name='Catch Angle')
|
|
||||||
slip = models.FloatField(default=0,null=True,verbose_name='Slip')
|
|
||||||
finish = models.FloatField(default=0,null=True,verbose_name='Finish Angle')
|
|
||||||
wash = models.FloatField(default=0,null=True,verbose_name='Wash')
|
|
||||||
peakforceangle = models.FloatField(default=0,null=True,verbose_name='Peak Force Angle')
|
|
||||||
rhythm = models.FloatField(default=1.0,null=True,verbose_name='Rhythm')
|
|
||||||
totalangle = models.FloatField(default=0.0,null=True,verbose_name='Total Stroke Length (deg)')
|
|
||||||
effectiveangle = models.FloatField(default=0.0,null=True,verbose_name='Effective Stroke Length (deg)')
|
|
||||||
efficiency = models.FloatField(default=-1,null=True,verbose_name='OTW Efficiency')
|
|
||||||
distanceperstroke = models.FloatField(default=-1,null=True,verbose_name='Distance per Stroke')
|
|
||||||
|
|
||||||
# A wrapper around the png files
|
# A wrapper around the png files
|
||||||
class GraphImage(models.Model):
|
class GraphImage(models.Model):
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ from rowers.models import (
|
|||||||
WorkoutComment,WorkoutCommentForm,RowerExportForm,
|
WorkoutComment,WorkoutCommentForm,RowerExportForm,
|
||||||
)
|
)
|
||||||
from rowers.models import FavoriteForm,BaseFavoriteFormSet,SiteAnnouncement
|
from rowers.models import FavoriteForm,BaseFavoriteFormSet,SiteAnnouncement
|
||||||
|
from rowers.metrics import rowingmetrics
|
||||||
from django.forms.formsets import formset_factory
|
from django.forms.formsets import formset_factory
|
||||||
import StringIO
|
import StringIO
|
||||||
from django.contrib.auth.decorators import login_required,user_passes_test
|
from django.contrib.auth.decorators import login_required,user_passes_test
|
||||||
@@ -5905,6 +5906,10 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
|||||||
axchoicesbasic.pop("cumdist")
|
axchoicesbasic.pop("cumdist")
|
||||||
|
|
||||||
if row.workouttype in ('water','coastal'):
|
if row.workouttype in ('water','coastal'):
|
||||||
|
for name,d in rowingmetrics:
|
||||||
|
if d['mode'] == 'erg':
|
||||||
|
axchoicespro.pop(name)
|
||||||
|
|
||||||
return render(request,
|
return render(request,
|
||||||
'flexchart3otw.html',
|
'flexchart3otw.html',
|
||||||
{'the_script':script,
|
{'the_script':script,
|
||||||
@@ -5927,14 +5932,9 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
|||||||
'maxfav':maxfav,
|
'maxfav':maxfav,
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
axchoicespro.pop('slip')
|
for name,d in rowingmetrics:
|
||||||
axchoicespro.pop('wash')
|
if d['mode'] == 'water':
|
||||||
axchoicespro.pop('catch')
|
axchoicespro.pop(name)
|
||||||
axchoicespro.pop('finish')
|
|
||||||
axchoicespro.pop('totalangle')
|
|
||||||
axchoicespro.pop('effectiveangle')
|
|
||||||
axchoicespro.pop('peakforceangle')
|
|
||||||
axchoicespro.pop('efficiency')
|
|
||||||
|
|
||||||
return render(request,
|
return render(request,
|
||||||
'flexchart3otw.html',
|
'flexchart3otw.html',
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ INSTALLED_APPS = [
|
|||||||
'analytical',
|
'analytical',
|
||||||
'cookielaw',
|
'cookielaw',
|
||||||
'django_extensions',
|
'django_extensions',
|
||||||
'tz_detect'
|
'tz_detect',
|
||||||
]
|
]
|
||||||
|
|
||||||
AUTHENTICATION_BACKENDS = (
|
AUTHENTICATION_BACKENDS = (
|
||||||
|
|||||||
Reference in New Issue
Block a user