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 maplibregl javascript and css -->
    <script src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-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: 50%;
            height: 100%;
        }
        #chart {
            width: 50%;
            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.322172, 48.890929]
        
            const attributionText = '<a href="https://www.targomo.com/developers/resources/attribution/" target="_blank">&copy; 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 maplibregl.Map({
                container: 'map',
                style: client.basemaps.getGLStyleURL('Light'),
                zoom: 12,
                center: lnglat,
                attributionControl: false
            })
                .addControl(new maplibregl.NavigationControl())
                .addControl(new maplibregl.AttributionControl({ compact: false, customAttribution: attributionText }))
        
            // disable scroll zoom
            map.scrollZoom.disable()
        
            const marker = new maplibregl.Marker({
                draggable: true
            }).setLngLat(lnglat).addTo(map)
        
            marker.on('dragend', getStats)
        
            const stats = {
                group: 123,
                individual: [
                    {
                        id: 21, name: 'Population_18_24', label: 'Population 18 - 24',
                        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: 22, name: 'Population_25_39', label: 'Population 25 - 39',
                        colors: ['rgba(26,152,80,0.5)', 'rgba(145,207,96,0.75)', 'rgba(217,239,139,0.75)', 'rgba(254,224,139,0.75)', 'rgba(252,141,89,0.75)', 'rgba(215,48,39,0.75)']
                    },
                    {
                        id: 23, name: 'Population_40_54', label: 'Population 40 - 54',
                        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)']
                    },
                    {
                        id: 24, name: 'Population_55_64', label: 'Population 55 - 64',
                        colors: ['rgba(26,152,80,0.25)', 'rgba(145,207,96,0.25)', 'rgba(217,239,139,0.25)', 'rgba(254,224,139,0.25)', 'rgba(252,141,89,0.25)', 'rgba(215,48,39,0.25)']
                    }
                ],
                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 Profile 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>
content_copy
Copied to clipboard