Skip to content

Instantly share code, notes, and snippets.

@ernesmb
Last active January 17, 2018 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ernesmb/473a7a8ab1662c51338e99ee5f773e70 to your computer and use it in GitHub Desktop.
Save ernesmb/473a7a8ab1662c51338e99ee5f773e70 to your computer and use it in GitHub Desktop.
Lasso tool with CARTO.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Carto.js Guide</title>
<!-- Include Leaflet 1.2.0 Library -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.css" />
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.js"></script>
<!-- Fonts -->
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
<!-- Include cartodb.js Library -->
<script src="https://cdn.rawgit.com/CartoDB/cartodb.js/@4.0.0-alpha.28/carto.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
html {
box-sizing: border-box;
height: 100%;
}
body {
background: #f2f6f9;
height: 100%;
font-family: "Open sans", Helvetica, Arial, sans-serif;
}
#container {
display: flex;
width: 100%;
height: 100%;
}
#map {
flex: 1;
margin: 10px;
}
#widgets {
width: 450px;
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>
<div id="container">
<div id="map"></div>
<div id="widgets">
<div id="avgPopulationWidget" class="widget widget-formula">
<h1>Total amount</h1>
<p>
<span class="js-average-population result">...</span> €</p>
</div>
<canvas id="myChart" height= "360px"></canvas>
</div>
</div>
<script>
var map = L.map('map', {drawControl: false}).setView([41.390205, 2.154007], 15);
var drawnItems = new L.FeatureGroup();
var drawControl = new L.Control.Draw({
draw: {
polygon: true,
polyline: false,
line: false,
marker: false,
rectangle: true,
circle: false,
circlemarker: false,
},
edit: {
featureGroup: drawnItems,
edit: false,
remove: false
}
});
map.addControl(drawControl);
map.addLayer(drawnItems);
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);
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);
var client = new carto.Client({
apiKey: 'ba14a8a9c44d49d8779d4033b7a412e763be660d',
username: 'juan-carto'
});
var transactionDataset = new carto.source.SQL('SELECT * FROM tx_0125_copy_copy');
var totalAmount = new carto.dataview.Formula(transactionDataset, 'amount', {
operation: carto.operation.SUM
});
totalAmount.on('dataChanged', function (newData) {
var $widget = document.querySelector('#avgPopulationWidget');
var $totalAmount = $widget.querySelector('.js-average-population');
$totalAmount.innerText = Math.round(newData.result);
});
client.addDataview(totalAmount);
var categories = new carto.dataview.Category(transactionDataset, 'category', {
operation: carto.operation.COUNT,
limit: 6,
operationColumn: 'cartodb_id'
});
client.addDataview(categories);
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: [],
datasets: [{
label: 'Count by category',
data: [],//categories.categories.map(x => x.value),
backgroundColor: [
"#E58606",
"#5D69B1",
"#52BCA3",
"#99C945",
"#CC61B0",
"#24796C",
],
borderWidth: 1
}]
},
options: {
// scales: {
// yAxes: [{
// ticks: {
// beginAtZero: true
// }
// }]
// }
}
});
categories.on('dataChanged', function (categories) {
myChart.data.labels = categories.categories.map(x => x.name);
myChart.data.datasets.forEach((dataset) => {
dataset.data = categories.categories.map(x => x.value);
});
myChart.update();
});
var style = new carto.style.CartoCSS(`
#layer {
marker-fill: ramp([category], ("#E58606",
"#5D69B1",
"#52BCA3",
"#99C945",
"#CC61B0",
"#24796C",
), category(5) );
marker-opacity: 0.8;
marker-width: ramp([amount], (6, 12, 18, 24), jenks(), >=);
marker-allow-overlap: false;
marker-line-width: 0.1;
marker-comp-op: src-over;
}`);
var cartoLayer = new carto.layer.Layer(transactionDataset, style, {
featureOverColumns: ['category', 'amount']
});
client.addLayers([cartoLayer]);
client.getLeafletLayer().addTo(map);
var popup = L.popup({offset:[0,-12],autoPan:false});
cartoLayer.on('featureOver', function (featureEvent) {
popup.setLatLng(featureEvent.latLng);
popup.setContent(`<b>Category:</b> ${featureEvent.data.category} <br> <b>Amount</b>: ${featureEvent.data.amount} €`);
popup.openOn(map);
});
map.on(L.Draw.Event.CREATED, function (e) {
var layer = e.layer;
const query = `SELECT * FROM tx_0125_copy_copy WHERE St_Intersects(the_geom, St_SetSRID(St_GeomFromGeoJSON(
'${JSON.stringify(layer.toGeoJSON().geometry)}'), 4326))`;
transactionDataset.setQuery(query);
map.addLayer(layer);
map.on('click', function(){
map.removeLayer(layer)
transactionDataset.setQuery('SELECT * FROM tx_0125_copy_copy');
});
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment