mirror of https://github.com/snachodog/mybuddy.git
Add actual events to timeline (WIP).
This commit is contained in:
parent
bc7b9a97fa
commit
ab1b9ee7a8
|
@ -11,13 +11,14 @@ import pandas as pd
|
||||||
import plotly.offline as plotly
|
import plotly.offline as plotly
|
||||||
import plotly.graph_objs as go
|
import plotly.graph_objs as go
|
||||||
|
|
||||||
from core.models import DiaperChange, Sleep
|
from core.models import DiaperChange, Feeding, Sleep, TummyTime
|
||||||
from core.utils import duration_string, duration_string_short
|
from core.utils import duration_string, duration_string_short
|
||||||
|
|
||||||
from .utils import default_graph_layout_options, split_graph_output
|
from .utils import default_graph_layout_options, split_graph_output
|
||||||
|
|
||||||
|
|
||||||
def diaperchange_types(child):
|
def diaperchange_types(child):
|
||||||
|
"""Create a graph showing types of totals for diaper changes."""
|
||||||
changes = DiaperChange.objects.filter(child=child) \
|
changes = DiaperChange.objects.filter(child=child) \
|
||||||
.annotate(date=TruncDate('time')) \
|
.annotate(date=TruncDate('time')) \
|
||||||
.values('date') \
|
.values('date') \
|
||||||
|
@ -243,3 +244,61 @@ def _add_sleep_entry(y_df, text_df, index, column, duration, text=''):
|
||||||
y_df.set_value(index, column, duration)
|
y_df.set_value(index, column, duration)
|
||||||
text_df.set_value(index, column, text)
|
text_df.set_value(index, column, text)
|
||||||
return index + 1
|
return index + 1
|
||||||
|
|
||||||
|
|
||||||
|
def timeline(child, date):
|
||||||
|
"""Create a time-sorted dictionary for all events for a child."""
|
||||||
|
min_date = date
|
||||||
|
max_date = date.replace(hour=23, minute=59, second=59)
|
||||||
|
events = []
|
||||||
|
instances = DiaperChange.objects.filter(child=child).filter(
|
||||||
|
time__range=(min_date, max_date)).order_by('-time')
|
||||||
|
for instance in instances:
|
||||||
|
events.append({
|
||||||
|
'time': timezone.localtime(instance.time),
|
||||||
|
'event': '{} had a diaper change.'.format(child.first_name),
|
||||||
|
'model_name': instance.model_name
|
||||||
|
})
|
||||||
|
instances = Feeding.objects.filter(child=child).filter(
|
||||||
|
start__range=(min_date, max_date)).order_by('-start')
|
||||||
|
for instance in instances:
|
||||||
|
events.append({
|
||||||
|
'time': timezone.localtime(instance.start),
|
||||||
|
'event': '{} started feeding.'.format(instance.child.first_name),
|
||||||
|
'model_name': instance.model_name
|
||||||
|
})
|
||||||
|
events.append({
|
||||||
|
'time': timezone.localtime(instance.end),
|
||||||
|
'event': '{} finished feeding.'.format(instance.child.first_name),
|
||||||
|
'model_name': instance.model_name
|
||||||
|
})
|
||||||
|
instances = Sleep.objects.filter(child=child).filter(
|
||||||
|
start__range=(min_date, max_date)).order_by('-start')
|
||||||
|
for instance in instances:
|
||||||
|
events.append({
|
||||||
|
'time': timezone.localtime(instance.start),
|
||||||
|
'event': '{} fell asleep.'.format(instance.child.first_name),
|
||||||
|
'model_name': instance.model_name
|
||||||
|
})
|
||||||
|
events.append({
|
||||||
|
'time': timezone.localtime(instance.end),
|
||||||
|
'event': '{} woke up.'.format(instance.child.first_name),
|
||||||
|
'model_name': instance.model_name
|
||||||
|
})
|
||||||
|
instances = TummyTime.objects.filter(child=child).filter(
|
||||||
|
start__range=(min_date, max_date)).order_by('-start')
|
||||||
|
for instance in instances:
|
||||||
|
events.append({
|
||||||
|
'time': timezone.localtime(instance.start),
|
||||||
|
'event': '{} started tummy time!'.format(
|
||||||
|
instance.child.first_name),
|
||||||
|
'model_name': instance.model_name
|
||||||
|
})
|
||||||
|
events.append({
|
||||||
|
'time': timezone.localtime(instance.end),
|
||||||
|
'event': '{} finished tummy time.'.format(
|
||||||
|
instance.child.first_name),
|
||||||
|
'model_name': instance.model_name
|
||||||
|
})
|
||||||
|
events.sort(key=lambda x: x['time'], reverse=True)
|
||||||
|
return events
|
||||||
|
|
|
@ -34,11 +34,7 @@
|
||||||
.card {
|
.card {
|
||||||
width: 47%;
|
width: 47%;
|
||||||
float: left;
|
float: left;
|
||||||
border: 1px solid #d4d4d4;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 10px;
|
|
||||||
position: relative;
|
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);
|
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.175);
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
|
|
|
@ -6,64 +6,20 @@
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="text-center">Timeline</h1>
|
<h1 class="text-center">Timeline</h1>
|
||||||
<h2 class="text-center text-muted">{{ object }}</h2>
|
<h2 class="text-center text-muted">{{ object }}</h2>
|
||||||
|
<h3 class="text-center">{{ date|date }}</h3>
|
||||||
<ul class="timeline">
|
<ul class="timeline">
|
||||||
{% for object in objects %}
|
{% for object in objects %}
|
||||||
<li>
|
<li>
|
||||||
<div class="timeline-badge bg-info"><i class="icon icon-{{ object.model_name }}"></i></div>
|
<div class="timeline-badge"><i class="icon icon-{{ object.model_name }}"></i></div>
|
||||||
<div class="card">
|
<div class="card text-right">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{{ object }}
|
{{ object.event }}
|
||||||
|
</div>
|
||||||
|
<div class="card-footer text-muted">
|
||||||
|
{{ object.time|time }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<li class="timeline-inverted">
|
|
||||||
<div class="timeline-badge bg-warning"><i class="fa fa-bed"></i></div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
This is some text within a card block.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="timeline-badge bg-danger"><i class="fa fa-spoon"></i></div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
This is some text within a card block.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li class="timeline-inverted">
|
|
||||||
<div class="timeline-badge bg-default"><i class="fa fa-spoon"></i></div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
This is some text within a card block.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="timeline-badge bg-default"><i class="fa fa-smile-o"></i></div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
This is some text within a card block.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="timeline-badge bg-default"><i class="fa fa-spoon"></i></div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
This is some text within a card block.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li class="timeline-inverted">
|
|
||||||
<div class="timeline-badge bg-success"><i class="fa fa-bed"></i></div>
|
|
||||||
<div class="card">
|
|
||||||
<div class="card-body">
|
|
||||||
This is some text within a card block.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
{% endblock %}
|
{% endblock %}
|
|
@ -7,7 +7,7 @@ from django.utils import timezone
|
||||||
|
|
||||||
from core.models import Child, DiaperChange
|
from core.models import Child, DiaperChange
|
||||||
|
|
||||||
from .graphs import diaperchange_types, sleep_pattern, sleep_totals
|
from .graphs import diaperchange_types, sleep_pattern, sleep_totals, timeline
|
||||||
|
|
||||||
|
|
||||||
class DiaperChangeTypesChildReport(PermissionRequiredMixin, DetailView):
|
class DiaperChangeTypesChildReport(PermissionRequiredMixin, DetailView):
|
||||||
|
@ -71,9 +71,8 @@ class TimelineChildReport(PermissionRequiredMixin, DetailView):
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super(TimelineChildReport, self).get_context_data(**kwargs)
|
context = super(TimelineChildReport, self).get_context_data(**kwargs)
|
||||||
date = self.request.GET.get('date', timezone.now().date())
|
date = self.request.GET.get('date', timezone.now().date())
|
||||||
|
date = timezone.datetime.strptime(date, '%Y-%m-%d')
|
||||||
changes = DiaperChange.objects.filter(child=self.object).filter(
|
date = timezone.localtime(timezone.make_aware(date))
|
||||||
time__contains=date).order_by('-time')
|
context['objects'] = timeline(self.object, date)
|
||||||
|
context['date'] = date
|
||||||
context['objects'] = changes
|
|
||||||
return context
|
return context
|
||||||
|
|
Loading…
Reference in New Issue