Skip to content
Branch: master
Find file Copy path
Find file Copy path
1 contributor

Users who have contributed to this file

321 lines (279 sloc) 13.5 KB
<!DOCTYPE html>
<title>Bubble Layer Options - Azure Maps Web SDK Samples</title>
<meta charset="utf-8" />
<meta http-equiv="x-ua-compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="This sample shows how the different options of the bubble layer affect rendering." />
<meta name="keywords" content="map, gis, API, SDK, circle, bubble, layer, data-driven, bubblelayer" />
<meta name="author" content="Microsoft Azure Maps" />
<!-- Add references to the Azure Maps Map control JavaScript and CSS files. -->
<link rel="stylesheet" href="" type="text/css" />
<script src=""></script>
<script src="../Common/scripts/clipboard.min.js"></script>
<script type='text/javascript'>
var map, datasource, bubbleLayer, defaultOptions, testDataSize = 100, removeDefaults;
function GetMap() {
//Initialize a map instance.
map = new atlas.Map('myMap', {
view: 'Auto',
//Add your Azure Maps subscription key to the map SDK. Get an Azure Maps key at
authOptions: {
authType: 'subscriptionKey',
subscriptionKey: '<Your Azure Maps Key>'
//Wait until the map resources are ready.'ready', function () {
//Create a style control and add it to the map.
map.controls.add(new atlas.control.StyleControl({
style: 'dark'
}), {
position: 'top-right'
//Create a data source and add it to the map.
datasource = new atlas.source.DataSource();
//Add random point features to data source.
//Create a layer to render the point feature data.
bubbleLayer = new atlas.layer.BubbleLayer(datasource);
defaultOptions = bubbleLayer.getOptions();
//Update the bubble layer with the options in the input fields.
new ClipboardJS('.copyBtn');
function updateBubbleLayer() {
var options = getInputOptions();
//Update all the options in the bubble layer.
document.getElementById('CodeOutput').value = JSON.stringify(options, null, '\t').replace(/\"([^(\")"]+)\":/g, "$1:");
function getInputOptions() {
removeDefaults = document.getElementById('RemoveDefaults').checked;
return {
color: getPropertyValue('color', document.getElementById('Color').value),
strokeColor: getPropertyValue('strokeColor', document.getElementById('StrokeColor').value),
blur: getPropertyValue('blur', parseFloat(document.getElementById('Blur').value)),
opacity: getPropertyValue('opacity', parseFloat(document.getElementById('Opacity').value)),
strokeOpacity: getPropertyValue('strokeOpacity', parseFloat(document.getElementById('StrokeOpacity').value)),
strokeWidth: getPropertyValue('strokeWidth', parseFloat(document.getElementById('StrokeWidth').value)),
radius: getPropertyValue('radius', parseFloat(document.getElementById('Radius').value)),
minZoom: getPropertyValue('minZoom', parseFloat(document.getElementById('MinZoom').value)),
maxZoom: getPropertyValue('maxZoom', parseFloat(document.getElementById('MaxZoom').value)),
visible: getPropertyValue('visible', document.getElementById('Visible').checked),
pitchAlignment: getPropertyValue('pitchAlignment', getSelectValue('PitchAlignment'))
function getPropertyValue(propertyName, value) {
if (removeDefaults && defaultOptions[propertyName] === value) {
return undefined;
return value;
function generateRandomPoints(cnt) {
var layerData = [];
for (var i = 0; i < cnt; i++) {
layerData.push(new[Math.random() * 360 - 180, Math.random() * 170 - 85]), {
title: 'Pin_' + i
return layerData;
function getSelectValue(id) {
var elm = document.getElementById(id);
return elm.options[elm.selectedIndex].value;
function openTab(elm, tabName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
document.getElementById(tabName).style.display = "block";
elm.className += " active";
#myMap {
position: relative;
width: calc(100% - 375px);
height: 600px;
.sidePanel {
width: 325px;
height: 580px;
float: left;
margin-right: 10px;
#CodeOutput {
width: 300px;
height: 420px;
overflow-y: auto;
.copyBtn {
float: right;
table td:nth-of-type(1) {
width: 120px;
table td:nth-of-type(2) {
width: 200px;
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 6px 8px;
transition: 0.3s;
font-size: 14px;
.tab button:hover {
background-color: #ddd;
.tab {
background-color: #ccc;
.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
<body onload="GetMap()">
<fieldset class="sidePanel">
<legend>Bubble Layer Options</legend>
This sample shows how the different options of the bubble layer affect rendering.
<br /><br />
<div class="tab">
<button class="tablinks active" onclick="openTab(this, 'StyleOptions')">Base Options</button>
<button class="tablinks" onclick="openTab(this, 'BubbleLayerOptions')">Bubble Options</button>
<button class="tablinks" onclick="openTab(this, 'Code')">Code</button>
<div id="StyleOptions" class="tabcontent" style="display:block;">
<tr title="An integer specifying the minimum zoom level to render the layer at.">
<td>Min Zoom:</td>
<form oninput="minz.value=MinZoom.value">
<input type="range" id="MinZoom" value="0" min="0" max="24" step="1" oninput="updateBubbleLayer()" onchange="updateBubbleLayer()" />
<output name="minz" for="MinZoom">0</output>
<tr title="An integer specifying the maximum zoom level to render the layer at.">
<td>Min Zoom:</td>
<form oninput="maxz.value=MaxZoom.value">
<input type="range" id="MaxZoom" value="24" min="0" max="24" step="1" oninput="updateBubbleLayer()" onchange="updateBubbleLayer()" />
<output name="maxz" for="MaxZoom">24</output>
<tr title="Specifies if the layer is visible or not.">
<td><input id="Visible" type="checkbox" onclick="updateBubbleLayer()" checked="checked" /></td>
In addition to the options in this tool, the BubbleLayer also has options for;
<li>sourceLayer - used with VectorTileSource.</li>
<li>filter - used to filter data in layer.</li>
Many options in this layer also support Expressions which are not demonstrated in this sample.
<div id="BubbleLayerOptions" class="tabcontent">
<tr title="The color to fill the circle symbol with.">
<td><input type="color" id="Color" value="#1A73AA" onchange="updateBubbleLayer()" /></td>
<tr title="A number between 0 and 1 that indicates the opacity at which the circles will be drawn.">
<form oninput="opacity.value=Opacity.value">
<input type="range" id="Opacity" value="1" min="0" max="1" step="0.1" oninput="updateBubbleLayer()" onchange="updateBubbleLayer()" />
<output name="opacity" for="Opacity">1</output>
<tr title="The color of the circles' outlines.">
<td>Stroke Color:</td>
<td><input type="color" id="StrokeColor" value="#FFFFFF" onchange="updateBubbleLayer()" /></td>
<tr title="The radius of the circle in pixels.">
<form oninput="radius.value=Radius.value">
<input type="range" id="Radius" value="5" min="0" max="50" step="1" oninput="updateBubbleLayer()" onchange="updateBubbleLayer()" />
<output name="radius" for="Radius">5</output>
<tr title="A number between 0 and 1 that indicates the opacity at which the circles' outlines will be drawn.">
<td>Stroke Opacity</td>
<form oninput="strokeOpacity.value=StrokeOpacity.value">
<input type="range" id="StrokeOpacity" value="1" min="0" max="1" step="0.1" oninput="updateBubbleLayer()" onchange="updateBubbleLayer()" />
<output name="strokeOpacity" for="StrokeOpacity">1</output>
<tr title="The width of the circles" outlines in pixels.">
<td>Stroke Width</td>
<form oninput="strokeWidth.value=StrokeWidth.value">
<input type="range" id="StrokeWidth" value="2" min="0" max="10" step="1" oninput="updateBubbleLayer()" onchange="updateBubbleLayer()" />
<output name="strokeWidth" for="StrokeWidth">2</output>
<tr title="The amount to blur the circles. A value of 1 blurs the circles such that only the center point if at full opacity.">
<form oninput="blur.value=Blur.value">
<input type="range" id="Blur" value="0" min="0" max="1" step="0.1" oninput="updateBubbleLayer()" onchange="updateBubbleLayer()" />
<output name="blur" for="Blur">0</output>
<tr title="Specifies the orientation of circle when map is pitched.">
<td>Pitch Alignment:</td>
<select id="PitchAlignment" onchange="updateBubbleLayer()">
<option value="map">map</option>
<option value="viewport" selected="selected">viewport</option>
<div id="Code" class="tabcontent">
<textarea id="CodeOutput"></textarea><br /><br />
<input id="RemoveDefaults" type="checkbox" onclick="updateBubbleLayer()" checked="checked" /> Remove defaults
<button class="copyBtn" data-clipboard-target="#CodeOutput">Copy to clipboard</button>
<div id="myMap"></div>
You can’t perform that action at this time.