made metrics and strokedata model dynamic
This commit is contained in:
@@ -1,32 +1,236 @@
|
||||
from utils import lbstoN
|
||||
|
||||
axes = (
|
||||
('time','Time',0,1e5,'basic'),
|
||||
('distance', 'Distance (m)',0,1e5,'basic'),
|
||||
('cumdist', 'Cumulative Distance (m)',0,1e5,'basic'),
|
||||
('hr','Heart Rate (bpm)',100,200,'basic'),
|
||||
('spm', 'Stroke Rate (spm)',15,45,'basic'),
|
||||
('pace', 'Pace (/500m)',1.0e3*210,1.0e3*75,'basic'),
|
||||
('power', 'Power (Watt)',0,600,'basic'),
|
||||
('averageforce', 'Average Drive Force (N)',0,900,'pro'),
|
||||
('drivelength', 'Drive Length (m)',0.5,2.0,'pro'),
|
||||
('peakforce', 'Peak Drive Force (N)',0,900,'pro'),
|
||||
('forceratio', 'Average/Peak Force Ratio',0,1,'pro'),
|
||||
('driveenergy', 'Work per Stroke (J)',0,1000,'pro'),
|
||||
('drivespeed', 'Drive Speed (m/s)',0,4,'pro'),
|
||||
('slip', 'Slip (degrees)',0,20,'pro'),
|
||||
('catch', 'Catch (degrees)',-40,-75,'pro'),
|
||||
('finish', 'Finish (degrees)',20,55,'pro'),
|
||||
('wash', 'Wash (degrees)',0,30,'pro'),
|
||||
('peakforceangle', 'Peak Force Angle (degrees)',-20,20,'pro'),
|
||||
('totalangle', 'Drive Length (deg)',40,140,'pro'),
|
||||
('effectiveangle', 'Effective Drive Length (deg)',40,140,'pro'),
|
||||
('rhythm', 'Stroke Rhythm (%)',20,55,'pro'),
|
||||
('efficiency', 'OTW efficiency (%)',0,110,'pro'),
|
||||
('distanceperstroke','Distance per Stroke (m)',0,15,'pro'),
|
||||
('None', 'None',0,1,'basic'),
|
||||
rowingmetrics = (
|
||||
('time',{
|
||||
'numtype':'float',
|
||||
'null':True,
|
||||
'verbose_name': 'Time',
|
||||
'ax_min': 0,
|
||||
'ax_max': 1e5,
|
||||
'mode':'both',
|
||||
'type': 'basic'}),
|
||||
|
||||
('hr',{
|
||||
'numtype':'integer',
|
||||
'null':True,
|
||||
'verbose_name': 'Heart Rate (bpm)',
|
||||
'ax_min': 100,
|
||||
'ax_max': 200,
|
||||
'mode':'both',
|
||||
'type': 'basic'}),
|
||||
|
||||
('pace',{
|
||||
'numtype':'float',
|
||||
'null':True,
|
||||
'verbose_name': 'Pace (/500m)',
|
||||
'ax_min': 1.0e3*210,
|
||||
'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}
|
||||
|
||||
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()
|
||||
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
|
||||
# the definition here is used only to enable easy Django migration
|
||||
# when the StrokeData are expanded.
|
||||
# No Django Instances of this model are managed. Strokedata table is
|
||||
# accesssed directly with SQL commands
|
||||
class StrokeData(models.Model):
|
||||
class Meta:
|
||||
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')
|
||||
StrokeData = type(str('StrokeData'), (models.Model,),
|
||||
attrs
|
||||
)
|
||||
|
||||
# A wrapper around the png files
|
||||
class GraphImage(models.Model):
|
||||
|
||||
@@ -48,6 +48,7 @@ from rowers.models import (
|
||||
WorkoutComment,WorkoutCommentForm,RowerExportForm,
|
||||
)
|
||||
from rowers.models import FavoriteForm,BaseFavoriteFormSet,SiteAnnouncement
|
||||
from rowers.metrics import rowingmetrics
|
||||
from django.forms.formsets import formset_factory
|
||||
import StringIO
|
||||
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")
|
||||
|
||||
if row.workouttype in ('water','coastal'):
|
||||
for name,d in rowingmetrics:
|
||||
if d['mode'] == 'erg':
|
||||
axchoicespro.pop(name)
|
||||
|
||||
return render(request,
|
||||
'flexchart3otw.html',
|
||||
{'the_script':script,
|
||||
@@ -5927,14 +5932,9 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
||||
'maxfav':maxfav,
|
||||
})
|
||||
else:
|
||||
axchoicespro.pop('slip')
|
||||
axchoicespro.pop('wash')
|
||||
axchoicespro.pop('catch')
|
||||
axchoicespro.pop('finish')
|
||||
axchoicespro.pop('totalangle')
|
||||
axchoicespro.pop('effectiveangle')
|
||||
axchoicespro.pop('peakforceangle')
|
||||
axchoicespro.pop('efficiency')
|
||||
for name,d in rowingmetrics:
|
||||
if d['mode'] == 'water':
|
||||
axchoicespro.pop(name)
|
||||
|
||||
return render(request,
|
||||
'flexchart3otw.html',
|
||||
|
||||
@@ -63,7 +63,7 @@ INSTALLED_APPS = [
|
||||
'analytical',
|
||||
'cookielaw',
|
||||
'django_extensions',
|
||||
'tz_detect'
|
||||
'tz_detect',
|
||||
]
|
||||
|
||||
AUTHENTICATION_BACKENDS = (
|
||||
|
||||
Reference in New Issue
Block a user