Rechercher dans le blog

Configurez les popups de vos couches cartographiques web

Après avoir créé une carte web à l'intérieur de laquelle nous avons ajouté une couche de données issues d'un fichier GeoJSON et dont nous avons modifié la symbologie en utilisant des WebStyleSymbols, il est temps de continuer notre série de tutoriels sur l'API JavaScript d'ArcGIS en configurant les popups de la couche.
Les popups, ou fenêtres contextuelles, sont très pratiques car elles permettent à l'utilisateur d'obtenir davantage d'information sur une entité en cliquant dessus. La popup est capable d'afficher plusieurs types de contenus : du texte (pouvant être dynamiquement issu de la table attributaire de la donnée), des relations vers des tables associées,  des expressions Arcade, ou encore des médias comme des images ou des graphiques. 
Comme d'habitude, vous pouvez suivre le tutoriel pas à pas ci-dessous pour apprendre à implémenter des popups, ou bien vous pouvez aller consulter ce CodePen pour tester directement le code de manière interactive.
Afin de créer nos popups, nous allons d'abord individuellement configurer le texte et l'image qu'elles vont accueillir, puis nous consoliderons ces différents éléments au sein du contenu du modèle de popup de la couche.

Configurer du texte dynamique

Nous allons commencer par configurer le texte qui s'affichera dans la fenêtre contextuelle. Il sera constitué d'un mélange de texte commun à toutes les entités, et de texte se mettant à jour dynamiquement selon l'entité sélectionnée en allant chercher des informations dans la table attributaire de la couche.
Pour cela, nous allons créer du contenu de type texte en nous appuyant sur le module TextContent de l'API, ce qui signifie que nous devons commencer par mettre à jour la directive require comme nous l'avions fait dans le second épisode de la série.
require([
        "esri/Map",
        "esri/Basemap",
        "esri/views/SceneView",
        "esri/layers/GeoJSONLayer",
        "esri/popup/content/TextContent",
      ], 
        
        (Map, Basemap, SceneView ,GeoJSONLayer,TextContent) => {
Afin de pouvoir afficher une partie du texte avant l'image et une partie du texte après l'image, nous allons créer deux instances TextContent distinctes.

const textElement1 = new TextContent();
textElement1.text = "Cet arbre remarquable est un <b>{com_nom_usuel}</b>(nom vernaculaire) ou <b>{com_nom_latin}</b>(nom latin). 
Il appartient à l'espèce {arbres_espece} du genre {arbres_genre} et mesure {arbres_hauteurenm} mètres  pour une circonférence de {arbres_circonferenceencm} centimètres. 
<br>
Date de plantation : {com_annee_plantation}" const textElement2 = new TextContent(); textElement2.text = "{com_descriptif}"
Nous commençons par créer une instance de TextContent, puis nous allons accéder à sa propriété text. Notez qu'ici, nous accédons à la propriété une fois que l'instance est créée, est non pas au moment de la création de l'instance comme nous avions pu le faire juste à présent (pour notre application, cela ne change rien mais nous permet de voir les deux manières de procéder). Nous pouvons désormais écrire le texte que nous souhaitons voir apparaître en paramètre de la propriété. 
En écrivant le nom d'un champ de la table attributaire de la donnée entre crochets {}, le texte sera mis à jour dynamiquement en fonction du contenu de la table attributaire dans ce champ pour l'entité sélectionnée. Cela demande une inspection préalable de vos données, pour savoir quel nom de champ renseigner.
Notez que vous pouvez utiliser des balises html classiques (par exemple ici <b> et <br>) pour mettre en forme le texte.
Nous répétons ensuite l'opération une seconde fois pour la deuxième partie du texte.

Configurer une image

Nous allons désormais faire en sorte d'ajouter une image aux popups. 
La table attributaire contient un champ, "com_url_photo1", contenant un lien vers des données hébergées en ligne. Afin d'afficher l'image, nous utiliserons du contenu de type media en faisant appel au module MediaContent. La propriété mediaInfos de celui-ci  nous permet d'afficher l'image devant être contenue dans une instance d'ImageMediaInfo. Cette instance est elle-même paramétrée avec une propriété de légende (caption), qui va venir chercher dans la table attributaire le contenu du champ "com_resume", et une propriété valeur (value). Cette deuxième propriété est configurée avec une instance d'ImageMediaInfoValue, qui prend en propriété la sourceURL, c'est à dire un lien vers l'image, ici retrouvé dans le champ "com_url_photo1".
Dans le code, nous commençons par créer la dernière instance décrite ci-dessus, pour qu'elle puisse être ainsi utilisée dans l'instance suivante, et ainsi de suite en cascade. Voici ce que cela donne :
let imageMediaInfoValue = new ImageMediaInfoValue({
   sourceURL: "{com_url_photo1}"
});

let imageElement = new ImageMediaInfo({
   caption: "{com_resume}",
   value: imageMediaInfoValue
});

let mediaElement = new MediaContent({
    mediaInfos: [ imageElement ]
});
Pensez également à compléter le require, qui avec ces nouveaux modules devrait ressembler à cela :
require([
        "esri/Map",
        "esri/Basemap",
        "esri/views/SceneView",
        "esri/layers/GeoJSONLayer",
        "esri/popup/content/TextContent",
        "esri/popup/content/MediaContent",
        "esri/popup/content/ImageMediaInfo",
        "esri/popup/content/support/ImageMediaInfoValue"
      ], 
        
        (Map, Basemap, SceneView ,GeoJSONLayer,TextContent,MediaContent,ImageMediaInfo,ImageMediaInfoValue) => {

Accéder au modèle de popup d'une couche et le modifier

Maintenant que les différents types de contenus ont été créés, nous pouvons accéder au modèle de popup (PopupTemplate) de la couche et agréger les différents éléments.
Nous accédons à la propriété popupTemplate de la couche. A nouveau ici, j'accède à la propriété après la création de l'instance du GeoJSONLayer, mais vous pouvez également le faire à l'intérieur de celle-ci si vous le souhaitez.
Nous configurons ensuite la propriété titre (title) des popups, qui contiendra le nom vernaculaire de l'arbre issu du champ "com_nom_usuel" ainsi que son nom latin issu du champ "com_nom-latin" de la table attributaire. 
Il ne nous reste plus qu'à paramétrer la propriété contenu (content), pour laquelle nous indiquons dans un liste le nom des différents contenus créés ci-dessus, dans l'ordre dans lequel nous souhaitons les voir apparaître.
arbresRemarquables.popupTemplate = {
    title: "{com_nom_usuel} / {com_nom_latin}",    
    content : [textElement1,mediaElement, textElement2]
};   

Épingler les popups dans la vue

Actuellement, les popups s'affichent automatiquement au-dessus de l'arbre en train d'être interrogé. Nous allons faire en sorte que la popup s'ancre en bas à droite de la vue, ce qui leur permettra notamment de prendre un peu plus de place et donc d'en faciliter la lecture.
Cela se joue dans la propriété popup de la SceneView, que nous avions créé lors du premier épisode. Nous allons venir compléter le constructeur de la SceneView en y ajoutant et paramétrant cette propriété :
popup: { //épinglera automatiquement les fenêtres contextuelles en bas à droite
    dockEnabled: true,
    dockOptions: {
       position: "bottom-right",
       breakpoint: false,
       buttonEnabled: true
     },
}
La propriété dockEnabled paramétrée sur true permet de déclencher l'ancrage automatique des popup. Nous pouvons ensuite paramétrer la propriété dockOptions, pour personnaliser le comportement de l'ancrage. La position indique à quel endroit de la vue sera affichée la popup ; ici en bas à droite. Le breakpoint permet de définir à partir de quelle dimension de la vue (liée par exemple à la taille de la fenêtre dans laquelle votre application est affichée) la popup sera ancrée si le paramètre est défini sur true. En le définissant sur false, nous nous assurons que la popup sera toujours ancrée quelle que soit la taille de fenêtre. Enfin, la propriété buttonEnabled permet d'afficher le bouton ci-dessous, dont l'utilisateur peut se servir s'il souhaite manuellement libérer la popup.

Modifier le style du titre des popups dans le fichier css

J'en parlais lors du premier tutoriel de la série, nous avons embarqué la feuille de style par défaut de l'API. C'est elle qui régit notamment comment la popup se comporte : taille de la fenêtre, police d'écriture, taille des bordures, couleurs, ... 
Dans notre feuille de style personnelle, à laquelle notre application est également connectée , vous trouverez à certains endroit des règles qui nous permettent de reprendre la main par rapport au comportement par défaut de la feuille de script de l'API. Ci-dessous par exemple, j'ai accédé à la couleur de tous les titres <h2> de la classe esri-widget__heading (cette classe régit les entête des widgets issus de l'API), et j'en ai modifié la couleur pour qu'elle s'adapte à ma charte graphique.
  h2.esri-widget__heading {
    color: #7B656F;
  }
Voici la différence de résultat entre la couleur donnée par la feuille de style par défaut, et celle que j'ai pu imposer en rajoutant la règle à mon css :
De la même manière, vous pouvez personnaliser ainsi les différents éléments de l'API. Voici par exemple le code que j'ai utilisé (et que vous pouvez aussi retrouver dans la feuille de style que j'ai utilisée) pour changer la couleur des icônes des boutons en haut à gauche présents par défaut lorsque vous créez une scène :
div.esri-widget--button {
  background-color: #FFF;
  color: #7B656F;
  z-index: 10
  }

Le tutoriel de cette semaine est terminé ! Vous pouvez retrouver l'ensemble du code que nous venons d'écrire sur Github ou sur Codepen.
Avec l'ajout de cette semaine, l'utilisateur peut cliquer sur les données pour obtenir des informations. Nous verrons la semaine prochaine comment lui donner des informations avant même qu'il n'ait à cliquer en labellisant nos données avec les étiquettes. N'hésitez pas à retrouver les autres épisodes de cette série si vous les avez manqués.

Aucun commentaire:

Enregistrer un commentaire