Hi,
Was hoping someone can show me how to add the opacity slider to a layer list with legend.
I am essentially trying to combine these two examples. preferably adding action items to the layer list with legend example.
https://developers.arcgis.com/javascript/latest/sample-code/sandbox/?sample=widgets-layerlist-legend
In the Add a Legend to LayerList sample, you can add an opacity slider by changing the contents of the script tag beginning on line 32 to the following:
require(["esri/WebMap", "esri/views/MapView", "esri/widgets/LayerList", "esri/widgets/Slider"], (
WebMap,
MapView,
LayerList,
Slider
) => {
const map = new WebMap({
portalItem: {
id: "d5dda743788a4b0688fe48f43ae7beb9"
}
});
// Add the map to a MapView
const view = new MapView({
container: "viewDiv",
map: map
});
async function defineActions(event) {
const item = event.item;
await item.layer.when();
if (item.title === "Census Tracts") {
const slider = new Slider({
min: 0,
max: 1,
precision: 2,
values: [1],
visibleElements: {
labels: true,
rangeLabels: true
}
});
item.panel = {
content: ["legend",slider],
open: true,
className: "esri-icon-sliders-horizontal",
title: "Layer Info"
};
slider.on("thumb-drag", (event) => {
const { value } = event;
item.layer.opacity = value;
});
}
}
// Add a legend instance to the panel of a
// ListItem in a LayerList instance
const layerList = new LayerList({
view: view,
listItemCreatedFunction: defineActions
});
view.ui.add(layerList, "top-right");
});
Thank you for taking a look!
Your code appears to add the opacity slider but removes the legend items. Below is the code snippet I am using to add the legend to layer list. I'm not sure how to add the slider event to the existing event.
// create a layerlist and expand widget and add to the view
const layerList = new LayerList({
view: view,
listItemCreatedFunction: (event) => {
const item = event.item;
if (item.layer.type != "group") {
// don't show legend twice
item.panel = {
content: "legend",
open: false
};
}
}
});
const llExpand = new Expand({
view: view,
content: layerList,
expanded: false
});
view.ui.add(llExpand, {
position: "top-left",
index: 0
});
If by "legend items" you mean "action items", then perhaps this is what you're looking for:
require(["esri/WebMap", "esri/views/MapView", "esri/widgets/LayerList", "esri/widgets/Slider"], (
WebMap,
MapView,
LayerList,
Slider
) => {
const map = new WebMap({
portalItem: {
id: "d5dda743788a4b0688fe48f43ae7beb9"
}
});
// Add the map to a MapView
const view = new MapView({
container: "viewDiv",
map: map
});
async function defineActions(event) {
const item = event.item;
await item.layer.when();
if (item.title === "Census Tracts") {
const slider = new Slider({
min: 0,
max: 1,
precision: 2,
values: [1],
visibleElements: {
labels: true,
rangeLabels: true
}
});
item.panel = {
content: ["legend",slider],
open: true,
className: "esri-icon-sliders-horizontal",
title: "Layer Info"
};
slider.on("thumb-drag", (event) => {
const { value } = event;
item.layer.opacity = value;
});
item.actionsSections = [
[
{
title: "Go to full extent",
className: "esri-icon-zoom-out-fixed",
id: "full-extent"
},
{
title: "Layer information",
className: "esri-icon-description",
id: "information"
}
],
[
{
title: "Increase opacity",
className: "esri-icon-up",
id: "increase-opacity"
},
{
title: "Decrease opacity",
className: "esri-icon-down",
id: "decrease-opacity"
}
]
];
}
}
// Add a legend instance to the panel of a
// ListItem in a LayerList instance
const layerList = new LayerList({
view: view,
listItemCreatedFunction: defineActions
});
layerList.on("trigger-action", (event) => {
// The layer visible in the view at the time of the trigger.
const visibleLayer = event.item.layer;
// Capture the action id.
const id = event.action.id;
if (id === "full-extent") {
// if the full-extent action is triggered then navigate
// to the full extent of the visible layer
view.goTo(visibleLayer.fullExtent).catch((error) => {
if (error.name != "AbortError") {
console.error(error);
}
});
} else if (id === "information") {
// if the information action is triggered, then
// open the item details page of the service layer
window.open(visibleLayer.url);
} else if (id === "increase-opacity") {
// if the increase-opacity action is triggered, then
// increase the opacity of the GroupLayer by 0.25
if (visibleLayer.opacity < 1) {
visibleLayer.opacity += 0.25;
}
} else if (id === "decrease-opacity") {
// if the decrease-opacity action is triggered, then
// decrease the opacity of the GroupLayer by 0.25
if (visibleLayer.opacity > 0) {
visibleLayer.opacity -= 0.25;
}
}
});
view.ui.add(layerList, "top-right");
});
Thanks for taking another look. If I use the code above it removes the legend within the layer list.
The solutions provided are specific to the samples, because that's how your original request was framed. If you copy and paste the code into the samples, you'll see the solutions do work, and do add an opacity slider into the layer list along with the legend.
I can't tell why it doesn't work in your application, because I can't access it or its source code. Perhaps since the code I've provided is specific to the samples, maybe you included the condition that restricts the modifications to a layer with the title "Census Tracts" (line 24 in both snippets).
Joel,
I got it to work. I feel goofy it didn't come to me earlier. Thank you for your time on this. Below is the solution, I just need to add this snippet
// create a layerlist and expand widget and add to the view
async function defineActions(event) {
const item = event.item;
await item.layer.when();
if (item.layer.type != "group") {
// don't show legend twice
item.panel = {
content: "legend",
open: false
};
}
if (item.title === "Imagery") {
const slider = new Slider({
min: 0,
max: 1,
precision: 2,
values: [1],
visibleElements: {
labels: true,
rangeLabels: true
}
});