Skip to content

Instantly share code, notes, and snippets.

@andrewbt
Created December 3, 2019 23:11
Show Gist options
  • Save andrewbt/2a0fade9d29e0c4da939a5c67f325c4e to your computer and use it in GitHub Desktop.
Save andrewbt/2a0fade9d29e0c4da939a5c67f325c4e to your computer and use it in GitHub Desktop.
Airship, CARTO.js and HighCharts Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Airship, CARTO.js and HighCharts Example</title>
<link rel="stylesheet" href="https://libs.cartocdn.com/airship-style/v2.1.1/airship.css">
<script src="https://libs.cartocdn.com/airship-components/v2.1.1/airship.js"></script>
<!-- Include Leaflet -->
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css" rel="stylesheet">
<!-- Include CARTO.js -->
<script src="https://libs.cartocdn.com/carto.js/v4.1.11/carto.min.js"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<style>
.map-area-text {
position: absolute;
z-index: 10;
top: 24px;
left: 8px;
padding: 8px;
background-color: #FFF;
}
.panel-text {
margin-right: 8px;
padding: 8px;
background-color: #FFF;
}
#widgets {
width: 300px;
margin: 10px 10px 10px 0;
}
.widget {
background: white;
padding: 10px;
margin-bottom: 10px;
}
.widget h1 {
font-size: 1.2em;
}
.widget-formula .result {
font-size: 2em;
}
</style>
</head>
<body class="as-app-body as-app">
<header class="as-toolbar">
<div class="as-toolbar__item as-title">Airship, CARTO.js and HighCharts Example</div>
</header>
<nav class="as-tabs"></nav>
<div class="as-content">
<main class="as-main">
<div class="as-map-area">
<div id="map"></div>
</div>
</main>
<aside class="as-sidebar--l as-sidebar--right">
<div class="as-container">
<div class="as-box as-title">
<div class="as-container as-container--border">
<section class="as-box">
<h1 class="as-title">Number of Crimes</h1>
<p class="as-subheader"><span class="js-crime-count" id="crime-count-result">xxx</span> crimes</p>
</section>
</div>
<div class="as-container as-container--scrollable">
<section class="as-box">
<h1 class="as-title">Crime Types</h1>
<div class="as-body" id="crimeTypesChart">
</div>
<a class="as-body" href="javascript:resetLayerQuery(crimeDataset, sqlCrimeBase);">Clear</a>
</section>
</div>
</div>
</div>
</aside>
</div>
<!-- Basic CARTO-VL MAP -->
<script>
// Highcharts code
var crimeTypesChart = new Highcharts.chart('crimeTypesChart', {
chart: {
type: 'bar'
},
title: {
text: null
},
xAxis: {
type: 'category',
title: {
text: null
}
},
yAxis: {
min: 0,
title: {
text: 'Number of crimes'
},
labels: {
overflow: 'justify'
}
},
tooltip: {
enabled: false,
valueSuffix: ' millions'
},
plotOptions: {
bar: {
allowPointSelect: true,
dataLabels: {
enabled: true
}
}
},
credits: {
enabled: false
},
legend: {
enabled: false
},
series: [{
name: 's1',
data: null,
cursor: 'pointer',
point: {
events: {
click: function() {
appendLayerQuery(crimeDataset, sqlCrimeBase, "WHERE crime_type = '" + this.name + "'");
}
}
}
}],
exporting: {
enabled: false
}
});
// CARTO.js code
var map = L.map('map').setView([51.5, 0.12], 8);
// Adding Voyager Basemap
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '&copy;<a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, &copy;<a href="https://carto.com/attribution">CARTO</a>'
}).addTo(map);
// Adding Voyager Labels
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_only_labels/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '&copy;<a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, &copy;<a href="https://carto.com/attribution">CARTO</a>',
zIndex: 100
}).addTo(map);
L.control.scale().addTo(map);
var cto = new carto.Client({
apiKey: 'vWtARiDwjgZdTEsFg8fh5g',
username: 'steve-carto'
});
var sqlCrimeBase = "SELECT * FROM merged_surrey_street_crime";
//var crimeDatasetSimple = new carto.source.Dataset('merged_surrey_street_crime');
var crimeDataset = new carto.source.SQL(sqlCrimeBase);
var crimeDatasetForWidget = new carto.source.SQL(sqlCrimeBase);
var crimeStyle = new carto.style.CartoCSS(`
#layer {
marker-width: 7;
marker-fill: ramp([crime_type], (#5F4690, #1D6996, #38A6A5, #0F8554, #73AF48, #EDAD08, #E17C05, #CC503E, #94346E, #6F4070, #666666), ("Anti-social behaviour", "Violence and sexual offences", "Criminal damage and arson", "Other theft", "Public order", "Burglary", "Vehicle crime", "Shoplifting", "Drugs", "Other crime"), "=");
marker-fill-opacity: 1;
marker-allow-overlap: true;
marker-line-width: 1;
marker-line-color: #FFFFFF;
marker-line-opacity: 1;
}`);
var crimeLayer = new carto.layer.Layer(crimeDataset, crimeStyle, {
//this makes columns available for Leaflet popups
featureClickColumns: ['location', 'crime_type', 'month']
});
cto.addLayer(crimeLayer);
cto.getLeafletLayer().addTo(map);
var popup = L.popup();
crimeLayer.on('featureClicked', function(featureEvent) {
popup.setLatLng(featureEvent.latLng);
popup.setContent(featureEvent.data.location + '<br/>' + featureEvent.data.crime_type + '<br/>' + featureEvent.data.month);
popup.openOn(map);
});
var crimeTypesDataview = new carto.dataview.Category(crimeDatasetForWidget, 'crime_type', {
limit: 100
});
var numberOfCrimes = new carto.dataview.Formula(crimeDataset, 'crime_type', {
operation: carto.operation.COUNT
});
crimeTypesDataview.on('dataChanged', function(newData) {
var crimeTypes = newData.categories.map(function(category) {
return [category.name, category.value];
}).sort(function(a, b) {
return b[1] - a[1]
});
refreshCrimetypesWidget(crimeTypes);
});
numberOfCrimes.on('dataChanged', function(newData) {
refreshNumberOfCrimesWidget(newData.result);
});
var refreshNumberOfCrimesWidget = function(numCrimes) {
var widget = document.querySelector('#numCrimesWidget');
var labelCrimes = $("#crime-count-result").text(Math.floor(numCrimes));
};
function refreshCrimetypesWidget(crimeTypes) {
crimeTypesChart.series[0].setData(crimeTypes, true);
};
function appendLayerQuery(dataset, sqlBase, appendText) {
var sql = sqlBase + ' ' + appendText;
dataset.setQuery(sql);
};
function resetLayerQuery(dataset, sqlBase) {
dataset.setQuery(sqlBase);
var selectedPoints = crimeTypesChart.getSelectedPoints();
$.each(selectedPoints, function(i, p) {
p.select(); //Set the selected points to unselected
});
crimeTypesChart.redraw();
};
cto.addDataview(crimeTypesDataview);
cto.addDataview(numberOfCrimes);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment