diff --git a/statistiques/templates/statistiques/test.html b/statistiques/templates/statistiques/frequentation.html
similarity index 88%
rename from statistiques/templates/statistiques/test.html
rename to statistiques/templates/statistiques/frequentation.html
index c7250be..e82f176 100644
--- a/statistiques/templates/statistiques/test.html
+++ b/statistiques/templates/statistiques/frequentation.html
@@ -15,11 +15,9 @@
{% block breadcrumbs %}
{{ block.super }}
-
Tests
+ Fréquentation
{% endblock %}
{% block page_content %}
{{ par_heure.as_html }}
-
- {{ par_heure_continu.as_html }}
{% endblock %}
diff --git a/statistiques/templates/statistiques/menu.html b/statistiques/templates/statistiques/menu.html
index f276fe0..97304f9 100644
--- a/statistiques/templates/statistiques/menu.html
+++ b/statistiques/templates/statistiques/menu.html
@@ -10,5 +10,10 @@
+
+ Fréquentation
+
+
+
diff --git a/statistiques/urls.py b/statistiques/urls.py
index ebc211b..2983a80 100644
--- a/statistiques/urls.py
+++ b/statistiques/urls.py
@@ -7,6 +7,6 @@ urlpatterns = [
url('^charts/$', views.PieChartView.as_view(), name="pies"),
url(r'^details/(?P[0-9]+)/$', views.StatistiquesDetailsView.as_view(), name="details"),
url(r'^update/(?P[0-9]+)/$', views.StatistiquesUpdateView.as_view(), name="update"),
- url(r'^tests/$', views.TestStatsView.as_view(), name="tests"),
+ url(r'^frequentation/$', views.FrequentationStatsView.as_view(), name="frequentation"),
]
diff --git a/statistiques/views.py b/statistiques/views.py
index 1bdefed..0ec6ead 100644
--- a/statistiques/views.py
+++ b/statistiques/views.py
@@ -175,58 +175,86 @@ class PieChartView(FilterMixin, generic.TemplateView):
return context
-import collections
+class FrequentationStatsView(FilterMixin, generic.TemplateView):
+ template_name = "statistiques/frequentation.html"
-def get_data_table(observations, continuous=False):
- return_zero = lambda: 0
- data_table = collections.defaultdict(return_zero)
+ @staticmethod
+ def calculer_frequentation_par_quart_heure(observations, continu=False):
+ """ Calcule le nombre d'observations, de 16h à 24h, par tranche de 15min.
+ L'algorithme est *très peu* efficace mais simple à comprendre : on calcule pour
+ chaque tranche les observations qui y sont contenues.
+ On peut calculer seulement les observations démarrées (continu = False) ou considérer
+ que l'observation est contenue dans un intervalle sur toute sa durée (continu = True).
- for o in observations:
- heure_debut = datetime.datetime.strptime("%s" % o.rencontre.heure_debut, "%H:%M:%S")
- if continuous:
- heure_fin = heure_debut + datetime.timedelta(0, o.rencontre.duree * 60)
- else:
- heure_fin = heure_debut
+ """
+ data = dict()
- for heure in range(heure_debut.hour, heure_fin.hour + 1):
- data_table[heure] += 1
+ def genere_filtre_pour(heure, indice):
+ """ Renvoie une fonction qui renvoie True si l'intervalle donné contient l'observation, c'est-à-dire :
+ 1. Elle démarre/finit dans l'intervalle.
+ 2. Elle démarre avant et fini après l'intervalle.
+ """
+ debut_intervalle = indice * 15
+ fin_intervalle = debut_intervalle + 15
+ rng = range(debut_intervalle, fin_intervalle)
- return data_table
+ def est_contenue(observation):
+ """ Vérifie l'observation est contenue dans l'intervalle """
+ debut = datetime.datetime.strptime(
+ "%s" % observation.rencontre.heure_debut,
+ "%H:%M:%S"
+ )
+ fin = debut + datetime.timedelta(0, observation.rencontre.duree * 60)
+ # L'observation démarre dans l'intervalle
+ if (debut.hour == heure and debut.minute in rng):
+ return True
+ # L'observation finit dans l'intervalle, seulement si continu est True
+ elif continu and (fin.hour == heure and fin.minute in rng):
+ return True
+ # L'observation démarre avant ET finit après l'intervalle,
+ # seulement si continu est True
+ elif ( continu
+ and (debut.hour <= heure and debut.minute <= debut_intervalle)
+ and (fin.hour >= heure and fin.minute >= fin_intervalle)):
+ return True
+
+ else:
+ return False
+ return est_contenue
+ for h in range(16, 24):
+ for i in range(4):
+
+ filtre = genere_filtre_pour(heure=h, indice=i)
+ contenus = list(filter(filtre, observations))
+
+ key = datetime.time(h, i * 15)
+ print("Resultat", h, ":", i*15, len(contenus))
+ data[key] = len(contenus)
+
+ return data
-class TestStatsView(FilterMixin, generic.TemplateView):
- template_name = "statistiques/test.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
observations = self.get_observations_queryset()
- par_heure = get_data_table(observations)
- context['par_heure'] = gchart.LineChart(
+ 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(
SimpleDataSource(
- [("Heure", "Nbr de rencontres")] +
- [(heure, par_heure[heure]) for heure in sorted(par_heure.keys())]
+ [("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())]
),
options = {
- "title": "Nombre de rencontres par heure (démarrée)"
+ "title": "Fréquentation de la maraude en fonction de l'heure (par quart d'heure)"
}
)
-
- en_continu = get_data_table(observations, continuous=True)
- context['par_heure_continu'] = gchart.LineChart(
- SimpleDataSource(
- [("Heure", "Nbr de rencontres")] +
- [(heure, en_continu[heure]) for heure in sorted(en_continu.keys())]
- ),
- options = {
- "title": "Nombre de rencontres par heure (en cumulé)"
- }
- )
-
return context