Skip to content

Instantly share code, notes, and snippets.

@oriolbx
Last active April 5, 2019 10:25
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 oriolbx/8a8771a5429680578b565f8a87c8feb5 to your computer and use it in GitHub Desktop.
Save oriolbx/8a8771a5429680578b565f8a87c8feb5 to your computer and use it in GitHub Desktop.
CARTO VL: Open popup from clicking barchart
<!DOCTYPE html>
<html>
<head>
<title>Category chart | CARTO</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta charset="UTF-8">
<script src="https://libs.cartocdn.com/carto-vl/v1.2.4/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.2.4/examples/maps/style.css" rel="stylesheet">
<!-- Include Chart JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>
</head>
<body>
<div id="map"></div>
<aside class="toolbox chart-toolbox">
<div class="box">
<header>
<h1>Region</h1>
</header>
<section>
<canvas id="histogram" width="300" height="300"></canvas>
</section>
</div>
</aside>
<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>
<script>
const map = new mapboxgl.Map({
container: 'map',
style: carto.basemaps.voyager,
center: [42.31, 22.88],
zoom: 2,
hash: true
});
const nav = new mapboxgl.NavigationControl({
showCompass: false
});
map.addControl(nav, 'top-left');
carto.setDefaultAuth({
username: 'oboix',
apiKey: 'default_public'
});
// Define pop-up
const popup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false
});
const ctx = document.getElementById('histogram').getContext('2d');
// Define the source
const source = new carto.source.SQL('SELECT * FROM world_borders_6 LIMIT 20');
// Define the visualization
const viz = new carto.Viz(`
@v_histogram: viewportHistogram($iso3)
color: #00718b
width: 5
strokeWidth: 0.5
`);
// Draw chart using Chart.js library (https://www.chartjs.org/)
const chartOptionsDefault = {
animation: {
duration: 0
},
legend: {
display: false
},
scales: {
yAxes: [{
gridLines: {
drawBorder: false,
display: false
},
ticks: {
suggestedMin: 1,
beginAtZero: true,
display: false
}
}],
xAxes: [{
gridLines: {
drawBorder: false,
display: false
},
ticks: {
display: true,
fontSize: 7,
autoSkip: false,
maxRotation: 0,
minRotation: 0
},
barPercentage: 0.9,
categoryPercentage: 1.0
}]
},
onClick: function(e){
// get label clicked element
selected_el = chart.getElementAtEvent(e)
input = selected_el[0]._model.label
return fetch(`https://oboix.carto.com/api/v2/sql?format=geojson&q=SELECT ST_Centroid(the_geom) as the_geom, name FROM world_borders_6 where iso3 = '${input}'`)
.then((resp) => resp.json())
.then((response) => {
openPopup(response.features[0])
})
}
};
const chart = new Chart(ctx, {
type: 'bar',
options: chartOptionsDefault
});
const layer = new carto.Layer('layer', source, viz);
const interactivity = new carto.Interactivity(layer);
const delay = 50;
let clickedFeatureId = null;
layer.addTo(map, 'watername_ocean');
layer.on('loaded', hideLoader);
layer.on('updated', () => {
// Save histogram variable
const histogram = layer.viz.variables.v_histogram;
// Get histogram data
const histogramData = histogram.value;
// Chart.js set up
const labels = histogramData.map(elem => elem.x);
const data = histogramData.map(elem => elem.y);
const backgroundColor = '#00718b';
chart.data = {
labels,
datasets: [{
data,
backgroundColor
}]
};
chart.update();
});
function hideLoader() {
document.getElementById('loader').style.opacity = '0';
}
function openPopup(features) {
console.log(features)
if (features) {
popup.setHTML(`
<div>
<h3 class ="h3">${features.properties.name}</h3>
</div>
`);
popup.setLngLat([features.geometry.coordinates[0], features.geometry.coordinates[1]]);
console.log(popup.isOpen())
if (!popup.isOpen()) {
popup.addTo(map);
}
} else {
popup.remove();
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment