map on home
This commit is contained in:
parent
a5cd69961f
commit
56f62c45bb
14 changed files with 588 additions and 15 deletions
|
@ -5,7 +5,7 @@
|
|||
{% block body %}
|
||||
<div class="container mt-4">
|
||||
<h1><i class="bi {{ icon }} fs-2"></i> {{ label }} <small class="text-muted">- {{ stats.name }}</small></h1>
|
||||
<canvas id="embedThemeChart" width="600" height="300"></canvas>
|
||||
<canvas id="embedThemeChart" width="600" height="400"></canvas>
|
||||
<div class="mb-3 mt-2">
|
||||
<a href="{{ path('app_admin_stats', {'insee_code': stats.zone}) }}" class="btn btn-info me-2">
|
||||
<i class="bi bi-bar-chart"></i> Voir la page de la ville
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</div>
|
||||
<div class="mb-4">
|
||||
<h3>Nombre de villes et complétion moyenne</h3>
|
||||
<canvas id="global-summary-chart" height="80"></canvas>
|
||||
<canvas id="global-summary-chart" height="400"></canvas>
|
||||
</div>
|
||||
<hr>
|
||||
<h3>Suivi par thématique</h3>
|
||||
|
@ -23,8 +23,8 @@
|
|||
<i class="bi {{ followup_icons[type]|default('bi-question-circle') }}"></i>
|
||||
{{ label }}
|
||||
</h5>
|
||||
<canvas id="chart-{{ type }}-count" height="60"></canvas>
|
||||
<canvas id="chart-{{ type }}-completion" height="60"></canvas>
|
||||
<canvas id="chart-{{ type }}-count" height="400"></canvas>
|
||||
<canvas id="chart-{{ type }}-completion" height="400"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<p>Historique des objets suivis (nombre et complétion).</p>
|
||||
{% for type, label in followup_labels %}
|
||||
<h2 id="title-{{ type }}"><i class="bi {{ followup_icons[type]|default('bi-question-circle') }} fs-2"></i> {{ label }}</h2>
|
||||
<canvas id="{{ type }}Chart" width="600" height="300"></canvas>
|
||||
<canvas id="{{ type }}Chart" width="600" height="400"></canvas>
|
||||
<div class="mb-3">
|
||||
{% set overpass_query = '[out:json][timeout:60];\narea["ref:INSEE"="' ~ stats.zone ~ '"]->.searchArea;\n(' ~ followup_overpass[type]|default('') ~ ');\n\n(._;>;);\n\nout meta;\n>;' %}
|
||||
<a href="https://overpass-turbo.eu/?Q={{ overpass_query|url_encode }}" target="_blank" class="btn btn-sm btn-outline-primary me-2">
|
||||
|
|
275
templates/admin/followup_theme_graph.html.twig
Normal file
275
templates/admin/followup_theme_graph.html.twig
Normal file
|
@ -0,0 +1,275 @@
|
|||
{% extends 'base_embed.html.twig' %}
|
||||
|
||||
{% block title %}Graphique {{ theme_label }} - {{ stats.name }}{% endblock %}
|
||||
|
||||
{% block stylesheets %}
|
||||
{{ parent() }}
|
||||
<style>
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.stats-header {
|
||||
background: #f8f9fa;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 15px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: white;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #dee2e6;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #0d6efd;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: #6c757d;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.chart-tabs {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.chart-tab {
|
||||
padding: 10px 20px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-bottom: 3px solid transparent;
|
||||
}
|
||||
|
||||
.chart-tab.active {
|
||||
border-bottom-color: #0d6efd;
|
||||
color: #0d6efd;
|
||||
}
|
||||
|
||||
.chart-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chart-content.active {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container-fluid">
|
||||
<div class="stats-header">
|
||||
<h2>
|
||||
<i class="bi {{ icons[theme]|default('bi-question-circle') }}"></i>
|
||||
{{ theme_label }} - {{ stats.name }}
|
||||
</h2>
|
||||
<p class="mb-0">Code INSEE: {{ stats.zone }}</p>
|
||||
</div>
|
||||
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="currentCount">-</div>
|
||||
<div class="stat-label">Nombre actuel</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="currentCompletion">-</div>
|
||||
<div class="stat-label">Complétion actuelle</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="dataPoints">-</div>
|
||||
<div class="stat-label">Points de données</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="lastUpdate">-</div>
|
||||
<div class="stat-label">Dernière mise à jour</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="chart-tabs">
|
||||
<button class="chart-tab active" data-chart="count">Nombre d'objets</button>
|
||||
<button class="chart-tab" data-chart="completion">Pourcentage de complétion</button>
|
||||
</div>
|
||||
|
||||
<div class="chart-content active" id="count-chart">
|
||||
<div class="chart-container">
|
||||
<canvas id="countChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="chart-content" id="completion-chart">
|
||||
<div class="chart-container">
|
||||
<canvas id="completionChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block javascripts %}
|
||||
{{ parent() }}
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
|
||||
|
||||
<script>
|
||||
const countData = {{ count_data|raw }};
|
||||
const completionData = {{ completion_data|raw }};
|
||||
|
||||
// Mettre à jour les statistiques
|
||||
function updateStats() {
|
||||
if (countData.length > 0) {
|
||||
const latestCount = countData[countData.length - 1];
|
||||
document.getElementById('currentCount').textContent = latestCount.value;
|
||||
document.getElementById('lastUpdate').textContent = new Date(latestCount.date).toLocaleDateString('fr-FR');
|
||||
}
|
||||
|
||||
if (completionData.length > 0) {
|
||||
const latestCompletion = completionData[completionData.length - 1];
|
||||
document.getElementById('currentCompletion').textContent = latestCompletion.value + '%';
|
||||
}
|
||||
|
||||
document.getElementById('dataPoints').textContent = Math.max(countData.length, completionData.length);
|
||||
}
|
||||
|
||||
// Configuration commune pour les graphiques
|
||||
const commonOptions = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
tooltip: {
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
type: 'time',
|
||||
time: {
|
||||
unit: 'day',
|
||||
displayFormats: {
|
||||
day: 'dd/MM/yyyy'
|
||||
}
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Date'
|
||||
}
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
title: {
|
||||
display: true
|
||||
}
|
||||
}
|
||||
},
|
||||
interaction: {
|
||||
mode: 'nearest',
|
||||
axis: 'x',
|
||||
intersect: false
|
||||
}
|
||||
};
|
||||
|
||||
// Graphique du nombre d'objets
|
||||
const countCtx = document.getElementById('countChart').getContext('2d');
|
||||
const countChart = new Chart(countCtx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'Nombre d\'objets',
|
||||
data: countData.map(d => ({
|
||||
x: new Date(d.date),
|
||||
y: d.value
|
||||
})),
|
||||
borderColor: '#0d6efd',
|
||||
backgroundColor: 'rgba(13, 110, 253, 0.1)',
|
||||
borderWidth: 2,
|
||||
fill: true,
|
||||
tension: 0.1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
...commonOptions,
|
||||
scales: {
|
||||
...commonOptions.scales,
|
||||
y: {
|
||||
...commonOptions.scales.y,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Nombre d\'objets'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Graphique de la complétion
|
||||
const completionCtx = document.getElementById('completionChart').getContext('2d');
|
||||
const completionChart = new Chart(completionCtx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'Pourcentage de complétion',
|
||||
data: completionData.map(d => ({
|
||||
x: new Date(d.date),
|
||||
y: d.value
|
||||
})),
|
||||
borderColor: '#198754',
|
||||
backgroundColor: 'rgba(25, 135, 84, 0.1)',
|
||||
borderWidth: 2,
|
||||
fill: true,
|
||||
tension: 0.1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
...commonOptions,
|
||||
scales: {
|
||||
...commonOptions.scales,
|
||||
y: {
|
||||
...commonOptions.scales.y,
|
||||
max: 100,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Pourcentage de complétion (%)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Gestion des onglets
|
||||
document.querySelectorAll('.chart-tab').forEach(tab => {
|
||||
tab.addEventListener('click', function() {
|
||||
// Retirer la classe active de tous les onglets
|
||||
document.querySelectorAll('.chart-tab').forEach(t => t.classList.remove('active'));
|
||||
document.querySelectorAll('.chart-content').forEach(c => c.classList.remove('active'));
|
||||
|
||||
// Ajouter la classe active à l'onglet cliqué
|
||||
this.classList.add('active');
|
||||
const chartId = this.getAttribute('data-chart') + '-chart';
|
||||
document.getElementById(chartId).classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
// Initialiser les statistiques
|
||||
updateStats();
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -170,6 +170,9 @@
|
|||
<span class="completion-badge {{ completion_class }}"></span><br>
|
||||
<i class="bi {{ followup_icons[type]|default('bi-question-circle') }} fs-2 mb-1"></i><br>
|
||||
<a href="http://127.0.0.1:8111/import?url=https://overpass-api.de/api/interpreter?data={{ overpass_query|url_encode }}" target="_blank" class="fw-bold text-decoration-underline text-dark" title="Charger dans JOSM">{{ followup_labels[type]|default(type|capitalize) }}</a><br>
|
||||
<a href="{{ path('admin_followup_theme_graph', {'insee_code': stats.zone, 'theme': type}) }}" target="_blank" class="btn btn-sm btn-outline-primary mt-1" title="Voir le graphique">
|
||||
<i class="bi bi-graph-up"></i>
|
||||
</a><br>
|
||||
<span title="Nombre"> {{ data.count is defined ? data.count.getMeasure() : '?' }}</span><br>
|
||||
<span title="Complétion"> {{ completion is not null ? completion : '?' }}%</span>
|
||||
{% if progression7Days[type] is defined %}
|
||||
|
@ -200,6 +203,9 @@
|
|||
<span class="completion-badge" style="background:#eee;"></span><br>
|
||||
<i class="bi bi-question-circle fs-2 mb-1"></i><br>
|
||||
<span class="fw-bold">{{ followup_labels[type]|default(type|capitalize) }}</span><br>
|
||||
<a href="{{ path('admin_followup_theme_graph', {'insee_code': stats.zone, 'theme': type}) }}" target="_blank" class="btn btn-sm btn-outline-secondary mt-1" title="Voir le graphique">
|
||||
<i class="bi bi-graph-up"></i> Graphique
|
||||
</a><br>
|
||||
<span title="Nombre">N = ?</span><br>
|
||||
<span title="Complétion">?%</span>
|
||||
</div>
|
||||
|
@ -280,7 +286,7 @@
|
|||
<div class="row ">
|
||||
|
||||
<div class="col-md-6 col-12 ">
|
||||
<canvas id="repartition_tags" width="600" height="300" style="max-width:100%; margin: 20px 0;"></canvas>
|
||||
<canvas id="repartition_tags" width="600" height="400" style="max-width:100%; margin: 20px 0;"></canvas>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -303,7 +309,7 @@
|
|||
</div>
|
||||
<div class="card mt-4">
|
||||
{% include 'admin/stats_history.html.twig' with {stat: stats} %}
|
||||
<canvas id="distribution_completion" class="mt-4 mb-4" height="600"></canvas>
|
||||
<canvas id="distribution_completion" class="mt-4 mb-4" height="400"></canvas>
|
||||
|
||||
|
||||
<div class="row">
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<h2>Évolution du taux de complétion</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="completionHistoryChart" height="500"></canvas>
|
||||
<canvas id="completionHistoryChart" height="400" style="height:400px !important; max-height:400px; min-height:200px;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue