diff --git a/logos/logofornk.psd b/logos/logofornk.psd new file mode 100644 index 00000000..f2ced586 Binary files /dev/null and b/logos/logofornk.psd differ diff --git a/logos/logofornk.xcf b/logos/logofornk.xcf index e9a1041f..a412cf93 100644 Binary files a/logos/logofornk.xcf and b/logos/logofornk.xcf differ diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 04c2ee23..248545b1 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -178,6 +178,56 @@ def interactive_forcecurve(theworkouts): plot.add_layout(avf) + peakflabel = Label(x=455,y=530,x_units='screen',y_units='screen', + text="Fpeak: {peakforceav:6.2f}".format(peakforceav=peakforceav), + background_fill_alpha=.7, + text_color='blue', + ) + + avflabel = Label(x=465,y=500,x_units='screen',y_units='screen', + text="Favg: {averageforceav:6.2f}".format(averageforceav=averageforceav), + background_fill_alpha=.7, + text_color='blue', + ) + + catchlabel = Label(x=460,y=470,x_units='screen',y_units='screen', + text="Catch: {catchav:6.2f}".format(catchav=catchav), + background_fill_alpha=0.7, + text_color='red', + ) + + peakforceanglelabel = Label(x=420,y=440,x_units='screen',y_units='screen', + text="Peak angle: {peakforceangleav:6.2f}".format(peakforceangleav=peakforceangleav), + background_fill_alpha=0.7, + text_color='red', + ) + + finishlabel = Label(x=455,y=410,x_units='screen',y_units='screen', + text="Finish: {finishav:6.2f}".format(finishav=finishav), + background_fill_alpha=0.7, + text_color='red', + ) + + sliplabel = Label(x=470,y=380,x_units='screen',y_units='screen', + text="Slip: {slipav:6.2f}".format(slipav=slipav), + background_fill_alpha=0.7, + text_color='red', + ) + + washlabel = Label(x=460,y=350,x_units='screen',y_units='screen', + text="Wash: {washav:6.2f}".format(washav=washav), + background_fill_alpha=0.7, + text_color='red', + ) + + plot.add_layout(peakflabel) + plot.add_layout(peakforceanglelabel) + plot.add_layout(avflabel) + plot.add_layout(catchlabel) + plot.add_layout(sliplabel) + plot.add_layout(washlabel) + plot.add_layout(finishlabel) + plot.xaxis.axis_label = "Angle" plot.yaxis.axis_label = "Force (lbs)" plot.title.text = theworkouts[0].name @@ -193,7 +243,14 @@ def interactive_forcecurve(theworkouts): source=source, source2=source2, avf=avf, - ), code=""" + avflabel=avflabel, + catchlabel=catchlabel, + finishlabel=finishlabel, + sliplabel=sliplabel, + washlabel=washlabel, + peakflabel=peakflabel, + peakforceanglelabel=peakforceanglelabel, + ), code=""" var data = source.data var data2 = source2.data @@ -254,6 +311,13 @@ def interactive_forcecurve(theworkouts): data['y'] = [0,thresholdforce,peakforceav,thresholdforce,0] avf.location = averageforceav + avflabel.text = 'Favg: '+averageforceav.toFixed(2) + catchlabel.text = 'Catch: '+catchav.toFixed(2) + finishlabel.text = 'Finish: '+finishav.toFixed(2) + sliplabel.text = 'Slip: '+slipav.toFixed(2) + washlabel.text = 'Wash: '+washav.toFixed(2) + peakflabel.text = 'Fpeak: '+peakforceav.toFixed(2) + peakforceanglelabel.text = 'Peak angle: '+peakforceangleav.toFixed(2) source.trigger('change'); """) diff --git a/rowers/models.py b/rowers/models.py index 87585c37..37177144 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -344,12 +344,17 @@ class WorkoutForm(ModelForm): duration = forms.TimeInput(format='%H:%M:%S.%f') class Meta: model = Workout - fields = ['name','date','starttime','duration','distance','workouttype','notes'] + fields = ['name','date','starttime','duration','distance','workouttype','boattype','notes'] widgets = { 'date': DateInput(), 'notes': forms.Textarea, 'duration': forms.TimeInput(format='%H:%M:%S.%f'), } + + def __init__(self, *args, **kwargs): + super(WorkoutForm, self).__init__(*args, **kwargs) + if self.instance.workouttype != 'water': + del self.fields['boattype'] class AdvancedWorkoutForm(ModelForm): class Meta: diff --git a/rowers/templates/advancedotw.html b/rowers/templates/advancedotw.html index 52d3751b..2892dcc4 100644 --- a/rowers/templates/advancedotw.html +++ b/rowers/templates/advancedotw.html @@ -7,177 +7,201 @@ {% block content %}
- {% if form.errors %} -

- Please correct the error{{ form.errors|pluralize }} below. -

- {% endif %} + {% if form.errors %} +

+ Please correct the error{{ form.errors|pluralize }} below. +

+ {% endif %} -

Advanced OTW features

- {% if user.rower.rowerplan == 'basic' %} -

This is a preview of the page with advanced functionality for Pro users. See the page about Pro membership for more information and to sign up for Pro Membership - {% endif %} -

-

- Edit Workout -

-
-
-

- Export -

+

Advanced OTW features

+ {% if user.rower.rowerplan == 'basic' %} +

This is a preview of the page with advanced functionality for Pro users. + See the page about Pro membership for more information and to sign up for Pro Membership +{% endif %} +

+

+ Edit Workout +

+
+
+

+ Export +

-
-
- - - - - - - - - - - - -
Date:{{ workout.date }}
Time:{{ workout.starttime }}
Distance:{{ workout.distance }}m
Duration:{{ workout.duration |durationprint:"%H:%M:%S.%f" }}
Public link to this workout - https://rowsandall.com/rowers/workout/{{ workout.id }} - -
+
+
+ + + + + + + + + + + + +
Date:{{ workout.date }}
Time:{{ workout.starttime }}
Distance:{{ workout.distance }}m
Duration:{{ workout.duration |durationprint:"%H:%M:%S.%f" }}
Public link to this workout + https://rowsandall.com/rowers/workout/{{ workout.id }} + +
-
-

- {% if user.rower.rowerplan == 'pro' %} - Compare Workouts - {% else %} - Compare Workouts - {% endif %} -

-

- Compare this workout to other workouts. Plot HR, SPM, or pace vs time or distance for the two workouts. -

-
-
-

- {% if user.rower.rowerplan == 'pro' %} - Smooth out Pace Data - {% else %} - Smooth out Pace Data - {% endif %} +

+

+ {% if user.rower.rowerplan == 'pro' %} + Compare Workouts + {% else %} + Compare Workouts + {% endif %} +

+

+ Compare this workout to other workouts. Plot HR, SPM, or pace vs time or distance for the two workouts. +

+
+ +
+

+ Flexible Interactive Plot +

+

+ Flexible Interactive plot. Pick your own X and Y axis parameters. +

+
+ +
+

+ {% if user.rower.rowerplan == 'pro' %} + Edit Intervals + {% else %} + Edit Intervals + {% endif %} +

+ Enter or change the interval and summary data for your workout + +

+ Enter or change the interval and summary data for your workout +

+
+
-

-

- This will reduce noise on your pace data (EWMA average). The smoothing is irreversible - but you can use the reset smoothing button. -

-
-
-

- {% if user.rower.rowerplan == 'pro' %} - Raw Data - {% else %} - Reset Smoothing - {% endif %} -

-

- Reset pace data to values before smoothing (as originally imported/uploaded) -

-
-
-
-

- {% if user.rower.rowerplan == 'pro' %} - CrewNerd Summary - {% else %} - CrewNerd Summary - {% endif %} +

+

+ {% if user.rower.rowerplan == 'pro' %} + CrewNerd Summary + {% else %} + CrewNerd Summary + {% endif %} + +

+

+ Upload a CrewNerd Summary (CSV file) to this workout. +

+
-

-

- Upload a CrewNerd Summary (CSV file) to this workout. -

-
-
-

- {% if user.rower.rowerplan == 'pro' %} - Geeky Stuff - {% else %} - Geeky Stuff - {% endif %} +

+

+ {% if user.rower.rowerplan == 'pro' %} + Stroke Profile (Empower) + {% else %} + Stroke Profile (Empower) + {% endif %} +

+ Analyze your stroke force profile (need Empower Oarlock data)

+ Interactive plot of Stroke Profile (with Empower Oarlock) +

+
-

-

- Add weather and current data and OTW power calculations. -

-
-
-

- Big Interactive Plot -

-

- See (and save) the big interactive plot -

-
- +
+

+ {% if user.rower.rowerplan == 'pro' %} + OTW Power Plot + {% else %} + OTW Power Plot + {% endif %} +

+ Note: You must run the OTW calculations under Geeky Stuff first. Otherwise the plot will be empty + +

+ Pace, wind corrected pace, power, equivalent erg power in a static plot +

+
+ +
+
+

+ {% if user.rower.rowerplan == 'pro' %} + Geeky Stuff + {% else %} + Geeky Stuff + {% endif %} + +

+

+ Add weather and current data and OTW power calculations. +

+
-
-

- Flexible Interactive Plot -

-

- Flexible Interactive plot. Pick your own X and Y axis parameters. -

+ +
+

+ {% if user.rower.rowerplan == 'pro' %} + Smooth out Pace Data + {% else %} + Smooth out Pace Data + {% endif %} + +

+ This will reduce noise on your pace data. The smoothing is irreversible but you can use the reset smoothing button. + +

+ Pace data too noisy? Press this button! +

+
+ -
-
-

- {% if user.rower.rowerplan == 'pro' %} - OTW Power Plot - {% else %} - OTW Power Plot - {% endif %} -

- Note: You must run the OTW calculations under Geeky Stuff first. Otherwise the plot will be empty +
+

+ {% if user.rower.rowerplan == 'pro' %} + Raw Data + {% else %} + Reset Smoothing + {% endif %} +

+

+ Reset pace data to values before smoothing +

+
+
-

-Pace, wind corrected pace, power, equivalent erg power in a static plot -

-
- -
-

- {% if user.rower.rowerplan == 'pro' %} - Edit Intervals - {% else %} - Edit Intervals - {% endif %} -

- Enter or change the interval and summary data for your workout - -

-Enter or change the interval and summary data for your workout -

-
+
+
+

+ Big Interactive Plot +

+

+ See (and save) the big interactive plot +

+
-
+
+ + + - - - - {{ interactiveplot |safe }} + {{ interactiveplot |safe }}