Examples
Using app panels with interactive map

Using App Panels with InteractiveMap

Render a basic interactive map with various panels and controls used by InteractiveMapApp and provided by the Apps module. The following example will display an interactive map with the timeline, legend, place search and local weather info panels similar to InteractiveMapApp but without the auto-managed map app container.

Panels with interactive map example

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Aeris JavaScript SDK - Using App Panels with Interactive Map</title>
    <script defer src="https://cdn.aerisapi.com/sdk/js/latest/aerisweather.min.js"></script>
    <link rel="stylesheet" href="https://cdn.aerisapi.com/sdk/js/latest/aerisweather.css">
 
    <style>
    #map-container {
        font-family: 'Helvetica','Aerial',sans-serif;
        height: 800px;
        margin: 30px auto;
        position: relative;
        width: 1200px;
    }
    #map {
        height: inherit;
        width: 100%;
    }
    </style>
 
</head>
<body>
 
<div id="map-container">
    <div id="map"></div>
</div>
 
<script>
 
    window.onload = () => {
 
        const aeris = new Xweather('CLIENT_ID', 'CLIENT_SECRET');
 
        aeris.views().then(views => {
            const map = new views.InteractiveMap(document.getElementById('map'), {
                center: {
                    lat: 39.0,
                    lon: -95.5
                },
                zoom: 4,
                layers: 'alerts,radar',
                timeline: {
                    from: -6 * 3600,
                    to: 0
                }
            });
 
            aeris.apps().then((apps) => {
                const container = document.getElementById('map-container');
                const account = aeris.account();
 
                // map timeline
                const timeline = new apps.panels.TimelinePanel(map.timeline);
                timeline.addTo(container);
                timeline.pinTo('bottom', { y: -10 });
 
                // place search
                const search = new apps.panels.PlaceSearchPanel({
                    account
                });
                search.on('select', (e) => {
                    const { result: { loc }} = e.data || {};
                    if (loc) {
                        const { lat, long: lon } = loc;
                        const coord = { lat, lon };
                        map.setView(coord, 8);
                    }
                });
                search.addTo(container);
                search.pinTo('top', { y: 10 });
 
                // legends
                const legends = new apps.panels.LegendPanel({
                    toggleable: true
                });
                legends.addTo(container);
                legends.pinTo('bottomright', { x: -10, y: -10 });
 
                // set up events on map layer add/remove to update legends
                map.on('layer:add', (e) => {
                    const { layer, id } = e.data || {};
                    const keys = layer || id;
                    if (keys) {
                        const layers = keys.replace(/\:[^,]+/g, '').split(',');
                        layers.forEach((code) => {
                            legends.legend.add(code, {
                                account: account
                            });
                            if (code === 'alerts' || /^alerts-/.test(code)) {
                                setTimeout(() => {
                                    legends.legend.update({
                                        account: account,
                                        within: {
                                            bounds: map.getBounds()
                                        }
                                    });
                                }, 500);
                            }
                        });
                    }
                }).on('layer:remove source:remove', (e) => {
                    const { layer, id } = e.data || {};
                    const keys = layer || id;
                    if (keys) {
                        const layers = keys.replace(/\:[^,]+/g, '').split(',');
                        layers.forEach((code) => {
                            legends.legend.remove(code);
                        });
                    }
                }).on('change:bounds', (e) => {
                    const opts = { account: account };
                    opts.within = {
                        bounds: map.getBounds()
                    };
                    legends.legend.update(opts);
                });
 
                // info panel
                const infoPanel = new apps.panels.InfoPanel();
                // set up the localweather view configuration and requests that will be used in the InfoPanel
                infoPanel.setContentView('localweather', {
                    request: () => {
                        const request = account.api();
                        const forecastFields = (`
                                timestamp,dateTimeISO,tempF,tempC,icon,weatherPrimary,windSpeedMPH,windSpeedKPH,windSpeedMinMPH,windSpeedMinKPH,
                                windSpeedMaxMPH,windSpeedMaxKPH,windGustMPH,windGustKPH,snowIN,snowCM,precipIN,precipMM
                            `).split(',').map((key) => `periods.${key}`);
                        request.addRequest(account.api().endpoint('forecasts').fields(forecastFields.join(',')).filter('3hr').limit(7));
                        request.addRequest(account.api().endpoint('places'));
                        request.addRequest(account.api().endpoint('observations'));;
                        return request;
                    },
                    views: [{
                        renderer: 'place'
                    },{
                        title: 'Observations',
                        renderer: 'obs'
                    },{
                        title: 'Short-Term Forecast',
                        renderer: 'forecast'
                    }]
                });
                infoPanel.addTo(container);
                infoPanel.pinTo('topleft', { x: 10, y: 10 });
 
                // show InfoPanel for location when map is clicked
                map.on('click', (e) => {
                    const { coord: { lat, lon }} = e.data || {};
                    infoPanel.showContent('localweather', 'Local Weather').load({
                        p: `${lat},${lon}`
                    });
                });
 
            })
        });
    };
 
</script>
 
</body>
</html>