When using group layers, the legend widget uses the group layer name as the name of all the group's children layers.
Solved! Go to Solution.
James,
It is actually very simple to fix that too. Just omit the "title" property from the layerInfos.
var legend = new Legend({
view: view,
layerInfos: [{
layer: demographicGroupLayer
}]
});
Don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question.
Has no one else experienced this? I am using feature layers (not a web map).
James,
You say
When using group layers
Then you say
I am using feature layers
How are you using Group Layers and feature layers?...
FeatureLayer only supports on layer of a map service.
The FeatureLayer is a sub layer for the GroupLayer. I have a few group layers and each group layer has a few feature layer sub layers. The layers property on GroupLayer is where these feature layers go. This works perfect with the LayerList widget (all namings are correct, including the sub layers). With the Legend widget, the group layer name is correct, but all sub layers, instead of using the feature layer "title", use the group layer "title".
James when I add the legend portion of the Legend widget sample to the widgets layerlist actions sample I do not see that issue at all:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>LayerList widget with actions - 4.5</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.5/esri/css/main.css">
<script src="https://js.arcgis.com/4.5/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/GroupLayer",
"esri/layers/MapImageLayer",
"esri/widgets/LayerList",
"esri/widgets/Legend",
"dojo/domReady!"
], function(
Map, MapView, GroupLayer, MapImageLayer, LayerList, Legend
) {
// Create layer showing household income.
var householdIncomeLayer = new MapImageLayer({
url: "https://server.arcgisonline.com/arcgis/rest/services/Demographics/USA_Median_Household_Income/MapSer...",
title: "US Median Household Income"
});
// Create layer showing median net worth.
// Set visibility to false so it's not visible on startup.
var medianNetWorthLayer = new MapImageLayer({
url: "https://server.arcgisonline.com/arcgis/rest/services/Demographics/USA_Median_Net_Worth/MapServer",
title: "US Median Net Worth",
visible: false
});
// Create GroupLayer with the two MapImageLayers created above
// as children layers.
var demographicGroupLayer = new GroupLayer({
title: "US Demographics",
visible: true,
visibilityMode: "exclusive",
layers: [householdIncomeLayer, medianNetWorthLayer],
opacity: 0.75
});
// Create a map and add the group layer to it
var map = new Map({
basemap: "dark-gray",
layers: [demographicGroupLayer]
});
// Add the map to a MapView
var view = new MapView({
center: [-98.5795, 39.8282],
zoom: 5,
container: "viewDiv",
map: map
});
// Creates actions in the LayerList.
function defineActions(event) {
// The event object contains an item property.
// is is a ListItem referencing the associated layer
// and other properties. You can control the visibility of the
// item, its title, and actions using this object.
var item = event.item;
if (item.title === "US Demographics") {
// An array of objects defining actions to place in the LayerList.
// By making this array two-dimensional, you can separate similar
// actions into separate groups with a breaking line.
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"
}]
];
}
}
view.then(function() {
// Create the LayerList widget with the associated actions
// and add it to the top-right corner of the view.
var layerList = new LayerList({
view: view,
// executes for each ListItem in the LayerList
listItemCreatedFunction: defineActions
});
// Event listener that fires each time an action is triggered
layerList.on("trigger-action", function(event) {
// The layer visible in the view at the time of the trigger.
var visibleLayer = householdIncomeLayer.visible ?
householdIncomeLayer : medianNetWorthLayer;
// Capture the action id.
var 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);
} 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 (demographicGroupLayer.opacity < 1) {
demographicGroupLayer.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 (demographicGroupLayer.opacity > 0) {
demographicGroupLayer.opacity -= 0.25;
}
}
});
// Add widget to the top right corner of the view
view.ui.add(layerList, "top-right");
var legend = new Legend({
view: view
});
// Add widget to the bottom right corner of the view
view.ui.add(legend, "bottom-right");
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Did you try it with feature layers? I'm not setting the layers [] property directly in the GroupLayer. I am using grpLyr.add(featLyr).
James,
Yep, it must be something in your code. Here is a sample using FeatureLayers and grouplayer.add:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>LayerList widget with actions - 4.5</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.5/esri/css/main.css">
<script src="https://js.arcgis.com/4.5/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/GroupLayer",
"esri/layers/FeatureLayer",
"esri/widgets/LayerList",
"esri/widgets/Legend",
"dojo/domReady!"
], function(
Map, MapView, GroupLayer, FeatureLayer, LayerList, Legend
) {
// Create layer showing household income.
var householdIncomeLayer = new FeatureLayer({
url: "https://server.arcgisonline.com/arcgis/rest/services/Demographics/USA_Median_Household_Income/MapSer...",
title: "US Median Household Income Counties"
});
// Create layer showing median net worth.
// Set visibility to false so it's not visible on startup.
var medianNetWorthLayer = new FeatureLayer({
url: "https://server.arcgisonline.com/arcgis/rest/services/Demographics/USA_Median_Net_Worth/MapServer/3",
title: "US Median Net Worth Counties",
visible: false
});
// Create GroupLayer with the two MapImageLayers created above
// as children layers.
var demographicGroupLayer = new GroupLayer({
title: "US Demographics",
visible: true,
visibilityMode: "exclusive",
//layers: [householdIncomeLayer, medianNetWorthLayer],
opacity: 0.75
});
demographicGroupLayer.add(medianNetWorthLayer);
demographicGroupLayer.add(householdIncomeLayer);
// Create a map and add the group layer to it
var map = new Map({
basemap: "dark-gray",
layers: [demographicGroupLayer]
});
// Add the map to a MapView
var view = new MapView({
center: [-98.5795, 39.8282],
zoom: 5,
container: "viewDiv",
map: map
});
view.then(function() {
// Create the LayerList widget with the associated actions
// and add it to the top-right corner of the view.
var layerList = new LayerList({
view: view
});
// Add widget to the top right corner of the view
view.ui.add(layerList, "top-right");
var legend = new Legend({
view: view
});
// Add widget to the bottom right corner of the view
view.ui.add(legend, "bottom-right");
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
After looking at your sample, I found the issue. I am setting the layerInfos property for the Legend widget. Once removed, the legend works fine with the group layers. Since I want to show all map layers in the legend, this is not an issue for me (removing the layerInfos property). However, if I only wanted to show a subset of layers by specifying layerInfos, then the legend widget has issues with GroupLayers.
James,
It is actually very simple to fix that too. Just omit the "title" property from the layerInfos.
var legend = new Legend({
view: view,
layerInfos: [{
layer: demographicGroupLayer
}]
});
Don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question.
I'll mark as answered, but it is painful dealing with some of these things. How would one know to remove the title property?