Skip to content

Instantly share code, notes, and snippets.

@ramiroaznar
Created December 27, 2017 23:31
Show Gist options
  • Save ramiroaznar/5352b329a46f5f41429a137f40357755 to your computer and use it in GitHub Desktop.
Save ramiroaznar/5352b329a46f5f41429a137f40357755 to your computer and use it in GitHub Desktop.
Change style and get metadata with CARTO.js 4
<!DOCTYPE html>
<html>
<head>
<title>Change style and get metadata with CARTO.js 4</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<link rel="shortcut icon" href="https://cartodb.com/assets/favicon.ico" />
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<!-- leaflet + jquery -->
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!-- selec2 -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
<!-- carto.js -->
<script src="https://cartodb-libs.global.ssl.fastly.net/carto.js/v4.0.0-beta.4/carto.min.js"></script>
<style>
* {
box-sizing: border-box;
}
body, *{ margin: 0; padding: 0; }
#map {
position: absolute;
height: 100%;
width: 100%;
z-index: 0;
}
#wraper-class-selector {
position: absolute;
top: 20px;
right: 20px;
z-index: 2;
}
.js-class-selector {
width: 160px;
}
#legend {
position: absolute;
bottom: 12px;
left: 12px;
height: auto;
width: auto;
padding: 20px 24px;
background: white;
box-shadow: 0 0 16px rgba(0, 0, 0, 0.12);
border-radius: 4px;
opacity: 0.7;
z-index: 1;
display: block;
list-style-type: none;
}
#legend h1 {
font: 800 12px/16px 'Montserrat';
color: #2D3C43;
}
#legend h2 {
font: 600 12px/16px 'Open Sans';
color: #2D3C43;
margin-bottom: 12px;
}
#legend li {
width: 40px;
height: 40px;
opacity: 0.9;
margin-bottom: 6px;
}
#legend-content span {
display: inline-block;
font: 500 12px/16px 'Open Sans';
color: #2D3C43;
margin-bottom: 6px;
}
</style>
</head>
<body>
<!-- map div -->
<div id="map"></div>
<!-- dropdown classification selector -->
<div id="wraper-class-selector">
<select class="js-class-selector">
<option value="quantiles" selected>Quantiles</option>
<option value="jenks">Jenks</option>
<option value="equal">Equal Intervals</option>
<option value="headtails">Head Tails</option>
</select>
</div>
<!-- legend -->
<div id="legend">
<h1>World Population Density</h1>
<h2>Inhabitants/Area</h2>
<div id="legend-content"></div>
</div>
<script type="text/cartocss" id="style">
#layer {
polygon-fill: ramp([pop_norm], cartocolor(Sunset), quantiles);
polygon-opacity: 0.7;
line-width: 0;
}
</script>
<script type="text/sql" id="query">
SELECT
*
FROM
world_borders
</script>
<script>
function main() {
// get styles, query, legend & selector
const style = $("#style").text(), query = $("#query").text(), legend = $("#legend-content"), selector = $(".js-class-selector"),
// add map variable
map = L.map('map', {
zoomControl: false,
center: [41, -25],
zoom: 3
});
// add Voyager Basemap
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {
maxZoom: 18,
}).addTo(map);
// Adding Voyager Labels
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_only_labels/{z}/{x}/{y}.png', {
maxZoom: 18,
zIndex: 100
}).addTo(map);
// add client
const client = new carto.Client({
apiKey: 'API_KEY',
username: 'ramirocartodb'
});
// define layer configuration
const worldDataset = new carto.source.SQL(query),
worldStyle = new carto.style.CartoCSS(style),
worldLayer = new carto.layer.Layer(worldDataset, worldStyle);
// add layer
client.addLayer(worldLayer);
client.getLeafletLayer().addTo(map);
// add selector
selector.select2();
selector.change(function(){
let input = $( ".js-class-selector option:selected" ).val();
console.log(input);
worldStyle.setContent(`
#layer {
polygon-fill: ramp([pop_norm], cartocolor(Sunset), ${input});
polygon-opacity: 0.7;
line-width: 0;
}
`);
});
const mins = [], maxs = [], colors = [];
// change legend when data classification method changes
worldLayer.on('metadataChanged', function(event){
colors.length = 0;
maxs.length = 0;
mins.length = 0;
legend.empty();
// get buckets
const buckets = event.styles[0]._buckets;
// populate mins, maxs and colors array
for (bucket of buckets){
mins.push(bucket.min.toFixed(2));
maxs.push(bucket.max.toFixed(2));
colors.push(bucket.value);
}
// append colors and ranges to the legend
$(colors).each(function(i, e) {
legend.append(`<li style="background: ${colors[i]}"></li><span>${mins[i]} - ${maxs[i]}</span>`)
});
});
}
window.onload = main;
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment