Skip to content

Instantly share code, notes, and snippets.

@andy-esch
Created October 16, 2018 20:48
Show Gist options
  • Save andy-esch/4bf730c6d0a326433af343006f6ec865 to your computer and use it in GitHub Desktop.
Save andy-esch/4bf730c6d0a326433af343006f6ec865 to your computer and use it in GitHub Desktop.
carto vl with legends for cartoframes
<!DOCTYPE html>
<html>
<head>
<title>CARTO VL + CARTOframes</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8">
<!-- Include CARTO VL JS -->
<script src="https://cartodb.github.io/carto-vl/dist/carto-vl.js"></script>
<!-- Include Mapbox GL JS -->
<script src="https://cartodb-libs.global.ssl.fastly.net/mapbox-gl/v0.48.0-carto1/mapbox-gl.js"></script>
<!-- Include Mapbox GL CSS -->
<link href="https://cartodb-libs.global.ssl.fastly.net/mapbox-gl/v0.48.0-carto1/mapbox-gl.css" rel="stylesheet" />
<link rel="stylesheet" type="text/css" href="https://cartodb.github.io/carto-vl/examples/style.css">
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<aside class="toolbox">
<div class="box">
<header>
<h1>Brookly Poverty Rates</h1>
</header>
<section>
<div id="controls">
<ul id="content"></ul>
</div>
</section>
<footer class="js-footer"></footer>
</div>
</aside>
<script>
const BASEMAPS = {
DarkMatter: 'https://basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json',
Voyager: 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json',
Positron: 'https://basemaps.cartocdn.com/gl/positron-gl-style/style.json',
};
if ("") {
mapboxgl.accessToken = "";
}
// Fetch CARTO basemap if it's there, else try to use other supplied style
const map = new mapboxgl.Map({
container: 'map',
style: BASEMAPS['DarkMatter'] || "DarkMatter",
zoom: 11,
dragRotate: false,
center: [-73.95, 40.6452228]
});
let credentials = {"user": "eschbacher", "api_key": "default_public"};
carto.setDefaultAuth({
user: credentials['user'],
apiKey: credentials['api_key'] || 'default_public'
});
var sources = [{"is_local": false, "styling": "color: ramp(globalEqIntervals($poverty_per_pop, 5), sunsetdark)\nwidth: 20\nstrokeWidth: 0", "source": "SELECT * FROM brooklyn_poverty where poverty_per_pop between 0 and 1", "interactivity": null}];
// map.fitBounds([[-180, -85.0511], [180, 85.0511]], {animate: false});
sources.forEach((elem, idx) => {
let temp_source = null;
if (elem.is_local) {
let local_json = JSON.parse(elem.source);
temp_source = new carto.source.GeoJSON(local_json);
} else {
temp_source = new carto.source.SQL(elem.source);
}
const viz = new carto.Viz(elem['styling']);
const temp = new carto.Layer(
'layer' + idx,
temp_source,
viz
);
temp.addTo(map);
temp.on('loaded', () => {
// Get the information for legend
console.log(temp);
const strokeColorLegend = temp.viz.color.getLegendData();
let colorLegendList = '';
strokeColorLegend.data.forEach((legend) => {
console.log(legend.value);
const colorHex = rgbToHex(legend.value);
console.log('key', legend.key);
colorLegendList +=
`<li><span class="point-mark" style="border:5px solid ${colorHex};"></span> <span>${boundsFormat(legend.key)}</span></li>\n`;
});
// Update the legend with the legend information
document.getElementById('content').innerHTML = colorLegendList;
});
var last_source = idx === 0 ? 'watername_ocean' : 'layer' + (idx - 1);
if (elem.interactivity) {
let interactivity = new carto.Interactivity(temp);
let tempPopup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
if (elem.interactivity.event == 'click') {
setPopupsClick(tempPopup, interactivity, elem.interactivity.header);
} else if (elem.interactivity.event == 'hover') {
setPopupsHover(tempPopup, interactivity, elem.interactivity.header);
}
}
});
function setPopupsClick(tempPopup, intera, popupHeader) {
intera.off('featureHover', (event) => {
updatePopup(tempPopup, event, popupHeader)
});
intera.on('featureClick', (event) => {
updatePopup(tempPopup, event, popupHeader, popupHeader)
});
}
function setPopupsHover(tempPopup, intera, popupHeader) {
intera.off('featureClick', (event) => {
updatePopup(tempPopup, event, popupHeader)
});
intera.on('featureHover', (event) => {
updatePopup(tempPopup, event, popupHeader)
});
}
function updatePopup(layer_popup, event, popupHeader) {
if (event.features.length > 0) {
const vars = event.features[0].variables;
let popupHTML = popupHeader ? `<h1>${popupHeader}</h1>` : ``;
Object.keys(vars).forEach((varName) => {
popupHTML += `
<h3 class="h3">${varName}</h3>
<p class="description open-sans">${vars[varName].value}</p>
`;
});
layer_popup.setLngLat([event.coordinates.lng, event.coordinates.lat])
.setHTML(`<div>${popupHTML}</div>`);
if (!layer_popup.isOpen()) {
layer_popup.addTo(map);
}
} else {
layer_popup.remove();
}
}
function rgbToHex(color) {
return "#" + ((1 << 24) + (color.r << 16) + (color.g << 8) + color.b).toString(16).slice(1);
}
function boundsFormat(a) {
const lower = isFinite(a[0]) ? Math.round(a[0] * 100) / 100 : '-&infin;';
const upper = isFinite(a[1]) ? Math.round(a[1] * 100) / 100 : '+&infin;';
return `[${lower}, ${upper}]`
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment