Layers Panel
An interactive map application contains a layers panel component, which is fully configurable and allows the user to toggle your desired layers on and off as well as filter a layer's vector data currently visible on the map.
Configuration
The following options are supported when configuring your InteractiveMapApp instance:
Option | Type | Description | Default |
---|---|---|---|
buttons | array | An array of button elements to render in the panel, where each button controls a single layer or layer group. Refer to the Button Configuration section below for more information. | |
title | string | Label title for the panel. The title is only rendered if the panel is toggleable and in the expanded state. | |
className | string | A CSS class name to add to the panel, which can be used for additional style customizations. | |
toggleable | boolean | A 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 |
icon | string | Icon HTML to display in the button when the panel is collapsed. This value can be any valid HTML, including an <img> or <svg> element. | |
position | object | Options to configure the position of the panel within its parent container. | |
position.pin | string | The position to pin the panel to relative to its parent container. Supports topleft , top , topright , left , center , right , bottomleft , bottom , or bottomleft . | |
position.translate | IPoint | Amount to translate the panel in the x and y axis relative to its pinned position. | { x: 0, y: 0 } |
Button Configuration
Option | Type | Description | Default |
---|---|---|---|
title | string | Button label title. | |
value | string | number | Value associated with the button, which is the either the map layer/source key or group key if it's a segmented button. | |
options | object | Optional custom data associated with the button. This is often used to store request parameters to be used when requesting map data associated with the button. | |
segments | array | An array of button configurations to be rendered as segment options for this button. These segments are usually associated with the parent button and are used to toggle between values or apply one or more filters to the button's value. Segments can only be defined for buttons at the root level, not for buttons defined as segments. | |
filter | boolean | A boolean value indicating whether the button segments should function as filter options to the parent button instead of toggling between values. | false |
multiselect | boolean | A boolean value indicating whether multiple child buttons or segments can be selected. | |
buttons | array | An array of button configurations to display as a group. The group will be rendered with a group title indicated by this object's title property. | |
controls | object | Optional configuration for additional controls rendered with the button, such as a close indicator on hover, layer settings popover, etc. See Button Controls below for more information. |
Default Configuration
The following is the default configuration object for a InteractiveMapApp instance:
{
buttons: undefined
}
Your implementation is responsible for declaring the series of button options to render within the panel.
Also review the default configuration for an InteractiveMapApp instance that is applied to its internal layers panel.
Segmented Buttons
Each button in the layers panel can define a series of segments for that button, which act as related values pertaining to the button or a series of filters that can be applied to the button's value. When a segment is selected, the button will trigger a value:change
with information about the button.
Segments as Values
When you set a button's filter
configuration option to false
, which is the default, then each segment within the button acts as its own value and only one segment can be selected at a time.
For instance, you want to group all satellite layer options into a single button while still allowing the user to toggle between the different types of satellite imagery. You would set this button up using the following configuration:
{
id: 'satellite',
title: 'Satellite',
segments: [{
value: 'satellite:75',
title: 'Infrared'
},{
value: 'satellite-infrared-color:75',
title: 'Color Infrared'
},{
value: 'satellite-visible:75',
title: 'Visible'
},{
value: 'satellite-geocolor',
title: 'Geocolor'
},{
value: 'satellite-water-vapor:75',
title: 'Water Vapor'
}],
options: {
style: {
zIndex: 0
}
}
}
Using the above configuration, when the user first selects the Satellite button, the first segment is selected and the satellite
layer is added to the map if a previous value has not already been set. Selecting one of the other segments will remove the previous satellite-related layer and add the selected one, toggling between the different satellite types.
In the above configuration, options
are also provided, which are the layer options to use when adding one of the layers to the interactive map. Setting the zIndex
to 0
will ensure that any satellite layer will be inserted below all other layers, such as radar or alerts.
Segments as Filters
Instead of having button segments toggle between a series of different values, you can set your button's filter
configuration option to true
to have the segments function as filters to the button's main value. This is useful for vector map content sources, such as markers or polygons. Additionally, if you set multiselect
to true
on your button, then multiple segments can be selected at once, meaning multiple filters can be applied to the button's source at a given time.
For example, you may want to allow the user to filter storm reports by category. You'd then define each category as its own segment in your main storm reports button:
{
id: 'stormreports',
value: 'stormreports',
title: 'Storm Reports',
filter: true,
multiselect: true,
segments: [{
value: 'all',
title: 'All'
},{
value: 'rain,flood',
title: 'Rain/Flood'
},{
value: 'wind',
title: 'Wind'
},{
value: 'snow',
title: 'Snow'
},{
value: 'hail',
title: 'Hail'
}]
}
With the above configuration, the button's main value
corresponds to the layer or map content source key to use. By default, the segment whose value is all
will be selected initially. Then when the user selects one or more of the other segments, the filter value are used to update the map content source's data on the map. Since multiselect
is enabled, each segment acts as a toggle to enable and disable the filter from the request.
If you have a segment with value of all
in your segments, selecting that segment will deselect all other selected segments so that all filters are removed from the map content source's data request.
Grouped Segments
You can also group related segments together into individual segments groups and have multiple segment groups for a single button. This is useful in use cases where you may have multiple filters you want to enable for a vector data source where each segment group controls the active filter for a specific property.
To create grouped segments for your button, you'll need to provide an object on your button's segments
option that contains a groups
property. Then, set up your segment groups as an array of configuration objects similar to an array of segmented button options. For instance, the following configuration would define an Observations layer control set up with two filters as segment groups: data property and station type:
{
value: 'obs-point',
title: 'Observations',
filter: true,
segments: {
groups: [{
id: 'fields',
title: 'Property',
segments: [{
value: 'tempF',
title: 'Temperatures'
},{
value: 'windSpeedMPH',
title: 'Winds'
},{
value: 'humidity',
title: 'Humidity'
},{
value: 'precipIN',
title: 'Precipitation'
},{
value: 'sky',
title: 'Sky Cover'
},{
value: 'uvi',
title: 'UV Index'
}]
},{
id: 'filter',
title: 'Station Type',
segments: [{
value: 'allstations',
title: 'All'
},{
value: 'metar',
title: 'METAR'
},{
value: 'madis',
title: 'MADIS'
},{
value: 'pws',
title: 'PWS'
}]
}]
}
}
Now, the layer's data will be updated based on the selected filter option from each segment group.
Button Groups
You can group related buttons within the layers panel so that groups of similar layers can be represented as a single collection visually. Creating a button group is simple as well. Simply create a nested buttons
array within your parent button item's configuration.
The following would create an “Observations” group consisting of a variety of radar, satellite and observation layers:
{
title: 'Observtions',
buttons: [{
id: 'radar',
value: 'radar:80',
title: 'Radar'
},{
id: 'satellite',
title: 'Satellite',
segments: [{
value: 'satellite:75',
title: 'Infrared'
},{
value: 'satellite-visible:75',
title: 'Visible'
},{
value: 'satellite-geocolor,states-outlines-dk',
title: 'Geocolor'
}],
options: {
style: {
zIndex: 0
}
}
},{
title: 'Surface',
value: 'surface-analysis'
},{
title: 'Temperatures',
value: 'temperatures:75,states-outlines-dk,temperatures-text'
},{
title: 'Winds',
value: 'wind-speeds:75,states-outlines-dk,wind-dir,wind-speeds-text'
},{
title: 'Humidity',
value: 'humidity:75,states-outlines-dk,humidity-text'
},{
id: 'visibility',
title: 'Visibility',
value: 'fvisibility'
},{
title: 'Air Quality',
value: 'air-quality'
}]
}
Button Controls
Button controls allow you to add additional functionality to a button instance. For instance, a close/remove icon can appear on hover indicating that clicking the currently selected button will remove that layer from the map. Or, you can display layer-specific options in a popover by configuring a settings
control for the button. For instance, you would use this settings
control to configure an opacity slider that enables real-time opacity changes for a specific layer on the map.
The following button control options are currently supported:
Option | Type | Description | Default |
---|---|---|---|
close | boolean | When enabled, displays a close/remove icon when a selected button is moused over. This indicates that clicking the button will deselect it and remove the associated layer from the map. | true |
activity | boolean | When enabled, an activity indicator will appear on the button when the associated layer is actively requesting data for the map. This is currently only for vector layers, not tile/raster layers. | true |
settings | array | Defines an array of options and controls to display in a popover component next to the button, allowing the user to adjust various settings for the associated layer (such as opacity). If settings are provided, a settings (gear) icon will be rendered on the button when in the selected state to present the settings popover when clicked. See the Setting Control Types section below for the list of supported control types you can use. |
Setting Control Types
Type | Description |
---|---|
slider | Supports setting a value within a min and max value range using a slider control. |
opacity | A built-in and properly configured slider control for adjusting an opacity value whose value ranges from 0 (0%) to 1 (100%). |
Receiving Control Events
If you are setting up a custom settings control for your buttons instead of one of the built-in ones, you will often want to be notified when those control values change. These events will be propagated up to your InteractiveMapApp
instance where you can set up an event handler for the layer:change:control
event:
app.on('layer:change:control', (e) => {
console.log('layer control changed', e.data);
});
The event's data
object will contain information about the control that triggered the event as well as the id
and value
of the button from which the change occurred.
Adding a Layer Opacity Slider
When working with raster/tile layers, you'll often want to be able to adjust the layer's opacity in order for underlying map features and layers to be partially visible. You can set the initial layer opacity by defining a custom raster layer style with your layer. However, you may want to allow the user to adjust the opacity afterwards from the map application interface.
Using the button controls configuration as outlined above, specifically the settings
option and built-in opacity
control, you can effortlessly add this functionality to your applications. You can also define the default opacity value to use for the layer and control by defining the necessary raster style configuration options:
{
title: 'Radar',
value: 'radar',
options: {
style: {
opacity: 0.5
}
},
controls: {
settings: [{
type: 'opacity'
}]
}
}
These same controls can be used for segmented button groups, in which case the opacity value in the control will be used for all raster layers within the group:
{
id: 'radar-type',
title: 'Radar',
segments: [{
title: 'Radar',
value: 'radar'
},{
title: 'Global Radar',
value: 'radar-est'
}],
options: {
style: {
opacity: 0.5
}
},
controls: {
settings: [{
type: 'opacity'
}]
}
}
When using this built-in opacity control, the layer opacity adjustments are automatically handled by the SDK. So you do not need to set up an event handler for the layer:change:control
event on your InteractiveMapApp
instance.
Adding and Removing Buttons
Buttons can be added and removed at runtime after the layers panel has been rendered. This is useful for extending the map application to provide custom functionality, such as the ability to toggle between base map styles.
The layers panel provides the following methods for managing its buttons:
Method | Description |
---|---|
add(:config, :events) | Adds a new button to the end of the set using the provided button configuration. If :events is true , then the default button events will be added to the button, which will trigger select and deselect events when the button is toggled (default is true ). |
insertAt(:index, :config, :events) | Similar to add() , but instead will insert a new button at a specific index in the array of buttons using the provided button configuration. |
removeAt(:index) | Removes the button at the specified index. |
removeForId(:id) | Removes the button that matches the specified identifier. |
See the custom layer buttons example for a sample use-case where these methods can be used.