Created
December 3, 2019 23:11
-
-
Save andrewbt/2a0fade9d29e0c4da939a5c67f325c4e to your computer and use it in GitHub Desktop.
Airship, CARTO.js and HighCharts Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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: '©<a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, ©<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: '©<a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, ©<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