v1 of workflow.html - need speed up chart generation
This commit is contained in:
@@ -2482,13 +2482,13 @@ def interactive_flex_chart2(id=0,promember=0,
|
|||||||
title="Max Distance",callback=callback)
|
title="Max Distance",callback=callback)
|
||||||
callback.args["maxdist"] = slider_dist_max
|
callback.args["maxdist"] = slider_dist_max
|
||||||
|
|
||||||
layout = layoutrow([layoutcolumn([slider_spm_min,
|
layout = layoutrow([layoutcolumn([annotation,
|
||||||
|
slider_spm_min,
|
||||||
slider_spm_max,
|
slider_spm_max,
|
||||||
slider_dist_min,
|
slider_dist_min,
|
||||||
slider_dist_max,
|
slider_dist_max,
|
||||||
slider_work_min,
|
slider_work_min,
|
||||||
slider_work_max,
|
slider_work_max,
|
||||||
annotation,
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
plot])
|
plot])
|
||||||
@@ -2499,6 +2499,197 @@ def interactive_flex_chart2(id=0,promember=0,
|
|||||||
|
|
||||||
return [script,div,js_resources,css_resources,workstrokesonly]
|
return [script,div,js_resources,css_resources,workstrokesonly]
|
||||||
|
|
||||||
|
def thumbnail_flex_chart(id=0,promember=0,
|
||||||
|
xparam='time',
|
||||||
|
yparam1='pace',
|
||||||
|
yparam2='hr',
|
||||||
|
plottype='line',
|
||||||
|
workstrokesonly=False):
|
||||||
|
|
||||||
|
|
||||||
|
#rowdata,row = dataprep.getrowdata_db(id=id)
|
||||||
|
columns = [xparam,yparam1,yparam2,'time']
|
||||||
|
|
||||||
|
rowdata = dataprep.getsmallrowdata_db(columns,ids=[id],doclean=True,
|
||||||
|
workstrokesonly=workstrokesonly)
|
||||||
|
|
||||||
|
if rowdata.empty:
|
||||||
|
rowdata = dataprep.getsmallrowdata_db(columns,ids=[id],doclean=True,
|
||||||
|
workstrokesonly=False)
|
||||||
|
workstrokesonly=False
|
||||||
|
|
||||||
|
try:
|
||||||
|
tests = rowdata[yparam2]
|
||||||
|
except KeyError:
|
||||||
|
yparam2 = 'None'
|
||||||
|
|
||||||
|
try:
|
||||||
|
tests = rowdata[yparam1]
|
||||||
|
except KeyError:
|
||||||
|
yparam1 = 'None'
|
||||||
|
|
||||||
|
rowdata.dropna(axis=1,how='all',inplace=True)
|
||||||
|
|
||||||
|
if rowdata.empty:
|
||||||
|
return "","No valid data"
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
rowdata.sort_values(by='time',ascending=True,inplace=True)
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
workoutstateswork = [1,4,5,8,9,6,7]
|
||||||
|
workoutstatesrest = [3]
|
||||||
|
workoutstatetransition = [0,2,10,11,12,13]
|
||||||
|
|
||||||
|
if workstrokesonly:
|
||||||
|
try:
|
||||||
|
rowdata = rowdata[~rowdata['workoutstate'].isin(workoutstatesrest)]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
tseconds = rowdata.ix[:,'time']
|
||||||
|
except KeyError:
|
||||||
|
return '','No time data - cannot make flex plot','',''
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
rowdata['x1'] = rowdata.ix[:,xparam]
|
||||||
|
except KeyError:
|
||||||
|
rowdata['x1'] = 0*rowdata.ix[:,'time']
|
||||||
|
|
||||||
|
try:
|
||||||
|
rowdata['y1'] = rowdata.ix[:,yparam1]
|
||||||
|
except KeyError:
|
||||||
|
rowdata['y1'] = 0*rowdata.ix[:,'time']
|
||||||
|
|
||||||
|
if yparam2 != 'None':
|
||||||
|
try:
|
||||||
|
rowdata['y2'] = rowdata.ix[:,yparam2]
|
||||||
|
except KeyError:
|
||||||
|
rowdata['y2'] = 0*rowdata.ix[:,'time']
|
||||||
|
else:
|
||||||
|
rowdata['y2'] = rowdata['y1']
|
||||||
|
|
||||||
|
if xparam=='time':
|
||||||
|
xaxmax = tseconds.max()
|
||||||
|
xaxmin = tseconds.min()
|
||||||
|
elif xparam=='distance' or xparam=='cumdist':
|
||||||
|
xaxmax = rowdata['x1'].max()
|
||||||
|
xaxmin = rowdata['x1'].min()
|
||||||
|
else:
|
||||||
|
xaxmax = yaxmaxima[xparam]
|
||||||
|
xaxmin = yaxminima[xparam]
|
||||||
|
|
||||||
|
x_axis_type = 'linear'
|
||||||
|
y_axis_type = 'linear'
|
||||||
|
if xparam == 'time':
|
||||||
|
x_axis_type = 'datetime'
|
||||||
|
|
||||||
|
if yparam1 == 'pace':
|
||||||
|
y_axis_type = 'datetime'
|
||||||
|
y1mean = rowdata.ix[:,'pace'].mean()
|
||||||
|
|
||||||
|
|
||||||
|
rowdata['xname'] = axlabels[xparam]
|
||||||
|
rowdata['yname1'] = axlabels[yparam1]
|
||||||
|
if yparam2 != 'None':
|
||||||
|
rowdata['yname2'] = axlabels[yparam2]
|
||||||
|
else:
|
||||||
|
rowdata['yname2'] = axlabels[yparam1]
|
||||||
|
|
||||||
|
|
||||||
|
# prepare data
|
||||||
|
source = ColumnDataSource(
|
||||||
|
rowdata
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
sizing_mode = 'fixed' # 'scale_width' also looks nice with this example
|
||||||
|
plot = Figure(x_axis_type=x_axis_type,y_axis_type=y_axis_type,
|
||||||
|
plot_width=200,plot_height=150,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
plot.toolbar.logo = None
|
||||||
|
plot.toolbar_location = None
|
||||||
|
#plot.yaxis.visible = False
|
||||||
|
plot.xaxis.axis_label_text_font_size = "7pt"
|
||||||
|
plot.yaxis.axis_label_text_font_size = "7pt"
|
||||||
|
plot.xaxis.major_label_text_font_size = "7pt"
|
||||||
|
plot.yaxis.major_label_text_font_size = "7pt"
|
||||||
|
# add watermark
|
||||||
|
plot.extra_y_ranges = {"watermark": watermarkrange}
|
||||||
|
plot.extra_x_ranges = {"watermark": watermarkrange}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if plottype=='line':
|
||||||
|
plot.line('x1','y1',source=source)
|
||||||
|
elif plottype=='scatter':
|
||||||
|
plot.scatter('x1','y1',source=source,fill_alpha=0.4,
|
||||||
|
line_color=None)
|
||||||
|
|
||||||
|
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') and (xparam != 'cumdist'):
|
||||||
|
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.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
|
||||||
|
#= {"yax2": yrange2}
|
||||||
|
|
||||||
|
if plottype=='line':
|
||||||
|
plot.line('x1','y2',color="red",y_range_name="yax2",
|
||||||
|
source=source)
|
||||||
|
|
||||||
|
elif plottype=='scatter':
|
||||||
|
plot.scatter('x1','y2',source=source,
|
||||||
|
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],
|
||||||
|
major_label_text_font_size="7pt",
|
||||||
|
axis_label_text_font_size="7pt",
|
||||||
|
),'right',
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
script, div = components(plot)
|
||||||
|
|
||||||
|
return [script,div]
|
||||||
|
|
||||||
|
|
||||||
def interactive_bar_chart(id=0,promember=0):
|
def interactive_bar_chart(id=0,promember=0):
|
||||||
# check if valid ID exists (workout exists)
|
# check if valid ID exists (workout exists)
|
||||||
|
|||||||
41
rowers/templates/workflow.html
Normal file
41
rowers/templates/workflow.html
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
{% load tz %}
|
||||||
|
|
||||||
|
|
||||||
|
{% get_current_timezone as TIME_ZONE %}
|
||||||
|
|
||||||
|
{% block title %}{{ workout.name }}{% endblock %}
|
||||||
|
{% block og_title %}{{ workout.name }}{% endblock %}
|
||||||
|
{% block description %}{{ workout.name }}
|
||||||
|
{{ workout.date }} - {{ workout.distance }}m - {{ workout.duration |durationprint:"%H:%M:%S.%f" }}{% endblock %}
|
||||||
|
{% block og_description %}{{ workout.name }}
|
||||||
|
{{ workout.date }} - {{ workout.distance }}m - {{ workout.duration |durationprint:"%H:%M:%S.%f" }}{% endblock %}
|
||||||
|
|
||||||
|
{% block meta %}
|
||||||
|
<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>
|
||||||
|
|
||||||
|
{% for chart in charts %}
|
||||||
|
{{ chart.script |safe }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div id="workouts" class="grid_12 alpha">
|
||||||
|
{% for chart in charts %}
|
||||||
|
<div class="grid_3 alpha">
|
||||||
|
<h2>{{ forloop.counter }}</h2>
|
||||||
|
<div class="grid_3 tooltip">
|
||||||
|
<a href="/rowers/workout/{{ workout.id }}/flexchart?favoritechart={{ forloop.counter |add:"-1" }}">
|
||||||
|
{{ chart.div | safe }}
|
||||||
|
</a>
|
||||||
|
<span class="tooltiptext">{{ chart.notes }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -327,6 +327,7 @@ urlpatterns = [
|
|||||||
url(r'^legal', TemplateView.as_view(template_name='legal.html'),name='legal'),
|
url(r'^legal', TemplateView.as_view(template_name='legal.html'),name='legal'),
|
||||||
url(r'^register$',views.rower_register_view),
|
url(r'^register$',views.rower_register_view),
|
||||||
url(r'^register/thankyou/$', TemplateView.as_view(template_name='registerthankyou.html'), name='registerthankyou'),
|
url(r'^register/thankyou/$', TemplateView.as_view(template_name='registerthankyou.html'), name='registerthankyou'),
|
||||||
|
url(r'^workout/(?P<id>\d+)/workflow$',views.workout_workflow_view),
|
||||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<plottype>\w+)/$',views.workout_flexchart3_view),
|
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<plottype>\w+)/$',views.workout_flexchart3_view),
|
||||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<plottype>\w+.*)$',views.workout_flexchart3_view),
|
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)/(?P<plottype>\w+.*)$',views.workout_flexchart3_view),
|
||||||
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)$',views.workout_flexchart3_view),
|
url(r'^workout/(?P<id>\d+)/flexchart/(?P<xparam>\w+.*)/(?P<yparam1>\w+.*)/(?P<yparam2>\w+.*)$',views.workout_flexchart3_view),
|
||||||
|
|||||||
@@ -5847,6 +5847,58 @@ def workout_comparison_view2(request,id1=0,id2=0,xparam='distance',
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
# Flex thumbnails
|
||||||
|
@login_required()
|
||||||
|
def workout_workflow_view(request,id):
|
||||||
|
try:
|
||||||
|
row = Workout.objects.get(id=id)
|
||||||
|
except Workout.DoesNotExist:
|
||||||
|
raise Http404("Workout doesn't exist")
|
||||||
|
|
||||||
|
r = getrower(request.user)
|
||||||
|
result = request.user.is_authenticated() and ispromember(request.user)
|
||||||
|
if result:
|
||||||
|
promember=1
|
||||||
|
if request.user == row.user.user:
|
||||||
|
mayedit=1
|
||||||
|
|
||||||
|
workouttype = 'ote'
|
||||||
|
if row.workouttype in ('water','coastal'):
|
||||||
|
workouttype = 'otw'
|
||||||
|
|
||||||
|
try:
|
||||||
|
favorites = FavoriteChart.objects.filter(user=r,
|
||||||
|
workouttype__in=[workouttype,'both']).order_by("id")
|
||||||
|
maxfav = len(favorites)-1
|
||||||
|
except:
|
||||||
|
favorites = None
|
||||||
|
maxfav = 0
|
||||||
|
|
||||||
|
charts = []
|
||||||
|
|
||||||
|
if favorites:
|
||||||
|
for f in favorites:
|
||||||
|
workstrokesonly = not f.reststrokes
|
||||||
|
script,div = thumbnail_flex_chart(id=id,promember=promember,
|
||||||
|
xparam=f.xparam,
|
||||||
|
yparam1=f.yparam1,
|
||||||
|
yparam2=f.yparam2,
|
||||||
|
plottype=f.plottype,
|
||||||
|
workstrokesonly=workstrokesonly)
|
||||||
|
|
||||||
|
charts.append({
|
||||||
|
'script':script,
|
||||||
|
'div':div,
|
||||||
|
'notes':f.notes})
|
||||||
|
|
||||||
|
|
||||||
|
return render(request,
|
||||||
|
'workflow.html',
|
||||||
|
{
|
||||||
|
'charts':charts,
|
||||||
|
'workout':row,
|
||||||
|
})
|
||||||
|
|
||||||
# The famous flex chart
|
# The famous flex chart
|
||||||
def workout_flexchart3_view(request,*args,**kwargs):
|
def workout_flexchart3_view(request,*args,**kwargs):
|
||||||
|
|
||||||
@@ -5978,12 +6030,6 @@ def workout_flexchart3_view(request,*args,**kwargs):
|
|||||||
css_resources = ""
|
css_resources = ""
|
||||||
|
|
||||||
|
|
||||||
# script = res[0]
|
|
||||||
# div = res[1]
|
|
||||||
# js_resources = res[2]
|
|
||||||
# css_resources = res[3]
|
|
||||||
|
|
||||||
|
|
||||||
axchoicesbasic = {ax[0]:ax[1] for ax in axes if ax[4]=='basic'}
|
axchoicesbasic = {ax[0]:ax[1] for ax in axes if ax[4]=='basic'}
|
||||||
axchoicespro = {ax[0]:ax[1] for ax in axes if ax[4]=='pro'}
|
axchoicespro = {ax[0]:ax[1] for ax in axes if ax[4]=='pro'}
|
||||||
noylist = ["time","distance"]
|
noylist = ["time","distance"]
|
||||||
|
|||||||
Reference in New Issue
Block a user