Info Panel

An interactive map application contains an info panel component, which is used to display additional content related to a specific geographical coordinate/location or map element, such as a selected marker or polygon. An info panel contains built-in section views for basic weather information like observations and forecasts, but is fully extensible so you can provide your own views and content as needed.

Example info panel

Example info panel

If you're creating an InfoPanel instance directly, such as for use outside of InteractiveMapApp, use the following code to create an info panel and link it with your InteractiveMap instance:

const target = document.getElementById('map-search');
 
// custom configuration options for the panel
const panelConfig = {};
const panel = new PlaceSearchPanel(panelConfig);
 
// `map` is an instance of InteractiveMap
// update the map center when a location is selected from the results
panel.on('select', (e) => {
    // get the selected location's coordinate info from the event data
    const { result: { loc }} = e.data || {};
    if (loc) {
        const { lat, long: lon } = loc;
        const coord = { lat, lon };
        map.setView(coord, 8);
    }
});
 
// add the panel to the DOM
panel.addTo(target);
 
// show the panel using a configured view (e.g. "localweather") when the map is clicked
map.on('click', (e) => {
    const { coord: { lat, lon }} = e.data || {};
    // 'localweather' is a content view we've configured on our InfoPanel
    panel.showContent('localweather', 'Local Weather').load({
        p: `${lat},${lon}`
    });
});

Refer to the Using Content Views section below and our custom info panel content example for more information about setting up your info panel's content views.

If you're using an instance of InteractiveMapApp, you don't have to use the above code since the info panel is already instantiated and managed for you.

Configuration

The following options are supported when configuring your InfoPanel instance:

OptionTypeDescriptionDefault
viewsobjectAn object containing the view configurations keyed by view identifier. Content views contain one or more section views and are used when displaying content within an info panel. An info panel will display a single content view at once. See the Content View Configuration section below for more information.
sectionsobjectAn object containing the section view configurations keyed by section identifier. View sections represent data for a single data type and are used within content views when rendering an info panel's content. See the View Section Configuration section below for more information.
titlestringLabel title for the panel. The title is only rendered if the panel is toggleable and in the expanded state.
metricbooleanWhether the info panel views should be configured to display Metric units by default. Default value is false.
classNamestringA CSS class name to add to the panel, which can be used for additional style customizations.
toggleablebooleanA boolean value indicating whether the panel is toggleable. A toggleable panel will display a button in the closed/collapsed state initially. Clicking on the button will expand the panel to its full size.false
iconstringIcon HTML to display in the button when the panel is collapsed. This value can be any valid HTML, including an <img> or <svg> element.
positionobjectOptions to configure the position of the panel within its parent container.
position.pinstringThe position to pin the panel to relative to its parent container. Supports topleft, top, topright, left, center, right, bottomleft, bottom, or bottomleft.
position.translateIPointAmount to translate the panel in the x and y axis relative to its pinned position.{ x: 0, y: 0 }

Content View Configuration

Content views contain one or more section views and are used when displaying content within an info panel. The following options define the configuration for a content view:

OptionTypeDescriptionDefault
viewsobject[]An array of section view configurations or section view keys to render as part of this content view. The order in which they appear in the array is the order in which the will be rendered in the info panel. See the View Section Configuration section below for more information.
dataobjectxxxxx
requestApiRequest or FunctionThe ApiRequest to use when loading data for this content view. The request should load all data that is required by all section views. This value can either be a request instance or a function that configures and returns a request instance.

View Section Configuration

View sections represent data for a single data type and are used within content views when rendering an info panel's content. The following options define the configuration for a section view:

OptionTypeDescription
titlestringView title. If provided, the title will be rendered at the top of the view section's container.
dataobject or FunctionThe data to use when rendering the view section. If a function is provided, the full data set from the parent content view will be passed as an argument and the function must return the specific data required for rendering this view section.
rendererstring or FunctionThe section renderer, which can either be an HTML string or a function that receives the view's data as an argument and returns the final HTML for the view.
initFunctionA callback function that is called when the view is rendered and added to the DOM to allow you to perform any additional setup on render. This callback function receives two parameters: the view instance and the parent content view that contains the view.
requiresDatabooleanIf true, then this view will only be rendered in the parent content view if valid data was returned by the data property or function. When false, the view will be rendered regardless if data is available for the view. Default value is false.
staticbooleanDetermines if the view should be treated as a static view, meaning it will only be rendered once initially and any updates to the parent content view will not re-render this view. Default value is false.

Default Configuration

The following is the default configuration object for a InfoPanel instance:

{
    views: undefined,
    sections: undefined
}

Also review the default configuration for an InteractiveMapApp instance that is applied to its internal info panel.

Built-in View Sections

A series of section views are already setup and configured for you for basic weather information, like observations, advisories, forecasts and threats. The following section views can be used within your own content view configurations:

KeyDescription
unitsDisplays an Imperial/Metric units toggle control to switch the active info panel units at runtime.
placeDisplays the formatted place name.
obsDisplays the latest observation information for the place.
forecastDisplays either an hourly or daily forecast for the place.
alertsDisplays the currently active weather alerts for the place.
threatsDisplays the current weather threats for the place.
outlookDisplays a short-term outlook phase for the place.
hazardsDisplays a series of weather hazard and their impacts for the place.

As an example, the following is the configuration for the built-in place section view:

{
    data: (data) => {
        if (!data) return null;
 
        data = data.places || data;
        return data.place;
    },
    renderer: (data) => {
        return (`
            <div class="place">
                <p class="name">${data.name}${!isEmpty(data.state) ? `, ${data.state}` : ''}, ${data.country}</p>
            </div>
        `);
    }
}

In the above place section view, the data property receives the full data set from the parent content view and returns just the data required for the view. The renderer function then receives this filtered data and outputs the final HTML snippet for this section view within the context of the parent content view.

Handling Units

Oftentimes when outputting numerical data values you'll want to display them in terms of a particular unit of measurement, such as temperature or pressure. You can handle this in your view's renderer function by accessing the units property that's automatically added to the data object provided to your renderer. This units property will either be a value of imperial or metric:

{
    renderer: (data) => {
        const metric = data.units === 'metric';
        return (`
            <div class="temp">
                The current temperature is ${metric ? `${data.tempC}&deg;F` : `${data.tempF}&deg;C`}.
            </div>
        `);
    }
}

You can then output the correct value that corresponds to the current units value associated with the parent info panel instance. When the current units value changes from the info panel, then your views will automatically be re-rendered to allow you to update the data values based on the active units value.

Using Content Views

Since an info panel's content view consists of one or more section views, you can piece together your content views using the above built-in section views, your custom section views, or a combination of both. Simply provide your custom section and content view configurations within the sections and views properties of your info panel's main configuration object.

An InteractiveMapApp instance also configures a default local weather content view that can be used for displaying weather information for a single location or coordinate.

Configuring a Content View

The following is the views configuration containing the general local weather content view that's built into InteractiveMapApp for displaying local weather information for a particular location:

{
    views: {
        localweather: {
            request: () => {
                // main batch request instance
                const request = aeris.api();
 
                // add a request for all data we need for each section in the content view
                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(aeris.api().endpoint('forecasts').fields(forecastFields.join(',')).filter('3hr').limit(7));
 
                request.addRequest(aeris.api().endpoint('places'));
                request.addRequest(aeris.api().endpoint('threats').radius('50mi'));
                request.addRequest(aeris.api().endpoint('alerts').fields('details.type,details.name,timestamps'));
                request.addRequest(aeris.api().endpoint('phrases/summary'));
                request.addRequest(aeris.api().endpoint('observations'));
                request.addRequest(aeris.api().endpoint('convective/outlook').action(ApiAction.CONTAINS));
                request.addRequest(aeris.api().endpoint('lightning/summary').action(ApiAction.CLOSEST).radius('60mi').limit(100));
 
                return request;
            },
            views: [{
                renderer: 'place'
            },{
                title: 'Active Threats',
                renderer: 'threats'
            },{
                title: 'Active Alerts',
                renderer: 'alerts'
            },{
                title: 'Impacts',
                renderer: 'hazards'
            },{
                title: 'Observations',
                renderer: 'obs'
            },{
                title: 'Outlook',
                renderer: 'outlook'
            },{
                title: 'Short-Term Forecast',
                renderer: 'forecast'
            }]
        }
    }
}

As demonstrated in the above example, when configuring a content view you must provide an array of section views to display and either the request to use for the view's data or the static data to use when rendering the view. This local weather content view uses all of the built-in section views that come with the SDK, so the renderer property values are just the section view keys documented above.

Refer to our examples section for more examples of creating custom section and content views for your info panel.

Showing Info Panel Content

Once you've configured your info panel's section and content views, you can show your map application's info panel using one of the configured content views easily using the showInfo() or showInfoAtCoord() method on your interactive map app instance.

At minimum, both methods require the content view key to render when showing the info panel. You can also provide a title to display in the title bar of the info panel and/or the static data to use when rendering the content view.

For instance, to show the built-in local weather content view for the coordinate where the map is clicked with a title of “Local Weather”:

app.map.on('click', (e) => {
    // the coordinate where the map was clicked is stored in the event
    // data, 'e.data.coord'
    app.showInfoAtCoord(e.data.coord, 'localweather', 'Local Weather');
});

The data will automatically be requested using the specified coordinate and the request configured for the content view.

If you're displaying content for a specific geographical coordinate, use showInfoAtCoord(). This method will automatically perform the configured request using the coordinate provided when called. However, if your content view needs to pass request parameters other than just the coordinate when loading its required data, use showInfo(). When using showInfo(), the associated info panel instance is returned and you are required to call load() with any request parameters your content view's request requires.

For example, if we've added a custom airports vector source to the map to display the current flight rules at major airports, we'd want to display additional information for an airport when clicking its marker on the map. We would then configure our info panel with a custom airport content view to use when an airport is selected. Since this related to airports and not a coordinate, we need to pass the airport code to the content view's request using showInfo() and then calling load():

app.map.on('marker:click', (e) => {
    const data = e.data.data || {};
 
    // check the source key that triggered the click event to make sure
    // we're only showing the info panel for airport markers
    const source = data.awxjs_source;
    if (source === 'airports') {
        const id = data.id;
        const place = data.place || {};
        const name = aeris.utils.strings.toName(place.name);
        app.showInfo('airport', `${id} - ${name}`).load({ p: id });
    }
});

In this example, the info panel will be shown and rendered immediately with the airport ICAO code and name displayed in the title bar. Instead of the airport content view being rendered at first, a loading indicator is displayed while the request for data is being made via our call to load(). Once data has loaded, the airport content view is rendered with the data and the info panel updates its content.

Refer to our collection of examples for complete demonstrations of creating and working with custom content views.