diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 3b807d55..bf527500 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -411,7 +411,7 @@ def save_workout_database(f2,r,dosmooth=True,workouttype='rower', summary='', makeprivate=False, oarlength=2.89,inboard=0.88, - consistencychecks=True): + consistencychecks=False): message = None powerperc = 100*np.array([r.pw_ut2, r.pw_ut1, diff --git a/rowers/interactiveplots.py b/rowers/interactiveplots.py index 824d7332..ccbcf226 100644 --- a/rowers/interactiveplots.py +++ b/rowers/interactiveplots.py @@ -12,7 +12,7 @@ from bokeh.palettes import Dark2_8 as palette import itertools from bokeh.plotting import figure, ColumnDataSource, Figure,curdoc from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation -from bokeh.charts import Histogram,HeatMap,Area,BoxPlot +from bokeh.charts import Histogram,HeatMap,Area,BoxPlot,Bar from bokeh.resources import CDN,INLINE from bokeh.embed import components from bokeh.layouts import layout,widgetbox @@ -219,6 +219,63 @@ def interactive_boxchart(datadf,fieldname,extratitle=''): return script,div +def interactive_activitychart(workouts,startdate,enddate): + if len(workouts) == 0: + return "","" + + dates = [] + types = [] + durations = [] + + for w in workouts: + if w.privacy == 'visible': + dd = w.date.strftime('%m/%d') + du = w.duration.hour*60+w.duration.minute + dates.append(dd) + durations.append(du) + types.append(w.workouttype) + + d = startdate + + while d<=enddate: + dates.append(d.strftime('%m/%d')) + durations.append(0) + types.append('rower') + d += datetime.timedelta(days=1) + + + df = pd.DataFrame({ + 'date':dates, + 'duration':durations, + 'type':types, + }) + + p = Bar(df,'date',values='duration',title='Activity', + stack='type', + plot_width=350, + plot_height=250, + toolbar_location = None, + ) + + for legend in p.legend: + new_items = [] + for legend_item in legend.items: + it = legend_item.label['value'] + tot = df[df['type']==it].duration.sum() + if tot != 0: + new_items.append(legend_item) + legend.items = new_items + + + p.legend.location = "top_left" + p.legend.background_fill_alpha = 0.7 + + p.yaxis.axis_label = 'Minutes' + + script, div = components(p) + + return script,div + def interactive_forcecurve(theworkouts,workstrokesonly=False): TOOLS = 'save,pan,box_zoom,wheel_zoom,reset,tap,hover,resize,crosshair' diff --git a/rowers/templates/list_workouts.html b/rowers/templates/list_workouts.html index 23ac50ca..d2158284 100644 --- a/rowers/templates/list_workouts.html +++ b/rowers/templates/list_workouts.html @@ -135,6 +135,35 @@ {% endif %} +
+ + + + {{ interactiveplot |safe }} + + + + {{ the_div |safe }} +
{% if announcements %}

What's New?

diff --git a/rowers/templates/teamstats.html b/rowers/templates/teamstats.html index 312097f4..83de0907 100644 --- a/rowers/templates/teamstats.html +++ b/rowers/templates/teamstats.html @@ -11,7 +11,7 @@

Links to the cumulative statistics pages for your team's members

- +
{% for u in theusers %} @@ -21,6 +21,8 @@ + + {% endfor %} diff --git a/rowers/views.py b/rowers/views.py index 7a3d0992..5f855ddb 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -4014,6 +4014,9 @@ def workouts_view(request,message='',successmessage='', enddate = startdate startdate = s + # start date for the small graph + activity_startdate = enddate-datetime.timedelta(days=15) + if teamid: try: theteam = Team.objects.get(id=teamid) @@ -4024,10 +4027,16 @@ def workouts_view(request,message='',successmessage='', workouts = Workout.objects.filter(team=theteam, startdatetime__gte=startdate, startdatetime__lte=enddate).order_by("-date", "-starttime") + g_workouts = Workout.objects.filter(team=theteam, + startdatetime__gte=activity_startdate, + startdatetime__lte=enddate).order_by("-date", "-starttime") elif theteam.viewing == 'coachonly': workouts = Workout.objects.filter(team=theteam,user=r, startdatetime__gte=startdate, startdatetime__lte=enddate).order_by("-date","-starttime") + g_workouts = Workout.objects.filter(team=theteam,user=r, + startdatetime__gte=activity_startdate, + enddatetime__lte=enddate).order_by("-date","-starttime") else: @@ -4035,6 +4044,9 @@ def workouts_view(request,message='',successmessage='', workouts = Workout.objects.filter(user=r, startdatetime__gte=startdate, startdatetime__lte=enddate).order_by("-date", "-starttime") + g_workouts = Workout.objects.filter(user=r, + startdatetime__gte=activity_startdate, + startdatetime__lte=enddate).order_by("-date","-starttime") query = request.GET.get('q') if query: @@ -4064,6 +4076,10 @@ def workouts_view(request,message='',successmessage='', "-id" ) + script,div = interactive_activitychart(g_workouts, + activity_startdate, + enddate) + messages.info(request,successmessage) messages.error(request,message) @@ -4075,6 +4091,8 @@ def workouts_view(request,message='',successmessage='', 'announcements':announcements[0:4], 'team':theteam, 'teams':get_my_teams(request.user), + 'interactiveplot':script, + 'the_div':div, }) @@ -7421,6 +7439,12 @@ def team_workout_upload_view(request,message="", url = reverse(team_workout_upload_view) response = HttpResponseRedirect(url) return response + elif id == -1: + message = 'The zip archive will be processed in the background. The files in the archive will only be uploaded without the extra actions. You will receive email when the workouts are ready.' + messages.info(request,message) + url = reverse(team_workout_upload_view) + response = HttpResponseRedirect(url) + return response else: successmessage = "The workout was added to the user's account" diff --git a/rowsandall_app/settings.py b/rowsandall_app/settings.py index 0a81b4fe..b90e576a 100644 --- a/rowsandall_app/settings.py +++ b/rowsandall_app/settings.py @@ -139,7 +139,7 @@ DATABASES = { 'PASSWORD': CFG['db_password'], 'HOST': CFG['db_host'], 'PORT': CFG['db_port'], - }, + }, 'slave': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), diff --git a/rowsandall_app/settings_dev.py b/rowsandall_app/settings_dev.py index 69cbd074..f851d022 100644 --- a/rowsandall_app/settings_dev.py +++ b/rowsandall_app/settings_dev.py @@ -15,7 +15,7 @@ DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - 'HOST': 'localhost' + 'HOST': 'localhost', }, # 'TEST': { # 'CHARSET': 'utf8',
Power Histogram Stats Box ChartOTW Ranking PiecesTrend Flex