Skip to content

Instantly share code, notes, and snippets.

@ramiroaznar
Created February 27, 2019 15:34
Show Gist options
  • Save ramiroaznar/37398ec65b7647cb6075af09278d98e5 to your computer and use it in GitHub Desktop.
Save ramiroaznar/37398ec65b7647cb6075af09278d98e5 to your computer and use it in GitHub Desktop.
CARTO VL + Interactivity + SVG Pie Chart
<!DOCTYPE html>
<html>
<head>
<title>CARTO VL + Interactivity + Vega Pie Chart</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,700|Open+Sans:300,400,600" rel="stylesheet">
<script src="https://libs.cartocdn.com/carto-vl/v1.1.1/carto-vl.min.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.52.0/mapbox-gl.js"></script>
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.52.0/mapbox-gl.css" rel="stylesheet" />
<link href="https://carto.com/developers/carto-vl/v1.1.1/examples/maps/style.css" rel="stylesheet">
<link href="style.css" rel="stylesheet">
</head>
<body>
<div id="app">
<div id="map"></div>
<div id="loader">
<div class="CDB-LoaderIcon CDB-LoaderIcon--big">
<svg class="CDB-LoaderIcon-spinner" viewBox="0 0 50 50">
<circle class="CDB-LoaderIcon-path" cx="25" cy="25" r="20" fill="none"></circle>
</svg>
</div>
</div>
</div>
<script src="main.js"></script>
<script src="interactivity.js"></script>
</body>
</html>
const interactivity = new carto.Interactivity(layer);
const popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
const delay = 50;
interactivity.on('featureClick', event => {
let feature = event.features[0],
vars = feature.variables,
city = vars.city.value,
city_pop = vars.pop.value,
country_pop = vars.totalPop.value,
percent_city_pop = city_pop * 100.00 / country_pop;
viz.color.blendTo('opacity(#ddd,0.7)', delay);
viz.strokeWidth.blendTo(1, delay);
viz.strokeColor.blendTo('#fff', delay);
popup.setHTML(`
<div>
<h3 class ="h3">${city}</h3>
<p class="description open-sans">Population: ${city_pop} inhab.</p>
<p class="description open-sans">Percentage: ${percent_city_pop.toFixed(2)} %</p>
<br>
<div>
<svg viewBox="0 0 64 64" class="chart">
<circle class="pie" r="25%" cx="50%" cy="50%" style="stroke-dasharray: ${percent_city_pop} 100; stroke: #E73F74;">
</circle>
</svg>
</div>
</div>
`);
popup.setLngLat([event.coordinates.lng, event.coordinates.lat]);
if (!popup.isOpen()) {
popup.addTo(map);
feature.color.blendTo('opacity(#E73F74, 0.7)', delay)
feature.strokeWidth.blendTo('7', delay);
feature.strokeColor.blendTo('opacity(#E73F74, 0.7)', delay);
} else {
popup.remove();
}
});
const map = new mapboxgl.Map({
container: 'map',
style: carto.basemaps.voyager,
center: [-3, 40],
zoom: 5,
scrollZoom: false,
});
const nav = new mapboxgl.NavigationControl({
showCompass: false
});
map.addControl(nav, 'top-left');
// Define user
carto.setDefaultAuth({
username: 'cartovl',
apiKey: 'default_public'
});
// Define layer
const source = new carto.source.SQL(`SELECT * FROM populated_places WHERE adm0name = 'Spain'`);
const viz = new carto.Viz(`
@totalPop: globalSum(@pop)
@maxPop: globalMax(@pop)
@minPop: globalMin(@pop)
@pop: $pop_max
@country: $adm0name
@city: $name
width: sqrt(@pop)/15
color: opacity(#ddd,0.7)
`);
const layer = new carto.Layer('layer', source, viz);
layer.addTo(map, 'watername_ocean');
layer.on('loaded', hideLoader);
function hideLoader() {
document.getElementById('loader').style.opacity = '0';
}
circle {
fill: #ddd;
stroke-width: 32;
transition: stroke-dasharray .3s ease;
}
svg {
margin: 0 auto;
transform: rotate(-90deg);
background: #ddd;
border-radius: 50%;
display: block;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment