Layer List legend displays incorrect symbology for layer

516
2
Jump to solution
04-28-2022 11:14 AM
FranklinAlexander
Occasional Contributor III

I have a Web Appbuilder developer application with 2 layers. Each layer is symbolized using a Unique Value Renderer with the following code:

let standAloneSymbol = new PictureMarkerSymbol ({
          "url": "./widgets/LocalLayer/images/StandAloneRamp_open.png",
          "height": 16,
          "width": 16,
          "type": "esriPMS",
          "angle": 0
        })

        let handLaunchSymbol = new PictureMarkerSymbol ({
          "url": "./widgets/LocalLayer/images/HandLaunch_open.png",
          "height": 16,
          "width": 16,
          "type": "esriPMS",
          "angle": 0
        })

        let withMarinaSymbol = new PictureMarkerSymbol ({
          "url": "./widgets/LocalLayer/images/RampWithMarina_open.png",
          "height": 16,
          "width": 16,
          "type": "esriPMS",
          "angle": 0
        })

        let  uvrJson = {
          type: "uniqueValue",
          field1: "RampType",
          //field2: "Status",
          fieldDelimiter: ", ",
          defaultSymbol: standAloneSymbol,
          uniqueValueInfos: [{
            value: "Stand Alone Ramp",
            label: "Stand Alone Ramp",
            symbol: standAloneSymbol
          }, {
            value: "Boat Ramp within Marina",
            label: "Boat Ramp within Marina",
            symbol: withMarinaSymbol
          }, {
            value: "Hand Launch Only,",
            label: "Hand Launch Only",
            symbol: handLaunchSymbol
          }]
        }
        
        const openRampsUrl = "https://mydomain/arcgis/rest/services/mapservicename/MapServer/0";
        const openRampLayer = new FeatureLayer(openRampsUrl, {
          id: "Open Boat Ramps",
          mode: FeatureLayer.MODE_SNAPSHOT,
          outFields: ["*"],
          opacity: 1
        });
        let layerName = this.config.layers.layer[1].name;
        openRampLayer.title = layerName;
        openRampLayer._titleForLegend = layerName;

        let options = ({
          title: "${RampName}",
          content: this._createPopupContent
        });
        let template = new InfoTemplate(options);
        openRampLayer.setInfoTemplate(template);

        //Add layer to map and set mouse events
        let sgRendUnique = new UniqueValueRenderer(uvrJson);
        openRampLayer.setRenderer(sgRendUnique);
        map.addLayer(openRampLayer, 2);

 

I have been trying to figure out where the LayerList widget gets the symbology because it doesn't appear to be from the renderer. This is the way the legend should appear according to the renderer and the map service:

boatrampslegend.png

The above legend is a screenshot from a version of the app prior to being exported to our local server. I am not using a custom renderer for the above legend so I assume the legend is being taken from the map service.

Here is an image of the current LayerList (which is incorrect). I am using a custom renderer for this version of the app, but as you can see from my code, I am clearing only defining 3 values. I don't know where the 'others' is coming from and haven't been able to figure out how to get rid of it. I can't see anything in the layer properties that provides any clues as to where this is coming from. I have also attempted to just remove the dom element, but this is proving to be extremely difficult. Does anyone know what I am missing? Thank you!

boatRampLegendWrong.png

 

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
FranklinAlexander
Occasional Contributor III

Thanks Kristian, 

Yes, that is probably the case. I normally create a new Web AppBuilder app, add all of my widgets and configure them as much as possible using the developer GUI before exporting the app to our server. If I need to do some customization, I will then use the JS API for that. 

I was able to find a work-around by removing the node after the fact, but it's not easy. I will try posting on the Web AppBuilder page to see if there is a different solution, but basically I couldn't find a way to access the function where the legend is created, so I still don't know where the legend is coming from. It doesn't appear to be obtained from the map service layer, or the renderer. Kind of a mystery. This is what worked for me in case anyone else has a similar issue:

In the LayerListView.js file, _foldOrUnfoldLayer function:

 

 

if (layerInfo.isLeaf()) {
            let dijit;
            if(layerInfo.id === "Open Boat Ramps") {
              dijit = '0';
            } else {
              dijit = '1'
            }
            var legendsNode = query(".legends-div", subNode)[0];
            var loadingImg = query(".legends-loading-img", legendsNode)[0];
            if (legendsNode && loadingImg) {
              layerInfo.drawLegends(legendsNode, this.layerListWidget.appConfig.portalUrl);
              let dijitLegend =  query("div[widgetid='esri_dijit_Legend_" + dijit + "']", this.layerListTable)[0];
              let othersNode = dijitLegend.children[0].children[1].children[2];
              if(othersNode) {
                domConstruct.destroy(othersNode);
              }
            }
          }

 

 

 

Result:

boatRampsLegendFixed.png

 

View solution in original post

0 Kudos
2 Replies
KristianEkenes
Esri Regular Contributor

That widget appears to be a custom widget developed for WebApp builder and not in the JS API. The JS API LayerList widget in our 3.x APIs doesn't support symbology. I would post this question in the WebApp builder community pages: https://community.esri.com/t5/arcgis-web-appbuilder-questions/bd-p/arcgis-web-appbuilder-questions since the WebApp builder team developed that widget.

Or if it is a bug, it would be better to reach out to Esri support so they can log the issue in your behalf and submit it to the WebApp builder team.

0 Kudos
FranklinAlexander
Occasional Contributor III

Thanks Kristian, 

Yes, that is probably the case. I normally create a new Web AppBuilder app, add all of my widgets and configure them as much as possible using the developer GUI before exporting the app to our server. If I need to do some customization, I will then use the JS API for that. 

I was able to find a work-around by removing the node after the fact, but it's not easy. I will try posting on the Web AppBuilder page to see if there is a different solution, but basically I couldn't find a way to access the function where the legend is created, so I still don't know where the legend is coming from. It doesn't appear to be obtained from the map service layer, or the renderer. Kind of a mystery. This is what worked for me in case anyone else has a similar issue:

In the LayerListView.js file, _foldOrUnfoldLayer function:

 

 

if (layerInfo.isLeaf()) {
            let dijit;
            if(layerInfo.id === "Open Boat Ramps") {
              dijit = '0';
            } else {
              dijit = '1'
            }
            var legendsNode = query(".legends-div", subNode)[0];
            var loadingImg = query(".legends-loading-img", legendsNode)[0];
            if (legendsNode && loadingImg) {
              layerInfo.drawLegends(legendsNode, this.layerListWidget.appConfig.portalUrl);
              let dijitLegend =  query("div[widgetid='esri_dijit_Legend_" + dijit + "']", this.layerListTable)[0];
              let othersNode = dijitLegend.children[0].children[1].children[2];
              if(othersNode) {
                domConstruct.destroy(othersNode);
              }
            }
          }

 

 

 

Result:

boatRampsLegendFixed.png

 

0 Kudos