mirror of https://github.com/snachodog/mybuddy.git
Display a message when there is not enough data to generate a report.
This commit is contained in:
parent
6ce6599b39
commit
c305d8038b
|
@ -17,10 +17,9 @@ from core.utils import duration_string, duration_parts
|
||||||
from . import utils
|
from . import utils
|
||||||
|
|
||||||
|
|
||||||
def diaperchange_lifetimes(child):
|
def diaperchange_lifetimes(changes):
|
||||||
"""Create a graph showing how long diapers last (time between changes)."""
|
"""Create a graph showing how long diapers last (time between changes).
|
||||||
changes = DiaperChange.objects.filter(child=child).order_by('time')
|
"""
|
||||||
|
|
||||||
durations = []
|
durations = []
|
||||||
last_change = changes.first()
|
last_change = changes.first()
|
||||||
for change in changes[1:]:
|
for change in changes[1:]:
|
||||||
|
@ -39,7 +38,7 @@ def diaperchange_lifetimes(child):
|
||||||
|
|
||||||
layout_args = utils.default_graph_layout_options()
|
layout_args = utils.default_graph_layout_options()
|
||||||
layout_args['height'] = 800
|
layout_args['height'] = 800
|
||||||
layout_args['title'] = '<b>Diaper Lifetimes</b><br>{}'.format(child)
|
layout_args['title'] = '<b>Diaper Lifetimes</b>'
|
||||||
layout_args['yaxis']['title'] = 'Time between changes (hours)'
|
layout_args['yaxis']['title'] = 'Time between changes (hours)'
|
||||||
layout_args['yaxis']['zeroline'] = False
|
layout_args['yaxis']['zeroline'] = False
|
||||||
layout_args['yaxis']['dtick'] = 1
|
layout_args['yaxis']['dtick'] = 1
|
||||||
|
@ -52,10 +51,10 @@ def diaperchange_lifetimes(child):
|
||||||
return utils.split_graph_output(output)
|
return utils.split_graph_output(output)
|
||||||
|
|
||||||
|
|
||||||
def diaperchange_types(child):
|
def diaperchange_types(changes):
|
||||||
"""Create a graph showing types of totals for diaper changes."""
|
"""Create a graph showing types of totals for diaper changes.
|
||||||
changes = DiaperChange.objects.filter(child=child) \
|
"""
|
||||||
.annotate(date=TruncDate('time')) \
|
changes = changes.annotate(date=TruncDate('time'))\
|
||||||
.values('date') \
|
.values('date') \
|
||||||
.annotate(wet_count=Count(Case(When(wet=True, then=1)))) \
|
.annotate(wet_count=Count(Case(When(wet=True, then=1)))) \
|
||||||
.annotate(solid_count=Count(Case(When(solid=True, then=1)))) \
|
.annotate(solid_count=Count(Case(When(solid=True, then=1)))) \
|
||||||
|
@ -82,7 +81,7 @@ def diaperchange_types(child):
|
||||||
|
|
||||||
layout_args = utils.default_graph_layout_options()
|
layout_args = utils.default_graph_layout_options()
|
||||||
layout_args['barmode'] = 'stack'
|
layout_args['barmode'] = 'stack'
|
||||||
layout_args['title'] = '<b>Diaper Change Types</b><br>{}'.format(child)
|
layout_args['title'] = '<b>Diaper Change Types</b>'
|
||||||
layout_args['xaxis']['title'] = 'Date'
|
layout_args['xaxis']['title'] = 'Date'
|
||||||
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
||||||
layout_args['yaxis']['title'] = 'Number of changes'
|
layout_args['yaxis']['title'] = 'Number of changes'
|
||||||
|
@ -95,10 +94,9 @@ def diaperchange_types(child):
|
||||||
return utils.split_graph_output(output)
|
return utils.split_graph_output(output)
|
||||||
|
|
||||||
|
|
||||||
def sleep_totals(child):
|
def sleep_totals(instances):
|
||||||
"""Create a graph showing total time sleeping for each day."""
|
"""Create a graph showing total time sleeping for each day.
|
||||||
instances = Sleep.objects.filter(child=child).order_by('start')
|
"""
|
||||||
|
|
||||||
totals = {}
|
totals = {}
|
||||||
for instance in instances:
|
for instance in instances:
|
||||||
start = timezone.localtime(instance.start)
|
start = timezone.localtime(instance.start)
|
||||||
|
@ -130,7 +128,7 @@ def sleep_totals(child):
|
||||||
|
|
||||||
layout_args = utils.default_graph_layout_options()
|
layout_args = utils.default_graph_layout_options()
|
||||||
layout_args['barmode'] = 'stack'
|
layout_args['barmode'] = 'stack'
|
||||||
layout_args['title'] = '<b>Sleep Totals</b><br>{}'.format(child)
|
layout_args['title'] = '<b>Sleep Totals</b>'
|
||||||
layout_args['xaxis']['title'] = 'Date'
|
layout_args['xaxis']['title'] = 'Date'
|
||||||
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
layout_args['xaxis']['rangeselector'] = utils.rangeselector_date()
|
||||||
layout_args['yaxis']['title'] = 'Hours of sleep'
|
layout_args['yaxis']['title'] = 'Hours of sleep'
|
||||||
|
@ -145,15 +143,16 @@ def sleep_totals(child):
|
||||||
|
|
||||||
def _duration_string_short(duration):
|
def _duration_string_short(duration):
|
||||||
"""Format a "short" duration string without seconds precision. This is
|
"""Format a "short" duration string without seconds precision. This is
|
||||||
intended to fit better in smaller spaces on a graph."""
|
intended to fit better in smaller spaces on a graph.
|
||||||
|
"""
|
||||||
h, m, s = duration_parts(duration)
|
h, m, s = duration_parts(duration)
|
||||||
return '{}h{}m'.format(h, m)
|
return '{}h{}m'.format(h, m)
|
||||||
|
|
||||||
|
|
||||||
def sleep_pattern(child):
|
def sleep_pattern(instances):
|
||||||
"""Create a graph showing blocked out periods of sleep during each day."""
|
"""Create a graph showing blocked out periods of sleep during each day.
|
||||||
|
"""
|
||||||
# TODO: Simplify this using the bar charts "base" property.
|
# TODO: Simplify this using the bar charts "base" property.
|
||||||
instances = Sleep.objects.filter(child=child).order_by('start')
|
|
||||||
y_df = pd.DataFrame()
|
y_df = pd.DataFrame()
|
||||||
text_df = pd.DataFrame()
|
text_df = pd.DataFrame()
|
||||||
last_end_time = None
|
last_end_time = None
|
||||||
|
@ -252,7 +251,7 @@ def sleep_pattern(child):
|
||||||
|
|
||||||
layout_args['barmode'] = 'stack'
|
layout_args['barmode'] = 'stack'
|
||||||
layout_args['hovermode'] = 'closest'
|
layout_args['hovermode'] = 'closest'
|
||||||
layout_args['title'] = '<b>Sleep Pattern</b><br>{}'.format(child)
|
layout_args['title'] = '<b>Sleep Pattern</b>'
|
||||||
layout_args['height'] = 800
|
layout_args['height'] = 800
|
||||||
|
|
||||||
layout_args['xaxis']['title'] = 'Date'
|
layout_args['xaxis']['title'] = 'Date'
|
||||||
|
@ -282,7 +281,8 @@ def sleep_pattern(child):
|
||||||
|
|
||||||
def _add_sleep_entry(y_df, text_df, index, column, duration, text=''):
|
def _add_sleep_entry(y_df, text_df, index, column, duration, text=''):
|
||||||
"""Create a duration and text description entry in a DataFrame and return
|
"""Create a duration and text description entry in a DataFrame and return
|
||||||
the next index on success."""
|
the next index on success.
|
||||||
|
"""
|
||||||
if column not in y_df:
|
if column not in y_df:
|
||||||
y_df.assign(**{column: 0 in range(0, len(y_df.index))})
|
y_df.assign(**{column: 0 in range(0, len(y_df.index))})
|
||||||
text_df.assign(**{column: 0 in range(0, len(text_df.index))})
|
text_df.assign(**{column: 0 in range(0, len(text_df.index))})
|
||||||
|
@ -294,7 +294,8 @@ def _add_sleep_entry(y_df, text_df, index, column, duration, text=''):
|
||||||
|
|
||||||
|
|
||||||
def timeline(child, date):
|
def timeline(child, date):
|
||||||
"""Create a time-sorted dictionary for all events for a child."""
|
"""Create a time-sorted dictionary for all events for a child.
|
||||||
|
"""
|
||||||
min_date = date
|
min_date = date
|
||||||
max_date = date.replace(hour=23, minute=59, second=59)
|
max_date = date.replace(hour=23, minute=59, second=59)
|
||||||
events = []
|
events = []
|
||||||
|
|
|
@ -11,7 +11,15 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
|
{% if html %}
|
||||||
{{ html|safe }}
|
{{ html|safe }}
|
||||||
|
{% else %}
|
||||||
|
<div class="jumbotron text-center">
|
||||||
|
<i class="icon icon-sad" aria-hidden="true"></i>
|
||||||
|
There is no enough data to generate this report.
|
||||||
|
<i class="icon icon-sad" aria-hidden="true"></i>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,15 @@ from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||||
from django.views.generic.detail import DetailView
|
from django.views.generic.detail import DetailView
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from core.models import Child
|
from core.models import Child, DiaperChange, Sleep
|
||||||
|
|
||||||
from .graphs import (diaperchange_types, diaperchange_lifetimes, sleep_pattern,
|
from .graphs import (diaperchange_types, diaperchange_lifetimes, sleep_pattern,
|
||||||
sleep_totals, timeline)
|
sleep_totals, timeline)
|
||||||
|
|
||||||
|
|
||||||
class DiaperChangeLifetimesChildReport(PermissionRequiredMixin, DetailView):
|
class DiaperChangeLifetimesChildReport(PermissionRequiredMixin, DetailView):
|
||||||
"""Graph of diaper changes by day and type."""
|
"""Graph of diaper changes by day and type.
|
||||||
|
"""
|
||||||
model = Child
|
model = Child
|
||||||
permission_required = ('core.view_child',)
|
permission_required = ('core.view_child',)
|
||||||
template_name = 'reports/diaperchange_lifetimes.html'
|
template_name = 'reports/diaperchange_lifetimes.html'
|
||||||
|
@ -21,12 +22,16 @@ class DiaperChangeLifetimesChildReport(PermissionRequiredMixin, DetailView):
|
||||||
context = super(
|
context = super(
|
||||||
DiaperChangeLifetimesChildReport, self).get_context_data(**kwargs)
|
DiaperChangeLifetimesChildReport, self).get_context_data(**kwargs)
|
||||||
child = context['object']
|
child = context['object']
|
||||||
context['html'], context['javascript'] = diaperchange_lifetimes(child)
|
changes = DiaperChange.objects.filter(child=child)
|
||||||
|
if changes and changes.count() > 1:
|
||||||
|
context['html'], context['javascript'] = diaperchange_lifetimes(
|
||||||
|
changes)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class DiaperChangeTypesChildReport(PermissionRequiredMixin, DetailView):
|
class DiaperChangeTypesChildReport(PermissionRequiredMixin, DetailView):
|
||||||
"""Graph of diaper changes by day and type."""
|
"""Graph of diaper changes by day and type.
|
||||||
|
"""
|
||||||
model = Child
|
model = Child
|
||||||
permission_required = ('core.view_child',)
|
permission_required = ('core.view_child',)
|
||||||
template_name = 'reports/diaperchange_types.html'
|
template_name = 'reports/diaperchange_types.html'
|
||||||
|
@ -35,12 +40,16 @@ class DiaperChangeTypesChildReport(PermissionRequiredMixin, DetailView):
|
||||||
context = super(DiaperChangeTypesChildReport, self).get_context_data(
|
context = super(DiaperChangeTypesChildReport, self).get_context_data(
|
||||||
**kwargs)
|
**kwargs)
|
||||||
child = context['object']
|
child = context['object']
|
||||||
context['html'], context['javascript'] = diaperchange_types(child)
|
changes = DiaperChange.objects.filter(child=child)
|
||||||
|
if changes:
|
||||||
|
context['html'], context['javascript'] = diaperchange_types(
|
||||||
|
changes)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class SleepPatternChildReport(PermissionRequiredMixin, DetailView):
|
class SleepPatternChildReport(PermissionRequiredMixin, DetailView):
|
||||||
"""Graph of sleep pattern comparing sleep to wake times by day."""
|
"""Graph of sleep pattern comparing sleep to wake times by day.
|
||||||
|
"""
|
||||||
model = Child
|
model = Child
|
||||||
permission_required = ('core.view_child',)
|
permission_required = ('core.view_child',)
|
||||||
template_name = 'reports/sleep_pattern.html'
|
template_name = 'reports/sleep_pattern.html'
|
||||||
|
@ -54,12 +63,15 @@ class SleepPatternChildReport(PermissionRequiredMixin, DetailView):
|
||||||
context = super(SleepPatternChildReport, self).get_context_data(
|
context = super(SleepPatternChildReport, self).get_context_data(
|
||||||
**kwargs)
|
**kwargs)
|
||||||
child = context['object']
|
child = context['object']
|
||||||
context['html'], context['javascript'] = sleep_pattern(child)
|
instances = Sleep.objects.filter(child=child).order_by('start')
|
||||||
|
if instances:
|
||||||
|
context['html'], context['javascript'] = sleep_pattern(instances)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
class SleepTotalsChildReport(PermissionRequiredMixin, DetailView):
|
class SleepTotalsChildReport(PermissionRequiredMixin, DetailView):
|
||||||
"""Graph of total sleep by day."""
|
"""Graph of total sleep by day.
|
||||||
|
"""
|
||||||
model = Child
|
model = Child
|
||||||
permission_required = ('core.view_child',)
|
permission_required = ('core.view_child',)
|
||||||
template_name = 'reports/sleep_totals.html'
|
template_name = 'reports/sleep_totals.html'
|
||||||
|
@ -73,7 +85,9 @@ class SleepTotalsChildReport(PermissionRequiredMixin, DetailView):
|
||||||
context = super(SleepTotalsChildReport, self).get_context_data(
|
context = super(SleepTotalsChildReport, self).get_context_data(
|
||||||
**kwargs)
|
**kwargs)
|
||||||
child = context['object']
|
child = context['object']
|
||||||
context['html'], context['javascript'] = sleep_totals(child)
|
instances = Sleep.objects.filter(child=child).order_by('start')
|
||||||
|
if instances:
|
||||||
|
context['html'], context['javascript'] = sleep_totals(instances)
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue