début de réorganisation de la partie statistique

This commit is contained in:
artus40
2017-08-14 19:12:18 +02:00
parent 0c887afaa3
commit c8c59b92a2
8 changed files with 116 additions and 111 deletions

View File

@@ -34,15 +34,15 @@ class PieWrapper(gchart.PieChart):
else:
raise ValueError("Could not guess labels for", field)
data = ([(field.name, 'count')] + # Headers
data = ([(field.name, 'count')] + # Headers
[(labels[item[field.name]],
item['nbr']) for item in queryset.values(
field.name
).annotate(
nbr=Count('pk')
).order_by()
if (not null_values
or item[field] not in null_values)
field.name
).annotate(
nbr=Count('pk')
).order_by()
if (not null_values
or item[field] not in null_values)
])
super().__init__(

View File

@@ -19,5 +19,9 @@
{% endblock %}
{% block page_content %}
{{ par_heure.as_html }}
{{ rencontres_par_heure.as_html }}
{{ rencontres_par_mois.as_html }}
<hr />
{{ rencontres_par_sujet.as_html }}
{% endblock %}

View File

@@ -8,6 +8,5 @@
// Wait for the chart to finish drawing before calling the getImageURI() method.
google.visualization.events.addListener(chart, 'ready', function () {
$("#image-{{ chart.get_html_id }}").attr("href", chart.getImageURI());
$("#wrapper-{{ chart.get_html_id}}").hide();
});
{% endblock %}

View File

@@ -15,46 +15,26 @@
{% block breadcrumbs %}
{{ block.super }}
<li>Tests</li>
<li>Données générales</li>
{% endblock %}
{% block page_content %}
<div class="alert alert-info alert-dismissible">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<p>Voici les données permettant une analyse statistiques des maraudes.</p>
<p>Vous pouvez sélectionner une période particulière ou l'ensemble des données</p>
<p>Les données sont réparties en trois catégories, accessibles par le menu sur la gauche</p>
<div class="col-lg-8 text-right">
<h3 class="page-header">Données générales</h3>
<table class="table table-bordered">
<tr><th>...</th><th>Maraudes</th><th>Nombre de rencontres <span class="badge">moyenne par maraude</span></th><th>Personnes</th></tr>
<tr><th>Total</th><td>{{nbr_maraudes}}</td><td>{{nbr_rencontres}} <span class="badge">{{nbr_rencontres_moyenne }}</span></td><td>{{nbr_sujets}}</td></tr>
<tr><th>Soirée</th><td>{{nbr_maraudes_nuit}}</td><td>{{nbr_rencontres_nuit}} <span class="badge">{{nbr_rencontres_nuit_moyenne }}</span></td><td>{{nbr_sujets_nuit}}</td></tr>
<tr><th>Journée</th><td>{{nbr_maraudes_jour}}</td><td>{{nbr_rencontres_jour}} <span class="badge">{{nbr_rencontres_jour_moyenne }}</span></td><td>{{nbr_sujets_jour}}</td></tr>
</table>
</div>
<div class="col-lg-4">
<h3 class="page-header">Données générales</h3>
<ul class="list-group">
<li class="list-group-item list-group-item-danger">
<span class="badge">{{ nbr_maraudes }}</span>
Nombre de maraudes
</li>
<li class="list-group-item">
<span class="badge">{{ nbr_maraudes_jour }}</span>
dont, Maraudes de journée
</li>
<li class="list-group-item list-group-item-danger">
<span class="badge">{{ nbr_rencontres }}</span>
Nombre total de rencontres
</li>
<li class="list-group-item">
<span class="badge">{{ moy_rencontres }}</span>
soit, en <strong>moyenne</strong> par maraude
</li>
<li class="list-group-item list-group-item-danger">
<span class="badge">{{ nbr_sujets_rencontres }}</span>
Nombre de sujets rencontrés
</li>
</ul>
<div class="alert alert-info">
<p>Voici les données permettant une analyse statistiques des maraudes.</p>
<p>Vous pouvez sélectionner une période particulière ou l'ensemble des données</p>
<p>Les données sont réparties en trois catégories, accessibles par le menu sur la gauche</p>
</div>
</div>
{% if rencontres_par_mois %}
<div class="col-lg-8">
<h3 class="page-header">Rencontres par mois</h3>
{{ rencontres_par_mois.as_html }}
</div>
{% endif %}
{% endblock %}

View File

@@ -6,7 +6,6 @@
{% block sidebar %}
{{ block.super }}
<hr />
<div class="panel panel-primary">
<div class="panel-body text-right">
{% include "statistiques/filter_form.html" %}
@@ -30,10 +29,6 @@
$("#tab-" + id).attr("class", "active");
$("#wrapper-" + id).show();
}
/*$( function() {
hideAll();
});*/
</script>
<ul class="nav nav-tabs">
{% for title, graph in graphs %}<li role="presentation" id="tab-{{graph.get_html_id}}"><a href="#" onclick="showGraph('{{graph.get_html_id}}');">{{ title }}</a></li>{% endfor %}

View File

@@ -15,7 +15,7 @@ from .forms import StatistiquesForm, SelectRangeForm
from .charts import PieWrapper, ColumnWrapper
from maraudes.notes import Observation
from maraudes.models import Maraude
from maraudes.models import Maraude, HORAIRES_APRESMIDI, HORAIRES_SOIREE
from notes.models import Sujet
###
@@ -62,8 +62,10 @@ class FilterMixin(generic.edit.FormMixin):
def get_fichestatistiques_queryset(self):
return FicheStatistique.objects.filter(pk__in=self.get_observations_queryset().values_list('sujet'))
def get_sujets_queryset(self):
return Sujet.objects.filter(pk__in=self.get_observations_queryset().values_list('sujet'))
def get_sujets_queryset(self, selection=None):
if not selection:
selection = self.get_observations_queryset()
return Sujet.objects.filter(pk__in=selection.values_list('sujet'))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@@ -85,50 +87,36 @@ class DashboardView(FilterMixin, generic.TemplateView):
context['nbr_maraudes'] = maraudes.count() or NO_DATA
context['nbr_maraudes_jour'] = maraudes.filter(
heure_debut=datetime.time(16,00)
heure_debut=HORAIRES_APRESMIDI
).count() or NO_DATA
context['nbr_maraudes_nuit'] = maraudes.filter(
heure_debut=HORAIRES_SOIREE
).count() or NO_DATA
context['nbr_rencontres'] = rencontres.count() or NO_DATA
try:
context['moy_rencontres'] = int(context['nbr_rencontres'] / context['nbr_maraudes'])
except (ZeroDivisionError, TypeError):
context['moy_rencontres'] = NO_DATA
if self.year and not self.month: #Show rencontres_par_mois graph
par_mois = rencontres.order_by().annotate(
mois=ExtractMonth('created_date')
).values(
'mois'
).annotate(
nbr=Count('pk')
rencontres_jour = rencontres.filter(
rencontre__maraude__heure_debut=HORAIRES_APRESMIDI
)
context['rencontres_par_mois'] = ColumnWrapper(
SimpleDataSource(
[("Mois", "Rencontres")] +
[(nom_mois[item['mois']], item['nbr']) for item in par_mois]
),
options = {
"title": "Nombre de rencontres par mois"
}
)
rencontres_nuit = rencontres.filter(
rencontre__maraude__heure_debut=HORAIRES_SOIREE
)
context['nbr_rencontres_jour'] = rencontres_jour.count() or NO_DATA
context['nbr_rencontres_nuit'] = rencontres_nuit.count() or NO_DATA
# Graph: Fréquence de rencontres par sujet
for r, m in [
('nbr_rencontres', 'nbr_maraudes'),
('nbr_rencontres_nuit', 'nbr_maraudes_nuit'),
('nbr_rencontres_jour', 'nbr_maraudes_jour'),
]:
try:
context['%s_moyenne' % r] = int(context[r] / context[m])
except (ZeroDivisionError, TypeError):
context['%s_moyenne' % r] = NO_DATA
nbr_rencontres = rencontres.values('sujet').annotate(nbr=Count('pk')).order_by()
context['nbr_sujets_rencontres'] = nbr_rencontres.count()
context['nbr_sujets'] = self.get_sujets_queryset(selection=rencontres).count()
context['nbr_sujets_jour'] = self.get_sujets_queryset(selection=rencontres_jour).count()
context['nbr_sujets_nuit'] = self.get_sujets_queryset(selection=rencontres_nuit).count()
categories = (
('Rencontre unique', (1,)),
('Entre 2 et 5 rencontres', range(2,6)),
('Entre 6 et 20 rencontres', range(6,20)),
('Plus de 20 rencontres', range(20,999)),
)
get_count_for_range = lambda rg: nbr_rencontres.filter(nbr__in=rg).count()
context['graph_rencontres'] = PieWrapper(
data= [('Type de rencontre', 'Nombre de sujets')] +
[(label, get_count_for_range(rg)) for label, rg in categories],
title= 'Fréquence de rencontres'
)
return context
@@ -245,7 +233,7 @@ class FrequentationStatsView(FilterMixin, generic.TemplateView):
par_heure = self.calculer_frequentation_par_quart_heure(observations, continu=False)
en_continu = self.calculer_frequentation_par_quart_heure(observations, continu=True)
context['par_heure'] = gchart.AreaChart(
context['rencontres_par_heure'] = gchart.AreaChart(
SimpleDataSource(
[("Heure", "Rencontres démarrées", "Au total (démarré + en cours)")] +
[(heure, par_heure[heure], en_continu[heure]) for heure in sorted(par_heure.keys())]
@@ -254,6 +242,41 @@ class FrequentationStatsView(FilterMixin, generic.TemplateView):
"title": "Fréquentation de la maraude en fonction de l'heure (par quart d'heure)"
}
)
par_mois = observations.order_by().annotate(
mois=ExtractMonth('created_date')
).values(
'mois'
).annotate(
nbr=Count('pk')
)
context['rencontres_par_mois'] = ColumnWrapper(
SimpleDataSource(
[("Mois", "Rencontres")] +
[(nom_mois[item['mois']], item['nbr']) for item in par_mois]
),
options = {
"title": "Nombre de rencontres par mois"
}
)
# Graph: Fréquence de rencontres par sujet
nbr_rencontres = observations.values('sujet').annotate(nbr=Count('pk')).order_by()
context['rencontres_par_sujet'] = nbr_rencontres.count()
categories = (
('Rencontre unique', (1,)),
('Entre 2 et 5 rencontres', range(2,6)),
('Entre 6 et 20 rencontres', range(6,20)),
('Plus de 20 rencontres', range(20,999)),
)
get_count_for_range = lambda rg: nbr_rencontres.filter(nbr__in=rg).count()
context['rencontres_par_sujet'] = PieWrapper(
data= [('Type de rencontre', 'Nombre de sujets')] +
[(label, get_count_for_range(rg)) for label, rg in categories],
title= 'Fréquence de rencontres'
)
return context