Skip to content

Commit 8b44327

Browse files
authored
feat(LayerSwitcher) : Mise en place de tooltips HTML avancés au survol des couches (#420)
1 parent 39de866 commit 8b44327

File tree

9 files changed

+422
-19
lines changed

9 files changed

+422
-19
lines changed

DRAFT_CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ __DATE__
1818
- Territories : Ajout d'un menu option pour permettre de charger une configuration des territoires (#408)
1919
- LayerSwitcher : Possibilité d'ajouter des outils externes (#418)
2020
- LayerSwitcher : Option pour verrouiller une couche (#414)
21+
- LayerSwitcher : Tooltips avancés en HTML sur le survol des couches (#420)
2122

2223
* 🔨 [Changed]
2324

doc/NOTE-LAYERSWITCHER.md

Lines changed: 237 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,181 @@ layerSwitcher.on("layerswitcher:change:visibility", e => console.log("Visibilit
6868
`LayerSwitcher` facilite la gestion interactive des couches sur une carte OpenLayers,
6969
tout en offrant de nombreuses options de personnalisation et une API d’événements riche pour les développeurs.
7070

71+
## Voici un résumé des principales options disponibles pour le contrôle **LayerSwitcher**
72+
73+
- **id** : Identifiant unique du widget (utile si plusieurs LayerSwitcher sur la même page).
74+
- **collapsed** *(booléen, défaut : true)* : Définit si le widget est replié (caché) ou déplié au chargement.
75+
- **draggable** *(booléen)* : Permet de déplacer le panneau du LayerSwitcher à la souris.
76+
- **counter** *(booléen)* : Affiche un compteur du nombre de couches visibles.
77+
- **panel** *(booléen)* : Affiche un en-tête (header) dans le panneau du LayerSwitcher.
78+
- **gutter** *(booléen)* : Ajoute ou retire l’espace (gutter) autour du panneau.
79+
- **allowEdit** *(booléen, défaut : true)* : Affiche le bouton d’édition pour les couches éditables (vecteur).
80+
- **allowGrayScale** *(booléen, défaut : true)* : Affiche le bouton N&B (niveaux de gris) pour les couches compatibles.
81+
- **allowTooltips** *(booléen, défaut : false)* : Active l’affichage des info-bulles (tooltips) sur les éléments du widget.
82+
- **advancedTools** *(array)* : Liste d’outils personnalisés à afficher pour chaque couche (boutons d’action, icônes, callbacks, etc.).
83+
- **layers** *(array)* : Liste des couches à configurer à l’initialisation, chaque entrée pouvant contenir :
84+
- **layer** : Objet `ol.layer.Layer` à gérer.
85+
- **config** : Métadonnées associées (titre, description, légendes, métadonnées, quicklookUrl, etc.).
86+
87+
---
88+
89+
**Résumé** :
90+
Les options du LayerSwitcher permettent de personnaliser l’apparence, le comportement, les fonctionnalités et les actions disponibles pour chaque couche, afin d’adapter le widget à vos besoins cartographiques et ergonomiques.
91+
92+
## Voici un exemple complet d’utilisation du contrôle **LayerSwitcher** avec OpenLayers
93+
94+
````javascript
95+
import 'ol/ol.css';
96+
import Map from 'ol/Map';
97+
import View from 'ol/View';
98+
import TileLayer from 'ol/layer/Tile';
99+
import OSM from 'ol/source/OSM';
100+
import VectorLayer from 'ol/layer/Vector';
101+
import VectorSource from 'ol/source/Vector';
102+
import {fromLonLat} from 'ol/proj';
103+
import LayerSwitcher from 'src/packages/Controls/LayerSwitcher/LayerSwitcher.js';
104+
105+
// Création des couches
106+
const osmLayer = new TileLayer({
107+
source: new OSM(),
108+
visible: true,
109+
opacity: 1,
110+
title: 'Fond OpenStreetMap'
111+
});
112+
113+
const vectorLayer = new VectorLayer({
114+
source: new VectorSource(),
115+
visible: true,
116+
opacity: 0.7,
117+
title: 'Annotations'
118+
});
119+
120+
// Création de la carte
121+
const map = new Map({
122+
target: 'map',
123+
layers: [osmLayer, vectorLayer],
124+
view: new View({
125+
center: fromLonLat([2.35, 48.85]), // Paris
126+
zoom: 12
127+
})
128+
});
129+
130+
// Ajout du LayerSwitcher avec options et métadonnées
131+
const layerSwitcher = new LayerSwitcher({
132+
layers: [
133+
{
134+
layer: osmLayer,
135+
config: {
136+
title: "Fond OpenStreetMap",
137+
description: "Fond cartographique OSM",
138+
locked: true // couche verrouillée
139+
}
140+
},
141+
{
142+
layer: vectorLayer,
143+
config: {
144+
title: "Annotations",
145+
description: "Couches d’annotations éditables"
146+
}
147+
}
148+
],
149+
options: {
150+
collapsed: false,
151+
panel: true,
152+
counter: true,
153+
allowEdit: true,
154+
allowGrayScale: true,
155+
allowTooltips: true,
156+
advancedTools: [
157+
{
158+
label: 'Exporter',
159+
icon: '📤',
160+
cb: (e, instance, layer, options) => {
161+
alert("Export de la couche : " + layer.get("title"));
162+
}
163+
},
164+
{
165+
label: 'Info',
166+
icon: '<svg width="16" height="16" fill="currentColor"><circle cx="8" cy="8" r="7" stroke="black" stroke-width="1" fill="none"/><text x="8" y="12" text-anchor="middle" font-size="10" fill="black">i</text></svg>',
167+
// Pas de cb : déclenche l'événement layerswitcher:custom
168+
}
169+
]
170+
}
171+
});
172+
173+
map.addControl(layerSwitcher);
174+
175+
// Exemple d’écoute d’événements
176+
layerSwitcher.on("layerswitcher:add", function (e) {
177+
console.log("Couche ajoutée :", e.layer);
178+
});
179+
layerSwitcher.on("layerswitcher:remove", function (e) {
180+
console.log("Couche supprimée :", e.layer);
181+
});
182+
layerSwitcher.on("layerswitcher:edit", function (e) {
183+
alert("Edition de la couche : " + e.layer.get("title"));
184+
});
185+
layerSwitcher.on("layerswitcher:custom", function (e) {
186+
alert("Action personnalisée sur : " + e.layer.get("title") + " (" + e.action + ")");
187+
});
188+
````
189+
190+
**À placer dans une page HTML avec un conteneur** :
191+
192+
```html
193+
<div id="map" style="width:100%;height:600px;"></div>
194+
<script type="module" src="example-layerswitcher.js"></script>
195+
```
196+
197+
---
198+
199+
**Ce que montre cet exemple :**
200+
- Création de couches raster et vecteur,
201+
- Ajout de métadonnées (titre, description, verrouillage),
202+
- Activation des options avancées (édition, N&B, tooltips, outils personnalisés),
203+
- Gestion des événements du LayerSwitcher,
204+
- Utilisation d’outils avancés avec ou sans callback.
205+
206+
Cet exemple est prêt à l’emploi pour tester toutes les fonctionnalités principales du LayerSwitcher.
207+
208+
## Voici une explication sur l’objet `layerOptions` dans le LayerSwitcher
209+
210+
### Fonctionnement de l’objet `layerOptions`
211+
212+
L’objet `layerOptions` est une structure centrale utilisée en interne par le LayerSwitcher pour stocker toutes les informations et états associés à chaque couche affichée dans le widget.
213+
214+
### Où est-il créé ?
215+
`layerOptions` est construit dans la méthode privée `_createLayerDiv(layerOptions)` et lors de l’ajout d’une couche via `addLayer` ou `_addMapLayers`.
216+
Il regroupe à la fois :
217+
- les propriétés de la couche OpenLayers (`layer`, `id`, `opacity`, `visibility`, etc.),
218+
- les métadonnées de configuration (titre, description, légendes, etc.),
219+
- les états d’interface (editable, grayable, inRange, locked, etc.),
220+
- les références DOM (div associée à la couche).
221+
222+
### Principaux champs de `layerOptions` :
223+
224+
- **layer** : la référence à l’objet `ol.layer.Layer` concerné.
225+
- **id** : identifiant unique de la couche dans le LayerSwitcher.
226+
- **name, service, type** : informations complémentaires (souvent pour les couches Geoportail).
227+
- **opacity, visibility, grayscale, locked** : états d’affichage de la couche.
228+
- **inRange** : indique si la couche est visible dans la vue courante (zoom/emprise).
229+
- **title, description** : informations affichées dans la liste et les tooltips.
230+
- **legends, metadata, quicklookUrl** : ressources associées à la couche.
231+
- **editable, grayable** : indique si la couche est éditable ou peut passer en N&B.
232+
- **advancedTools** : liste des outils personnalisés à afficher pour la couche.
233+
- **div** : référence à la div DOM représentant la couche dans le LayerSwitcher.
234+
235+
### Utilité
236+
237+
- Permet de centraliser toutes les informations nécessaires à l’affichage, à l’interaction et à la gestion de chaque couche dans le widget.
238+
- Facilite la synchronisation entre l’état de la carte, la configuration utilisateur et l’interface graphique.
239+
- Sert de point d’accès unique pour toutes les opérations (édition, suppression, changement d’opacité, etc.).
240+
241+
---
242+
243+
**Résumé :**
244+
`layerOptions` est l’objet de référence pour chaque couche dans le LayerSwitcher : il regroupe toutes les données, états et références nécessaires à la gestion et à l’affichage de la couche dans le widget.
245+
71246
## Voici une explication sur la notion de couches « grisées » (hors plage de visibilité, via `isInRange`) dans la classe `LayerSwitcher`
72247

73248
### Couches grisées (isInRange)
@@ -230,7 +405,7 @@ const layerSwitcher = new LayerSwitcher({
230405
**Résumé :**
231406
Le mode N&B dans le LayerSwitcher permet d’afficher certaines couches en niveaux de gris, offrant ainsi une meilleure lisibilité et une personnalisation avancée de la carte pour l’utilisateur.
232407

233-
## Voici une explication à ajouter à votre documentation concernant les **actions utilisateurs via l’option `advancedTools`** dans le LayerSwitcher
408+
## Voici une explication concernant les **actions utilisateurs via l’option `advancedTools`** dans le LayerSwitcher
234409

235410
### Actions utilisateurs via l’option `advancedTools`
236411

@@ -348,6 +523,21 @@ Voici quelques exemples concrets :
348523
}
349524
```
350525

526+
- **Bouton avec un icone dsfr**
527+
Permet d'utiliser les icones du DSFR :
528+
```javascript
529+
{
530+
label: 'Exporter',
531+
icon: 'fr-icon-export',
532+
cb: (e, instance, layer, options) => {
533+
alert("Export de la couche : " + layer.get("title"));
534+
},
535+
styles: {
536+
color: "blue"
537+
}
538+
}
539+
```
540+
351541
Si l’option `cb` n’est pas renseignée dans un objet `advancedTools`, le bouton est tout de même affiché et, lors du clic, **un événement personnalisé est déclenché** par le LayerSwitcher (généralement `layerswitcher:custom`).
352542
Cet événement contient les informations sur le bouton cliqué, la couche concernée, etc.
353543

@@ -366,3 +556,49 @@ Cela permet de centraliser la gestion des actions non définies directement par
366556

367557
**Résumé :**
368558
L’option `advancedTools` du LayerSwitcher permet d’ajouter facilement des boutons d’action personnalisés pour chaque couche, afin d’enrichir l’interface et de proposer des fonctionnalités avancées adaptées à vos besoins.
559+
560+
## Voici une explication détaillée du fonctionnement des **tooltips** dans le LayerSwitcher
561+
562+
---
563+
564+
### Fonctionnement des tooltips dans le LayerSwitcher
565+
566+
Le LayerSwitcher propose une option `allowTooltips` qui permet d’afficher des info-bulles (tooltips) sur les éléments de l’interface, afin d’améliorer l’ergonomie et l’accessibilité.
567+
568+
### Initialisation
569+
570+
- Lors de l’ajout du contrôle à la carte (`setMap`), si l’option `allowTooltips` est activée, le module `ToolTips` initialise un conteneur HTML dédié pour les info-bulles.
571+
- Ce conteneur est un `<div>` positionné en absolu, stylisé pour ressembler à une info-bulle classique.
572+
573+
### Activation sur les éléments
574+
575+
- Chaque nom de couche du LayerSwitcher recoit un attribut `data-tooltip` contenant le texte à afficher.
576+
- Le module `ToolTips` ajoute des écouteurs d’événements `mouseenter` et `mouseleave` sur ces éléments :
577+
- Au survol (`mouseenter`), le contenu du tooltip est affiché près du curseur.
578+
- À la sortie (`mouseleave`), le tooltip disparaît.
579+
580+
### Contenu des tooltips
581+
582+
- Pour le nom d’une couche, le tooltip affiche généralement le titre complet ou la description.
583+
- Pour les couches hors plage ou verrouillées, un message spécifique explique la raison de l’état.
584+
585+
### Utilité
586+
587+
- **Accessibilité** : Les tooltips aident à comprendre la fonction de chaque élément, même sans documentation.
588+
- **Aide contextuelle** : Ils fournissent des explications sur l’état ou l’action possible.
589+
- **Ergonomie** : Ils évitent la surcharge visuelle tout en offrant une aide à la demande.
590+
591+
### Exemple d’activation
592+
593+
```javascript
594+
const layerSwitcher = new LayerSwitcher({
595+
options: {
596+
allowTooltips: true // Active l’affichage des tooltips
597+
}
598+
});
599+
```
600+
601+
---
602+
603+
**Résumé :**
604+
Les tooltips dans le LayerSwitcher sont des info-bulles contextuelles qui s’affichent au survol des éléments, facilitant la compréhension et l’utilisation du gestionnaire de couches, notamment pour les utilisateurs novices ou en situation de handicap.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "geopf-extensions-openlayers",
33
"description": "French Geoportal Extensions for OpenLayers libraries",
4-
"version": "1.0.0-beta.5-421",
5-
"date": "28/07/2025",
4+
"version": "1.0.0-beta.5-420",
5+
"date": "25/07/2025",
66
"module": "src/index.js",
77
"directories": {},
88
"engines": {
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{{#extend "ol-sample-modules-dsfr-layout"}}
2+
3+
{{#content "vendor"}}
4+
5+
<link rel="stylesheet" href="{{ baseurl }}/dist/modules/GpfExtOlLayerSwitcher.css" />
6+
<script src="{{ baseurl }}/dist/modules/GpfExtOlLayerSwitcher.js"></script>
7+
<script src="{{ baseurl }}/dist/modules/GpfExtOlLayers.js"></script>
8+
{{/content}}
9+
10+
{{#content "head"}}
11+
<title>Sample openlayers LayerSwitcher</title>
12+
{{/content}}
13+
14+
{{#content "style"}}
15+
<style>
16+
div#map {
17+
width: 100%;
18+
height: 500px;
19+
}
20+
</style>
21+
{{/content}}
22+
23+
{{#content "body"}}
24+
<h2>Ajout du gestionnaire de couches avec les options par défaut</h2>
25+
<!-- map -->
26+
<div id="map">
27+
</div>
28+
{{/content}}
29+
30+
{{#content "js"}}
31+
<script type="text/javascript">
32+
var map;
33+
var createMap = function () {
34+
// on cache l'image de chargement du Géoportail.
35+
document.getElementById('map').style.backgroundImage = 'none';
36+
37+
map = new ol.Map({
38+
target : "map",
39+
view : new ol.View({
40+
center : [288074.8449901076, 6247982.515792289],
41+
zoom : 16
42+
}),
43+
layers : [
44+
new ol.layer.GeoportalWMTS({
45+
layer : "GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2"
46+
})
47+
]
48+
});
49+
50+
var layerSwitcher = new ol.control.LayerSwitcher({
51+
options :{
52+
panel: true,
53+
allowTooltips: true
54+
}
55+
});
56+
map.addControl(layerSwitcher);
57+
58+
// Couches
59+
var plan = new ol.layer.GeoportalMapBox({
60+
layer : "PLAN.IGN"
61+
});
62+
plan.on("mapbox:style:loaded", (e) => {
63+
console.log(e);
64+
});
65+
map.addLayer(plan);
66+
};
67+
Gp.Services.getConfig({
68+
customConfigFile : "{{ resources }}/data/configuration/config-catalog.json",
69+
callbackSuffix : "",
70+
// apiKey: "{{ apikey }}",
71+
timeOut : 20000,
72+
onSuccess : createMap,
73+
onFailure : (e) => {
74+
console.error(e);
75+
}
76+
});
77+
</script>
78+
{{/content}}
79+
80+
{{/extend}}

0 commit comments

Comments
 (0)