The LayerPanel
is a convenient way to view things that are on the map. The original intent is to view layers but with this LayerPanel
you can view whatever you want. Build pages into the LayerPanel
that will show up in their own tabs to make whatever customization you want. Another common page that works well with the LayerPanel
is a Legends page which you can make with a LayerPanelPage
component.
Its as simple as that. This will give you a LayerPanel
placed on the right side of the screen that allows you to view the Layers from the map and toggle visibility/remove.
import { LayerPanel } from '@bayer/ol-kit'
return <LayerPanel />
If you want an easy way to add a second page use the LayerPanelPage
component and give it an icon. We use @material-ui/icons
most of the time, they work well. This gives you a second page that has it's own tab to toggle through.
import { LayerPanel, LayerPanelPage, LayerPanelPage, LayerPanelContent } from '@bayer/ol-kit'
import VpnKeyIcon from '@material-ui/icons/VpnKeyIcon'
return (
<LayerPanel>
<LayerPanelPage tabIcon={<VpnKeyIcon />}>
<LayerPanelContent>
Legends Page
</LayerPanelContent>
</LayerPanelPage>
</LayerPanel>
)
Use a LayerPanelHeader
to get a nice header at the top. There are several props for the Header component. (title, avatar, and actions)
import {
LayerPanel,
LayerPanelPage,
LayerPanelHeader,
LayerPanelContent } from '@bayer/ol-kit'
import VpnKeyIcon from '@material-ui/icons/VpnKeyIcon'
return (
<LayerPanel>
<LayerPanelPage tabIcon={<VpnKeyIcon />}>
<LayerPanelHeader title='Legends Page' />
<LayerPanelContent>
Place your legend images here...
</LayerPanelContent>
</LayerPanelPage>
</LayerPanel>
)
The LayerPanelHeader
can be powerful. If you want actions in your header pass a LayerPanelActions
component with the actions you want in it. We have built in actions in ol-kit
. Check out the docs for all of them. In the example we're using LayerPanelActionRemove
which is from ol-kit
and the Update Legends @material-ui/core/MenuItem
is custom.
import {
LayerPanel,
LayerPanelPage,
LayerPanelHeader,
LayerPanelContent,
LayerPanelActions,
LayerPanelActionRemove } from '@bayer/ol-kit'
import VpnKeyIcon from '@material-ui/icons/VpnKeyIcon'
import MoreHorizIcon from '@material-ui/icons/MoreHorizIcon'
import MenuItem from '@material-ui/core/MenuItem'
return (
<LayerPanel>
<LayerPanelPage tabIcon={<VpnKeyIcon />}>
<LayerPanelHeader
title='Legends Page'
avatar={<VpnKeyIcon />}
actions={
<LayerPanelActions icon={<MoreHorizIcon />}>
<LayerPanelActionRemove />
<MenuItem onClick={this.updateLegends}>Update Legends</MenuItem>
</LayerPanelActions>
} />
<LayerPanelContent>
Place your legend images here...
</LayerPanelContent>
</LayerPanelPage>
</LayerPanel>
)
You can make a list by passing items down. Which should be an array. There's also a built in drag for the LayerPanelListItem
. You can disable it buy passing the prop disableDrag
to the LayerPanelList
. If you want to persist the reorder of items then you'll need to pass the onReorderedItems callback to the LayerPanelList
and update the items in your parent component.
import {
LayerPanel,
LayerPanelPage,
LayerPanelHeader,
LayerPanelContent,
LayerPanelActions,
LayerPanelActionRemove,
LayerPanelList } from '@bayer/ol-kit'
import VpnKeyIcon from '@material-ui/icons/VpnKeyIcon'
import MoreHorizIcon from '@material-ui/icons/MoreHorizIcon'
import MenuItem from '@material-ui/core/MenuItem'
return (
<LayerPanel>
<LayerPanelPage tabIcon={<VpnKeyIcon />}>
<LayerPanelHeader
title='Legends Page'
avatar={<VpnKeyIcon />}
actions={
<LayerPanelActions icon={<MoreHorizIcon />}>
<LayerPanelActionRemove />
<MenuItem onClick={this.updateLegends}>Update Legends</MenuItem>
<MenuItem onClick={this.setLegendsToOriginalOrder}>Original Order Legends</MenuItem>
</LayerPanelActions>
} />
<LayerPanelContent>
<LayerPanelList items={legends} onReorderedItems={this.handleReorderedItems} />
</LayerPanelContent>
</LayerPanelPage>
</LayerPanel>
)
Below you can see how we add custom actions to our LayerPanel
and also that you can render an array of LayerPanelListItem
's in your LayerPanelList
. Also the list is draggable and has a callback to allow you to reorder the items however you want. Theres an onSort
prop that receives a Javascript Sort function to customize the way the items get sorted.
import {
LayerPanel,
LayerPanelPage,
LayerPanelHeader,
LayerPanelContent,
LayerPanelActions,
LayerPanelActionRemove,
LayerPanelList } from '@bayer/ol-kit'
import VpnKeyIcon from '@material-ui/icons/VpnKeyIcon'
import MoreHorizIcon from '@material-ui/icons/MoreHorizIcon'
import MenuItem from '@material-ui/core/MenuItem'
class MyCustomLayerPanelContainer extends React.Component {
constructor (props) {
super(props)
this.state = { legends: ['First Legend', 'Second Legend', 'Third Legend'] }
this.updateLegends = this.updateLegends.bind(this)
this.handleReorderedItems = this.handleReorderedItems.bind(this)
}
updateLegends () {
console.log('updated my legends')
}
handleReorderedItems (newItems) {
this.setState({ legends: newItems })
}
render () {
const { maps } = this.props
const { legends } = this.state
return (
<LayerPanel>
<LayerPanelPage tabIcon={<VpnKeyIcon />}>
<LayerPanelHeader
title='Legends Page'
avatar={<VpnKeyIcon />}
actions={
<LayerPanelActions icon={<MoreHorizIcon />}>
<LayerPanelActionRemove />
<MenuItem onClick={this.updateLegends}>Update Legends</MenuItem>
</LayerPanelActions>
} />
<LayerPanelContent>
<LayerPanelList items={legends} onReorderedItems={this.handleReorderedItems}>
{legends.map(legend => {
return <LayerPanelListItem>{legend}</LayerPanelListItem>
})}
</LayerPanelList>
</LayerPanelContent>
</LayerPanelPage>
</LayerPanel>
)
}
}
We also have a prebuilt page that ships with the LayerPanel
called LayerPanelLayersPage
. It's a simple drop in that allows you to customize things like handleFeatureDoubleClick of a list item and quite a few other props. Check out the docs on the LayerPanelLayersPage
to see more of the props you can pass. You can either customize it by importing it yourself (which requires you to switch to the LayerPanelBase
as the parent component) or you can pass the props of the LayerPanelLayersPage
down through the prebuilt LayerPanel
.
import { LayerPanel, LayerPanelPage, LayerPanelHeader, LayerPanelContent } from '@bayer/ol-kit'
import VpnKeyIcon from '@material-ui/icons/VpnKeyIcon'
// Passing the props through the LayerPanel component
<LayerPanel handleFeatureDoubleClick={this.onFeatureDoubleClick}>
<LayerPanelPage tabIcon={<VpnKeyIcon />}>
<LayerPanelHeader
title='Legends Page'
avatar={<VpnKeyIcon />} />
<LayerPanelContent>
Hello world
</LayerPanelContent>
</LayerPanelPage>
</LayerPanel>
// Directly pulling in the LayerPanelLayersPage and passing props through it
<LayerPanelBase>
<LayerPanelLayersPage handleFeatureDoubleClick={this.onFeatureDoubleClick}>
<LayerPanelPage tabIcon={<VpnKeyIcon />}>
<LayerPanelHeader
title='Legends Page'
avatar={<VpnKeyIcon />} />
<LayerPanelContent>
Hello world
</LayerPanelContent>
</LayerPanelPage>
</LayerPanelBase>
To show you the amount of customization possible with these pages, here's the LayerPanelLayersPage
.
import {
LayerPanel,
LayerPanelPage,
LayerPanelHeader,
LayerPanelContent,
LayerPanelActions,
LayerPanelCheckbox,
LayerPanelActionRemove,
LayerPanelActionImport,
LayerPanelActionExport,
LayerPanelList,
LayerPanelListItem } from '@bayer/ol-kit'
import VpnKeyIcon from '@material-ui/icons/VpnKeyIcon'
import MoreHorizIcon from '@material-ui/icons/MoreHorizIcon'
return (
<LayerPanelPage>
<LayerPanelHeader
title={'Active Layers'}
translations={translations}
avatar={<LayerPanelCheckbox checkboxState={masterCheckboxVisibility} handleClick={this.setVisibilityForAllLayers} />}
actions={customActions ||
<LayerPanelActions
icon={<MoreHorizIcon />}
translations={translations}
layers={layers}
map={map}>
<LayerPanelActionRemove
removeFeaturesForLayer={this.removeFeaturesForLayer}
shouldAllowLayerRemoval={shouldAllowLayerRemoval} />
{onFileImport && <LayerPanelActionImport handleImport={onFileImport} />}
{onExportFeatures && <LayerPanelActionExport onExportFeatures={onExportFeatures} />}
</LayerPanelActions>} />
{enableFilter &&
<TextField
id='feature-filter-input'
label={'Filter Layers'}
type='text'
style={{ margin: '8px' }}
fullWidth
value={filterText}
onChange={(e) => this.handleFilter(e.target.value)} />
}
<LayerPanelContent>
<LayerPanelList disableDrag={disableDrag} onSort={this.zIndexSort} onReorderedItems={this.reorderLayers} items={layers} >
{layerFilter(layers).filter((layer) => {
const filteredFeatures = this.getFeaturesForLayer(layer)
return !enableFilter || !(layer instanceof olLayerVector) ? true : filteredFeatures?.length
}).sort(this.zIndexSort).map((layer, i) => {
const features = this.getFeaturesForLayer(layer)
return (
<div key={i}>
<LayerPanelListItem handleDoubleClick={() => { handleLayerDoubleClick(layer) }}>
{<LayerPanelCheckbox
checkboxState={!layer ? null : layer.getVisible()}
handleClick={(e) => this.handleVisibility(e, layer)} />}
{<LayerPanelExpandableList show={!!features} open={expandedLayer} handleClick={this.handleExpandedLayer} />}
<ListItemText primary={layer.get('title') || 'Untitled Layer'} />
<ListItemSecondaryAction>
<LayerPanelActions
icon={<MoreVertIcon />}
translations={translations}
layer={layer}
map={map} >
{getMenuItemsForLayer(layer) ||
[<LayerPanelActionRemove key='removeLayer' shouldAllowLayerRemoval={shouldAllowLayerRemoval} />,
<LayerPanelActionExtent key='gotoExtent' />,
<LayerPanelActionOpacity key='layerOpacity' />]}
</LayerPanelActions>
</ListItemSecondaryAction>
</LayerPanelListItem>
{ features
? <Collapse in={expandedLayer} timeout='auto' unmountOnExit>
<List component='div' disablePadding style={{ paddingLeft: '36px' }}>
{features.map((feature, i) => {
return (
<ListItem key={i} hanldeDoubleClick={() => handleFeatureDoubleClick(feature)}>
<LayerPanelCheckbox
handleClick={(event) => this.handleFeatureCheckbox(layer, feature, event)}
checkboxState={feature.get('_feature_visibility')} />
<ListItemText inset={false} primary={feature.get('name') || `Feature ${i}`} />
</ListItem>
)
})}
</List>
</Collapse> : null }
</div>
)
})}
</LayerPanelList>
</LayerPanelContent>
</LayerPanelPage>
)