close #359
This commit is contained in:
@@ -30,7 +30,7 @@ class EmailForm(forms.Form):
|
||||
botcheck = forms.CharField(max_length=5)
|
||||
message = forms.CharField()
|
||||
|
||||
|
||||
|
||||
|
||||
# Upload the CrewNerd Summary CSV
|
||||
class CNsummaryForm(forms.Form):
|
||||
@@ -105,6 +105,7 @@ from utils import (
|
||||
defaultleft,defaultmiddle
|
||||
)
|
||||
|
||||
|
||||
|
||||
# Form to change Workflow page layout
|
||||
class WorkFlowLeftPanelForm(forms.Form):
|
||||
@@ -533,6 +534,20 @@ ww = list(workouttypes)
|
||||
ww.append(tuple(('all','All')))
|
||||
workouttypes = tuple(ww)
|
||||
|
||||
class DataFrameColumnsForm(forms.Form):
|
||||
cols = ['ftime','cumdist','fpace','spm',
|
||||
'hr','power','driveenergy','drivelength','averageforce',
|
||||
'peakforce','distance','drivespeed','workoutstate',
|
||||
'catch','finish','peakforceangle','wash','slip','rhythm',
|
||||
'effectiveangle','totalangle','distanceperstroke','velo']
|
||||
|
||||
colchoices = [
|
||||
(c, c) for c in cols
|
||||
]
|
||||
|
||||
cols = forms.MultipleChoiceField(choices=colchoices,
|
||||
label='Table Columns')
|
||||
|
||||
# form to select modality and boat type for trend flex
|
||||
class TrendFlexModalForm(forms.Form):
|
||||
modality = forms.ChoiceField(choices=workouttypes,
|
||||
|
||||
@@ -259,6 +259,10 @@
|
||||
<i class="fas fa-cut fa-fw"></i> Split Workout
|
||||
</a>
|
||||
</li>
|
||||
<li id="data-view">
|
||||
<a href="/rowers/workout/{{ workout.id }}/data">
|
||||
<i class="fal fa-table fa-fw"></i> Explore Raw Data
|
||||
</a>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="has-children" id="advanced">
|
||||
|
||||
29
rowers/templates/workout_data.html
Normal file
29
rowers/templates/workout_data.html
Normal file
@@ -0,0 +1,29 @@
|
||||
{% extends "newbase.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load rowerfilters %}
|
||||
|
||||
{% block title %}Workout Data{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<h1>Workout Data for {{ workout.name }}</h1>
|
||||
|
||||
<ul class="main-content">
|
||||
<li class="grid_4">
|
||||
<p>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
{{ form.as_table }}
|
||||
{% csrf_token %}
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</p>
|
||||
</li>
|
||||
<li class="grid_4">
|
||||
{{ htmltable|safe }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
{% include 'menu_workout.html' %}
|
||||
{% endblock %}
|
||||
@@ -246,6 +246,7 @@ urlpatterns = [
|
||||
url(r'^workout/(?P<id>\d+)/instroke/(?P<metric>\w+.*)$',views.instroke_chart),
|
||||
url(r'^workout/(?P<id>\d+)/instroke$',views.instroke_view),
|
||||
url(r'^workout/(?P<id>\d+)/stats$',views.workout_stats_view),
|
||||
url(r'^workout/(?P<id>\d+)/data$',views.workout_data_view),
|
||||
url(r'^workout/(?P<id>\d+)/otwsetpower$',views.workout_otwsetpower_view),
|
||||
url(r'^workout/(?P<id>\d+)/interactiveotwplot$',views.workout_otwpowerplot_view),
|
||||
url(r'^workout/(?P<id>\d+)/wind$',views.workout_wind_view),
|
||||
|
||||
101
rowers/views.py
101
rowers/views.py
@@ -44,7 +44,7 @@ from rowers.forms import (
|
||||
PlannedSessionTeamForm,PlannedSessionTeamMemberForm,
|
||||
VirtualRaceSelectForm,WorkoutRaceSelectForm,CourseSelectForm,
|
||||
RaceResultFilterForm,PowerIntervalUpdateForm,FlexAxesForm,
|
||||
FlexOptionsForm
|
||||
FlexOptionsForm,DataFrameColumnsForm,
|
||||
)
|
||||
from django.core.urlresolvers import reverse, reverse_lazy
|
||||
|
||||
@@ -8093,6 +8093,100 @@ def cumstats(request,theuser=0,
|
||||
|
||||
return response
|
||||
|
||||
|
||||
# data explorer
|
||||
@login_required()
|
||||
def workout_data_view(request, id=0):
|
||||
|
||||
r = getrower(request.user)
|
||||
w = get_workout(id)
|
||||
|
||||
if not checkworkoutuser(request.user,w):
|
||||
raise PermissionDenied('Access Denied')
|
||||
|
||||
breadcrumbs = [
|
||||
{
|
||||
'url':'/rowers/list-workouts',
|
||||
'name':'Workouts'
|
||||
},
|
||||
{
|
||||
'url':get_workout_default_page(request,id),
|
||||
'name': str(w.id)
|
||||
},
|
||||
{
|
||||
'url':reverse(workout_data_view,kwargs={'id':id}),
|
||||
'name': 'Data Explorer'
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
|
||||
datadf,row = dataprep.getrowdata_db(id=id)
|
||||
|
||||
|
||||
datadf.sort_values(['ftime'],inplace=True)
|
||||
|
||||
datadf.drop(labels=[
|
||||
'id','time','hr_an','hr_at','hr_bottom','hr_max',
|
||||
'hr_tr','hr_ut1','hr_ut2','x_right',
|
||||
],inplace=True,axis=1)
|
||||
|
||||
|
||||
cols = ['ftime','cumdist','fpace','spm',
|
||||
'hr','power','driveenergy','drivelength','averageforce',
|
||||
'peakforce','distance','drivespeed','workoutstate',
|
||||
'catch','finish','peakforceangle','wash','slip','rhythm',
|
||||
'effectiveangle','totalangle','distanceperstroke','velo']
|
||||
|
||||
|
||||
tcols = ['ftime','cumdist','fpace','spm','hr','power']
|
||||
|
||||
datadf = datadf[cols]
|
||||
datadf.loc[:,'hr'] = datadf['hr'].astype('int')
|
||||
datadf.loc[:,'power'] = datadf['power'].astype('int')
|
||||
datadf.loc[:,'distance'] = datadf['distance'].astype('int')
|
||||
datadf.loc[:,'spm'] = 10*datadf['spm'].astype('int')/10.
|
||||
|
||||
|
||||
if request.method == 'POST':
|
||||
form = DataFrameColumnsForm(request.POST)
|
||||
if form.is_valid():
|
||||
tcols = form.cleaned_data['cols']
|
||||
|
||||
else:
|
||||
form = DataFrameColumnsForm(initial = {'cols':tcols})
|
||||
|
||||
datadf = datadf[tcols]
|
||||
|
||||
for col in cols:
|
||||
try:
|
||||
if datadf[col].mean() == 0 and datadf[col].std() == 0:
|
||||
datadf.drop(labels=[col],axis=1,inplace=True)
|
||||
except (TypeError,KeyError):
|
||||
pass
|
||||
|
||||
# pd.set_option('display.width', 1000)
|
||||
pd.set_option('colheader_justify', 'left')
|
||||
|
||||
htmltable = datadf.to_html(
|
||||
bold_rows=True,
|
||||
show_dimensions=True,border=1,
|
||||
classes='pandastable',justify='justify'
|
||||
)
|
||||
|
||||
return render(request,
|
||||
'workout_data.html',
|
||||
{
|
||||
'htmltable': htmltable,
|
||||
'form':form,
|
||||
'teams':get_my_teams(request.user),
|
||||
'workout': w,
|
||||
'breadcrumbs': breadcrumbs,
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
# Stats page
|
||||
@login_required()
|
||||
def workout_stats_view(request,id=0,message="",successmessage=""):
|
||||
@@ -8130,10 +8224,7 @@ def workout_stats_view(request,id=0,message="",successmessage=""):
|
||||
# prepare data frame
|
||||
datadf,row = dataprep.getrowdata_db(id=id)
|
||||
if (checkworkoutuser(request.user,row)==False):
|
||||
message = "You are not allowed to see the stats of this workout"
|
||||
messages.error(request,message)
|
||||
url = reverse(workouts_view)
|
||||
return HttpResponseRedirect(url)
|
||||
raise PermissionDenied('Access Denied')
|
||||
|
||||
datadf = dataprep.clean_df_stats(datadf,workstrokesonly=workstrokesonly)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user