shortening cum_flex chart
This commit is contained in:
@@ -4081,309 +4081,19 @@ def interactive_cum_flex_chart2(theworkouts, promember=0,
|
|||||||
metrics_list = [{'name': name, 'rowingmetrics':d } for name, d in metrics.rowingmetrics]
|
metrics_list = [{'name': name, 'rowingmetrics':d } for name, d in metrics.rowingmetrics]
|
||||||
|
|
||||||
chart_data = {
|
chart_data = {
|
||||||
'title': 'Some Chart',
|
'title': extratitle,
|
||||||
'x': xparam,
|
'x': xparam,
|
||||||
'y1': yparam1,
|
'y1': yparam1,
|
||||||
'y2': yparam2,
|
'y2': yparam2,
|
||||||
'data': data_dict,
|
'data': data_dict,
|
||||||
'metrics': metrics_list,
|
'metrics': metrics_list,
|
||||||
|
'trendline': trendline,
|
||||||
}
|
}
|
||||||
|
|
||||||
script, div = get_chart("/dots", chart_data)
|
script, div = get_chart("/dots", chart_data)
|
||||||
|
|
||||||
return script, div
|
return script, div
|
||||||
|
|
||||||
source = ColumnDataSource(
|
|
||||||
datadf
|
|
||||||
)
|
|
||||||
|
|
||||||
source2 = ColumnDataSource(
|
|
||||||
datadf.copy()
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add hover to this comma-separated string and see what changes
|
|
||||||
if (promember == 1):
|
|
||||||
TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,crosshair'
|
|
||||||
else: # pragma: no cover
|
|
||||||
TOOLS = 'pan,box_zoom,wheel_zoom,reset,tap,crosshair'
|
|
||||||
|
|
||||||
plot = figure(x_axis_type=x_axis_type, y_axis_type=y_axis_type,
|
|
||||||
tools=TOOLS,
|
|
||||||
toolbar_location="above",
|
|
||||||
toolbar_sticky=False)
|
|
||||||
|
|
||||||
# add watermark
|
|
||||||
watermarkurl = "/static/img/logo7.png"
|
|
||||||
watermarkrange = Range1d(start=0, end=1)
|
|
||||||
watermarkalpha = 0.6
|
|
||||||
watermarkx = 0.99
|
|
||||||
watermarky = 0.01
|
|
||||||
watermarkw = 184
|
|
||||||
watermarkh = 35
|
|
||||||
watermarkanchor = 'bottom_right'
|
|
||||||
plot.extra_y_ranges = {"watermark": watermarkrange}
|
|
||||||
plot.extra_x_ranges = {"watermark": watermarkrange}
|
|
||||||
#plot.sizing_mode = 'stretch_both'
|
|
||||||
|
|
||||||
if extratitle:
|
|
||||||
plot.title.text = extratitle
|
|
||||||
|
|
||||||
|
|
||||||
plot.image_url([watermarkurl], watermarkx, watermarky,
|
|
||||||
watermarkw, watermarkh,
|
|
||||||
global_alpha=watermarkalpha,
|
|
||||||
w_units='screen',
|
|
||||||
h_units='screen',
|
|
||||||
anchor=watermarkanchor,
|
|
||||||
dilate=True,
|
|
||||||
x_range_name="watermark",
|
|
||||||
y_range_name="watermark",
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
xlabel = Label(x=50, y=80, x_units='screen', y_units='screen',
|
|
||||||
text=axlabels[xparam] +
|
|
||||||
": {x1mean:6.2f}".format(x1mean=x1mean),
|
|
||||||
background_fill_alpha=.7,
|
|
||||||
background_fill_color='white',
|
|
||||||
text_color='green',
|
|
||||||
)
|
|
||||||
|
|
||||||
sliderlabel = Label(x=10, y=470, x_units='screen', y_units='screen',
|
|
||||||
text='',
|
|
||||||
background_fill_alpha=0.7,
|
|
||||||
background_fill_color='white',
|
|
||||||
text_color='black', text_font_size='10pt',
|
|
||||||
)
|
|
||||||
|
|
||||||
plot.add_layout(x1means)
|
|
||||||
plot.add_layout(xlabel)
|
|
||||||
plot.add_layout(y1means)
|
|
||||||
plot.add_layout(sliderlabel)
|
|
||||||
|
|
||||||
y1label = Label(x=50, y=50, x_units='screen', y_units='screen',
|
|
||||||
text=axlabels[yparam1] +
|
|
||||||
": {y1mean:6.2f}".format(y1mean=y1mean),
|
|
||||||
background_fill_alpha=.7,
|
|
||||||
background_fill_color='white',
|
|
||||||
text_color='blue',
|
|
||||||
)
|
|
||||||
|
|
||||||
if yparam1 != 'time' and yparam1 != 'pace':
|
|
||||||
plot.add_layout(y1label)
|
|
||||||
|
|
||||||
y2label = y1label
|
|
||||||
plot.circle('x1', 'y1', source=source2, fill_alpha=0.3, line_color=None,
|
|
||||||
legend_label=yparamname1,
|
|
||||||
)
|
|
||||||
|
|
||||||
plot.xaxis.axis_label = axlabels[xparam]
|
|
||||||
plot.yaxis.axis_label = axlabels[yparam1]
|
|
||||||
|
|
||||||
yrange1 = Range1d(start=yaxminima[yparam1], end=yaxmaxima[yparam1])
|
|
||||||
plot.y_range = yrange1
|
|
||||||
|
|
||||||
xrange1 = Range1d(start=yaxminima[xparam], end=yaxmaxima[xparam])
|
|
||||||
plot.x_range = xrange1
|
|
||||||
|
|
||||||
if yparam1 == 'pace': # pragma: no cover
|
|
||||||
plot.yaxis[0].formatter = DatetimeTickFormatter(
|
|
||||||
seconds=["%S"],
|
|
||||||
minutes=["%M"]
|
|
||||||
)
|
|
||||||
|
|
||||||
# trendline
|
|
||||||
if trendline:
|
|
||||||
plot.line('x1', 'ytrend', source=source2, legend_label=yparamname1+' (trend)')
|
|
||||||
|
|
||||||
if yparam2 != 'None':
|
|
||||||
yrange2 = Range1d(start=yaxminima[yparam2], end=yaxmaxima[yparam2])
|
|
||||||
plot.extra_y_ranges["yax2"] = yrange2
|
|
||||||
|
|
||||||
plot.circle('x1', 'y2', color="red", y_range_name="yax2",
|
|
||||||
legend_label=yparamname2,
|
|
||||||
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)
|
|
||||||
y2label = Label(x=50, y=20, x_units='screen', y_units='screen',
|
|
||||||
text=axlabels[yparam2] +
|
|
||||||
": {y2mean:6.2f}".format(y2mean=y2mean),
|
|
||||||
background_fill_alpha=.7,
|
|
||||||
background_fill_color='white',
|
|
||||||
text_color='red',
|
|
||||||
)
|
|
||||||
if yparam2 != 'pace' and yparam2 != 'time':
|
|
||||||
plot.add_layout(y2label)
|
|
||||||
|
|
||||||
callback = CustomJS(args=dict(source=source, source2=source2,
|
|
||||||
x1means=x1means,
|
|
||||||
y1means=y1means,
|
|
||||||
y1label=y1label,
|
|
||||||
y2label=y2label,
|
|
||||||
xlabel=xlabel,
|
|
||||||
sliderlabel=sliderlabel,
|
|
||||||
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 index1 = data['index']
|
|
||||||
|
|
||||||
var distance1 = data['distance']
|
|
||||||
var power1 = data['power']
|
|
||||||
var driveenergy1 = data['driveenergy']
|
|
||||||
var xname = data['xname']
|
|
||||||
var yname1 = data['yname1']
|
|
||||||
var yname2 = data['yname2']
|
|
||||||
var workoutid1 = data['workoutid']
|
|
||||||
var ytrend = data['ytrend']
|
|
||||||
|
|
||||||
var minspm = minspm.value
|
|
||||||
var maxspm = maxspm.value
|
|
||||||
var mindist = mindist.value
|
|
||||||
var maxdist = maxdist.value
|
|
||||||
var minwork = minwork.value
|
|
||||||
var maxwork = maxwork.value
|
|
||||||
|
|
||||||
sliderlabel.text = 'SPM: '+minspm.toFixed(0)+'-'+maxspm.toFixed(0)
|
|
||||||
sliderlabel.text += ', Dist: '+mindist.toFixed(0)+'-'+maxdist.toFixed(0)
|
|
||||||
sliderlabel.text += ', WpS: '+minwork.toFixed(0)+'-'+maxwork.toFixed(0)
|
|
||||||
|
|
||||||
var xm = 0
|
|
||||||
var ym1 = 0
|
|
||||||
var ym2 = 0
|
|
||||||
|
|
||||||
data2['x1'] = []
|
|
||||||
data2['y1'] = []
|
|
||||||
data2['y2'] = []
|
|
||||||
data2['distance'] = []
|
|
||||||
data2['power'] = []
|
|
||||||
data2['x1mean'] = []
|
|
||||||
data2['y1mean'] = []
|
|
||||||
data2['y2mean'] = []
|
|
||||||
data2['driveenergy'] = []
|
|
||||||
data2['workoutid'] = []
|
|
||||||
data2['xname'] = []
|
|
||||||
data2['yname1'] = []
|
|
||||||
data2['yname2'] = []
|
|
||||||
data2['spm'] = []
|
|
||||||
data2['ytrend'] = []
|
|
||||||
|
|
||||||
for (var i=0; i<x1.length; i++) {
|
|
||||||
if (spm1[i]>=minspm && spm1[i]<=maxspm) {
|
|
||||||
if (distance1[i]>=mindist && distance1[i]<=maxdist) {
|
|
||||||
if (driveenergy1[i]>=minwork && driveenergy1[i]<=maxwork) {
|
|
||||||
data2['x1'].push(x1[i])
|
|
||||||
data2['y1'].push(y1[i])
|
|
||||||
data2['y2'].push(y2[i])
|
|
||||||
data2['spm'].push(spm1[i])
|
|
||||||
data2['driveenergy'].push(driveenergy1[i])
|
|
||||||
data2['distance'].push(distance1[i])
|
|
||||||
data2['power'].push(power1[i])
|
|
||||||
data2['workoutid'].push(0)
|
|
||||||
data2['xname'].push(0)
|
|
||||||
data2['yname1'].push(0)
|
|
||||||
data2['yname2'].push(0)
|
|
||||||
data2['ytrend'].push(ytrend[i])
|
|
||||||
|
|
||||||
xm += x1[i]
|
|
||||||
ym1 += y1[i]
|
|
||||||
ym2 += y2[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
xm /= data2['x1'].length
|
|
||||||
ym1 /= data2['x1'].length
|
|
||||||
ym2 /= data2['x1'].length
|
|
||||||
|
|
||||||
for (var i=0; i<data2['x1'].length; i++) {
|
|
||||||
data2['x1mean'].push(xm)
|
|
||||||
data2['y1mean'].push(ym1)
|
|
||||||
data2['y2mean'].push(ym2)
|
|
||||||
}
|
|
||||||
|
|
||||||
x1means.location = xm
|
|
||||||
y1means.location = ym1
|
|
||||||
y2means.location = ym2
|
|
||||||
y1label.text = yname1[0]+': '+(ym1).toFixed(2)
|
|
||||||
y2label.text = yname2[0]+': '+(ym2).toFixed(2)
|
|
||||||
xlabel.text = xname[0]+': '+(xm).toFixed(2)
|
|
||||||
|
|
||||||
source2.change.emit();
|
|
||||||
""")
|
|
||||||
|
|
||||||
slider_spm_min = Slider(width=140, start=15.0, end=55, value=15.0, step=.1,
|
|
||||||
title="Min SPM")
|
|
||||||
slider_spm_min.js_on_change('value', callback)
|
|
||||||
callback.args["minspm"] = slider_spm_min
|
|
||||||
|
|
||||||
slider_spm_max = Slider(width=140, start=15.0, end=55, value=55.0, step=.1,
|
|
||||||
title="Max SPM")
|
|
||||||
slider_spm_max.js_on_change('value', callback)
|
|
||||||
callback.args["maxspm"] = slider_spm_max
|
|
||||||
|
|
||||||
slider_work_min = Slider(width=140, start=0.0, end=1500, value=0.0, step=10,
|
|
||||||
title="Min Work per Stroke")
|
|
||||||
slider_work_min.js_on_change('value', callback)
|
|
||||||
callback.args["minwork"] = slider_work_min
|
|
||||||
|
|
||||||
slider_work_max = Slider(width=140, start=0.0, end=1500, value=1500.0, step=10,
|
|
||||||
title="Max Work per Stroke")
|
|
||||||
slider_work_max.js_on_change('value', callback)
|
|
||||||
callback.args["maxwork"] = slider_work_max
|
|
||||||
|
|
||||||
try:
|
|
||||||
distmax = 100+100*int(datadf['distance'].max()/100.)
|
|
||||||
except KeyError: # pragma: no cover
|
|
||||||
distmax = 1000.
|
|
||||||
|
|
||||||
slider_dist_min = Slider(width=140, start=0, end=distmax, value=0, step=50,
|
|
||||||
title="Min Distance")
|
|
||||||
slider_dist_min.js_on_change('value', callback)
|
|
||||||
callback.args["mindist"] = slider_dist_min
|
|
||||||
|
|
||||||
slider_dist_max = Slider(width=140, start=0, end=distmax, value=distmax,
|
|
||||||
step=50,
|
|
||||||
title="Max Distance")
|
|
||||||
slider_dist_max.js_on_change('value', callback)
|
|
||||||
callback.args["maxdist"] = slider_dist_max
|
|
||||||
|
|
||||||
thesliders = layoutcolumn([slider_spm_min,
|
|
||||||
slider_spm_max,
|
|
||||||
slider_dist_min,
|
|
||||||
slider_dist_max,
|
|
||||||
slider_work_min,
|
|
||||||
slider_work_max,
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
mylayout = layoutrow([thesliders, plot])
|
|
||||||
|
|
||||||
#mylayout.sizing_mode = 'stretch_both'
|
|
||||||
|
|
||||||
script, div = components(mylayout)
|
|
||||||
js_resources = INLINE.render_js()
|
|
||||||
css_resources = INLINE.render_css()
|
|
||||||
|
|
||||||
return [script, div, js_resources, css_resources]
|
|
||||||
|
|
||||||
|
|
||||||
def interactive_flexchart_stacked(id, r, xparam='time',
|
def interactive_flexchart_stacked(id, r, xparam='time',
|
||||||
|
|||||||
Reference in New Issue
Block a user