Charting Reachable Statistics
Mapping the results is nice, but the data are the important part. Move the pin to re-calculate the reachable statistics.
<!DOCTYPE html>
<html>
<head>
<!-- Include mapboxgl javascript and css -->
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.6.0/mapbox-gl.js"></script>
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.6.0/mapbox-gl.css" rel="stylesheet">
<!-- Include targomo core -->
<script src="https://releases.targomo.com/core/latest.min.js"></script>
<!-- Include chartjs for adding charts -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
<!-- Include micro progress bar -->
<script src="https://www.targomo.com/developers/scripts/mipb.min.js"></script>
<style>
body, html {
margin: 0;
width: 100%;
height: 100%;
}
body {
display: flex;
}
#map {
width: 40%;
height: 100%;
}
#chart {
width: 60%;
height: 100%;
position: relative;
border-right: 1px solid #ddd;
}
</style>
</head>
<body>
<!-- where the chart will live -->
<div id="chart">
<canvas id="canvas"></canvas>
</div>
<!-- where the map will live -->
<div id="map"></div>
<script>
window.onload = function () {
const chartContainer = document.getElementById('chart');
chartContainer.style.height = chartContainer.clientHeight + 'px';
// create targomo client
const client = new tgm.TargomoClient('westcentraleurope', '__targomo_key_here__');
// Coordinates to center the map
const lnglat = [2.374513, 48.844334];
const attributionText = `<a href="https://www.targomo.com/developers/resources/attribution/" target="_blank">© Targomo</a>`;;
// set the progress bar
const pBar = new mipb({ fg: "#FF8319" });
// add the map and set the initial center to berlin
const map = new mapboxgl.Map({
container: 'map',
style: 'https://api.maptiler.com/maps/positron/style.json?key=__your_maptiler_api_key__',
zoom: 12,
center: lnglat,
attributionControl: false
})
.addControl(new mapboxgl.NavigationControl())
.addControl(new mapboxgl.AttributionControl({ compact: true, customAttribution: attributionText }));
// disable scroll zoom
map.scrollZoom.disable();
const marker = new mapboxgl.Marker({
draggable: true
}).setLngLat(lnglat).addTo(map);
marker.on('dragend', getStats);
const stats = {
group: 26,
individual: [
{
id: 8, name: "Population", label: "Total population",
colors: ["rgba(26,152,80,1)", "rgba(145,207,96,1)", "rgba(217,239,139,1)", "rgba(254,224,139,1)", "rgba(252,141,89,1)", "rgba(215,48,39,1)"]
},
{
id: 14, name: "Population_25", label: "Population 25 and older",
colors: ["rgba(26,152,80,0.5)", "rgba(145,207,96,0.5)", "rgba(217,239,139,0.5)", "rgba(254,224,139,0.5)", "rgba(252,141,89,0.5)", "rgba(215,48,39,0.5)"]
}
],
weights: [300, 600, 900, 1200, 1500, 1800],
colors: ['#d73027', '#fc8d59', '#fee08b', '#d9ef8b', '#91cf60', '#1a9850'].reverse()
}
async function getStats() {
// show progress bar
pBar.show();
const sources = [{ ...marker.getLngLat(), id: 1 }];
const statisticsResults = await client.statistics.dependent(sources, {
maxEdgeWeight: Math.max(...stats.weights), travelType: "Walk", // 30 minutes on foot
statisticsGroup: stats.group,
statistics: stats.individual
});
const formatted = stats.individual.map((s) => {
// map stats return to an array we can filter
const curStat = Object.entries(statisticsResults.statistics[s.name].values).map(([key, val]) => {
return {
weight: +key, stat: val
}
});
// filter and sum the statistics
const tallies = stats.weights.map(w => {
const sum = curStat.filter(s => s.weight <= w).reduce((a, b) => {
return { stat: a.stat + b.stat }
}, { stat: 0 });
return Math.round(sum.stat)
})
return {
label: s.label, backgroundColor: s.colors,
borderWidth: 0, data: tallies
}
})
// update chart
chart.data.datasets = formatted;
chart.update();
// hide progress bar
pBar.hide()
}
var chartOptions = {
responsive: true,
maintainAspectRatio: false,
layout: {
padding: { left: 8, right: 8, top: 20, bottom: 50 }
},
legend: { display: false },
title: {
display: true,
text: "Population Accessed in 30 Minutes Walking"
}
}
const ctx = document.getElementById("canvas").getContext("2d");
const chart = new Chart(ctx, {
type: "bar",
data: {
labels: ['5min', '10min', '15min', '20min', '25min', '30min']
},
options: chartOptions
});
getStats();
};
</script></body>
</html>
Copied to clipboard