toc
This bundle provides a widget that displays the contents of the map in its hierarchical order. The visibility of this content can be controlled and certain actions can be performed for each element. Optionally, a legend for each layer can be displayed in the TOC and basemaps can be controlled.
Usage
To make the toc available to the user, add the tool ID tocToggleTool
to a tool set.
This bundle contains a set of actions that can be run from an action menu of a layer, such as zooming to the extent of a layer or controlling its transparency. For a description of these actions and the conditions under which they are visible in the TOC, see provided actions. To add custom actions, see Use Cases.
For more details, see the API documentation.
Constraints
Legends for layers of type WMTSLayer
(and their sublayers) and layer types not supported by the Legend widget cannot be displayed.
Configuration reference
The following code sample shows the configurable properties and their default values:
"Config": {
"actions": ["*"],
"showBasemaps": false,
"showLayerLegend": false,
"maxBasemapsThreshold": 3,
"maxVisibleTitleLines": 3,
"autoActivateParentLayer": true,
"autoExpandLegend": false
}
Property | Type | Description |
---|---|---|
actions |
Array | Defines which actions are available in the action menu. The order of actions in this array represents the order in the menu. The value [*] defines that all available actions are used, grouped by their layout type (button , slider , text-value ). For details about the provided actions, see provided actions. |
showBasemaps |
Boolean | To show and control basemap, set this property to true . |
showLayerLegend |
Boolean | To show a legend for each layer or sublayer, set this property to true . If the corresponding layer is not visible, the legend is hidden. |
maxBasemapsThreshold |
Number | Maximum number of basemaps displayed in a flat list. If the number of basemaps is greater than the specified number, a dropdown is displayed. |
maxVisibleTitleLines |
Number | Number of text lines displayed for layer and service titles. If the titles are longer than this value, the texts are truncated. |
autoActivateParentLayer |
Boolean | By default, parent layers are activated automatically, when a child layer is activated. To keep the parent layer state unchanged, when a child layer is activated, set this property to false . |
autoExpandLegend |
Boolean | To automatically expand the layer legend when the layer is visible on the map and a legend is available, set this property to true . |
Provided actions
The following code sample shows the actions provided by this bundle:
"Config": {
"actions": [
"show-description",
"zoom-to-extent",
"activate-children",
"deactivate-children",
"change-opacity",
"show-copyright"
]
}
The visibility of an action is based on the available properties of the element referenced by the toc item, such as a layer or a group layer.
Name | Visibility condition | Description |
---|---|---|
zoom-to-extent |
The element has extent information with a valid value. | The map is zoomed to this extent. |
activate-children |
The element has at least one child. | The visibility of the element and all children are set to true . |
deactivate-children |
The element has at least one child. | The visibility of the element and all children are set to false . |
change-opacity |
The opacity value of the element can be changed. | A slider is shown to change the layer's opacity. |
show-description |
The element has a description property. |
The content of the description property is displayed in the menu. To show the content of the serviceDescription property, create a custom action. |
show-copyright |
The element has a copyright property. |
The content of the copyright property is displayed in the menu. |
Use cases
How to hide layers from the TOC
To hide a single layer from the toc, set the layer property listMode
to hide
.
To hide the children of a layer but not the layer itself, set listMode
to hide-children
.
How to hide legends of certain layers
To hide the legend of a layer and all its children, set the layer property legendEnabled
to false
.
How to expand layers in toc widget
To expand a layer and show all its children in toc, set the layer property initiallyExpandedInToc to true
.
How to customize basemap thumbnails
A thumbnail of the basemap is displayed before the name of each basemap.
To customize this thumbnail, change the thumbnailUrl
property of each basemap, as described in the map-init bundle documentation.
How to add a custom action
To add a custom action, provide a custom ActionDefinitionFactory
.
An ActionDefinition
transports properties which depend on the chosen UI type and methods implementing the behavior.
The following UI types are provided:
UI type | Description |
---|---|
button |
Action is shown as a button. |
button-row |
Action is shown as multiple buttons in a row. |
slider |
Action is shown as a slider. |
text-label |
Action is shown as as a label. |
Common structure of an ActionDefinitionFactory (custom action)
To create new action definitions, add components to the manifest.json
file of your bundle, that implement the toc.ActionDefinitionFactory
interface:
class MyCustomActionDefinitionFactory {
constructor(){
// which ids are recognized by this factory
// important to support the ["*"] expression
this.supportedIds = ["my-custom-id"];
}
// create a definition object
createDefinitionById(id) {
if(id !=="my-custom-id"){
return;
}
return {
// important to identify the ID of the created action
id: "my-custom-id",
// choose a ui type
type: "button" | "slider" | "text-label",
// other properties and methods depend on the selected ui type
...
};
}
}
An ActionDefinitionFactory has to be registered as toc.ActionDefinitionFactory
:
{
"components": [
{
"name": "MyCustomActionDefinitionFactory",
"provides": "toc.ActionDefinitionFactory"
}
]
}
Properties of a custom button
action
The following shows a sample of a custom button action and all available options:
export default class MyCustomButtonActionDefinitionFactory {
constructor() {
this.supportedIds = ["my-button-action"];
}
createDefinitionById(id) {
return {
id,
type: "button",
// Label of the button menu entry
label: "Do it",
// Icon of the button entry
icon: "search",
// Method to decide if this action is available for a given tocItem
isVisibleForItem(tocItem) {
return true;
},
// method to decide if the action should be shown as disabled (optional)
isDisabledForItem(tocItem) {
return false;
},
// method triggered if the menu item is clicked
trigger(tocItem) {
// do some thing
}
};
}
}
Properties of a custom button-row
action
The following shows a sample of a custom button-row action and all available options:
export default class MyCustomButtonRowActionDefinitionFactory {
constructor() {
this.supportedIds = ["my-button-row-action"];
}
createDefinitionById(id) {
return {
id,
type: "button-row",
// Label of the button menu entry
label: "Do it",
// Icons for the buttons
icons: ["action-1", "action-2"],
// Label that is used as Aria-Label
actionLabels: ["My Action Label 1", "My Action Label 2"],
// optional tooltip. When not defined, the 'label' will be displayed as tooltip
actionTooltips: ["tooltiptext-1", "tooltiptext-2"],
// Method to decide if this action
// is available for a given tocItem
isVisibleForItem(tocItem) {
return true;
},
// Method to decide if one of the buttons should be shown as
// disabled (optional)
// It is important that an array is returned
// in matching order to the icons property.
isDisabledForItem(tocItem) {
return [true, false];
},
// Method triggered if the a button is clicked
// The actionIndex identifies the target action
trigger(tocItem, actionIndex) {
// do something
}
};
}
}
Properties of a custom slider
action
The following shows a sample of a custom slider action and all available options:
export default class MyCustomSliderActionDefinitionFactory {
constructor() {
this.supportedIds = ["my-custom-slider"];
}
createDefinitionById(id) {
return {
id,
type: "slider",
// Label/title of the slider menu entry
label: "Opacity",
// Icon of the menu entry
icon: "",
// Label of the left side of the slider
fromLabel: "",
// Icon of the left side of the slider
fromIcon: "",
// Label of the right side of the slider
toLabel: "",
// Icon of the right side of the slider
toIcon: "",
// Minimum slider value (left side)
min: 0,
// Maximum slider value (right side)
max: 1,
// Increment value of the slider
step: 0.01,
// Method to decide if this action
// is available for a given tocItem
isVisibleForItem(tocItem) {
return typeof tocItem.ref.opacity === "number";
},
// Method should return current value of the item
valueOf(tocItem) {
return tocItem.ref.opacity;
},
// Method is called by the slider if the value is changed
changeValueOf(tocItem, val) {
tocItem.ref.opacity = val;
}
};
}
}
Properties of a custom text-label
action
The following shows a sample of a custom text-label action and all available options:
export default class MyCustomTextActionDefinitionFactory {
constructor(props) {
this.supportedIds = ["my-custom-text"];
}
createDefinitionById(id) {
return {
id,
type: "text-label",
// Label/title of the slider menu entry
label: "Copyright",
// Icon of the menu entry
icon: "copyright",
// Label for the "show more" link
labelMore: "..more",
// Threshold that defines when to auto shorten the text and
// provide a "show more" link instead.
// If set to -1 text is never truncated.
truncationThreshold: 200,
// Method to decide if this action
// is available for a given tocItem
isVisibleForItem(tocItem) {
return !!tocItem.ref.copyright;
},
// Method should return text value of the item
valueOf(tocItem) {
return tocItem.ref.copyright;
},
// Method which is called when the "show more" link is clicked
// Only required if truncationThreshold is used
trigger(tocItem) {
// Do something (for example opening a window to show the whole text)
}
};
}
}
Support for asynchronous behavior in actions
All action types have the method isVisibleForItem
in common. This method is allowed to be asynchronous (return a Promise value).
The following sample of a custom asynchronous action (here of type text-label
) shows the change:
export default class MyCustomAsyncActionDefinitionFactory {
constructor(props) {
this.supportedIds = ["my-custom-async"];
}
createDefinitionById(id) {
return {
id,
type: "text-label",
// Label/title of the slider menu entry
label: "Async Action",
// Method makes a request to decides asynchronously
// if data is available for a given tocItem
async isVisibleForItem(tocItem) {
const data = await makeRequestForData(tocItem.ref);
return !!data;
},
// Method should return text value of the item
valueOf(tocItem) {
// this must not return a promise!
return requestedData.lookupInfoFor(tocItem.ref);
}
};
}
}
Lifecycle of a custom action
An action is reused for multiple toc items, therefore it should not store any state or reference to a toc item. There are no lifecycle hooks available.
How to implement behavior in a custom action
The meta information about the current focused toc item is provided to the methods of a custom action. This information can be used to identify a layer in the map for example. See TocItem for more details.
How to enhance the reason messages why a layer is not yet visible
By default the toc checks the loaded
state of a layer and the min/max scale requirements.
If these requirements are not fulfilled, an icon is displayed that indicates why a service is not visible.
These messages can be extended by implementing a custom toc.StateChecker
.
class MyStateChecker {
// This is called if the viewpoint of the map changes
// or a layer is added/loaded
checkState({ tocItem, mapWidgetModel }) {
const visible = .... // check visibility
if (visible){
// nothing to do
return;
}
// produce information about the reasons
// decide what level of information you provide:
return {
// use infos for "info" level
infos: ["my custom info"],
// use warnings for "warning" level
warnings: ["my custom warning"],
// use errors for "errors" level
errors: ["my custom error"],
};
// NOTE: you can return a promise
return new Promise((resolve)=>{
resolve({
infos: ["my custom info"]
});
});
}
}
The meta information about the current toc item is provided by the TocItem parameter. Information about the current map state can be resolved from the given mapWidgetModel.
A custom StateChecker has to be registered as toc.StateChecker
:
{
"components": [
{
"name": "MyStateChecker",
"provides": "toc.StateChecker"
}
]
}