diff --git a/rowers/forms.py b/rowers/forms.py index 58f20188..8b9ff819 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -15,30 +15,6 @@ from django.forms import formset_factory from utils import landingpages from metrics import axes -class SelectWidget(Select): - """ - Subclass of Django's select widget that allows disabling options. - """ - def __init__(self, *args, **kwargs): - self._disabled_choices = [] - super(SelectWidget, self).__init__(*args, **kwargs) - - @property - def disabled_choices(self): - return self._disabled_choices - - @disabled_choices.setter - def disabled_choices(self, other): - self._disabled_choices = other - - def create_option(self, name, value, label, selected, index, subindex=None, attrs=None): - option_dict = super(SelectWidget, self).create_option( - name, value, label, selected, index, subindex=subindex, attrs=attrs - ) - if value in self.disabled_choices: - option_dict['attrs']['disabled'] = 'disabled' - - return option_dict # login form class LoginForm(forms.Form): @@ -963,11 +939,11 @@ class FlexAxesForm(forms.Form): xaxis = forms.ChoiceField( - choices=axchoices,label='X-Axis',widget=SelectWidget,required=True) + choices=axchoices,label='X-Axis',required=True) yaxis1 = forms.ChoiceField( - choices=yaxchoices,label='Left Axis',widget=SelectWidget,required=True) + choices=yaxchoices,label='Left Axis',required=True) yaxis2 = forms.ChoiceField( - choices=yaxchoices2,label='Right Axis',widget=SelectWidget,required=True) + choices=yaxchoices2,label='Right Axis',required=True) def __init__(self,request,*args,**kwargs): super(FlexAxesForm, self).__init__(*args, **kwargs) diff --git a/rowers/templates/histo.html b/rowers/templates/histo.html index f952ec58..37b9c270 100644 --- a/rowers/templates/histo.html +++ b/rowers/templates/histo.html @@ -1,16 +1,16 @@ -{% extends "base.html" %} +{% extends "newbase.html" %} {% load staticfiles %} {% load rowerfilters %} -{% block title %}Rowsandall Histogram {% endblock %} +{% block title %}Rowsandall {% endblock %} -{% block content %} +{% block main %} - - -{{ interactiveplot |safe }} +
+ + +
+
+ + - - +
+ + -
-
- {% if theuser %} -

{{ theuser.first_name }}'s Stroke Analysis

- {% else %} -

{{ user.first_name }}'s Stroke Analysis

- {% endif %} -
-
- {% if user.is_authenticated and user|is_manager %} -
- -
- {% for member in user|team_members %} - {{ member.first_name }} {{ member.last_name }} - {% endfor %} -
- {% else %} -   -
- {% endif %} -
-
-
-
-

Warning: Large date ranges may take a long time to load. Huge date ranges may crash your browser.

-
- {% csrf_token %} -
- - {{ optionsform.as_table }} -
-
-
- - -
-
-
-
-

Use this form to select a different date range:

-

- Select start and end date for a date range: -

- -
- - - {{ form.as_table }} -
- {% csrf_token %} -
-
- -
-
-
- Or use the last {{ deltaform }} days. -
-
- {% csrf_token %} - - -
-
-
- -
- +
+ +
+ +
    + +
  • Summary for {{ theuser.first_name }} {{ theuser.last_name }} between {{ startdate|date }} and {{ enddate|date }}

    -
- + -
- - {{ the_div|safe }} - -
+
  • +
    + + {{ the_div|safe }} +
    +
  • +
  • +
    + + {{ optionsform.as_table }} +
    + +
  • +
  • + + {{ form.as_table }} +
    +
  • +
  • + {% csrf_token %} + + +
  • + {% endblock %} + +{% block scripts %} + + + + +{% endblock %} + +{% block sidebar %} +{% include 'menu_analytics.html' %} +{% endblock %} diff --git a/rowers/urls.py b/rowers/urls.py index 4f52e9a7..9d408257 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -214,13 +214,9 @@ urlpatterns = [ url(r'^flexall/user/(?P\d+)/$',views.cum_flex), url(r'^flexall/$',views.cum_flex), url(r'^flexalldata/$',views.cum_flex_data), - - url(r'^histo/u/(?P\d+)$',views.histo), - url(r'^flexall/u/(?P\d+)$',views.cum_flex), + url(r'^histo/user/(?P\d+)$',views.histo), + url(r'^histodata$',views.histo_data), url(r'^(?P\d+)/histo/(?P\w+.*)/(?P\w+.*)$',views.histo), - url(r'^(?P\d+)/histo/(?P\d+)$',views.histo), - url(r'^histo/(?P\w+.*)/(?P\w+.*)$',views.histo), - url(r'^histo/(?P\d+)$',views.histo), url(r'^histo/$',views.histo), url(r'^cumstats/u/(?P\d+)$',views.cumstats), url(r'^cumstats/(?P\w+.*)/(?P\w+.*)/p/(?P\w+.*)$',views.cumstats), diff --git a/rowers/views.py b/rowers/views.py index 04994b73..eb30c489 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -2558,6 +2558,99 @@ def cum_flex_data( return JSONResponse(data) +# The Flex plot for a large selection of workouts +@login_required() +def histo_data( + request, + options={ + 'includereststrokes':False, + 'rankingonly':False, + 'modality':'all', + 'waterboattype':types.waterboattype, + 'theuser':0, + 'enddatestring':'', + 'startdatestring':'', + 'deltadays':-1, + }): + + def_options = options + + + if 'options' in request.session: + options = request.session['options'] + + modality = keyvalue_get_default('modality',options,def_options) + rankingonly = keyvalue_get_default('rankingonly',options,def_options) + includereststrokes = keyvalue_get_default('includereststrokes',options,def_options) + waterboattype = keyvalue_get_default('waterboattype',options,def_options) + workstrokesonly = not includereststrokes + theuser = keyvalue_get_default('theuser',options,def_options) + startdatestring = keyvalue_get_default('startdatestring',options,def_options) + enddatestring = keyvalue_get_default('enddatestring',options,def_options) + + if modality == 'all': + modalities = [m[0] for m in types.workouttypes] + else: + modalities = [modality] + + try: + startdate = iso8601.parse_date(startdatestring) + except ParseError: + startdate = timezone.now()-datetime.timedelta(days=7) + + try: + enddate = iso8601.parse_date(enddatestring) + except ParseError: + enddate = timezone.now() + + + if enddate < startdate: + s = enddate + enddate = startdate + startdate = s + + promember=0 + if theuser == 0: + theuser = request.user.id + + if not request.user.is_anonymous(): + r = getrower(request.user) + result = request.user.is_authenticated() and ispromember(request.user) + if result: + promember=1 + + r2 = getrower(theuser) + + if rankingonly: + rankingpiece = [True,] + else: + rankingpiece = [True,False] + + allworkouts = Workout.objects.filter(user=r2, + workouttype__in=modalities, + boattype__in=waterboattype, + startdatetime__gte=startdate, + startdatetime__lte=enddate, + rankingpiece__in=rankingpiece) + + if allworkouts: + res = interactive_histoall(allworkouts) + script = res[0] + div = res[1] + else: + script = '' + div = '

    No pieces uploaded for this date range.

    ' + + scripta = script.split('\n')[2:-1] + script = ''.join(scripta) + + data = { + "script":script, + "div":div, + } + + return JSONResponse(data) + @@ -2893,29 +2986,50 @@ def histo(request,theuser=0, options={ 'includereststrokes':False, 'workouttypes':[i[0] for i in types.workouttypes], - 'waterboattype':types.waterboattype + 'waterboattype':types.waterboattype, + 'rankingonly': False, }): - if 'options' in request.session: - options = request.session['options'] + r = getrequestrower(request,userid=theuser) + theuser = r.user + + if 'waterboattype' in request.session: + waterboattype = request.session['waterboattype'] + else: + waterboattype = types.waterboattype + + + if 'rankingonly' in request.session: + rankingonly = request.session['rankingonly'] + else: + rankingonly = False + + if 'modalities' in request.session: + modalities = request.session['modalities'] + if len(modalities) > 1: + modality = 'all' + else: + modality = modalities[0] + else: + modalities = [m[0] for m in types.workouttypes] + modality = 'all' + try: - workouttypes = options['workouttypes'] - includereststrokes = options['includereststrokes'] - waterboattype = options['waterboattype'] + rankingonly = options['rankingonly'] except KeyError: - workouttypes = [i[0] for i in types.workouttypes] - waterboattype = types.waterboattype - includereststrokes = False + rankingonly = False + try: + includereststrokes = options['includereststrokes'] + except KeyError: + includereststrokes = False + + workstrokesonly = not includereststrokes + waterboattype = types.waterboattype -# checktypes = ['water','rower','dynamic','slides','skierg', -# 'paddle','snow','coastal','other'] - - if deltadays>0: - startdate = enddate-datetime.timedelta(days=int(deltadays)) if startdatestring != "": startdate = iso8601.parse_date(startdatestring) @@ -2928,27 +3042,13 @@ def histo(request,theuser=0, enddate = startdate startdate = s - promember=0 - r = getrequestrower(request,userid=theuser) - theuser = r.user.id - - - if not request.user.is_anonymous(): - r = getrower(request.user) - result = request.user.is_authenticated() and ispromember(request.user) - if result: - promember=1 - - if not promember: - return HttpResponseRedirect("/rowers/promembership/") # get all indoor rows of in date range # process form - if request.method == 'POST' and "daterange" in request.POST: + if request.method == 'POST': form = DateRangeForm(request.POST) - deltaform = DeltaDaysForm(request.POST) - optionsform = StatsOptionsForm() + modalityform = TrendFlexModalForm(request.POST) if form.is_valid(): startdate = form.cleaned_data['startdate'] enddate = form.cleaned_data['enddate'] @@ -2956,118 +3056,90 @@ def histo(request,theuser=0, s = enddate enddate = startdate startdate = s - elif request.method == 'POST' and "datedelta" in request.POST: - deltaform = DeltaDaysForm(request.POST) - optionsform = StatsOptionsForm() - if deltaform.is_valid(): - deltadays = deltaform.cleaned_data['deltadays'] - if deltadays != 0 and deltadays != None: - enddate = timezone.now() - startdate = enddate-datetime.timedelta(days=deltadays) - if startdate > enddate: - s = enddate - enddate = startdate - startdate = s - form = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) + if modalityform.is_valid(): + modality = modalityform.cleaned_data['modality'] + waterboattype = modalityform.cleaned_data['waterboattype'] + rankingonly = modalityform.cleaned_data['rankingonly'] + if modality == 'all': + modalities = [m[0] for m in types.workouttypes] else: - form = DateRangeForm() - optionsform = StatsOptionsForm() - elif request.method == 'POST' and 'options' in request.POST: - optionsform = StatsOptionsForm(request.POST) - if optionsform.is_valid(): - includereststrokes = optionsform.cleaned_data['includereststrokes'] - workstrokesonly = not includereststrokes - waterboattype = optionsform.cleaned_data['waterboattype'] - workouttypes = [] - for type in types.checktypes: - if optionsform.cleaned_data[type]: - workouttypes.append(type) - - - options = { - 'includereststrokes':includereststrokes, - 'workouttypes':workouttypes, - 'waterboattype':waterboattype, - } - request.session['options'] = options - form = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - deltaform = DeltaDaysForm() - else: - form = DateRangeForm(initial={ - 'startdate': startdate, - 'enddate': enddate, - }) - deltaform = DeltaDaysForm() + modalities = [modality] + if modality != 'water': + waterboattype = [b[0] for b in types.boattypes] + + + request.session['modalities'] = modalities + request.session['waterboattype'] = waterboattype + request.session['rankingonly'] = rankingonly + form = DateRangeForm(initial={ + 'startdate': startdate, + 'enddate': enddate, + }) else: form = DateRangeForm(initial={ 'startdate': startdate, 'enddate': enddate, }) - deltaform = DeltaDaysForm() - optionsform = StatsOptionsForm() - try: - r2 = getrower(theuser) - allergworkouts = Workout.objects.filter(user=r2, - workouttype__in=workouttypes, - boattype__in=waterboattype, - startdatetime__gte=startdate, - startdatetime__lte=enddate) - - except Rower.DoesNotExist: - allergworkouts = [] - r2=0 + includereststrokes = False - try: - u = User.objects.get(id=theuser) - except User.DoesNotExist: - u = '' + workstrokesonly = not includereststrokes + modalityform = TrendFlexModalForm( + initial={ + 'modality':modality, + 'waterboattype':waterboattype, + 'rankingonly':rankingonly, + } + ) - if allergworkouts: - res = interactive_histoall(allergworkouts) - script = res[0] - div = res[1] - else: - script = '' - typesstring = ', '.join('{}'.format(item) for i,item in enumerate(workouttypes)) - if 'water' in workouttypes: - boatsstring = 'water ('+', '.join('{}'.format(item) for i,item in enumerate(waterboattype))+')' - typesstring = typesstring.replace('water',boatsstring) - div = '

    No pieces found for '+typesstring+' for this date range.

    ' - - # set options form correctly - initial = {} - initial['includereststrokes'] = includereststrokes - - initial['waterboattype'] = waterboattype - - for wtype in types.checktypes: - if wtype in workouttypes: - initial[wtype] = True - else: - initial[wtype] = False + negtypes = [] + for b in types.boattypes: + if b[0] not in waterboattype: + negtypes.append(b[0]) - optionsform = StatsOptionsForm(initial=initial) + + script = '' + div = get_call() + js_resources = '' + css_resources = '' + + + + options = { + 'modality': modality, + 'theuser': theuser.id, + 'waterboattype':waterboattype, + 'startdatestring':startdatestring, + 'enddatestring':enddatestring, + 'rankingonly':rankingonly, + 'includereststrokes':includereststrokes, + } + + request.session['options'] = options + + promember=0 + mayedit=0 + if not request.user.is_anonymous(): + result = request.user.is_authenticated() and ispromember(request.user) + if result: + promember = 1 + + request.session['options'] = options return render(request, 'histo.html', {'interactiveplot':script, 'the_div':div, 'id':theuser, - 'theuser':u, + 'active':'nav-analysis', + 'theuser':theuser, + 'rower':r, 'startdate':startdate, 'enddate':enddate, 'form':form, - 'optionsform':optionsform, - 'deltaform':deltaform, + 'optionsform':modalityform, 'teams':get_my_teams(request.user), })