Ajouter une fenêtre contextuelle à la carte
Cet article vous explique comment ajouter une fenêtre contextuelle à un point sur une carte.
Comprendre le code
Le code suivant ajoute à la carte une fonctionnalité de point avec des propriétés name
et description
à l’aide d’un calque de symboles. Une instance de la classe Popup est créée, mais elle n’est pas affichée. Les événements de souris sont ajoutés au calque de symboles pour déclencher l’ouverture et la fermeture de la fenêtre contextuelle. Quand vous survolez le symbole de marqueur, la propriété position
de la fenêtre contextuelle est mise à jour avec la position du marqueur, et l’option content
est mise à jour avec du code HTML qui encapsule les propriétés name
et description
de la caractéristique de point survolée. La fenêtre contextuelle est ensuite affichée sur la carte à l’aide de sa fonction open
.
//Define an HTML template for a custom popup content laypout.
var popupTemplate = '<div class="customInfobox"><div class="name">{name}</div>{description}</div>';
//Create a data source and add it to the map.
var dataSource = new atlas.source.DataSource();
map.sources.add(dataSource);
dataSource.add(new atlas.data.Feature(new atlas.data.Point([-122.1333, 47.63]), {
name: 'Microsoft Building 41',
description: '15571 NE 31st St, Redmond, WA 98052'
}));
//Create a layer to render point data.
var symbolLayer = new atlas.layer.SymbolLayer(dataSource);
//Add the polygon and line the symbol layer to the map.
map.layers.add(symbolLayer);
//Create a popup but leave it closed so we can update it and display it later.
popup = new atlas.Popup({
pixelOffset: [0, -18],
closeButton: false
});
//Add a hover event to the symbol layer.
map.events.add('mouseover', symbolLayer, function (e) {
//Make sure that the point exists.
if (e.shapes && e.shapes.length > 0) {
var content, coordinate;
var properties = e.shapes[0].getProperties();
content = popupTemplate.replace(/{name}/g, properties.name).replace(/{description}/g, properties.description);
coordinate = e.shapes[0].getCoordinates();
popup.setOptions({
//Update the content of the popup.
content: content,
//Update the popup's position with the symbol's coordinate.
position: coordinate
});
//Open the popup.
popup.open(map);
}
});
map.events.add('mouseleave', symbolLayer, function (){
popup.close();
});
Réutilisation d’une fenêtre contextuelle avec plusieurs points
Dans certains cas, la meilleure approche consiste à créer une fenêtre contextuelle et à la réutiliser. Par exemple, vous pouvez avoir un grand nombre de points et souhaiter afficher une seule fenêtre contextuelle à la fois. En réutilisant la fenêtre contextuelle, le nombre d’éléments DOM créés par l’application est nettement réduit, ce qui peut offrir un meilleur niveau de performance. L’exemple suivant crée des caractéristiques à trois points. Si vous sélectionnez l’un d’eux, une fenêtre contextuelle s’affiche avec le contenu de ce point.
Pour obtenir un exemple entièrement fonctionnel qui montre comment créer une fenêtre contextuelle et la réutiliser au lieu de créer une fenêtre contextuelle pour chaque fonctionnalité de point, consultez Réutilisation d’une fenêtre contextuelle avec plusieurs épingles dans les Exemples d’Azure Maps. Pour obtenir le code source de cet exemple, consultez Réutilisation d’une fenêtre contextuelle avec plusieurs points.
Personnalisation d’une fenêtre contextuelle
Par défaut, la fenêtre contextuelle a un arrière-plan blanc, une flèche de pointeur au bas et un bouton de fermeture dans le coin supérieur droit. L’exemple suivant change la couleur d’arrière-plan en noir à l’aide de l’option fillColor
de la fenêtre contextuelle. Le bouton Fermer est supprimé en affectant la valeur false à l’option CloseButton
. Le contenu HTML de la fenêtre contextuelle utilise un remplissage de 10 pixels par rapport aux bords de la fenêtre contextuelle. Le texte de couleur blanche s’affiche correctement sur l’arrière-plan noir.
Pour obtenir un exemple entièrement fonctionnel qui montre comment personnaliser l’apparence d’une fenêtre contextuelle, consultez Personnaliser une fenêtre contextuelle dans les Exemples d’Azure Maps. Pour obtenir le code source de cet exemple, consultez Personnaliser une fenêtre contextuelle.
Ajouter des modèles de fenêtre contextuelle à la carte
Les modèles de fenêtre contextuelle facilitent la création de dispositions axées sur les données dans les fenêtres contextuelles. Les sections suivantes montrent comment différents modèles de fenêtre contextuelle sont utilisés pour générer du contenu mis en forme à l’aide des propriétés de fonctionnalités.
Notes
Par défaut, tout le contenu affiché dans le modèle de fenêtre contextuelle est placé dans un bac à sable (sandbox) à l’intérieur d’un IFrame en tant que fonctionnalité de sécurité. Toutefois, des limitations s’appliquent :
- Les scripts, les formulaires, le verrou de pointeur et la fonctionnalité de navigation supérieure sont désactivés. Les liens sont autorisés à s’ouvrir dans un nouvel onglet lorsqu’ils sont sélectionnés.
- Les navigateurs plus anciens qui ne prennent pas en charge le paramètre
srcdoc
sur Iframes sont limités au rendu d’une petite quantité de contenu.
Si vous avez confiance dans les données chargées dans les fenêtres contextuelles et souhaitez potentiellement que ces scripts chargés dans les fenêtres contextuelles puissent accéder à votre application, vous pouvez désactiver ce comportement en définissant l’option sandboxContent
des modèles de fenêtre contextuelle sur la valeur False.
Modèle String
Le modèle String remplace les espaces réservés par les valeurs des propriétés de la fonctionnalité. Il n’est pas nécessaire d’attribuer des valeurs de type String aux propriétés de la fonctionnalité. Par exemple, value1
contient un entier. Ces valeurs sont ensuite transmises à la propriété content de popupTemplate
.
L’option numberFormat
spécifie le format du nombre à afficher. Si numberFormat
n’est pas spécifié, le code utilise le format de date du modèle de fenêtre contextuelle. L’option numberFormat
met en forme les nombres à l’aide de la fonction Number.toLocaleString. Pour mettre en forme les nombres importants, envisagez d’utiliser l’option numberFormat
avec les fonctions de NumberFormat.format. Par exemple, l’extrait de code suivant utilise maximumFractionDigits
pour limiter le nombre de chiffres de fraction à deux.
Notes
Le modèle String ne peut afficher les images que d’une seule façon. Pour commencer, le modèle String doit contenir une balise d’image. La valeur transmise à la balise d’image doit être une URL qui mène à une image. Ensuite, le paramètre isImage
de l’option HyperLinkFormatOptions
du modèle String doit être défini sur true. L’option isImage
indique que le lien hypertexte se rapporte à une image et qu’il sera chargé dans une balise d’image. L’image s’ouvrira une fois que l’utilisateur aura cliqué sur le lien hypertexte.
var templateOptions = {
content: 'This template uses a string template with placeholders.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
numberFormat: {
maximumFractionDigits: 2
}
};
var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {
title: 'Template 1 - String template',
value1: 1.2345678,
value2: {
subValue: 'Pizza'
},
arrayValue: [3, 4, 5, 6]
});
var popup = new atlas.Popup({
content: atlas.PopupTemplate.applyTemplate(feature.properties, templateOptions),
position: feature.geometry.coordinates
});
Modèle PropertyInfo
Le modèle PropertyInfo affiche les propriétés disponibles de la fonctionnalité. L’option label
indique le texte à afficher pour l’utilisateur. Si label
n’est pas spécifié, le lien hypertexte s’affiche. Par ailleurs, si le lien hypertexte est une image, la valeur affectée à la balise « alt » s’affiche. dateFormat
indique le format de la date. Si aucun format de date n’est spécifié, la date s’affiche sous forme de chaîne. L’option hyperlinkFormat
affiche les liens cliquables. De la même manière, l’option email
peut être utilisée pour afficher les adresses e-mail cliquables.
Avant de présenter les propriétés à l’utilisateur final, le modèle PropertyInfo vérifie de manière récursive que les propriétés sont bel et bien définies pour cette fonctionnalité. Par ailleurs, il n’affiche pas les propriétés de style et title. Par exemple, les propriétés color
, size
, anchor
, strokeOpacity
et visibility
ne sont pas affichées. Ainsi, une fois la vérification du chemin des propriétés terminée en arrière-plan, le modèle PropertyInfo affiche le contenu sous forme de tableau.
var templateOptions = {
content: [
{
propertyPath: 'createDate',
label: 'Created Date'
},
{
propertyPath: 'dateNumber',
label: 'Formatted date from number',
dateFormat: {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'UTC',
timeZoneName: 'short'
}
},
{
propertyPath: 'url',
label: 'Code samples',
hideLabel: true,
hyperlinkFormat: {
lable: 'Go to code samples!',
target: '_blank'
}
},
{
propertyPath: 'email',
label: 'Email us',
hideLabel: true,
hyperlinkFormat: {
target: '_blank',
scheme: 'mailto:'
}
}
]
};
var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {
title: 'Template 2 - PropertyInfo',
createDate: new Date(),
dateNumber: 1569880860542,
url: 'https://samples.azuremaps.com/',
email: 'info@microsoft.com'
}),
var popup = new atlas.Popup({
content: atlas.PopupTemplate.applyTemplate(feature.properties, templateOptions),
position: feature.geometry.coordinates
});
Modèles multicontenus
Une fonctionnalité peut aussi afficher du contenu en combinant le modèle String et le modèle PropertyInfo. Dans ce cas, le modèle String affiche les valeurs des espaces réservés sur un arrière-plan blanc. Parallèlement, le modèle PropertyInfo affiche une image en pleine largeur à l’intérieur d’un tableau. Dans cet exemple, les propriétés sont similaires à celles que nous avons expliquées dans les exemples précédents.
var templateOptions = {
content: [
'This template has two pieces of content; a string template with placeholders and a array of property info which renders a full width image.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
[{
propertyPath: 'imageLink',
label: 'Image',
hideImageLabel: true,
hyperlinkFormat: {
isImage: true
}
}]
],
numberFormat: {
maximumFractionDigits: 2
}
};
var feature = new atlas.data.Feature(new atlas.data.Point([0, 0]), {
title: 'Template 3 - Multiple content template',
value1: 1.2345678,
value2: {
subValue: 'Pizza'
},
arrayValue: [3, 4, 5, 6],
imageLink: 'https://samples.azuremaps.com/images/Pike_Market.jpg'
});
var popup = new atlas.Popup({
content: atlas.PopupTemplate.applyTemplate(feature.properties, templateOptions),
position: feature.geometry.coordinates
});
Points sans modèle défini
Quand le modèle de fenêtre contextuelle (Popup) n’est pas défini comme étant un modèle String, un modèle PropertyInfo ou une combinaison des deux, il utilise les paramètres par défaut. Quand title
et description
sont les seules propriétés affectées, le modèle de fenêtre contextuelle présente un arrière-plan blanc et un bouton de fermeture dans l’angle supérieur droit. De plus, sur les écrans de petit et moyen format, il affiche une flèche au bas. Les paramètres par défaut s’affichent à l’intérieur d’un tableau pour toutes les propriétés autres que title
et description
. Même en revenant aux paramètres par défaut, le modèle de fenêtre contextuelle peut toujours être manipulé par programmation. Par exemple, les utilisateurs peuvent désactiver la détection des liens hypertexte, mais les paramètres par défaut s’appliqueront toujours aux autres propriétés.
Une fois en cours d’exécution, vous pouvez sélectionner les points sur la carte pour afficher la fenêtre contextuelle. Il existe sur la carte un point pour chacun des modèles de fenêtre contextuelle suivants : modèle String, modèle PropertyInfo et modèle multicontenu. Il y a aussi trois points qui montrent comment les modèles s’affichent avec les paramètres par défaut.
function InitMap()
{
var map = new atlas.Map('myMap', {
zoom: 2,
view: "Auto",
//Add authentication details for connecting to Azure Maps.
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '{Your-Azure-Maps-Subscription-key}'
}
});
//Wait until the map resources are ready.
map.events.add('ready', function() {
//Create a data source and add it to the map.
var datasource = new atlas.source.DataSource();
map.sources.add(datasource);
//Add sample data.
datasource.add([
new atlas.data.Feature(new atlas.data.Point([-20, 20]), {
title: 'No template - title/description',
description: 'This point doesn\'t have a template defined, fallback to title and description properties.'
}),
new atlas.data.Feature(new atlas.data.Point([20, 20]), {
title: 'No template - property table',
message: 'This point doesn\'t have a template defined, fallback to title and table of properties.',
randomValue: 10,
url: 'https://samples.azuremaps.com/',
imageLink: 'https://samples.azuremaps.com/images/Pike_Market.jpg',
email: 'info@microsoft.com'
}),
new atlas.data.Feature(new atlas.data.Point([40, 0]), {
title: 'No template - hyperlink detection disabled',
message: 'This point doesn\'t have a template defined, fallback to title and table of properties.',
randomValue: 10,
url: 'https://samples.azuremaps.com/',
email: 'info@microsoft.com',
popupTemplate: {
detectHyperlinks: false
}
}),
new atlas.data.Feature(new atlas.data.Point([-20, -20]), {
title: 'Template 1 - String template',
value1: 1.2345678,
value2: {
subValue: 'Pizza'
},
arrayValue: [3, 4, 5, 6],
popupTemplate: {
content: 'This template uses a string template with placeholders.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
numberFormat: {
maximumFractionDigits: 2
}
}
}),
new atlas.data.Feature(new atlas.data.Point([20, -20]), {
title: 'Template 2 - PropertyInfo',
createDate: new Date(),
dateNumber: 1569880860542,
url: 'https://samples.azuremaps.com/',
email: 'info@microsoft.com',
popupTemplate: {
content: [{
propertyPath: 'createDate',
label: 'Created Date'
},
{
propertyPath: 'dateNumber',
label: 'Formatted date from number',
dateFormat: {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
timeZone: 'UTC',
timeZoneName: 'short'
}
},
{
propertyPath: 'url',
label: 'Code samples',
hideLabel: true,
hyperlinkFormat: {
lable: 'Go to code samples!',
target: '_blank'
}
},
{
propertyPath: 'email',
label: 'Email us',
hideLabel: true,
hyperlinkFormat: {
target: '_blank',
scheme: 'mailto:'
}
}
]
}
}),
new atlas.data.Feature(new atlas.data.Point([0, 0]), {
title: 'Template 3 - Multiple content template',
value1: 1.2345678,
value2: {
subValue: 'Pizza'
},
arrayValue: [3, 4, 5, 6],
imageLink: 'https://samples.azuremaps.com/images/Pike_Market.jpg',
popupTemplate: {
content: [
'This template has two pieces of content; a string template with placeholders and a array of property info which renders a full width image.<br/><br/> - Value 1 = {value1}<br/> - Value 2 = {value2/subValue}<br/> - Array value [2] = {arrayValue/2}',
[{
propertyPath: 'imageLink',
label: 'Image',
hideImageLabel: true,
hyperlinkFormat: {
isImage: true
}
}]
],
numberFormat: {
maximumFractionDigits: 2
}
}
}),
]);
//Create a layer that defines how to render the points on the map.
var layer = new atlas.layer.BubbleLayer(datasource);
map.layers.add(layer);
//Create a popup but leave it closed so we can update it and display it later.
popup = new atlas.Popup();
//Add a click event to the layer.
map.events.add('click', layer, showPopup);
});
function showPopup(e) {
if (e.shapes && e.shapes.length > 0) {
var properties = e.shapes[0].getProperties();
popup.setOptions({
//Update the content of the popup.
content: atlas.PopupTemplate.applyTemplate(properties, properties.popupTemplate),
//Update the position of the popup with the pins coordinate.
position: e.shapes[0].getCoordinates()
});
//Open the popup.
popup.open(map);
}
}
}
Réutiliser le modèle de fenêtre contextuelle
Vous pouvez réutiliser les modèles de fenêtre contextuelle comme vous réutiliseriez une fenêtre contextuelle. Cette approche s’avère utile quand vous voulez seulement afficher un modèle de fenêtre contextuelle à la fois, pour plusieurs points. La réutilisation des modèles de fenêtre contextuelle réduit le nombre d’éléments DOM créés par l’application, ce qui améliore les performances de vos applications. L’exemple suivant utilise le même modèle de fenêtre contextuelle pour les trois points. Si vous sélectionnez l’un d’eux, une fenêtre contextuelle s’affiche avec le contenu de ce point.
Pour obtenir un exemple entièrement fonctionnel qui montre comment réutiliser un modèle de fenêtre contextuelle unique avec plusieurs fonctionnalités qui partagent un ensemble commun de champs de propriétés, consultez Réutiliser un modèle de fenêtre contextuelle dans les Exemples d’Azure Maps. Pour obtenir le code source de cet exemple, consultez Réutiliser le modèle de fenêtre contextuelle.
Événements de fenêtres contextuelles
Les fenêtres contextuelles peuvent être ouvertes, fermées et déplacées. La classe popup fournit des événements pour aider les développeurs à réagir à ces événements. L’exemple suivant met en évidence les événements qui se déclenchent lorsque l’utilisateur ouvre, ferme ou fait glisser la fenêtre contextuelle.
Pour obtenir un exemple entièrement fonctionnel qui montre comment ajouter des événements à des fenêtres contextuelles, consultez Événements contextuels dans les Exemples Azure Maps. Pour obtenir le code source de cet exemple, consultez Événements de fenêtres contextuelles.
Étapes suivantes
En savoir plus sur les classes et les méthodes utilisées dans cet article :
Pour voir des exemples de codes complets, consultez les articles suivants qui sont très intéressants :