suivi global

This commit is contained in:
Tykayn 2025-06-29 18:32:24 +02:00 committed by tykayn
parent afc120ef2a
commit e3f8680472
6 changed files with 531 additions and 48 deletions

View file

@ -0,0 +1,105 @@
{% extends 'base.html.twig' %}
{% block title %}Suivi global de toutes les villes{% endblock %}
{% block body %}
<div class="container mt-4">
<h1>Suivi global de toutes les villes</h1>
<div class="mb-4">
<h3>Nombre de villes et complétion moyenne</h3>
<canvas id="global-summary-chart" height="80"></canvas>
</div>
<hr>
<h3>Suivi par thématique</h3>
<div class="row">
{% set themes = [
'fire_hydrant', 'charging_station', 'toilets', 'bus_stop', 'defibrillator', 'camera', 'recycling', 'substation', 'laboratory', 'school', 'police', 'healthcare', 'places'
] %}
{% for theme in themes %}
<div class="col-md-6 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ theme|replace({'_': ' '})|title }}</h5>
<canvas id="chart-{{ theme }}-count" height="60"></canvas>
<canvas id="chart-{{ theme }}-completion" height="60"></canvas>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0"></script>
<script>
const series = {{ series|json_encode|raw }};
// Graphe global summary
const ctxSummary = document.getElementById('global-summary-chart').getContext('2d');
const cityCountData = (series['city_count'] || []).map(e => ({x: e.date, y: e.value}));
const completionAvgData = (series['global_completion_average'] || []).map(e => ({x: e.date, y: e.value}));
new Chart(ctxSummary, {
type: 'line',
data: {
datasets: [
{
label: 'Nombre de villes',
data: cityCountData,
borderColor: 'blue',
yAxisID: 'y1',
},
{
label: 'Complétion moyenne (%)',
data: completionAvgData,
borderColor: 'green',
yAxisID: 'y2',
}
]
},
options: {
responsive: true,
interaction: {mode: 'index', intersect: false},
stacked: false,
scales: {
x: {type: 'time', time: {unit: 'day'}},
y1: {type: 'linear', position: 'left', title: {display: true, text: 'Villes'}},
y2: {type: 'linear', position: 'right', title: {display: true, text: '%'}},
}
}
});
// Graphes par thème
const themes = {{ themes|json_encode|raw }};
themes.forEach(theme => {
// Count
const countData = (series[theme + '_count'] || []).map(e => ({x: e.date, y: e.value}));
const ctxCount = document.getElementById('chart-' + theme + '-count').getContext('2d');
new Chart(ctxCount, {
type: 'line',
data: {
datasets: [{
label: 'Nombre',
data: countData,
borderColor: 'orange',
}]
},
options: {
responsive: true,
scales: {x: {type: 'time', time: {unit: 'day'}}, y: {beginAtZero: true}}
}
});
// Completion
const completionData = (series[theme + '_completion'] || []).map(e => ({x: e.date, y: e.value}));
const ctxCompletion = document.getElementById('chart-' + theme + '-completion').getContext('2d');
new Chart(ctxCompletion, {
type: 'line',
data: {
datasets: [{
label: 'Complétion (%)',
data: completionData,
borderColor: 'green',
}]
},
options: {
responsive: true,
scales: {x: {type: 'time', time: {unit: 'day'}}, y: {beginAtZero: true, max: 100}}
}
});
});
</script>
{% endblock %}