AnsweredAssumed Answered

legend event "finished"

Question asked by abjones on May 22, 2018
Latest reply on May 23, 2018 by rscheitlin

ArcGIS API 4.6;  I want to create user interface elements within a legend.  There seems to be no ESRI methods for this, so I am trying to capture the document elements created by the legend widget.  I want a static legend.

 

First I create a number of FeatureLayer with empty source features array.   I add these to a map and create the legend.  Next, I want to copy the innerHTML of the document element containing legend and finally destroy the legend and remove all FeatureLayer.  From the copy I can construct my version of legend.

 

My problem is event timing.  Is there a deterministic method to signal complete construction of new esriLegend in the DOM?  I have tried watchUtil.when(legend,"container") property, but I cant find a method to use with dojo/aspect.after.

 

What works is to invoke esriLegend then use setTimeout(), set for a few hundred miliseconds, at which point I can copy the completed DOM element and destroy the legend.

 

Please suggest a better way!

Thanks, Blair

 

//  makeLegend.js    May 22, 2018    abj3
if (!window.VaFWIS) { window.VaFWIS = {}; }
if (!VaFWIS.lib) { VaFWIS.lib = {}; }

 

require([
    "esri/layers/FeatureLayer",
    "esri/widgets/Legend"
], function (FeatureLayer, esriLegend) {

 

        VaFWIS.lib.makeLegend = function () {

 

// esri/widgets/legend creates a dynamic symbol legend connected to map featureLayers
// VaFWIS.lib.makeLegend - make an esriLegend and copy DOM element as a static legend
//  1) map.add featureLayers created from VaFWIS.layerDef having layerInfo
//  2) define legend info
//  3) invoke esri/widgets/legend which dynamically inserts HTML into "theLegend"
//  4) save  "theLegendContainer" innerHTML
//  5) destroy legend
//  6) map.remove featureLayers
//  7) restore saved "theLegendContainer" innerHTML
//  8) (future) add legend item specific ui controls
//      a) re-order layers by dragging
//      b) change opacity

 

            var legendLayerInfos = [];
            var keys = Object.keys(VaFWIS.layerDef);
            for (var k = 0; k < keys.length; k++) {
                var layerDef = VaFWIS.layerDef[keys[k]];
                if (layerDef.layerInfo) {
                    if (VaFWIS.debug == true) {
                        console.log("makeLegend for " + layerDef.id);
                    }
                    var featureLayer = FeatureLayer(
                        {
                            "fields": layerDef.layerInfo.fields
                            , "geometryType": layerDef.layerInfo.geometryType
                            , "id": "theLegend_" + layerDef.id
                            , "objectIdField": layerDef.layerInfo.objectIdField
                            , "popupTemplate": layerDef.layerInfo.popupTemplate
                            , "renderer": layerDef.layerInfo.renderer
                            , "spatialReference": layerDef.layerInfo.spatialReference
                            , "source": []
                            , "visible": true
                        }
                    );
                    VaFWIS.map.add(featureLayer);
                    legendLayerInfos.push(
                        {
                            "layer": featureLayer
                            , title: layerDef.title
                        });
                }
            }
            // construct legend; after scheduleRenderer then save HTML and destroy legend
            legend = new esriLegend(
                {
                    view: VaFWIS.mapView,
                    container: "theLegend",
                    layerInfos: legendLayerInfos
                }
            );
            setTimeout(function (legend) {
                var containerContent = $("#theLegendContainer").html();
                legend.destroy();
                VaFWIS.map.removeMany(VaFWIS.map.layers.filter(
                    function (lyr) {
                        return lyr.id.indexOf("theLegend_") == 0;
                    }
                ));
                $("#theLegendContainer").html(containerContent);
                $("#theLegendContainer").css("visibility", "visible");
            }.bind(null, legend), 250);
        }
    });

Outcomes