Visualize Mobile Network Antennae by Providers

Visualize antennae for telecommunications mobile network operators, grouped by provider

HTML

<link rel="stylesheet" href="https://js.api.here.com/v3/3.0/mapsjs-ui.css">
<link rel="stylesheet" href="https://apps.datalens.api.here.com/jsapi/examples/categorical/example.css">
<!-- SCRIPTS -->
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-core.js"></script>
<script type="text/javascript" src="  https://js.api.here.com/v3/3.0/mapsjs-service.js"></script>
<script type="text/javascript" src="  https://js.api.here.com/v3/3.0/mapsjs-ui.js"></script>
<script type="text/javascript" src="  https://js.api.here.com/v3/3.0/mapsjs-mapevents.js"></script>
<script type="text/javascript" src="  https://js.api.here.com/v3/3.0/mapsjs-clustering.js"></script>
<script type="text/javascript" src="  https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript" src="  https://js.datalens.api.here.com/2.0.0/mapsjs-datalens.js"></script>

<!-- BODY -->
<h1>Visualize Mobile Network Antennae by Providers</h1>
<p><div>This example displays a visualization of groups of&nbsp;mobile network antennae on a map. &nbsp;We introduce the concept of the Data Lens REST API query which is used to fetch and process the data, and then demonstrate how&nbsp;the Data Lens JavaScript libraries are used to&nbsp;produce the visualization.</div><div><br></div><div>The dataset used for the visualization contains antenna attributes such as its location, provider and technology. &nbsp;(Note that the actual data used here is simulated.) &nbsp;Single antennae are represented by colored circles, while groups of antennae ("clusters") are represented by pie chart symbols ("categorical markers"). &nbsp;These are designed as follows:</div><div><br></div><ul><li>Each single-antenna marker is displayed as a circle, colored by its&nbsp;provider</li><li>Each cluster marker is displayed as a pie chart, with a black inner circle&nbsp;and colored ring&nbsp;segments around the perimeter</li><li>Each cluster marker's inner circle includes a number that&nbsp;indicates the number of...

CSS

code, h1, h2 {
  color: #124191;
  letter-spacing: -0.03em;
}
body {
  font-family:"Lucida Grande",Tahoma,sans-serif;
  color: rgb(102, 102, 102);
  font-size: 80%;
}
b, strong {
  color: black;
}
code {
  font-weight: 700;
  font-size: 120%;
}
.legend {
    position: absolute;
    padding: 20px;
    border-radius: 2px;
    background-color: rgba(14,24,42,0.75);
    box-shadow: 0 7px 7px 0 rgba(0,0,0,0.25);
    width: 200px;
    top: 20px;
    right: 20px;
    font-weight: 100;
}

.dropdown {
    position: relative;
    transition: all 0.3s ease-out;
}

.dropdown:hover {
    box-shadow: 0 7px 7px 0 rgba(0,0,0,0.25);
}

.dropdown__title {
    border-radius: 3px;
    background-color: rgba(0,0,0,0.75);
    padding-left: 10px;
    border: none;
    height: 30px;
    line-height: 30px;
    color: white;
    text-align: left;
    position: relative;
    transition: all 0.3s ease-out;
    opacity: 0.8;
}

.dropdown__title:hover {
    opacity: 1;
}

.dropdown__title:after {
    content: '';
    width: 11px;
    height: 12px;
    position: absolute;
    top: 5px;
    border: 3px solid gray;
    border-top: none;
    border-right: none;
    background: transparent;
    transform: rotate(-45deg);
    left: 85%;
    opacity: 0.3;
    transition: all 0.3s ease-out;
}

.dropdown__title:hover:after {
    opacity: 1;
    border-color: #00c9ff;
}

.dropdown__content {
    position: absolute;
    width: 100%;
    border-radius: 0 0 2px 2px;
    overflow: hidden;
    opacity: 0;
    transition: all 0.3s ease-out;
    box-shadow: 0 7px 7px 0 rgba(0,0,0,0.25);
    /*display:none;*/
}

.dropdown:hover .dropdown__content {
    opacity: 1;
    background-color: rgba(0,0,0,0.75);
    z-index: 2;
}

.dropdown__option {
    border-top: 1px solid black;
    display: block;
    padding: 5px 15px;
    color: white;
    transition: all 0.3s ease-out;
    cursor: pointer;
}

.dropdown__option:hover {
    background-color: #00c9ff;
    color: black;
}

.categories {
    color:...

JavaScript

//initialize the platform
var platform = new H.service.Platform({
    app_id: 'DemoAppId01082013GAL',
    app_code: 'AJKnXv84fjrb0KIHawS0Tg',
    useCIT: true,
    useHTTPS: true
});

//instantiate datalens service
var service = new H.datalens.Service();
service.configure(
    'DemoAppId01082013GAL',
    'AJKnXv84fjrb0KIHawS0Tg',
    true,                   // useHTTPS
    false,                  // useCIT
    'https://api.here.com'  // baseUrl
);

//define pixelRatio (1 or 2)
var pixelRatio = devicePixelRatio > 1 ? 2 : 1;

//add base map
var baseLayer = platform.getMapTileService({type: 'base'}).createTileLayer(
    'maptile',
    'reduced.day',
    256 * pixelRatio, //take bigger tiles for retina
    'png'
);

//display a map
var mapHolder = document.getElementById('map');
var map = new H.Map(
    mapHolder,
    baseLayer,
    {
        pixelRatio: pixelRatio,
        center:  new H.geo.Point(40.769832, -73.974726),
        zoom: 13
    }
);

//add interactivity to map
new H.mapevents.Behavior(new H.mapevents.MapEvents(map));

//initialize datalens provider
var TILED_QUERY = 'fd93e6f122a8456dace65ad4f33673bd';
var queryProvider = new H.datalens.QueryTileProvider(
    service,
    {
        queryId: TILED_QUERY,
        tileParamNames: {x: 'x', y: 'y', z: 'z'}
    }
);

//connect UI to provider
document.addEventListener('click', function(e) {
    var filterValue = e.target.innerText;
    if (e.target.className === 'dropdown__option') {
        //update dynamic parameter
        queryProvider.setQueryParams({
            technology_filter: filterValue
        });
        queryProvider.reload();
    }
});

var layer = new H.datalens.ObjectLayer(
    queryProvider,
    {
        clustering: {
            rowToDataPoint: function(row) {
                return new H.clustering.DataPoint(
                    row.lat, row.lon, 1
                );
            },
            options: function(zoom) {
                return {
                    strategy:...