Private
Public Access
1
0

different pie chart for types

This commit is contained in:
Sander Roosendaal
2020-05-09 15:50:52 +02:00
parent 95739145a9
commit 24750be04e
4 changed files with 52 additions and 62 deletions

View File

@@ -26,6 +26,7 @@ from bokeh.models import CustomJS,Slider, TextInput,BoxAnnotation
from bokeh.resources import CDN,INLINE from bokeh.resources import CDN,INLINE
from bokeh.embed import components from bokeh.embed import components
from bokeh.layouts import layout,widgetbox from bokeh.layouts import layout,widgetbox
from bokeh.palettes import Category20c
from bokeh.layouts import row as layoutrow from bokeh.layouts import row as layoutrow
from bokeh.layouts import column as layoutcolumn from bokeh.layouts import column as layoutcolumn
from bokeh.models import LinearAxis,LogAxis,Range1d,DatetimeTickFormatter,HoverTool from bokeh.models import LinearAxis,LogAxis,Range1d,DatetimeTickFormatter,HoverTool
@@ -37,6 +38,7 @@ from bokeh.models import (
ResetTool, TapTool,CrosshairTool,BoxZoomTool, ResetTool, TapTool,CrosshairTool,BoxZoomTool,
Span, Label Span, Label
) )
from bokeh.transform import cumsum
from bokeh.models.glyphs import ImageURL from bokeh.models.glyphs import ImageURL
from bokeh.models import OpenURL, TapTool from bokeh.models import OpenURL, TapTool
from rowers.opaque import encoder from rowers.opaque import encoder
@@ -251,65 +253,48 @@ def interactive_hr_piechart(df,rower,title):
return components(z) return components(z)
def pretty_timedelta(secs):
hours, remainder = divmod(secs,3600)
minutes, seconds = divmod(remainder,60)
return '{}:{:02}:{:02}'.format(int(hours),int(minutes),int(seconds))
def interactive_workouttype_piechart(workouts): def interactive_workouttype_piechart(workouts):
if len(workouts) == 0: if len(workouts) == 0:
return "","Not enough workouts to make a chart" return "","Not enough workouts to make a chart"
datadict = {} datadict = {}
labels = []
types = []
for w in workouts: for w in workouts:
try: try:
datadict[w.workouttype] += 3600*w.duration.hour+60*w.duration.minute+w.duration.second label = mytypes.workouttypes_ordered[w.workouttype]
except KeyError: except KeyError:
datadict[w.workouttype] = 3600*w.duration.hour+60*w.duration.minute+w.duration.second labels = w.workouttype
types += [w.workouttype]
try: try:
labels += [mytypes.workouttypes_ordered[w.workouttype]] datadict[label] += 60*(60*w.duration.hour+w.duration.minute)+w.duration.second
except KeyError: except KeyError:
labels += [w.workouttype] datadict[label] = 60*(60*w.duration.hour+w.duration.minute)+w.duration.second
total = 0 data = pd.Series(datadict).reset_index(name='value').rename(columns={'index':'type'})
source_starts = [0] data['angle'] = data['value']/data['value'].sum() * 2*pi
source_ends = [] data['color'] = Category20c[len(datadict)]
for type in types: data['totaltime'] = pd.Series([pretty_timedelta(v) for v in data['value']])
total += datadict[type]
source_starts.append(total)
source_ends.append(total)
source_ends.append(total) p = figure(plot_height=350, title="Types", toolbar_location=None,
tools="hover,save", tooltips="@type: @totaltime", x_range=(-0.5, 1.0))
source_starts = pd.Series(source_starts)*2*pi/total p.wedge(x=0, y=1, radius=0.4,
source_ends = pd.Series(source_ends)*2*pi/total start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
line_color="white", fill_color='color', source=data,legend='type', )
size = 350 p.axis.axis_label=None
TOOLS = 'save' p.axis.visible=False
p.grid.grid_line_color = None
p.outline_line_color = None
p.toolbar_location = 'right'
z = figure(title="Workout Types", x_range=(-1,1), y_range=(-1,1), width=size, height=size, return components(p)
tools=TOOLS,
)
colors = palette
print(source_ends)
print(labels)
for start, end , legend, color in zip(source_starts, source_ends, labels,
colors[0:len(source_starts)]):
print(start,end,color,legend)
z.wedge(x=0, y=0, radius=1, start_angle=start, end_angle=end, color=color, legend=legend)
z.toolbar_location = 'right'
z.legend.location = 'top_right'
#z.legend.visible = False
z.axis.visible = False
z.xgrid.grid_line_color = None
z.ygrid.grid_line_color = None
z.outline_line_color = None
return components(z)

View File

@@ -47,6 +47,8 @@
<input type="submit" value="Submit"/> <input type="submit" value="Submit"/>
</form> </form>
</p> </p>
</li>
<li class="grid_2">
<h2>All workouts</h2> <h2>All workouts</h2>
<p> <p>
@@ -56,7 +58,7 @@
<td>Total Distance</td><td>{{ totalsdict|lookup:"distance"}} meters</td> <td>Total Distance</td><td>{{ totalsdict|lookup:"distance"}} meters</td>
</tr> </tr>
<tr> <tr>
<td>Total Duration</td><td>{{ totalsdict|lookup:"duration"}} hours</td> <td>Total Duration</td><td>{{ totalsdict|lookup:"duration"}} </td>
</tr> </tr>
<tr> <tr>
<td>Number of workouts</td><td>{{ totalsdict|lookup:"nrworkouts"}}</td> <td>Number of workouts</td><td>{{ totalsdict|lookup:"nrworkouts"}}</td>
@@ -97,7 +99,7 @@
<td>Total Distance</td><td>{{ ddict|lookup:"distance"}} meters</td> <td>Total Distance</td><td>{{ ddict|lookup:"distance"}} meters</td>
</tr> </tr>
<tr> <tr>
<td>Total Duration</td><td>{{ ddict|lookup:"duration"}} hours</td> <td>Total Duration</td><td>{{ ddict|lookup:"duration"}} </td>
</tr> </tr>
<tr> <tr>
<td>Number of workouts</td><td>{{ ddict|lookup:"nrworkouts"}}</td> <td>Number of workouts</td><td>{{ ddict|lookup:"nrworkouts"}}</td>

View File

@@ -4699,7 +4699,7 @@ def history_view(request,userid=0):
tscript,tdiv = interactive_workouttype_piechart(g_workouts) tscript,tdiv = interactive_workouttype_piechart(g_workouts)
totalmeters,totalhours, totalminutes = get_totals(g_workouts) totalmeters,totalhours, totalminutes, totalseconds = get_totals(g_workouts)
totalminutes = "{totalminutes:02d}".format(totalminutes=totalminutes) totalminutes = "{totalminutes:02d}".format(totalminutes=totalminutes)
# meters, duration per workout type # meters, duration per workout type
@@ -4716,7 +4716,7 @@ def history_view(request,userid=0):
for wtype in wtypes: for wtype in wtypes:
a_workouts = g_workouts.filter(workouttype=wtype) a_workouts = g_workouts.filter(workouttype=wtype)
wmeters, whours, wminutes = get_totals(a_workouts) wmeters, whours, wminutes,wseconds = get_totals(a_workouts)
ddict = {} ddict = {}
ddict['id'] = wtype ddict['id'] = wtype
try: try:
@@ -4724,9 +4724,10 @@ def history_view(request,userid=0):
except KeyError: except KeyError:
ddict['wtype'] = wtype ddict['wtype'] = wtype
ddict['distance'] = wmeters ddict['distance'] = wmeters
ddict['duration'] = "{whours}:{wminutes:02d}".format( ddict['duration'] = "{whours}:{wminutes:02d}:{wseconds:02d}".format(
whours=whours, whours=whours,
wminutes=wminutes wminutes=wminutes,
wseconds=wseconds,
) )
ddict['nrworkouts'] = a_workouts.count() ddict['nrworkouts'] = a_workouts.count()
listofdicts.append(ddict) listofdicts.append(ddict)
@@ -4737,9 +4738,10 @@ def history_view(request,userid=0):
totaldiv = get_call() totaldiv = get_call()
totalsdict = {} totalsdict = {}
totalsdict['duration'] = "{totalhours}:{totalminutes}".format( totalsdict['duration'] = "{totalhours}:{totalminutes}:{totalseconds}".format(
totalhours=totalhours, totalhours=totalhours,
totalminutes=totalminutes totalminutes=totalminutes,
totalseconds=totalseconds
) )
totalsdict['distance'] = totalmeters totalsdict['distance'] = totalmeters
@@ -4836,7 +4838,7 @@ def history_view_data(request,userid=0):
df = dataprep.clean_df_stats(df,workstrokesonly=True, df = dataprep.clean_df_stats(df,workstrokesonly=True,
ignoreadvanced=True) ignoreadvanced=True)
totalmeters,totalhours, totalminutes = get_totals(g_workouts) totalmeters,totalhours, totalminutes,totalseconds = get_totals(g_workouts)
totalminutes = "{totalminutes:02d}".format(totalminutes=totalminutes) totalminutes = "{totalminutes:02d}".format(totalminutes=totalminutes)
@@ -4853,7 +4855,7 @@ def history_view_data(request,userid=0):
for wtype in wtypes: for wtype in wtypes:
a_workouts = g_workouts.filter(workouttype=wtype) a_workouts = g_workouts.filter(workouttype=wtype)
wmeters, whours, wminutes = get_totals(a_workouts) wmeters, whours, wminutes,wseconds = get_totals(a_workouts)
ddict = {} ddict = {}
try: try:
ddict['wtype'] = mytypes.workouttypes_ordered[wtype] ddict['wtype'] = mytypes.workouttypes_ordered[wtype]
@@ -4862,9 +4864,9 @@ def history_view_data(request,userid=0):
ddict['id'] = wtype ddict['id'] = wtype
ddict['distance'] = wmeters ddict['distance'] = wmeters
ddict['duration'] = "{whours}:{wminutes:02d}".format( ddict['duration'] = "{whours}:{wminutes:02d}:{wseconds:02d}".format(
whours=whours, whours=whours,
wminutes=wminutes wminutes=wminutes,wseconds=wseconds,
) )
ddf = getsmallrowdata_db(columns,ids=[w.id for w in a_workouts]) ddf = getsmallrowdata_db(columns,ids=[w.id for w in a_workouts])
try: try:

View File

@@ -260,16 +260,17 @@ from django_mailbox.models import Message,Mailbox,MessageAttachment
from rules.contrib.views import permission_required, objectgetter from rules.contrib.views import permission_required, objectgetter
def get_totals(workouts): def get_totals(workouts):
totalminutes = 0 totalseconds = 0
totalmeters = 0 totalmeters = 0
for w in workouts: for w in workouts:
totalmeters += w.distance totalmeters += w.distance
totalminutes += w.duration.hour*60+w.duration.minute totalseconds += 60*(w.duration.hour*60+w.duration.minute)+w.duration.second
totalhour, totalminutes = divmod(totalminutes,60) hours, remainder = divmod(totalseconds,3600)
minutes, seconds = divmod(remainder,60)
return totalmeters,totalhour, totalminutes return totalmeters,hours, minutes, seconds
# creating shareable views # creating shareable views
def allow_shares(view_func): def allow_shares(view_func):