mirror of https://github.com/snachodog/mybuddy.git
Add a sleep totals graph.
This commit is contained in:
parent
e77c2a5639
commit
83aaab5bde
|
@ -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>
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{% extends 'reports/report_base.html' %}
|
||||
|
||||
{% block title %}Sleep Totals - {{ object }}{% endblock %}
|
||||
|
||||
{% block javascript %}
|
||||
{{ block.super }}
|
||||
{{ javascript|safe }}
|
||||
{% endblock %}
|
|
@ -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'),
|
||||
]
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue