Hi all,
I am attempting to make a combined LayerList and Legend panel inside of a React application. Pulling out the LayerList and adding buttons and sliders for visibility and opacity was pretty straight forward, but I've been stuck on how to pull out the symbology in the legend.
I'm including a minimal sample where I print out the items to the console but iterating over them doesn't seem to work even though the docs shows methods for a Collection of ActiveInfoLayers that would let me iterate over them. There also seems to be a difference in how the symbology is structured within these objects too. I.e. FeatureLayer symbology is represented by an <svg> element, whereas a MapImageLayer seems to be represented by a base64 string that (I think) would be converted to an image.
Am I on the correct route for this? Is there a way that I can take a layer/sublayer id and pull out the layer symbology to use elsewhere in my app?
attaching a few screenshots to help show what I mean:
This shows how a MapImageLayer sublayer is available
This shows how a FeatureLayer symbology is available
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Intro to MapImageLayer | Sample | ArcGIS Maps SDK for JavaScript 4.28</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.28/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.28/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require(["esri/Map", "esri/views/MapView", "esri/layers/MapImageLayer", "esri/layers/FeatureLayer", "esri/widgets/Legend", "esri/core/reactiveUtils"], (
Map,
MapView,
MapImageLayer,
FeatureLayer,
Legend,
reactiveUtils
) => {
/*****************************************************************
* Create a MapImageLayer instance pointing to a Map Service
* containing data about pool permits in Southern California
*****************************************************************/
const permitsLayer = new MapImageLayer({
portalItem: {
// autocasts as new PortalItem()
id: "d7892b3c13b44391992ecd42bfa92d01"
}
});
const qFaultsLayer = new MapImageLayer({
url: 'https://webmaps.geology.utah.gov/arcgis/rest/services/Hazards/quaternary_faults_with_labels/MapServer',
sublayers: [
{
id: 0,
visible: true,
},
{
id: 1,
visible: true,
},
],
title: 'Hazardous (Quaternary age) Faults',
visible: true,
});
const quadBoundariesLayer = new FeatureLayer({
url: 'https://services.arcgis.com/ZzrwjTRez6FJiOq4/arcgis/rest/services/Utah_Geologic_Hazards_Supplemental_Data_View/FeatureServer/0',
title: 'USGS 1:24,000-Scale Quadrangle Boundaries',
visible: true,
});
/*****************************************************************
* Add the layer to a map
*****************************************************************/
const map = new Map({
basemap: "dark-gray-vector",
layers: [permitsLayer, quadBoundariesLayer, qFaultsLayer]
});
const view = new MapView({
container: "viewDiv",
map: map
});
// add a legend
const legend = new Legend({
view: view,
});
view.ui.add(legend, "bottom-left");
// extract legend items from the legend viewmodel
const legendViewModel = legend.viewModel;
const activeLayerInfos = legendViewModel.activeLayerInfos;
// activeLayerInfos.items shows data for the layers in the legend
console.log(activeLayerInfos.items);
// shows nothing
activeLayerInfos.forEach(element => {
console.log(element);
})
// shows nothing
activeLayerInfos.items.forEach(item => {
console.log(item);
})
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Hi @Clinton_Lunn ,
Have you seen this sample application that adds a legend into the layer list? As a heads up we are refactoring the LayerList widget in the next release (4.29) to use calcite components. This might break many of your custom modifications. If you really want to go down the custom widget route, you might want to take advantage of the renderPreviewHTML method for the symbology