Skip to content

Instantly share code, notes, and snippets.

@eamador
Last active November 21, 2017 18:18
Show Gist options
  • Save eamador/c7b7804eada9e019f510cd77ca49a6b6 to your computer and use it in GitHub Desktop.
Save eamador/c7b7804eada9e019f510cd77ca49a6b6 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CARTO.js Hackaton</title>
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"></script>
<script src="https://rawgit.com/CartoDB/cartodb.js/dist/carto.js"></script>
<link href="styles.css" rel="stylesheet" />
</head>
<body>
<header>
<h1>Total expenditure by payer postal code</h1>
<h2>Data from Madrid on 2015</h2>
</header>
<div id="map"></div>
<div class="closeBtn">X</div>
<div class="widgetsFloatingWrapper shown">
<h2>Postalcode Ranking</h2>
<ul id="stats" class="categoryWidget"></ul>
</div>
<script type="text/javascript" src="map.js"></script>
</body>
</html>
var map = L.map('map').setView([40.4149, -3.7110], 12);
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/light_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/light_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: '928462ed22efced49da1b4566df11005694391bd',
username: 'raulyeguas'
});
var closeBtn = document.querySelector('.closeBtn');
var stats = document.querySelector('#stats');
var widgetWrapper = document.querySelector('.widgetsFloatingWrapper');
var tilesDataset = new carto.source.Dataset('mad_tiles');
var tilesStyles = new carto.style.CartoCSS(`
#layer {
polygon-fill: #408ec9;
polygon-opacity: 0.5;
::outline {
line-color: #FFFFFF;
line-width: 0.5;
line-opacity: 0.5;
}
}`);
var tilesSelectedStyles = new carto.style.CartoCSS(`
#layer {
polygon-fill: #FFFFFF;
polygon-opacity: 0.5;
::outline {
line-color: #FFFFFF;
line-width: 0.5;
line-opacity: 0.5;
}
}`);
var tilesPaymentsLayer = new carto.layer.Layer(tilesDataset, tilesStyles);
tilesPaymentsLayer.setFeatureClickColumns(['cartodb_id']);
client.addLayer(tilesPaymentsLayer);
var layerPC, layerSelectedTile;
var tilesPostalCodeData;
tilesPostalCodeData = new carto.source.SQL('SELECT the_geom_webmercator FROM mad_tile_postalcode;');
selectedTileData = new carto.source.SQL('SELECT the_geom_webmercator FROM mad_tiles;');
tilesPostalCodeStyle = new carto.style.CartoCSS(`#layer {
polygon-fill: ramp([sum], (#201c27, #2b213a, #362351, #40216c, #4b2188, #581faa, #6216cf, #6d08ff));
polygon-opacity: 0.8;
::outline {
line-color: transparent;
line-width: 10;
line-opacity: 0.5;
}
}`);
var popup = L.popup();
tilesPaymentsLayer.on('featureClicked', function(e) {
tilesPostalCodeData.setQuery(`
SELECT pc.the_geom, pc.the_geom_webmercator, mp.cartodb_id, pc.code, mp.ammount as sum
FROM mad_tile_postalcode mp
JOIN mad_postal_codes pc ON pc.cartodb_id = postal_code_id
WHERE tile_code_id=${e.data.cartodb_id}
`);
selectedTileData.setQuery(`
SELECT cartodb_id, the_geom, the_geom_webmercator
FROM mad_tiles where cartodb_id=${e.data.cartodb_id}`);
layerPC = new carto.layer.Layer(tilesPostalCodeData, tilesPostalCodeStyle);
layerSelectedTile = new carto.layer.Layer(selectedTileData, tilesSelectedStyles);
layerPC.setFeatureClickColumns(['cartodb_id', 'sum', 'code']);
tilesPaymentsLayer.hide();
layerPC.on('featureOver', function (e) {
popup.setLatLng(e.latLng);
popup.setContent(`<h4>Postalcode ${e.data.code}</h4>${e.data.sum.toFixed(2)} €`);
popup.openOn(map);
});
client.addLayer(layerPC);
client.addLayer(layerSelectedTile);
updateAmmountByPostalCodeOrigin(e.data.cartodb_id);
closeBtn.classList.add('shown');
});
closeBtn.addEventListener('click', function() {
closeBtn.classList.remove('shown');
client.removeLayer(layerPC);
client.removeLayer(layerSelectedTile);
tilesPaymentsLayer.show();
stats.innerHTML = '';
map.closePopup(popup);
widgetWrapper.classList.remove('shown');
clearAmmountByPostalCodeOrigin();
});
client.getLeafletLayer().addTo(map);
function showLayer(layer) {
layer.show();
}
function hideLayer(layer) {
layer.hide();
}
let ammountByPostalCodeOriginQuery = new carto.source.SQL(`
SELECT pc.cartodb_id,
pc.code,
ammount
FROM mad_tile_postalcode
JOIN mad_postal_codes pc
ON postal_code_id = pc.cartodb_id
`);
ammountByPostalCodeOriginQuery._originalQuery = ammountByPostalCodeOriginQuery.getQuery();
let ammountByPostalCodeOrigin = new carto.dataview.Category(ammountByPostalCodeOriginQuery, 'code', {
limit: 10,
operation: carto.operation.SUM,
operationColumn: 'ammount'
});
ammountByPostalCodeOrigin.on('dataChanged', (data)=>{
let html = '';
let max = data.max;
for(let row of data.categories){
html += `
<li>
<div class="infoWrapper">
<span class="label">${row.name}</span>
<span class="value">${row.value.toFixed(2)} €</span>
</div>
<div class="barWrapper">
<div class="barValue" style="width: ${100 * row.value/max}%;"></div>
</div>
</li>
`;
}
stats.innerHTML = html;
});
client.addDataview(ammountByPostalCodeOrigin);
function updateAmmountByPostalCodeOrigin(tile_id){
stats.innerHTML = 'Loading...';
widgetWrapper.classList.add('shown');
ammountByPostalCodeOriginQuery.setQuery(`
SELECT pc.cartodb_id,
pc.code,
ammount
FROM mad_tile_postalcode
JOIN mad_postal_codes pc
ON postal_code_id = pc.cartodb_id
WHERE tile_code_id = ${tile_id}
`);
}
function clearAmmountByPostalCodeOrigin(){
ammountByPostalCodeOriginQuery.setQuery(
ammountByPostalCodeOriginQuery._originalQuery
);
}
* { padding: 0; margin: 0; box-sizing: border-box; }
html, body {
margin: 0;
padding: 0;
font-family: 'Roboto', sans-serif;
height: 100vh;
display: flex;
flex-direction: column;
align-items: stretch;
}
header {
flex: 0 0 auto;
padding: 12px;
}
h1 {
font-size: 1.2em;
line-height: 1em;
}
h2 {
font-size: .8em;
line-height: 1em;
color: #333;
}
.closeBtn {
position: absolute;
top: 69px;
right: 12px;
width: 24px;
height: 24px;
padding: 6px;
font-size: 12px;
text-align: center;
border-radius: 50%;
z-index: 1000;
background-color: #FFF;
cursor: pointer;
opacity: 0;
box-shadow: 0 1px 10px 0 rgba(0,0,0,0.5);
}
.closeBtn.shown {
opacity: 1;
}
#map {
flex: 1 1 100%;
}
.widgetsFloatingWrapper {
display: none;
position: absolute;
width: 300px;
max-height: 500px;
height: auto;
overflow: auto;
left: 0;
bottom: 0;
background-color: #383D4C;
z-index: 999;
border-radius: 2px;
padding: 10px 20px;
}
.widgetsFloatingWrapper.shown {
display: block;
}
.widgetsFloatingWrapper h2 {
color: white;
}
.categoryWidget {
margin-top: 20px;
}
.widgetsFloatingWrapper .categoryWidget:empty {
display: none;
}
.widgetsFloatingWrapper .categoryWidget:not(:empty) {
display: block;
color: #FFFFFF;
list-style-type: none;
padding: 0;
}
.categoryWidget li {
margin-bottom: 14px;
}
.categoryWidget li .infoWrapper {
display: flex;
justify-content: space-between;
margin-bottom: 4px;
}
.infoWrapper .label {
font-family: Roboto;
font-size: 14px;
line-height: 14px;
}
.infoWrapper .value {
font-family: Roboto;
font-size: 18px;
line-height: 18px;
}
.categoryWidget li .barWrapper {
height: 6px;
background-color: #4B505F;
width: 100%;
border-radius: 2px;
}
.categoryWidget li .barValue {
height: 6px;
background-color: #16969D;
border-radius: 2px 0 0 2px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment