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
// 😎 (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];
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);
}
});