Added weekly stats
This commit is contained in:
parent
e991a17151
commit
debb3bbee9
5 changed files with 141 additions and 0 deletions
55
counter/static/js/dateformat.js
Normal file
55
counter/static/js/dateformat.js
Normal file
|
@ -0,0 +1,55 @@
|
|||
'use strict';
|
||||
|
||||
(function(globals) {
|
||||
var replacements = {
|
||||
'd': 'DD',
|
||||
'D': 'ddd',
|
||||
'j': 'D',
|
||||
'l': 'dddd',
|
||||
'N': 'E',
|
||||
'S': 'o',
|
||||
'w': 'e',
|
||||
'z': 'DDD',
|
||||
'W': 'W',
|
||||
'F': 'MMMM',
|
||||
'm': 'MM',
|
||||
'M': 'MMM',
|
||||
'n': 'M',
|
||||
't': '', // no equivalent
|
||||
'L': '', // no equivalent
|
||||
'o': 'YYYY',
|
||||
'Y': 'YYYY',
|
||||
'y': 'YY',
|
||||
'a': 'a',
|
||||
'A': 'A',
|
||||
'B': '', // no equivalent
|
||||
'g': 'h',
|
||||
'G': 'H',
|
||||
'h': 'hh',
|
||||
'H': 'HH',
|
||||
'i': 'mm',
|
||||
's': 'ss',
|
||||
'u': 'SSS',
|
||||
'e': 'zz', // deprecated since version 1.6.0 of moment.js
|
||||
'I': '', // no equivalent
|
||||
'O': '', // no equivalent
|
||||
'P': '', // no equivalent
|
||||
'T': '', // no equivalent
|
||||
'Z': '', // no equivalent
|
||||
'c': '', // no equivalent
|
||||
'r': '', // no equivalent
|
||||
'U': 'X',
|
||||
};
|
||||
|
||||
globals.djangoToMomentFmt = function(djangoFormat) {
|
||||
djangoFormat = djangoFormat.replace(/(\w+)/g, function (f) {
|
||||
return '[' + f + ']';
|
||||
});
|
||||
Object.keys(replacements).forEach(function(key) {
|
||||
djangoFormat = djangoFormat.replace("[" + key + "]", replacements[key])
|
||||
});
|
||||
return djangoFormat;
|
||||
};
|
||||
}(this));
|
||||
|
||||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
{% if user.is_authenticated %}
|
||||
<li><a href="{% url "count_list" %}">Counts</a></li>
|
||||
<li><a href="{% url "stats" %}">Weekly stats</a></li>
|
||||
<li class="divider" tabindex="-1"></li>
|
||||
{% if user.is_superuser %}
|
||||
<li><a href="{% url "admin:index" %}">Admin</a></li>
|
||||
|
|
52
counter/templates/stats.html
Normal file
52
counter/templates/stats.html
Normal file
|
@ -0,0 +1,52 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block title %}Weekly stats{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script id="data" type="application/json">
|
||||
{% autoescape off %}{{ weeklyArrows }}{% endautoescape %}
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
|
||||
<script src="{% static 'js/dateformat.js' %}"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
var data = JSON.parse($('#data').text()),
|
||||
format = djangoToMomentFmt(django.get_format('SHORT_DATE_FORMAT'));
|
||||
console.log(format);
|
||||
var labels = [], dataset = [];
|
||||
data.forEach(function(d) {
|
||||
labels.push(moment(d.weekStarts).format(format) + ' - ' +
|
||||
moment(d.weekEnds).format(format));
|
||||
dataset.push(d.sum_count);
|
||||
});
|
||||
console.log(data);
|
||||
var myChart = new Chart($('#chart'), {
|
||||
type: 'horizontalBar',
|
||||
data: {
|
||||
labels: labels,
|
||||
datasets: [{
|
||||
label: '# of Arrows',
|
||||
data: dataset,
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h1 class="center">Weekly stats</h1>
|
||||
<canvas id="chart"></canvas>
|
||||
{% endblock %}
|
|
@ -4,6 +4,7 @@ from . import views
|
|||
|
||||
urlpatterns = [
|
||||
path('', views.index, name='index'),
|
||||
path('stats', views.count_stats, name='stats'),
|
||||
path('count/list', views.arrow_count_list, name='count_list'),
|
||||
path('count/new', login_required(views.NewArrowCount.as_view()),
|
||||
name='count_new'),
|
||||
|
|
|
@ -9,11 +9,43 @@ from django.contrib.auth.decorators import login_required
|
|||
from django.conf import settings
|
||||
from django.core.exceptions import SuspiciousOperation
|
||||
from django.utils.translation import gettext as _
|
||||
from django.db.models.functions import Extract, ExtractWeek
|
||||
from django.db.models import Sum
|
||||
from datetime import datetime, timedelta, date
|
||||
import json
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
|
||||
# https://stackoverflow.com/questions/5882405
|
||||
def tofirstdayinisoweek(year, week):
|
||||
ret = datetime.strptime('%04d-%02d-1' % (year, week), '%Y-%W-%w')
|
||||
if date(year, 1, 4).isoweekday() > 4:
|
||||
ret -= timedelta(days=7)
|
||||
return ret
|
||||
|
||||
def index(request):
|
||||
template = loader.get_template('index.html')
|
||||
return HttpResponse(template.render({}, request))
|
||||
|
||||
def count_stats(request):
|
||||
template = loader.get_template('stats.html')
|
||||
|
||||
# Group counts by week (extract isoyear works only on psql and DB2)
|
||||
weeklyArrows = ArrowCount.objects \
|
||||
.filter(user = request.user) \
|
||||
.annotate(isoyear=Extract('date', lookup_name='isoyear')) \
|
||||
.annotate(week=ExtractWeek('date')) \
|
||||
.values('isoyear', 'week') \
|
||||
.annotate(sum_count=Sum('count')) \
|
||||
.order_by('-isoyear', '-week')
|
||||
|
||||
for w in weeklyArrows:
|
||||
w['weekStarts'] = tofirstdayinisoweek(w['isoyear'], w['week'])
|
||||
w['weekEnds'] = w['weekStarts'] + timedelta(days=6)
|
||||
|
||||
return HttpResponse(template.render({
|
||||
'weeklyArrows': json.dumps(list(weeklyArrows), cls=DjangoJSONEncoder)
|
||||
}, request))
|
||||
|
||||
@login_required
|
||||
def arrow_count_list(request):
|
||||
page = request.GET.get('page')
|
||||
|
|
Loading…
Reference in a new issue