diff --git a/reports/graphs.py b/reports/graphs.py index d72c052a..847ecf59 100644 --- a/reports/graphs.py +++ b/reports/graphs.py @@ -105,6 +105,7 @@ def sleep_totals(child): def sleep_pattern(child): """Create a graph showing blocked out periods of sleep during each day.""" + # TODO: Simplify this using the bar charts "base" property. instances = Sleep.objects.filter(child=child).order_by('start') y_df = pd.DataFrame() text_df = pd.DataFrame() diff --git a/reports/static_src/scss/timeline.scss b/reports/static_src/scss/timeline.scss new file mode 100644 index 00000000..54c967b1 --- /dev/null +++ b/reports/static_src/scss/timeline.scss @@ -0,0 +1,157 @@ +/* Adapted for Bootstrap 4 from https://www.bootply.com/SzXin8KDZJ. */ +.timeline { + list-style: none; + padding: 10px 0 10px; + position: relative; + + &:before { + top: 0; + bottom: 0; + position: absolute; + content: " "; + width: 3px; + background-color: #eeeeee; + left: 50%; + margin-left: -1.5px; + + } + + li { + margin-bottom: 10px; + position: relative; + + &:before { + content: " "; + display: table; + } + + &:after { + content: " "; + display: table; + clear: both; + } + + .card { + width: 47%; + float: left; + border: 1px solid #d4d4d4; + border-radius: 2px; + padding: 10px; + position: relative; + -webkit-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175); + box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175); + + &:before { + position: absolute; + top: 26px; + right: -15px; + display: inline-block; + border-top: 15px solid transparent; + border-left: 15px solid #ccc; + border-right: 0 solid #ccc; + border-bottom: 15px solid transparent; + content: " "; + } + + &:after { + position: absolute; + top: 27px; + right: -14px; + display: inline-block; + border-top: 14px solid transparent; + border-left: 14px solid #fff; + border-right: 0 solid #fff; + border-bottom: 14px solid transparent; + content: " "; + } + } + + &.timeline-inverted { + .card { + float: right; + + &:before { + border-left-width: 0; + border-right-width: 15px; + left: -15px; + right: auto; + } + + &:after { + border-left-width: 0; + border-right-width: 14px; + left: -14px; + right: auto; + } + } + } + + .timeline-badge { + color: #fff; + width: 50px; + height: 50px; + line-height: 50px; + font-size: 1.4em; + text-align: center; + position: absolute; + top: 16px; + left: 50%; + margin-left: -25px; + background-color: #999999; + z-index: 100; + border-radius: 50%; + } + + .timeline-badge.arrow { + color: #fff; + width: 50px; + height: 50px; + line-height: 50px; + font-size: 1.4em; + text-align: center; + position: absolute; + top: 26px; + left: 50%; + margin-left: -25px; + background-color: #999999; + z-index: 100; + border-radius: 50%; + } + } +} + +@media (max-width: 767px) { + ul.timeline:before { + left: 40px; + } + + ul.timeline > li > .card { + width: calc(100% - 90px); + width: -moz-calc(100% - 90px); + width: -webkit-calc(100% - 90px); + } + + ul.timeline > li > .timeline-badge { + left: 15px; + margin-left: 0; + top: 16px; + } + + ul.timeline > li > .card { + float: right; + } + + ul.timeline > li > .card:before { + border-left-width: 0; + border-right-width: 15px; + left: -15px; + right: auto; + } + + ul.timeline > li > .card:after { + border-left-width: 0; + border-right-width: 14px; + left: -14px; + right: auto; + } +} \ No newline at end of file diff --git a/reports/templates/reports/timeline.html b/reports/templates/reports/timeline.html new file mode 100644 index 00000000..2cb09d3b --- /dev/null +++ b/reports/templates/reports/timeline.html @@ -0,0 +1,67 @@ +{% extends 'babyblotter/page.html' %} +{% load static %} + +{% block title %}Timeline - {{ object }}{% endblock %} + +{% block content %} +

Timeline

+

{{ object }}

+ +{% endblock %} \ No newline at end of file diff --git a/reports/urls.py b/reports/urls.py index 59063985..1491ed28 100644 --- a/reports/urls.py +++ b/reports/urls.py @@ -16,4 +16,8 @@ urlpatterns = [ url(r'^reports/sleep/totals/(?P[^/.]+)$', views.SleepTotalsChildReport.as_view(), name='report-sleep-totals-child'), + + url(r'^reports/timeline/(?P[^/.]+)$', + views.TimelineChildReport.as_view(), + name='report-timeline-child'), ] diff --git a/reports/views.py b/reports/views.py index 379a2959..d93e7fd6 100644 --- a/reports/views.py +++ b/reports/views.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals from django.contrib.auth.mixins import PermissionRequiredMixin from django.views.generic.detail import DetailView +from django.utils import timezone from core.models import Child @@ -16,7 +17,8 @@ class DiaperChangeTypesChildReport(PermissionRequiredMixin, DetailView): template_name = 'reports/diaperchange_types.html' def get_context_data(self, **kwargs): - context = super(DiaperChangeTypesChildReport, self).get_context_data(**kwargs) + context = super(DiaperChangeTypesChildReport, self).get_context_data( + **kwargs) child = context['object'] context['html'], context['javascript'] = diaperchange_types(child) return context @@ -34,7 +36,8 @@ class SleepPatternChildReport(PermissionRequiredMixin, DetailView): self.javascript = '' def get_context_data(self, **kwargs): - context = super(SleepPatternChildReport, self).get_context_data(**kwargs) + context = super(SleepPatternChildReport, self).get_context_data( + **kwargs) child = context['object'] context['html'], context['javascript'] = sleep_pattern(child) return context @@ -52,7 +55,21 @@ class SleepTotalsChildReport(PermissionRequiredMixin, DetailView): self.javascript = '' def get_context_data(self, **kwargs): - context = super(SleepTotalsChildReport, self).get_context_data(**kwargs) + context = super(SleepTotalsChildReport, self).get_context_data( + **kwargs) child = context['object'] context['html'], context['javascript'] = sleep_totals(child) return context + + +class TimelineChildReport(PermissionRequiredMixin, DetailView): + """Graph of total sleep by day.""" + model = Child + permission_required = ('core.view_child',) + template_name = 'reports/timeline.html' + + def get_context_data(self, **kwargs): + context = super(TimelineChildReport, self).get_context_data(**kwargs) + date = kwargs.get('date', timezone.now().date()) + print(date) + return context