mirror of
https://forge.chapril.org/tykayn/osm-commerces
synced 2025-10-04 17:04:53 +02:00
263 lines
No EOL
14 KiB
Twig
263 lines
No EOL
14 KiB
Twig
{% extends 'base.html.twig' %}
|
|
|
|
{% block title %}Histogramme de fraîcheur OSM{% endblock %}
|
|
|
|
{% block body %}
|
|
<div class="container mt-4">
|
|
<h1>Histogramme de fraîcheur des données OSM</h1>
|
|
<h2>Par année</h2>
|
|
<canvas id="fraicheurHistogrammeAnnee" width="800" height="400" style="max-width:100%; margin: 20px 0;"></canvas>
|
|
<h2>Par trimestre</h2>
|
|
<canvas id="fraicheurHistogrammeTrimestre" width="800" height="400" style="max-width:100%; margin: 20px 0;"></canvas>
|
|
|
|
<h2>Par mois</h2>
|
|
<canvas id="fraicheurHistogramme" width="800" height="400" style="max-width:100%; margin: 20px 0;"></canvas>
|
|
|
|
<h2>Distribution des villes selon le nombre d'habitants par lieu (par pas de 10)</h2>
|
|
<canvas id="distributionHabitantsParLieu" width="800" height="400" style="max-width:100%; margin: 20px 0;"></canvas>
|
|
<p>
|
|
Une ville avec un petit nombre d'habitants par lieu sera très fournie en services divers et variés, sur la gauche de ce graphique de répartition. Survolez pour voir les noms des villes les plus civilisées. À droite du graphique, vous êtes plus proche d'habiter dans un désert.
|
|
</p>
|
|
<div id="fraicheurMeta" class="mb-3"></div>
|
|
<a href="{{ path('admin_fraicheur_calculate') }}" class="btn btn-primary">Régénérer les statistiques</a>
|
|
<a href="{{ path('admin_fraicheur_download') }}" class="btn btn-secondary">Télécharger le JSON des lieux</a>
|
|
<a href="{{ path('admin_distribution_villes_lieux_par_habitant_download') }}" class="btn btn-secondary">Télécharger le JSON villes/lieux/habitant</a>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block javascripts %}
|
|
{{ parent() }}
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
fetch('/admin/fraicheur/download')
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
if(data.error){
|
|
document.getElementById('fraicheurMeta').innerHTML = '<div class="alert alert-danger">'+data.error+'</div>';
|
|
return;
|
|
}
|
|
const ctx = document.getElementById('fraicheurHistogramme').getContext('2d');
|
|
const labels = Object.keys(data.histogram);
|
|
const values = Object.values(data.histogram);
|
|
document.getElementById('fraicheurMeta').innerHTML =
|
|
'<b>Date de génération :</b> ' + data.generated_at + '<br>' +
|
|
'<b>Total lieux :</b> ' + data.total;
|
|
new Chart(ctx, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: labels,
|
|
datasets: [{
|
|
label: 'Nombre de lieux modifiés ce mois',
|
|
data: values,
|
|
backgroundColor: 'rgba(54, 162, 235, 0.7)',
|
|
borderColor: 'rgba(54, 162, 235, 1)',
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: true,
|
|
plugins: {
|
|
legend: { display: false },
|
|
title: { display: true, text: 'Fraîcheur des données OSM (par mois)' }
|
|
},
|
|
scales: {
|
|
y: { beginAtZero: true, title: { display: true, text: 'Nombre de lieux' } },
|
|
x: { title: { display: true, text: 'Mois' } }
|
|
}
|
|
}
|
|
});
|
|
|
|
// Agrégation par trimestre
|
|
const trimestreAgg = {};
|
|
for(const key in data.histogram){
|
|
// key = YYYY-MM
|
|
const [year, month] = key.split('-');
|
|
const m = parseInt(month, 10);
|
|
let trimestre = 1;
|
|
if(m >= 4 && m <= 6) trimestre = 2;
|
|
else if(m >= 7 && m <= 9) trimestre = 3;
|
|
else if(m >= 10 && m <= 12) trimestre = 4;
|
|
const trimestreKey = `${year}-T${trimestre}`;
|
|
if(!trimestreAgg[trimestreKey]) trimestreAgg[trimestreKey] = 0;
|
|
trimestreAgg[trimestreKey] += data.histogram[key];
|
|
}
|
|
const trimestreLabels = Object.keys(trimestreAgg).sort();
|
|
const trimestreValues = trimestreLabels.map(k => trimestreAgg[k]);
|
|
const ctxTrim = document.getElementById('fraicheurHistogrammeTrimestre').getContext('2d');
|
|
new Chart(ctxTrim, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: trimestreLabels,
|
|
datasets: [{
|
|
label: 'Nombre de lieux modifiés ce trimestre',
|
|
data: trimestreValues,
|
|
backgroundColor: 'rgba(255, 159, 64, 0.7)',
|
|
borderColor: 'rgba(255, 159, 64, 1)',
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: true,
|
|
plugins: {
|
|
legend: { display: false },
|
|
title: { display: true, text: 'Fraîcheur des données OSM (par trimestre)' }
|
|
},
|
|
scales: {
|
|
y: { beginAtZero: true, title: { display: true, text: 'Nombre de lieux' } },
|
|
x: { title: { display: true, text: 'Trimestre' } }
|
|
}
|
|
}
|
|
});
|
|
|
|
// Agrégation par année
|
|
const anneeAgg = {};
|
|
for(const key in data.histogram){
|
|
// key = YYYY-MM
|
|
const [year] = key.split('-');
|
|
if(!anneeAgg[year]) anneeAgg[year] = 0;
|
|
anneeAgg[year] += data.histogram[key];
|
|
}
|
|
const anneeLabels = Object.keys(anneeAgg).sort();
|
|
const anneeValues = anneeLabels.map(k => anneeAgg[k]);
|
|
const ctxAnnee = document.getElementById('fraicheurHistogrammeAnnee').getContext('2d');
|
|
new Chart(ctxAnnee, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: anneeLabels,
|
|
datasets: [{
|
|
label: 'Nombre de lieux modifiés cette année',
|
|
data: anneeValues,
|
|
backgroundColor: 'rgba(75, 192, 192, 0.7)',
|
|
borderColor: 'rgba(75, 192, 192, 1)',
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: true,
|
|
plugins: {
|
|
legend: { display: false },
|
|
title: { display: true, text: 'Fraîcheur des données OSM (par année)' }
|
|
},
|
|
scales: {
|
|
y: { beginAtZero: true, title: { display: true, text: 'Nombre de lieux' } },
|
|
x: { title: { display: true, text: 'Année' } }
|
|
}
|
|
}
|
|
});
|
|
|
|
// Histogramme distribution villes/lieux/habitant
|
|
fetch('/admin/distribution_villes_lieux_par_habitant_download')
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
if(data.error){
|
|
document.getElementById('distributionVillesLieuxParHabitant').insertAdjacentHTML('afterend', '<div class="alert alert-danger">Erreur de chargement des données : '+data.error+'</div>');
|
|
return;
|
|
}
|
|
// Histogramme habitants par lieu (pas de 10)
|
|
fetch('/admin/distribution_villes_lieux_par_habitant_villes')
|
|
.then(r2 => r2.json())
|
|
.then(villesData => {
|
|
// Histogramme habitants par lieu
|
|
if(!data.histogram_10){
|
|
document.getElementById('distributionHabitantsParLieu').insertAdjacentHTML('afterend', '<div class="alert alert-danger">Erreur : données histogram_10 absentes. Cliquez sur "Régénérer les statistiques".</div>');
|
|
return;
|
|
}
|
|
const ctxHPL = document.getElementById('distributionHabitantsParLieu').getContext('2d');
|
|
const labelsHPL = Object.keys(data.histogram_10);
|
|
const valuesHPL = Object.values(data.histogram_10);
|
|
const villesByBin10 = villesData.villes_by_bin_10 || {};
|
|
console.log('HPL', labelsHPL, villesByBin10);
|
|
new Chart(ctxHPL, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: labelsHPL,
|
|
datasets: [{
|
|
label: "Nombre de villes",
|
|
data: valuesHPL,
|
|
backgroundColor: 'rgba(255, 99, 132, 0.7)',
|
|
borderColor: 'rgba(255, 99, 132, 1)',
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: true,
|
|
plugins: {
|
|
legend: { display: false },
|
|
title: { display: true, text: "Distribution des villes par habitants/lieu (par pas de 10)" },
|
|
tooltip: {
|
|
callbacks: {
|
|
afterBody: function(context) {
|
|
const bin = context[0].label;
|
|
const villes = villesByBin10[bin] || [];
|
|
if(villes.length > 0){
|
|
return ['Villes :'].concat(villes.map(v => '• ' + v));
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
}
|
|
},
|
|
scales: {
|
|
y: { beginAtZero: true, title: { display: true, text: 'Nombre de villes' } },
|
|
x: { title: { display: true, text: 'Habitants par lieu (arrondi à 10)' } }
|
|
}
|
|
}
|
|
});
|
|
// Histogramme lieux/habitant (pas de 0.01)
|
|
if(!data.histogram_001){
|
|
document.getElementById('distributionVillesLieuxParHabitant').insertAdjacentHTML('afterend', '<div class="alert alert-danger">Erreur : données histogram_001 absentes. Cliquez sur "Régénérer les statistiques".</div>');
|
|
return;
|
|
}
|
|
const ctx = document.getElementById('distributionVillesLieuxParHabitant').getContext('2d');
|
|
const labels = Object.keys(data.histogram_001);
|
|
const values = Object.values(data.histogram_001);
|
|
const villesByBin001 = villesData.villes_by_bin_001 || {};
|
|
console.log('LPH', labels, villesByBin001);
|
|
new Chart(ctx, {
|
|
type: 'bar',
|
|
data: {
|
|
labels: labels,
|
|
datasets: [{
|
|
label: "Nombre de villes",
|
|
data: values,
|
|
backgroundColor: 'rgba(153, 102, 255, 0.7)',
|
|
borderColor: 'rgba(153, 102, 255, 1)',
|
|
borderWidth: 1
|
|
}]
|
|
},
|
|
options: {
|
|
responsive: true,
|
|
maintainAspectRatio: true,
|
|
plugins: {
|
|
legend: { display: false },
|
|
title: { display: true, text: "Distribution des villes par lieux/habitant (par pas de 0,01)" },
|
|
tooltip: {
|
|
callbacks: {
|
|
afterBody: function(context) {
|
|
const bin = context[0].label;
|
|
const villes = villesByBin001[bin] || [];
|
|
if(villes.length > 0){
|
|
return ['Villes :'].concat(villes.map(v => '• ' + v));
|
|
}
|
|
return [];
|
|
}
|
|
}
|
|
}
|
|
},
|
|
scales: {
|
|
y: { beginAtZero: true, title: { display: true, text: 'Nombre de villes' } },
|
|
x: { title: { display: true, text: 'Lieux par habitant (arrondi à 0,01)' } }
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %} |