Private
Public Access
1
0

force curve with lines

This commit is contained in:
Sander Roosendaal
2019-04-02 19:00:00 +02:00
parent e735d98dcf
commit d251b1ddd4
5 changed files with 127 additions and 34 deletions

View File

@@ -723,6 +723,7 @@ class TrendFlexModalForm(forms.Form):
required=False)
# This form sets options for the summary stats page
class StatsOptionsForm(forms.Form):
includereststrokes = forms.BooleanField(initial=False,label='Include Rest Strokes',required=False)
@@ -1181,9 +1182,20 @@ class FlexOptionsForm(forms.Form):
('line','Line Plot'),
('scatter','Scatter Plot'),
)
plottype = forms.ChoiceField(choices=plotchoices,initial='scatter',
plottype = forms.ChoiceField(choices=plotchoices,initial='line',
label='Chart Type')
class ForceCurveOptionsForm(forms.Form):
includereststrokes = forms.BooleanField(initial=False, required = False,
label='Include Rest Strokes')
plotchoices = (
('line','Force Curve Collection Plot'),
('scatter','Peak Force Scatter Plot'),
('none','Only aggregrate data')
)
plottype = forms.ChoiceField(choices=plotchoices,initial='scatter',
label='Individual Stroke Chart Type')
class FlexAxesForm(forms.Form):
axchoices = list(

View File

@@ -17,6 +17,7 @@ from math import pi
from django.utils import timezone
from bokeh.palettes import Dark2_8 as palette
from bokeh.models.glyphs import MultiLine
import itertools
from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc
from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation
@@ -374,7 +375,7 @@ def interactive_activitychart(workouts,startdate,enddate,stack='type'):
script,div = components(p)
return script,div
def interactive_forcecurve(theworkouts,workstrokesonly=False):
def interactive_forcecurve(theworkouts,workstrokesonly=True,plottype='scatter'):
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
ids = [int(w.id) for w in theworkouts]
@@ -642,12 +643,20 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
rowdata
)
if plottype == 'scatter':
sourcepoints = ColumnDataSource(
data = dict(
peakforceangle = rowdata['peakforceangle'],
peakforce = rowdata['peakforce']
)
)
else:
sourcepoints = ColumnDataSource(
data = dict(
peakforceangle = [],
peakforce = []
))
sourcerange = ColumnDataSource(
data = dict(
@@ -697,6 +706,50 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
plot.circle('xslip','yslip',source=sourceslipwash,color="red")
plot.circle('peakforceangle','peakforce',source=sourcepoints,color='black',alpha=0.1)
if plottype == 'line':
multilinedatax = []
multilinedatay = []
for i in range(len(rowdata)):
x = [
rowdata['catch'].values[i],
rowdata['slip'].values[i]+rowdata['catch'].values[i],
rowdata['peakforceangle'].values[i],
rowdata['finish'].values[i]-rowdata['wash'].values[i],
rowdata['finish'].values[i]
]
y = [
0,
thresholdforce,
rowdata['peakforce'].values[i],
thresholdforce,
0]
multilinedatax.append(x)
multilinedatay.append(y)
sourcemultiline = ColumnDataSource(dict(
x=multilinedatax,
y=multilinedatay,
))
sourcemultiline2 = ColumnDataSource(dict(
x=multilinedatax,
y=multilinedatay,
))
glyph = MultiLine(xs='x',ys='y',line_color='black',line_alpha=0.05)
plot.add_glyph(sourcemultiline,glyph)
else:
sourcemultiline = ColumnDataSource(dict(
x=[],y=[]))
sourcemultiline2 = ColumnDataSource(dict(
x=[],y=[]))
plot.line('x','y',source=source,color="red")
plot.add_layout(avf)
@@ -801,11 +854,20 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
peakforceanglelabel=peakforceanglelabel,
annolabel=annolabel,
sliderlabel=sliderlabel,
plottype=plottype,
sourcemultiline=sourcemultiline,
sourcemultiline2=sourcemultiline2
), code="""
var data = source.data
var data2 = source2.data
var dataslipwash = sourceslipwash.data
var datapoints = sourcepoints.data
var multilines = sourcemultiline.data
var multilines2 = sourcemultiline2.data
var plottype = plottype
var multilinesx = multilines['xs']
var multilinesy = multilines['ys']
var x = data['x']
var y = data['y']
@@ -826,6 +888,9 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
var peakforce = data2['peakforce']
var averageforce = data2['averageforce']
var peakforcepoints = datapoints['peakforce']
var peakforceanglepoints = datapoints['peakforceangle']
var annotation = annotation.value
var minspm = minspm.value
var maxspm = maxspm.value
@@ -849,13 +914,21 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
datapoints['peakforceangle'] = []
datapoints['peakforce'] = []
multilines['xs'] = []
multilines['ys'] = []
for (i=0; i<c.length; i++) {
if (spm1[i]>=minspm && spm1[i]<=maxspm) {
if (distance1[i]>=mindist && distance1[i]<=maxdist) {
if (driveenergy1[i]>=minwork && driveenergy1[i]<=maxwork) {
if (plottype=='scatter') {
datapoints['peakforceangle'].push(peakforceangle[i])
datapoints['peakforce'].push(peakforce[i])
}
if (plottype=='line') {
multilines['xs'].push(multilinesx[i])
multilines['ys'].push(multilinesy[i])
}
catchav += c[i]
finishav += finish[i]
slipav += slip[i]
@@ -897,6 +970,7 @@ def interactive_forcecurve(theworkouts,workstrokesonly=False):
source.change.emit();
sourceslipwash.change.emit()
sourcepoints.change.emit();
sourcemultiline.change.emit();
""")
annotation = TextInput(title="Type your plot notes here", value="",

View File

@@ -22,27 +22,24 @@
<h1>Empower Force Curve</h1>
<ul class="main-content">
<li class="grid_4">
{% if user.is_authenticated and mayedit %}
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
{% csrf_token %}
{% if workstrokesonly %}
<input type="hidden" name="workstrokesonly" value="True">
<input class="button blue small" value="Remove Rest Strokes" type="Submit">
{% else %}
<input class="button blue small" type="hidden" name="workstrokesonly" value="False">
<input class="button blue small" value="Include Rest Strokes" type="Submit">
</form>
{% endif %}
<span class="tooltiptext">If your data source allows, this will show or hide strokes taken during rest intervals.</span>
{% endif %}
</li>
<li class="grid_4">
<div id="theplot" class="flexplot">
{{ the_div|safe }}
</div>
</li>
<li class="grid_4">
<form enctype="multipart/form-data" action="" method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<p>
<input name="chartform" type="submit"
value="Update Chart">
</p>
</form>
</li>
</ul>

View File

@@ -48,6 +48,7 @@ from django.http import (
)
from django.contrib.auth import authenticate, login, logout
from rowers.forms import (
ForceCurveOptionsForm,
LoginForm,DocumentsForm,UploadOptionsForm,ImageForm,CourseForm,
TeamUploadOptionsForm,WorkFlowLeftPanelForm,WorkFlowMiddlePanelForm,
WorkFlowLeftPanelElement,WorkFlowMiddlePanelElement,

View File

@@ -26,15 +26,24 @@ def workout_forcecurve_view(request,id=0,workstrokesonly=False):
if not promember:
return HttpResponseRedirect("/rowers/about/")
if request.method == 'POST' and 'workstrokesonly' in request.POST:
workstrokesonly = request.POST['workstrokesonly']
if workstrokesonly == 'True':
workstrokesonly = True
if request.method == 'POST':
form = ForceCurveOptionsForm(request.POST)
if form.is_valid():
includereststrokes = form.cleaned_data['includereststrokes']
plottype = form.cleaned_data['plottype']
workstrokesonly = not includereststrokes
else:
workstrokesonly = False
workstrokesonly = True
plottype = 'line'
else:
form = ForceCurveOptionsForm()
plottype = 'line'
script,div,js_resources,css_resources = interactive_forcecurve([row],
workstrokesonly=workstrokesonly)
script,div,js_resources,css_resources = interactive_forcecurve(
[row],
workstrokesonly=workstrokesonly,
plottype=plottype,
)
breadcrumbs = [
{
@@ -59,6 +68,7 @@ def workout_forcecurve_view(request,id=0,workstrokesonly=False):
{
'the_script':script,
'rower':r,
'form':form,
'workout':row,
'breadcrumbs':breadcrumbs,
'active':'nav-workouts',
@@ -67,7 +77,6 @@ def workout_forcecurve_view(request,id=0,workstrokesonly=False):
'css_res':css_resources,
'id':id,
'mayedit':mayedit,
'workstrokesonly': not workstrokesonly,
'teams':get_my_teams(request.user),
})