Pour certains organismes, aucun point ne s'affiche sur la carte #121

Open
opened 2026-07-15 23:03:17 +02:00 by ColinMaudry · 1 comment
ColinMaudry commented 2026-07-15 23:03:17 +02:00 (Migrated from github.com)

Exemple :

  • /acheteurs/21240037800015 (Bergerac)
  • /titulaires/32933888301011

Le problème touche aussi de nombreuses configurations (ensembles de filtres) de l'observatoire, particulièrement lorsqu'il y a beaucoup de marchés. Mais celle-ci fonctionne: /observatoire?annee=2020&titulaire_id=32933888301011. C'est suprenant puisque la page du titulaire filtré (/titulaires/32933888301011 et filtré sur l'année 2020 comme dans le filtre observatoire), ne fonctionne pas.

Par contre pour ce titulaire pas de problème : /titulaires/32420439500028. J'ai du mal à voir un pattern.

Exemple : - /acheteurs/21240037800015 (Bergerac) - /titulaires/32933888301011 Le problème touche aussi de nombreuses configurations (ensembles de filtres) de l'observatoire, particulièrement lorsqu'il y a beaucoup de marchés. Mais celle-ci fonctionne: /observatoire?annee=2020&titulaire_id=32933888301011. C'est suprenant puisque la page du titulaire filtré (/titulaires/32933888301011 et filtré sur l'année 2020 comme dans le filtre observatoire), ne fonctionne pas. Par contre pour ce titulaire pas de problème : /titulaires/32420439500028. J'ai du mal à voir un pattern.
ColinMaudry commented 2026-07-19 12:53:08 +02:00 (Migrated from github.com)

Diagnostic

La carte dash-leaflet s'affichait sans aucun point (fond de carte + zoom OK, 0 marqueur) sur certains organismes / certaines vues de l'observatoire.

Cause racine : le bundle dash-ag-grid (async-community.js, chargé en lazy chunk dès qu'une AgGrid monte) fuit un helper esbuild __spreadValues sous le nom global L, ce qui écrase le window.L de Leaflet. Nos fonctions clientside pointToLayer/clusterToLayer (src/assets/dash_clientside.js) lisent le L global → récupèrent le helper au lieu de Leaflet → L.point/L.circleMarker is not a function → l'exception casse tout le calque GeoJSON → carte vide.

dash-leaflet appelle pointToLayer(feature, latlng) sans passer Leaflet en argument : ces fonctions dépendent donc forcément du global.

Pourquoi le pattern semblait aléatoire (« surtout quand beaucoup de marchés ») : c'est une course entre le chargement du chunk AG Grid et le rendu de la carte. Plus il y a de points, plus la carte rend tard, plus le clobber a déjà eu lieu. D'où :

  • /observatoire?annee=2020&titulaire_id=… (peu de points) → marche parfois ;
  • /titulaires/… (tous millésimes, beaucoup de points) → cassé.

Symptôme diagnostique dans la console : typeof window.L === "function" et window.L.version === undefined (le vrai L de Leaflet est un objet avec .version, .circleMarker, .point…).

À noter : impossible à reproduire avec un repro dash-leaflet minimal (sans AG Grid, window.L reste Leaflet). Il a fallu lancer la vraie app avec les données de prod et lire la console navigateur.

Solution

Dans src/assets/dash_clientside.js, une IIFE en tête intercepte les affectations de window.L via Object.defineProperty et mémorise en privé le vrai Leaflet (celui exposant circleMarker), sans changer ce que window.L renvoie (AG Grid continue d'utiliser son helper). window.leafletReal() rend le vrai Leaflet ; pointToLayer/clusterToLayer font const L = window.leafletReal(); en première ligne.

Vérifié sur la vraie app (données de prod) : carte peuplée, plus d'erreur console, rendu OK après changement d'année. S'applique aussi à /acheteur et /observatoire (même fichier).

## Diagnostic La carte dash-leaflet s'affichait **sans aucun point** (fond de carte + zoom OK, 0 marqueur) sur certains organismes / certaines vues de l'observatoire. **Cause racine :** le bundle **dash-ag-grid** (`async-community.js`, chargé en lazy chunk dès qu'une AgGrid monte) fuit un helper esbuild `__spreadValues` sous le nom **global `L`**, ce qui **écrase le `window.L` de Leaflet**. Nos fonctions clientside `pointToLayer`/`clusterToLayer` (`src/assets/dash_clientside.js`) lisent le `L` global → récupèrent le helper au lieu de Leaflet → `L.point`/`L.circleMarker is not a function` → l'exception casse tout le calque GeoJSON → carte vide. dash-leaflet appelle `pointToLayer(feature, latlng)` **sans** passer Leaflet en argument : ces fonctions dépendent donc forcément du global. **Pourquoi le pattern semblait aléatoire** (« surtout quand beaucoup de marchés ») : c'est une **course** entre le chargement du chunk AG Grid et le rendu de la carte. Plus il y a de points, plus la carte rend tard, plus le clobber a déjà eu lieu. D'où : - `/observatoire?annee=2020&titulaire_id=…` (peu de points) → marche parfois ; - `/titulaires/…` (tous millésimes, beaucoup de points) → cassé. Symptôme diagnostique dans la console : `typeof window.L === "function"` et `window.L.version === undefined` (le vrai `L` de Leaflet est un objet avec `.version`, `.circleMarker`, `.point`…). À noter : impossible à reproduire avec un repro dash-leaflet minimal (sans AG Grid, `window.L` reste Leaflet). Il a fallu lancer la vraie app avec les données de prod et lire la console navigateur. ## Solution Dans `src/assets/dash_clientside.js`, une IIFE en tête intercepte les affectations de `window.L` via `Object.defineProperty` et **mémorise en privé le vrai Leaflet** (celui exposant `circleMarker`), **sans changer ce que `window.L` renvoie** (AG Grid continue d'utiliser son helper). `window.leafletReal()` rend le vrai Leaflet ; `pointToLayer`/`clusterToLayer` font `const L = window.leafletReal();` en première ligne. Vérifié sur la vraie app (données de prod) : carte peuplée, plus d'erreur console, rendu OK après changement d'année. S'applique aussi à `/acheteur` et `/observatoire` (même fichier).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: colin/colibre#121