diff --git a/assets/js/map-utils.js b/assets/js/map-utils.js
index 0172253..e69de29 100644
--- a/assets/js/map-utils.js
+++ b/assets/js/map-utils.js
@@ -1,161 +0,0 @@
-// Fonctions utilitaires pour la gestion des marqueurs et popups sur la carte
-
-function getCompletionColor(completion) {
- if (completion === undefined || completion === null) {
- return '#808080'; // Gris pour pas d'information
- }
- // Convertir le pourcentage en couleur verte (0% = blanc, 100% = vert foncé)
- const intensity = Math.floor((completion / 100) * 255);
- return `rgb(0, ${intensity}, 0)`;
-}
-
-function calculateCompletion(element) {
- let completionCount = 0;
- let totalFields = 0;
- let missingFields = [];
-
- const fieldsToCheck = [
- { name: 'name', label: 'Nom du commerce' },
- { name: 'contact:street', label: 'Rue' },
- { name: 'contact:housenumber', label: 'Numéro' },
- { name: 'opening_hours', label: 'Horaires d\'ouverture' },
- { name: 'contact:website', label: 'Site web' },
- { name: 'contact:phone', label: 'Téléphone' },
- { name: 'wheelchair', label: 'Accessibilité PMR' }
- ];
-
- fieldsToCheck.forEach(field => {
- totalFields++;
- if (element.tags && element.tags[field.name]) {
- completionCount++;
- } else {
- missingFields.push(field.label);
- }
- });
-
- return {
- percentage: (completionCount / totalFields) * 100,
- missingFields: missingFields
- };
-}
-
-function createPopupContent(element) {
- const completion = calculateCompletion(element);
- let content = `
-
-
${element.tags?.name || 'Sans nom'}
-
-
- `;
-
- if (completion.percentage < 100) {
- content += `
-
-
Informations manquantes :
-
- ${completion.missingFields.map(field => `- ${field}
`).join('')}
-
-
- `;
- }
-
- content += '';
-
- // Ajouter tous les tags
- if (element.tags) {
- for (const tag in element.tags) {
- content += `${tag} | ${element.tags[tag]} |
`;
- }
- }
-
- content += '
';
- return content;
-}
-
-function updateMarkers(features, map, currentMarkerType, dropMarkers, overpassData) {
- // Supprimer tous les marqueurs existants
- dropMarkers.forEach(marker => marker.remove());
- dropMarkers = [];
-
- features.forEach(feature => {
- if (currentMarkerType === 'drop') {
- const el = document.createElement('div');
- el.className = 'marker';
- el.style.backgroundColor = getCompletionColor(feature.properties.completion);
- el.style.width = '15px';
- el.style.height = '15px';
- el.style.borderRadius = '50%';
- el.style.border = '2px solid white';
- el.style.cursor = 'pointer';
-
- const marker = new maplibregl.Marker(el)
- .setLngLat(feature.geometry.coordinates)
- .addTo(map);
-
- // Ajouter l'événement de clic
- el.addEventListener('click', () => {
- const element = overpassData[feature.properties.id];
- if (element) {
- const popup = new maplibregl.Popup()
- .setLngLat(feature.geometry.coordinates)
- .setHTML(createPopupContent(element));
- popup.addTo(map);
- }
- });
-
- dropMarkers.push(marker);
- } else {
- // Créer un cercle pour chaque feature
- const circle = turf.circle(
- feature.geometry.coordinates,
- 0.5, // rayon en kilomètres
- { steps: 64, units: 'kilometers' }
- );
-
- // Ajouter la source et la couche pour le cercle
- if (!map.getSource(feature.id)) {
- map.addSource(feature.id, {
- type: 'geojson',
- data: circle
- });
-
- map.addLayer({
- id: feature.id,
- type: 'fill',
- source: feature.id,
- paint: {
- 'fill-color': getCompletionColor(feature.properties.completion),
- 'fill-opacity': 0.6,
- 'fill-outline-color': '#fff'
- }
- });
-
- // Ajouter l'événement de clic sur le cercle
- map.on('click', feature.id, () => {
- const element = overpassData[feature.properties.id];
- if (element) {
- const popup = new maplibregl.Popup()
- .setLngLat(feature.geometry.coordinates)
- .setHTML(createPopupContent(element));
- popup.addTo(map);
- }
- });
- }
- }
- });
-
- return dropMarkers;
-}
-
-// Exporter les fonctions
-window.getCompletionColor = getCompletionColor;
-window.calculateCompletion = calculateCompletion;
-window.createPopupContent = createPopupContent;
-window.updateMarkers = updateMarkers;
\ No newline at end of file
diff --git a/templates/admin/stats.html.twig b/templates/admin/stats.html.twig
index 2cf0edf..0822950 100644
--- a/templates/admin/stats.html.twig
+++ b/templates/admin/stats.html.twig
@@ -400,6 +400,170 @@
let dropMarkers = []; // Tableau pour stocker les marqueurs en goutte
let contextMenu = null; // Menu contextuel
+
+function calculateCompletion(element) {
+ let completionCount = 0;
+ let totalFields = 0;
+ let missingFields = [];
+
+ const fieldsToCheck = [
+ { name: 'name', label: 'Nom du commerce' },
+ { name: 'contact:street', label: 'Rue' },
+ { name: 'contact:housenumber', label: 'Numéro' },
+ { name: 'opening_hours', label: 'Horaires d\'ouverture' },
+ { name: 'contact:website', label: 'Site web' },
+ { name: 'contact:phone', label: 'Téléphone' },
+ { name: 'wheelchair', label: 'Accessibilité PMR' }
+ ];
+
+ fieldsToCheck.forEach(field => {
+ totalFields++;
+ if (element.tags && element.tags[field.name]) {
+ completionCount++;
+ } else {
+ missingFields.push(field.label);
+ }
+ });
+
+ return {
+ percentage: (completionCount / totalFields) * 100,
+ missingFields: missingFields
+ };
+}
+// Fonctions utilitaires pour la gestion des marqueurs et popups sur la carte
+
+function getCompletionColor(completion) {
+ if (completion === undefined || completion === null) {
+ return '#808080'; // Gris pour pas d'information
+ }
+ // Convertir le pourcentage en couleur verte (0% = blanc, 100% = vert foncé)
+ const intensity = Math.floor((completion / 100) * 255);
+ return `rgb(0, ${intensity}, 0)`;
+}
+
+
+function createPopupContent(element) {
+ const completion = calculateCompletion(element);
+ let content = `
+
+
${element.tags?.name || 'Sans nom'}
+
+
+ `;
+
+ if (completion.percentage < 100) {
+ content += `
+
+
Informations manquantes :
+
+ ${completion.missingFields.map(field => `- ${field}
`).join('')}
+
+
+ `;
+ }
+
+ content += '';
+
+ // Ajouter tous les tags
+ if (element.tags) {
+ for (const tag in element.tags) {
+ content += `${tag} | ${element.tags[tag]} |
`;
+ }
+ }
+
+ content += '
';
+ return content;
+}
+
+function updateMarkers(features, map, currentMarkerType, dropMarkers, overpassData) {
+ // Supprimer tous les marqueurs existants
+ dropMarkers.forEach(marker => marker.remove());
+ dropMarkers = [];
+
+ features.forEach(feature => {
+ if (currentMarkerType === 'drop') {
+ const el = document.createElement('div');
+ el.className = 'marker';
+ el.style.backgroundColor = getCompletionColor(feature.properties.completion);
+ el.style.width = '15px';
+ el.style.height = '15px';
+ el.style.borderRadius = '50%';
+ el.style.border = '2px solid white';
+ el.style.cursor = 'pointer';
+
+ const marker = new maplibregl.Marker(el)
+ .setLngLat(feature.geometry.coordinates)
+ .addTo(map);
+
+ // Ajouter l'événement de clic
+ el.addEventListener('click', () => {
+ const element = overpassData[feature.properties.id];
+ if (element) {
+ const popup = new maplibregl.Popup()
+ .setLngLat(feature.geometry.coordinates)
+ .setHTML(createPopupContent(element));
+ popup.addTo(map);
+ }
+ });
+
+ dropMarkers.push(marker);
+ } else {
+ // Créer un cercle pour chaque feature
+ const circle = turf.circle(
+ feature.geometry.coordinates,
+ 0.5, // rayon en kilomètres
+ { steps: 64, units: 'kilometers' }
+ );
+
+ // Ajouter la source et la couche pour le cercle
+ if (!map.getSource(feature.id)) {
+ map.addSource(feature.id, {
+ type: 'geojson',
+ data: circle
+ });
+
+ map.addLayer({
+ id: feature.id,
+ type: 'fill',
+ source: feature.id,
+ paint: {
+ 'fill-color': getCompletionColor(feature.properties.completion),
+ 'fill-opacity': 0.6,
+ 'fill-outline-color': '#fff'
+ }
+ });
+
+ // Ajouter l'événement de clic sur le cercle
+ map.on('click', feature.id, () => {
+ const element = overpassData[feature.properties.id];
+ if (element) {
+ const popup = new maplibregl.Popup()
+ .setLngLat(feature.geometry.coordinates)
+ .setHTML(createPopupContent(element));
+ popup.addTo(map);
+ }
+ });
+ }
+ }
+ });
+
+ return dropMarkers;
+}
+
+// Exporter les fonctions
+window.getCompletionColor = getCompletionColor;
+window.calculateCompletion = calculateCompletion;
+window.createPopupContent = createPopupContent;
+window.updateMarkers = updateMarkers;
+
+
function calculateCompletionDistribution(elements) {
// Créer des buckets de 10% (0-10%, 10-20%, etc.)
const buckets = Array(11).fill(0);