mirror of https://github.com/snachodog/mybuddy.git
Add example timeline view (WIP).
This commit is contained in:
parent
0ae9c5a408
commit
1f1d96093b
|
@ -105,6 +105,7 @@ def sleep_totals(child):
|
||||||
|
|
||||||
def sleep_pattern(child):
|
def sleep_pattern(child):
|
||||||
"""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.
|
||||||
instances = Sleep.objects.filter(child=child).order_by('start')
|
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()
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
{% extends 'babyblotter/page.html' %}
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block title %}Timeline - {{ object }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1 class="text-center">Timeline</h1>
|
||||||
|
<h2 class="text-center text-muted">{{ object }}</h2>
|
||||||
|
<ul class="timeline">
|
||||||
|
<li>
|
||||||
|
<div class="timeline-badge bg-info"><i class="fa fa-trash"></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-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>
|
||||||
|
{% endblock %}
|
|
@ -16,4 +16,8 @@ urlpatterns = [
|
||||||
url(r'^reports/sleep/totals/(?P<slug>[^/.]+)$',
|
url(r'^reports/sleep/totals/(?P<slug>[^/.]+)$',
|
||||||
views.SleepTotalsChildReport.as_view(),
|
views.SleepTotalsChildReport.as_view(),
|
||||||
name='report-sleep-totals-child'),
|
name='report-sleep-totals-child'),
|
||||||
|
|
||||||
|
url(r'^reports/timeline/(?P<slug>[^/.]+)$',
|
||||||
|
views.TimelineChildReport.as_view(),
|
||||||
|
name='report-timeline-child'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,6 +3,7 @@ from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
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 core.models import Child
|
from core.models import Child
|
||||||
|
|
||||||
|
@ -16,7 +17,8 @@ class DiaperChangeTypesChildReport(PermissionRequiredMixin, DetailView):
|
||||||
template_name = 'reports/diaperchange_types.html'
|
template_name = 'reports/diaperchange_types.html'
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
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']
|
child = context['object']
|
||||||
context['html'], context['javascript'] = diaperchange_types(child)
|
context['html'], context['javascript'] = diaperchange_types(child)
|
||||||
return context
|
return context
|
||||||
|
@ -34,7 +36,8 @@ class SleepPatternChildReport(PermissionRequiredMixin, DetailView):
|
||||||
self.javascript = ''
|
self.javascript = ''
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
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']
|
child = context['object']
|
||||||
context['html'], context['javascript'] = sleep_pattern(child)
|
context['html'], context['javascript'] = sleep_pattern(child)
|
||||||
return context
|
return context
|
||||||
|
@ -52,7 +55,21 @@ class SleepTotalsChildReport(PermissionRequiredMixin, DetailView):
|
||||||
self.javascript = ''
|
self.javascript = ''
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
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']
|
child = context['object']
|
||||||
context['html'], context['javascript'] = sleep_totals(child)
|
context['html'], context['javascript'] = sleep_totals(child)
|
||||||
return context
|
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
|
||||||
|
|
Loading…
Reference in New Issue