Add a sleep totals graph.

This commit is contained in:
Christopher Charbonneau Wells 2017-09-13 11:53:32 -04:00
parent e77c2a5639
commit 83aaab5bde
5 changed files with 67 additions and 7 deletions

View File

@ -23,6 +23,7 @@
{% if perms.core.view_sleep %}
<h6 class="dropdown-header"><i class="fa fa-bed" aria-hidden="true"></i> Sleep</h6>
<a class="dropdown-item" href="{% url 'reports:report-sleep-pattern-child' object.slug %}">Sleep Pattern</a>
<a class="dropdown-item" href="{% url 'reports:report-sleep-totals-child' object.slug %}">Sleep Totals</a>
{% endif %}
</div>
</div>

View File

@ -58,19 +58,48 @@ def diaperchange_types(child):
return split_graph_output(output)
def sleep_amount(child):
def sleep_totals(child):
"""Create a graph showing total time sleeping for each day."""
instances = Sleep.objects.filter(child=child).order_by('start')
totals = {}
for instance in instances:
start_time = timezone.localtime(instance.start)
start_date = start_time.date().isoformat()
start = timezone.localtime(instance.start)
end = timezone.localtime(instance.end)
if start.date() not in totals.keys():
totals[start.date()] = timezone.timedelta(seconds=0)
if end.date() not in totals.keys():
totals[end.date()] = timezone.timedelta(seconds=0)
if start_date not in totals.keys():
totals[start_date] = timezone.timedelta()
# Account for dates crossing midnight.
if start.date() != end.date():
totals[start.date()] += end.replace(
day=start.day, hour=23, minute=59, second=59) - start
totals[end.date()] += end - start.replace(
day=end.day, hour=0, minute=0, second=0)
else:
totals[start.date()] += instance.duration
totals[start_date] += instance.duration
trace = go.Bar(
name='Total sleep',
x=list(totals.keys()),
y=[td.seconds/3600 for td in totals.values()],
hoverinfo='text',
text=[duration_string(td) for td in totals.values()]
)
layout_args = default_graph_layout_options()
layout_args['barmode'] = 'stack'
layout_args['title'] = '<b>Sleep Totals</b><br>{}'.format(child)
layout_args['xaxis']['title'] = 'Date'
layout_args['yaxis']['title'] = 'Hours of sleep'
fig = go.Figure({
'data': [trace],
'layout': go.Layout(**layout_args)
})
output = plotly.plot(fig, output_type='div', include_plotlyjs=False)
return split_graph_output(output)
def sleep_pattern(child):

View File

@ -0,0 +1,8 @@
{% extends 'reports/report_base.html' %}
{% block title %}Sleep Totals - {{ object }}{% endblock %}
{% block javascript %}
{{ block.super }}
{{ javascript|safe }}
{% endblock %}

View File

@ -9,7 +9,11 @@ urlpatterns = [
url(r'^reports/changes/types/(?P<slug>[^/.]+)/$',
views.DiaperChangeTypesChildReport.as_view(),
name='report-diaperchange-types-child'),
url(r'^reports/sleep/pattern/(?P<slug>[^/.]+)$',
views.SleepPatternChildReport.as_view(),
name='report-sleep-pattern-child'),
url(r'^reports/sleep/totals/(?P<slug>[^/.]+)$',
views.SleepTotalsChildReport.as_view(),
name='report-sleep-totals-child'),
]

View File

@ -6,7 +6,7 @@ from django.views.generic.detail import DetailView
from core.models import Child
from .graphs import diaperchange_types, sleep_pattern
from .graphs import diaperchange_types, sleep_pattern, sleep_totals
class DiaperChangeTypesChildReport(PermissionRequiredMixin, DetailView):
@ -38,3 +38,21 @@ class SleepPatternChildReport(PermissionRequiredMixin, DetailView):
child = context['object']
context['html'], context['javascript'] = sleep_pattern(child)
return context
class SleepTotalsChildReport(PermissionRequiredMixin, DetailView):
"""Graph of total sleep by day."""
model = Child
permission_required = ('core.view_child',)
template_name = 'reports/sleep_totals.html'
def __init__(self):
super(SleepTotalsChildReport, self).__init__()
self.html = ''
self.javascript = ''
def get_context_data(self, **kwargs):
context = super(SleepTotalsChildReport, self).get_context_data(**kwargs)
child = context['object']
context['html'], context['javascript'] = sleep_totals(child)
return context