début de réorganisation de la partie statistique
This commit is contained in:
@@ -5,20 +5,24 @@ from . import managers
|
||||
|
||||
# Extends 'notes' module
|
||||
|
||||
|
||||
class Observation(Note):
|
||||
""" Note dans le cadre d'une rencontre """
|
||||
|
||||
objects = managers.ObservationManager()
|
||||
rencontre = models.ForeignKey( 'maraudes.Rencontre',
|
||||
rencontre = models.ForeignKey('maraudes.Rencontre',
|
||||
models.CASCADE,
|
||||
related_name="observations"
|
||||
)
|
||||
related_name="observations")
|
||||
|
||||
# Note attributes proxies
|
||||
def note_author(self): return self.rencontre.maraude.referent
|
||||
|
||||
def note_date(self): return self.rencontre.date
|
||||
|
||||
def note_time(self): return self.rencontre.heure_debut
|
||||
|
||||
def note_labels(self): return [self.rencontre.lieu, self.rencontre.heure_debut]
|
||||
|
||||
def note_bg_colors(self): return ("info", "info")
|
||||
|
||||
class Appel(Note):
|
||||
|
||||
@@ -2,8 +2,6 @@ import datetime
|
||||
import calendar
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from django.utils import timezone
|
||||
from django.shortcuts import redirect, reverse
|
||||
from django.views import generic
|
||||
@@ -13,19 +11,21 @@ from django.contrib import messages
|
||||
|
||||
from utilisateurs.mixins import MaraudeurMixin
|
||||
|
||||
from .models import ( Maraude, Maraudeur,
|
||||
from .models import (Maraude, Maraudeur,
|
||||
CompteRendu,
|
||||
Rencontre, Lieu,
|
||||
Planning, )
|
||||
Planning,)
|
||||
from .notes import Signalement
|
||||
# Forms
|
||||
from .forms import ( RencontreForm,
|
||||
from .forms import (RencontreForm,
|
||||
ObservationInlineFormSet,
|
||||
MaraudeHiddenDateForm, MonthSelectForm,
|
||||
AppelForm, SignalementForm,
|
||||
SendMailForm )
|
||||
SendMailForm)
|
||||
from notes.mixins import NoteFormMixin
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def derniers_sujets_rencontres():
|
||||
""" Renvoie le 'set' des sujets rencontrés dans les deux dernières maraudes """
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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">×</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 %}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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
|
||||
rencontres_jour = rencontres.filter(
|
||||
rencontre__maraude__heure_debut=HORAIRES_APRESMIDI
|
||||
)
|
||||
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
|
||||
|
||||
for r, m in [
|
||||
('nbr_rencontres', 'nbr_maraudes'),
|
||||
('nbr_rencontres_nuit', 'nbr_maraudes_nuit'),
|
||||
('nbr_rencontres_jour', 'nbr_maraudes_jour'),
|
||||
]:
|
||||
try:
|
||||
context['moy_rencontres'] = int(context['nbr_rencontres'] / context['nbr_maraudes'])
|
||||
context['%s_moyenne' % r] = int(context[r] / context[m])
|
||||
except (ZeroDivisionError, TypeError):
|
||||
context['moy_rencontres'] = NO_DATA
|
||||
context['%s_moyenne' % r] = 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')
|
||||
)
|
||||
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"
|
||||
}
|
||||
)
|
||||
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()
|
||||
|
||||
# Graph: Fréquence de rencontres par sujet
|
||||
|
||||
nbr_rencontres = rencontres.values('sujet').annotate(nbr=Count('pk')).order_by()
|
||||
context['nbr_sujets_rencontres'] = 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['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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user