mirror of
https://forge.chapril.org/tykayn/osm-commerces
synced 2025-10-04 17:04:53 +02:00
275 lines
No EOL
8.8 KiB
Twig
275 lines
No EOL
8.8 KiB
Twig
{% 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 %} |