Private
Public Access
1
0

Cumulative Flex Plot v1

This commit is contained in:
sanderroosendaal
2016-10-31 15:18:11 +01:00
parent bb39d2b0af
commit 49f93da544
121 changed files with 362 additions and 465 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -787,6 +787,12 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
thedata['driveenergy'] = thedata[' DriveLength (meters)']*thedata[' AverageDriveForce (lbs)']*4.44822
# throw out zeros from dataframe
thedata = thedata[thedata[csvcolumns[yparam1]] > 0]
thedata = thedata[thedata[csvcolumns[xparam]] > 0]
if yparam2 != 'None':
thedata = thedata[thedata[csvcolumns[yparam2]] > 0]
spm = thedata.ix[:,csvcolumns['spm']]
f = thedata['TimeStamp (sec)'].diff().mean()
@@ -806,8 +812,6 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
thedata['drivespeed'] = drivelength/thedata[' DriveTime (ms)']*1.0e3
# get user
# u = User.objects.get(id=row.user.id)
x1 = thedata.ix[:,csvcolumns[xparam]]
@@ -819,9 +823,31 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
if xparam=='time':
xaxmax = x1.max()
xaxmin = x1.min()
xaxmax = get_datetimes([x1.max()])[0]
xaxmin = get_datetimes([x1.min()])[0]
x1 = get_datetimes(x1,tzinfo=1)
elif xparam=='distance':
xaxmax = x1.max()
xaxmin = x1.min()
else:
xaxmax = yaxmaxima[xparam]
xaxmin = yaxminima[xparam]
# average values
if xparam != 'time':
x1mean = x1.mean()
else:
x1mean = 0
y1mean = y1.mean()
y2mean = y2.mean()
if xparam != 'time':
xvals = xaxmin+np.arange(100)*(xaxmax-xaxmin)/100.
else:
xvals = np.arange(100)
x_axis_type = 'linear'
y_axis_type = 'linear'
@@ -836,7 +862,6 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
time = thedata.ix[:,csvcolumns['time']]
time = time-time[0]
hr = thedata.ix[:,csvcolumns['hr']]
if windowsize > 3:
@@ -849,6 +874,7 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
power = thedata.ix[:,csvcolumns['power']]
# Add hover to this comma-separated string and see what changes
if (promember==1):
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair'
@@ -856,11 +882,21 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,hover,crosshair'
plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type,
plot_width=900,
tools=TOOLS,
toolbar_location="above",
toolbar_sticky=False)
x1means = Span(location=x1mean,dimension='height',line_color='green',
line_dash=[6,6], line_width=2)
y1means = Span(location=y1mean,dimension='width',line_color='blue',
line_dash=[6,6],line_width=2)
y2means = y1means
if (xparam != 'time') and (xparam != 'distance'):
plot.add_layout(x1means)
plot.add_layout(y1means)
source = ColumnDataSource(
data = dict(
@@ -877,9 +913,24 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
)
)
source2 = ColumnDataSource(
data = dict(
x1=x1,
y1=y1,
y2=y2,
time=niceformat(get_datetimes(time,tzinfo=1)),
pace=nicepaceformat(get_datetimes(pace)),
hr = hr,
spm = spm,
spmc=np.rint(10*spm)/10.,
distance=distance,
power=power,
)
)
# plot.circle('x1','y1',source=source,legend=yparam1,size=3)
plot.circle('x1','y1',source=source,fill_alpha=0.3,line_color=None,
plot.circle('x1','y1',source=source2,fill_alpha=0.3,line_color=None,
legend=yparamname1,
)
@@ -921,11 +972,17 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
plot.circle('x1','y2',color="red",y_range_name="yax2",
legend=yparamname2,
source=source,fill_alpha=0.3,line_color=None)
source=source2,fill_alpha=0.3,line_color=None)
plot.add_layout(LinearAxis(y_range_name="yax2",
axis_label=axlabels[yparam2]),'right')
y2means = Span(location=y2mean,dimension='width',line_color='red',
line_dash=[6,6],line_width=2,y_range_name="yax2")
plot.add_layout(y2means)
hover = plot.select(dict(type=HoverTool))
@@ -939,11 +996,119 @@ def interactive_cum_flex_chart(theworkouts,promember=0,
hover.mode = 'mouse'
callback = CustomJS(args = dict(source=source,source2=source2,
x1means=x1means,
y1means=y1means,
y2means=y2means), code="""
var data = source.data
var data2 = source2.data
var x1 = data['x1']
var y1 = data['y1']
var y2 = data['y2']
var spm1 = data['spm']
var time1 = data['time']
var pace1 = data['pace']
var hr1 = data['hr']
var spmc1 = data['spmc']
var distance1 = data['distance']
var power1 = data['power']
var minspm = minspm.value
var maxspm = maxspm.value
var mindist = mindist.value
var maxdist = maxdist.value
var xm = 0
var ym1 = 0
var ym2 = 0
data2['x1'] = []
data2['y1'] = []
data2['y2'] = []
data2['spm'] = []
data2['time'] = []
data2['pace'] = []
data2['hr'] = []
data2['spmc'] = []
data2['distance'] = []
data2['power'] = []
data2['x1mean'] = []
data2['y1mean'] = []
data2['y2mean'] = []
data2['xvals'] = []
data2['y1vals'] = []
data2['y2vals'] = []
for (i=0; i<x1.length; i++) {
if (spm1[i]>=minspm && spm1[i]<=maxspm) {
if (distance1[i]>=mindist && distance1[i]<=maxdist) {
data2['x1'].push(x1[i])
data2['y1'].push(y1[i])
data2['y2'].push(y2[i])
data2['spm'].push(spm1[i])
data2['time'].push(time1[i])
data2['pace'].push(pace1[i])
data2['hr'].push(hr1[i])
data2['spmc'].push(spmc1[i])
data2['distance'].push(distance1[i])
data2['power'].push(power1[i])
xm += x1[i]
ym1 += y1[i]
ym2 += y2[i]
}
}
}
xm /= data2['x1'].length
ym1 /= data2['x1'].length
ym2 /= data2['x1'].length
data2['x1mean'] = [xm,xm]
data2['y1mean'] = [ym1,ym1]
data2['y2mean'] = [ym2,ym2]
x1means.location = xm
y1means.location = ym1
y2means.location = ym2
source2.trigger('change');
""")
slider_spm_min = Slider(start=15.0, end=55,value=15.0, step=.1,
title="Min SPM",callback=callback)
callback.args["minspm"] = slider_spm_min
slider_spm_max = Slider(start=15.0, end=55,value=55.0, step=.1,
title="Max SPM",callback=callback)
callback.args["maxspm"] = slider_spm_max
distmax = 100+100*int(distance.max()/100.)
slider_dist_min = Slider(start=0,end=distmax,value=0,step=1,
title="Min Distance",callback=callback)
callback.args["mindist"] = slider_dist_min
slider_dist_max = Slider(start=0,end=distmax,value=distmax,
step=1,
title="Max Distance",callback=callback)
callback.args["maxdist"] = slider_dist_max
layout = layoutrow([layoutcolumn([slider_spm_min,
slider_spm_max,
slider_dist_min,
slider_dist_max,
],
),
plot])
script, div = components(layout)
js_resources = INLINE.render_js()
css_resources = INLINE.render_css()
script, div = components(plot)
return [script,div]
return [script,div,js_resources,css_resources]

Binary file not shown.

View File

@@ -21,6 +21,7 @@ from bokeh.models import (
GMapPlot, GMapOptions, ColumnDataSource, Circle,
DataRange1d, PanTool, WheelZoomTool, BoxSelectTool,
SaveTool, ResizeTool, ResetTool, TapTool,CrosshairTool,BoxZoomTool,
Span,
)
#from bokeh.models.widgets import Slider, Select, TextInput
from bokeh.core.properties import value
@@ -1394,29 +1395,26 @@ def interactive_flex_chart2(id=0,promember=0,
xaxmax = get_datetimes([xaxmax],tzinfo=1)[0]
xaxmin = get_datetimes([xaxmin],tzinfo=1)[0]
x1 = get_datetimes(x1,tzinfo=1)
if xparam=='distance':
elif xparam=='distance':
xaxmax = x1.max()
xaxmin = x1.min()
else:
xaxmax = yaxmaxima[xparam]
xaxmin = yaxminima[xparam]
# average values
y1mean = y1.mean()+0.0*np.arange(100)
y2mean = y2.mean()+0.0*np.arange(100)
if xparam != 'time':
x1mean = x1.mean()+0.0*np.arange(100)
x1mean = x1.mean()
else:
x1mean = 0+0.0*np.arange(100)
x1mean = 0
y1mean = y1.mean()
y2mean = y2.mean()
if xparam != 'time' and xparam != 'distance' and yparam1 != 'pace':
xvals = yaxminima[xparam]+np.arange(100)*(yaxmaxima[xparam]-yaxminima[xparam])/100.
y1vals = yaxminima[yparam1]+np.arange(100)*(yaxmaxima[yparam1]-yaxminima[yparam1])/100.
if xparam != 'time':
xvals = xaxmin+np.arange(100)*(xaxmax-xaxmin)/100.
else:
xvals = np.arange(100)
y1vals = np.arange(100)
# constant power plot
if yparam1 == 'driveenergy':
@@ -1466,11 +1464,10 @@ def interactive_flex_chart2(id=0,promember=0,
spmc=np.rint(10*spm)/10.,
distance=distance,
power=power,
xvals=xvals,
y1mean=y1mean,
y2mean=y2mean,
x1mean=x1mean,
y1vals=y1vals,
# xvals=xvals,
y1mean=[y1mean,y1mean],
y2mean=[y2mean,y2mean],
x1mean=[x1mean,x1mean],
)
)
@@ -1487,11 +1484,10 @@ def interactive_flex_chart2(id=0,promember=0,
spmc=np.rint(10*spm)/10.,
distance=distance,
power=power,
xvals=xvals,
y1mean=y1mean,
y2mean=y2mean,
x1mean=x1mean,
y1vals=y1vals,
# xvals=xvals,
y1mean=[y1mean,y1mean],
y2mean=[y2mean,y2mean],
x1mean=[x1mean,x1mean],
)
)
@@ -1510,9 +1506,109 @@ def interactive_flex_chart2(id=0,promember=0,
toolbar_sticky=False,
# plot_width=900,
)
x1means = Span(location=x1mean,dimension='height',line_color='green',
line_dash=[6,6], line_width=2)
y1means = Span(location=y1mean,dimension='width',line_color='blue',
line_dash=[6,6],line_width=2)
y2means = y1means
if (xparam != 'time') and (xparam != 'distance'):
plot.add_layout(x1means)
plot.add_layout(y1means)
callback = CustomJS(args = dict(source=source,source2=source2), code="""
# average values
if yparam1 == 'driveenergy':
if xparam == 'spm':
plot.line(xvals,yconstantpower,color="green",legend="Constant Power")
if plottype=='line':
plot.line('x1','y1',source=source2,legend=axlabels[yparam1])
elif plottype=='scatter':
# plot.circle('x1','y1',source=source2,legend=yparam1,size=3)
plot.scatter('x1','y1',source=source2,legend=axlabels[yparam1],fill_alpha=0.4,
line_color=None)
plot.title.text = row.name
plot.title.text_font_size=value("1.0em")
plot.xaxis.axis_label = axlabels[xparam]
plot.yaxis.axis_label = axlabels[yparam1]
yrange1 = Range1d(start=yaxminima[yparam1],end=yaxmaxima[yparam1])
plot.y_range = yrange1
if (xparam != 'time') and (xparam != 'distance'):
xrange1 = Range1d(start=yaxminima[xparam],end=yaxmaxima[xparam])
plot.x_range = xrange1
if xparam == 'time':
xrange1 = Range1d(start=xaxmin,end=xaxmax)
plot.x_range = xrange1
plot.xaxis[0].formatter = DatetimeTickFormatter(
hours = ["%H"],
minutes = ["%M"],
seconds = ["%S"],
days = ["0"],
months = [""],
years = [""]
)
if yparam1 == 'pace':
plot.y_range = Range1d(ymin,ymax)
plot.yaxis[0].formatter = DatetimeTickFormatter(
seconds = ["%S"],
minutes = ["%M"]
)
if yparam2 != 'None':
yrange2 = Range1d(start=yaxminima[yparam2],end=yaxmaxima[yparam2])
plot.extra_y_ranges = {"yax2": yrange2}
if plottype=='line':
plot.line('x1','y2',color="red",y_range_name="yax2",
legend=axlabels[yparam2],
source=source2)
elif plottype=='scatter':
# plot.circle(x1,y2,color="red",y_range_name="yax2",legend=yparam2,
# source=source,size=3)
plot.scatter('x1','y2',source=source2,legend=axlabels[yparam2]
,fill_alpha=0.4,
line_color=None,color="red",y_range_name="yax2")
plot.add_layout(LinearAxis(y_range_name="yax2",
axis_label=axlabels[yparam2]),'right')
y2means = Span(location=y2mean,dimension='width',line_color='red',
line_dash=[6,6],line_width=2,y_range_name="yax2")
plot.add_layout(y2means)
hover = plot.select(dict(type=HoverTool))
hover.tooltips = OrderedDict([
('Time','@time'),
('Distance','@distance'),
('Pace','@pace'),
('HR','@hr'),
('SPM','@spmc{1.1}'),
('Power','@power{int}'),
])
hover.mode = 'mouse'
callback = CustomJS(args = dict(source=source,source2=source2,
x1means=x1means,
y1means=y1means,
y2means=y2means), code="""
var data = source.data
var data2 = source2.data
var x1 = data['x1']
@@ -1568,6 +1664,7 @@ def interactive_flex_chart2(id=0,promember=0,
xm += x1[i]
ym1 += y1[i]
ym2 += y2[i]
}
}
}
@@ -1579,10 +1676,9 @@ def interactive_flex_chart2(id=0,promember=0,
data2['x1mean'] = [xm,xm]
data2['y1mean'] = [ym1,ym1]
data2['y2mean'] = [ym2,ym2]
data2['xvals'] = [0,3e4]
data2['y1vals'] = [0,3e4]
data2['y2vals'] = [0,3e4]
x1means.location = xm
y1means.location = ym1
y2means.location = ym2
source2.trigger('change');
""")
@@ -1606,89 +1702,6 @@ def interactive_flex_chart2(id=0,promember=0,
step=1,
title="Max Distance",callback=callback)
callback.args["maxdist"] = slider_dist_max
# average values
plot.line('xvals','y1mean',color="black",source=source2)
plot.line('x1mean','y1vals',color="black",source=source2)
if yparam1 == 'driveenergy':
if xparam == 'spm':
plot.line(xvals,yconstantpower,color="green",legend="Constant Power")
if plottype=='line':
plot.line('x1','y1',source=source2,legend=axlabels[yparam1])
elif plottype=='scatter':
# plot.circle('x1','y1',source=source2,legend=yparam1,size=3)
plot.scatter('x1','y1',source=source2,legend=axlabels[yparam1],fill_alpha=0.4,
line_color=None)
plot.title.text = row.name
plot.title.text_font_size=value("1.0em")
plot.xaxis.axis_label = axlabels[xparam]
plot.yaxis.axis_label = axlabels[yparam1]
yrange1 = Range1d(start=yaxminima[yparam1],end=yaxmaxima[yparam1])
plot.y_range = yrange1
if (xparam != 'time') and (xparam != 'distance'):
xrange1 = Range1d(start=yaxminima[xparam],end=yaxmaxima[xparam])
plot.x_range = xrange1
if xparam == 'time':
xrange1 = Range1d(start=xaxmin,end=xaxmax)
plot.x_range = xrange1
plot.xaxis[0].formatter = DatetimeTickFormatter(
hours = ["%H"],
minutes = ["%M"],
seconds = ["%S"],
days = ["0"],
months = [""],
years = [""]
)
if yparam1 == 'pace':
plot.y_range = Range1d(ymin,ymax)
plot.yaxis[0].formatter = DatetimeTickFormatter(
seconds = ["%S"],
minutes = ["%M"]
)
if yparam2 != 'None':
yrange2 = Range1d(start=yaxminima[yparam2],end=yaxmaxima[yparam2])
plot.extra_y_ranges = {"yax2": yrange2}
plot.line('xvals','y2mean',color="black",y_range_name="yax2",
source=source2)
if plottype=='line':
plot.line('x1','y2',color="red",y_range_name="yax2",
legend=axlabels[yparam2],
source=source2)
elif plottype=='scatter':
# plot.circle(x1,y2,color="red",y_range_name="yax2",legend=yparam2,
# source=source,size=3)
plot.scatter('x1','y2',source=source2,legend=axlabels[yparam2]
,fill_alpha=0.4,
line_color=None,color="red",y_range_name="yax2")
plot.add_layout(LinearAxis(y_range_name="yax2",
axis_label=axlabels[yparam2]),'right')
hover = plot.select(dict(type=HoverTool))
hover.tooltips = OrderedDict([
('Time','@time'),
('Distance','@distance'),
('Pace','@pace'),
('HR','@hr'),
('SPM','@spmc{1.1}'),
('Power','@power{int}'),
])
hover.mode = 'mouse'
layout = layoutrow([layoutcolumn([slider_spm_min,
slider_spm_max,

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -6,28 +6,17 @@
{% block content %}
{{ js_res | safe }}
{{ css_res| safe }}
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script type="text/javascript" src="/static/js/bokeh-widgets-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
{{ interactiveplot |safe }}
<script>
// 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.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}

View File

@@ -6,7 +6,7 @@
{% block content %}
<script type="text/javascript" src="/static/js/bokeh-0.11.1.min.js"></script>
<script type="text/javascript" src="/static/js/bokeh-0.12.3.min.js"></script>
<script async="true" type="text/javascript">
Bokeh.set_log_level("info");
</script>
@@ -59,7 +59,7 @@
<a class="button blue small alpha" href="/rowers/flexall/peakforce/{{ yparam1 }}/{{ yparam2 }}">Peak Force</a>
<a class="button blue small alpha" href="/rowers/flexall/averageforce/{{ yparam1 }}/{{ yparam2 }}">Average Force</a>
<a class="button blue small alpha" href="/rowers/flexall/drivelength/{{ yparam1 }}/{{ yparam2 }}">Drive Length</a>
<a class="button blue small alpha" href="/rowers/flexall/driveenergy/{{ yparam1 }}/{{ yparam2 }}">Drive Energy</a>
<a class="button blue small alpha" href="/rowers/flexall/driveenergy/{{ yparam1 }}/{{ yparam2 }}">Work per Stroke</a>
<a class="button blue small alpha" href="/rowers/flexall/drivespeed/{{ yparam1 }}/{{ yparam2 }}">Drive Speed</a>
{% else %}
<a class="button rosy small" href="/rowers/promembership">Power (Pro)</a>
@@ -68,7 +68,7 @@
<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">Drive Length (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Energy (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 %}
@@ -86,13 +86,13 @@
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/peakforce/{{ yparam2 }}">Peak Force</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/averageforce/{{ yparam2 }}">Average Force</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/drivelength/{{ yparam2 }}">Drive Length</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/driveenergy/{{ yparam2 }}">Drive Energy</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/driveenergy/{{ yparam2 }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/drivespeed/{{ yparam2 }}">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">Drive Length (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Energy (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 %}
@@ -109,13 +109,13 @@
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/peakforce">Peak Force</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/averageforce">Average Force</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/drivelength">Drive Length</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/driveenergy">Drive Energy</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/driveenergy">Work per Stroke</a>
<a class="button blue small" href="/rowers/flexall/{{ xparam }}/{{ yparam1 }}/drivespeed">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">Drive Length (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">Drive Energy (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 %}

View File

@@ -51,17 +51,17 @@
<div class="grid_2 alpha dropdown">
<button class="grid_2 alpha button blue small dropbtn">X-axis</button>
<div class="dropdown-content">
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart2/time/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">Time</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart2/distance/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">Distance</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/time/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">Time</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/distance/{{ yparam1 }}/{{ yparam2 }}/{{ plottype }}">Distance</a>
{% if promember %}
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart2/power/{{ yparam1 }}/{{ yparam2 }}/scatter">Power</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart2/hr/{{ yparam1 }}/{{ yparam2 }}/scatter">HR</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart2/spm/{{ yparam1 }}/{{ yparam2 }}/scatter">SPM</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart2/peakforce/{{ yparam1 }}/{{ yparam2 }}/scatter">Peak Force</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart2/averageforce/{{ yparam1 }}/{{ yparam2 }}/scatter">Average Force</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart2/drivelength/{{ yparam1 }}/{{ yparam2 }}/scatter">Drive Length</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart2/driveenergy/{{ yparam1 }}/{{ yparam2 }}/scatter">Work per Stroke</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart2/drivespeed/{{ yparam1 }}/{{ yparam2 }}/scatter">Drive Speed</a>
<a class="button blue small alpha" href="/rowers/workout/{{ id }}/flexchart/power/{{ yparam1 }}/{{ yparam2 }}/scatter">Power</a>
<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/spm/{{ yparam1 }}/{{ yparam2 }}/scatter">SPM</a>
<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/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>
{% else %}
<a class="button rosy small" href="/rowers/promembership">Power (Pro)</a>
<a class="button rosy small" href="/rowers/promembership">HR (Pro)</a>
@@ -79,16 +79,16 @@
<div class="grid_2 dropdown">
<button class="grid_2 alpha button blue small dropbtn">Left</button>
<div class="dropdown-content">
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/pace/{{ yparam2 }}/{{ plottype }}">Pace</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/hr/{{ yparam2 }}/{{ plottype }}">HR</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/spm/{{ yparam2 }}/{{ plottype }}">SPM</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/power/{{ yparam2 }}/{{ plottype }}">Power</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/pace/{{ yparam2 }}/{{ plottype }}">Pace</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/hr/{{ yparam2 }}/{{ plottype }}">HR</a>
<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 }}/power/{{ yparam2 }}/{{ plottype }}">Power</a>
{% if promember %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/peakforce/{{ yparam2 }}/{{ plottype }}">Peak Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/averageforce/{{ yparam2 }}/{{ plottype }}">Average Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/drivelength/{{ yparam2 }}/{{ plottype }}">Drive Length</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/driveenergy/{{ yparam2 }}/{{ plottype }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/drivespeed/{{ yparam2 }}/{{ plottype }}">Drive Speed</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/peakforce/{{ yparam2 }}/{{ plottype }}">Peak Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/averageforce/{{ yparam2 }}/{{ plottype }}">Average Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/drivelength/{{ yparam2 }}/{{ plottype }}">Drive Length</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/driveenergy/{{ yparam2 }}/{{ plottype }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/drivespeed/{{ yparam2 }}/{{ 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>
@@ -103,15 +103,15 @@
<div class="grid_2 dropdown omega">
<button class="grid_2 alpha button blue small dropbtn">Right</button>
<div class="dropdown-content">
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/{{ yparam1 }}/hr/{{ plottype }}">HR</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/{{ yparam1 }}/spm/{{ plottype }}">SPM</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/{{ yparam1 }}/power/{{ plottype }}">Power</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/hr/{{ plottype }}">HR</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/spm/{{ plottype }}">SPM</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/power/{{ plottype }}">Power</a>
{% if promember %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/{{ yparam1 }}/peakforce/{{ plottype }}">Peak Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/{{ yparam1 }}/averageforce/{{ plottype }}">Average Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/{{ yparam1 }}/drivelength/{{ plottype }}">Drive Length</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/{{ yparam1 }}/driveenergy/{{ plottype }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/{{ yparam1 }}/drivespeed/{{ plottype }}">Drive Speed</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/peakforce/{{ plottype }}">Peak Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/averageforce/{{ plottype }}">Average Force</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/drivelength/{{ plottype }}">Drive Length</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/driveenergy/{{ plottype }}">Work per Stroke</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/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>
@@ -120,7 +120,7 @@
<a class="button rosy small" href="/rowers/promembership">Drive Speed (Pro)</a>
{% endif %}
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/{{ yparam1 }}/None/{{ plottype }}">None</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/None/{{ plottype }}">None</a>
</div>
</div>
@@ -141,10 +141,10 @@
<span class="tooltiptext">If your data source allows, this will show or hide strokes taken during rest intervals.</span>
</div>
<div class="grid_2">
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/line">Line Plot</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/line">Line Plot</a>
</div>
<div class="grid_2 omega">
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart2/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/scatter">Scatter Plot</a>
<a class="button blue small" href="/rowers/workout/{{ id }}/flexchart/{{ xparam }}/{{ yparam1 }}/{{ yparam2 }}/scatter">Scatter Plot</a>
</div>
</div>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1295,14 +1295,19 @@ def cum_flex(request,theuser=0,
promember=promember)
script = res[0]
div = res[1]
js_resources = res[2]
css_resources = res[3]
else:
script = ''
div = '<p>No erg pieces uploaded for this date range.</p>'
js_resources = ''
css_resources = ''
return render(request, 'cum_flex.html',
{'interactiveplot':script,
'the_div':div,
'js_res': js_resources,
'css_res':css_resources,
'id':theuser,
'theuser':u,
'startdate':startdate,

Binary file not shown.

View File

@@ -354,10 +354,10 @@ def add_workout_from_strokedata(user,importid,data,strokedata,source='c2'):
pace = strokedata.ix[:,'p']/10.
velo = 500./pace
if (source=='c2'):
power = 2.8*velo**3
else:
power = 0.0*velo
# if (source=='c2' or source=='strava'):
power = 2.8*velo**3
# else:
# power = 0.0*velo
# save csv
# Create data frame with all necessary data to write to csv
@@ -2457,15 +2457,15 @@ def workout_flexchart3_view(request,id=0,xparam='distance',yparam1='pace',
workstrokesonly=workstrokesonly)
script = res[0]
div = res[1]
widgetscript = res[2]
widgetdiv1 = res[3]
widgetdiv2 = res[4]
js_resources = res[2]
css_resources = res[3]
return render(request,
'flexchart2.html',
{'interactiveplot':script,
'flexchart3.html',
{'the_script':script,
'the_div':div,
'js_res': js_resources,
'css_res':css_resources,
'id':id,
'xparam':xparam,
'yparam1':yparam1,
@@ -2474,9 +2474,6 @@ def workout_flexchart3_view(request,id=0,xparam='distance',yparam1='pace',
'mayedit':mayedit,
'promember':promember,
'workstrokesonly': not workstrokesonly,
'widgetscript': widgetscript,
'widgetdiv1': widgetdiv1,
'widgetdiv2': widgetdiv2,
})
def testbokeh(request):
@@ -2557,7 +2554,7 @@ def testbokeh(request):
hover.mode = 'mouse'
layout = row([column([s1,s2,s3,s4]),plot])
layout = layoutrow([layoutcolumn([s1,s2,s3,s4]),plot])
# widgetbox(s)
script, div = components(layout)
js_resources = INLINE.render_js()
@@ -4040,10 +4037,10 @@ def workout_summary_edit_view(request,id,message="",successmessage=""
savebutton = 'nosavebutton'
# We have submitted the mini language interpreter
if request.method == 'POST' and "intervalstring" in request.POST:
form = SummaryStringForm(request.POST)
if form.is_valid():
#something
cd = form.cleaned_data
s = cd["intervalstring"]
rowdata.updateinterval_string(s)
@@ -4052,6 +4049,7 @@ def workout_summary_edit_view(request,id,message="",successmessage=""
nrintervals = len(idist)
savebutton = 'savestringform'
# we are saving the results obtained from the mini language interpreter
elif request.method == 'POST' and "savestringform" in request.POST:
s = request.POST["savestringform"]
rowdata.updateinterval_string(s)
@@ -4059,7 +4057,7 @@ def workout_summary_edit_view(request,id,message="",successmessage=""
itime,idist,itype = rowdata.intervalstats_values()
nrintervals = len(idist)
row.summary = intervalstats
intervalstats = rowdata.allstats()
#intervalstats = rowdata.allstats()
row.notes += "\n"+s
row.save()
rowdata.write_csv(f1)
@@ -4067,6 +4065,7 @@ def workout_summary_edit_view(request,id,message="",successmessage=""
form = SummaryStringForm(initial=data)
savebutton = 'savestringform'
# we are saving the results obtained from the detailed form
elif request.method == 'POST' and "savedetailform" in request.POST:
savebutton = 'savedetailform'
form = SummaryStringForm()
@@ -4117,6 +4116,7 @@ def workout_summary_edit_view(request,id,message="",successmessage=""
form = SummaryStringForm()
# we are processing the details form
elif request.method == 'POST' and "nrintervals" in request.POST:
savebutton = 'savedetailform'
nrintervals = int(request.POST['nrintervals'])

Binary file not shown.