Select to view content in your preferred language

GenerateRendererTask results and the Legend digit

1875
10
09-21-2012 01:12 PM
JoanneMcGraw
Frequent Contributor
Hello all,

Within my application, the legend digit does not appear to accommodate a renderer definition applied to a layer dynamically during a refresh. I'm hoping someone can provide some pointers as to what I might be missing because I've been trying to get this all working for days and am stuck with what to try next.

I have an ArcGISDynamicMapServiceLayer that has no visible layers at startup but contains 7 different ones in total. The end user is able to indicate which layer in the service they wish to work with, pick an attribute from that layer, specify how they would like the layer displayed (e.g., with a ClassBreaksDefinition), the number of classes and the colours to ramp between in displaying the data. All this is very similar to the "Change the Attribute Field Used to Render Data" sample found at: http://help.arcgis.com/en/webapi/javascript/arcgis/demos/renderer/renderer_dynamic_layer_change_attr...

The sample has one layer within the mapping service and when it calls the show() on the layer, the legend gets updated.

In my application, I set the layer drawing options for the layer in question, set that layer visible and the legend gets updated...incorrectly. In my case, it adds the layer to the legend but uses the default unclassified renderer definition in the mapping service itself. That is, all the polygons in the layers are just solid blue areas in the mapping service (because they are all turned off anyway) so, although the map appears with the requested classification scheme, the legend appears with a solid blue square. I have included a picture to show the result. The map's classification is all in yellows and greens, but the Legend is showing them as solid pale blue.

[ATTACH=CONFIG]17888[/ATTACH]

My code to apply the GenerateRendererTask's results is as follows:
        cbExecuteGenerateRendererTask: function(renderer){
            var optionsArray = [];
            var drawingOptions = new esri.layers.LayerDrawingOptions();
            drawingOptions.renderer = renderer;
            optionsArray[selectedlayerId] = drawingOptions;
            dynLayer.setLayerDrawingOptions(optionsArray);
            dynLayer.setVisibleLayers([selectedlayerId]);
            dynLayer.show();
        }

I thought perhaps there was a timing issue in that the legend digit was updating itself before the renderer had finished getting applied, but I introduced an "onUpdateEnd" event handler where I do a legend.refresh(), but it doesn't make any difference. The legend stays a solid blue area when the legend.refresh() is called even after the map has completed updating its display.

In case I'm just doing that part wrong, here is my code for that too:
            dojo.connect(
                dynLayer
                ,"onUpdateEnd"
                ,function() {
                    if (app.legend != null){
                        app.legend.refresh();
                    }
                }
            );


Could someone who is more familiar with the actual code in the Legend digit provide some indication what I might be missing that is causing it to ignore the renderer definition being used? I've downloaded it and had a look but nothing jumps out at me, not being familiar with it at all.

Cheers,
jtm
0 Kudos
10 Replies
JohnGravois
Deactivated User
i looked into this and found an instance in which another customer experienced similar errors, but noticed that the legend was updated if they zoomed the map in or out afterwards.  is this the case for you also by chance?
0 Kudos
JoanneMcGraw
Frequent Contributor
Thank you for your response, jgravois. In my case, I'm afraid, the legend does not update properly even after zooming. The legend remains a single pale blue icon.

Can you provide a link to the other customer's instance? Perhaps there might be something useful in it anyway. I've searched the forums as minutely as I can and haven't come across anything useful to try to deal with this.

Cheers,
jtm
0 Kudos
JohnGravois
Deactivated User
unfortunately i never saw the sample, but in that case setting an event handler to wait for a dynamic join and rendering task to complete before refreshing provided a workaround.
0 Kudos
JoanneMcGraw
Frequent Contributor
setting an event handler to wait for a dynamic join and rendering task to complete before refreshing provided a workaround.


Is that somehow different from what I am doing with this code?
            dojo.connect(
                dynLayer
                ,"onUpdateEnd"
                ,function() {
                    if (app.legend != null){
                        app.legend.refresh();
                    }
                }
            );
 

If so, could you provide more information? Is there a specific rendering event that I can trap for?

cheers,
jtm
0 Kudos
JohnGravois
Deactivated User
that solution only resolved the problem in the situation where zooming in and out updated the legend as well.  i wasn't suggesting it as a fix for you, just providing the information in case it helps someone down the line.

can you put together a sample with public data so i can check it out?
0 Kudos
JoanneMcGraw
Frequent Contributor
Well, I can reproduce the problem in my application using public data. Pointing to the "http://servicesbeta2.esri.com/arcgis/rest/services/Census/MapServer" mapping service, I can see in my application that after the GenerateRendererTask callback function included previously is complete the legend is using the default symbology defined in the mapping service for the layer and that it continues to show the same after zooming in one level.

[ATTACH=CONFIG]17941[/ATTACH]
[ATTACH=CONFIG]17942[/ATTACH]

I'll try to pull apart the pieces of my app to create something that actually resembles what I am doing and illustrates the problem but I'm not certain I'll be able to as it's somewhat complicated.

One additional piece of info that might be indicative of something... the legend.refresh() calls aren't actually considering anything as having changed with respect to the dynamic layer after the different symbology is applied. It doesn't seem to be registering that the display is different because it is not actually requesting an updated legend display from the server. When I watch the traffic with Fiddler (that is, the URL requests and responses), after the generateRenderer request, there are no calls to get the legend for that layer. Whereas, in the "http://help.arcgis.com/en/webapi/javascript/arcgis/demos/renderer/renderer_dynamic_layer_change_attr..." sample, after the generateRenderer request is made, a legend request is also sent to update the legend's display as you can see in these two requests (from the sample page, that is):

http://servicesbeta2.esri.com/arcgis/rest/services/Census/MapServer/2/generateRenderer?classificationDef={"baseSymbol":{"color":null,"type":"esriSFS","style":"esriSFSSolid"},"colorRamp":{"type":"algorithmic","algorithm":"esriHSVAlgorithm","fromColor":[255,255,204,255],"toColor":[0,104,55,255]},"type":"classBreaksDef","classificationField":"WHITE","classificationMethod":"esriClassifyNaturalBreaks","breakCount":5}&f=json
http://servicesbeta2.esri.com/arcgis/rest/services/Census/MapServer/legend?f=json&dynamicLayers=[{"id":2,"source":{"type":"mapLayer","mapLayerId":2},"drawingInfo":{"renderer":{"type":"classBreaks","field":"WHITE","minValue":-99,"classBreakInfos":[{"classMaxValue":84181,"label":"-99 - 84181","description":"","symbol":{"color":[255,255,204,255],"type":"esriSFS","style":"esriSFSSolid"}},{"classMaxValue":294324,"label":"84182 - 294324","description":"","symbol":{"color":[184,217,130,255],"type":"esriSFS","style":"esriSFSSolid"}},{"classMaxValue":759924,"label":"294325 - 759924","description":"","symbol":{"color":[96,179,71,255],"type":"esriSFS","style":"esriSFSSolid"}},{"classMaxValue":1997123,"label":"759925 - 1997123","description":"","symbol":{"color":[28,140,45,255],"type":"esriSFS","style":"esriSFSSolid"}},{"classMaxValue":4637062,"label":"1997124 - 4637062","description":"","symbol":{"color":[0,105,56,255],"type":"esriSFS","style":"esriSFSSolid"}}]}}}]


In my application, only the first request is made, the second never is. So, it always just displays the legend definition that it had when the esri.digit.Legend was instantiated and its startup called. Whatever exists in the map at that time, with respect to these dynamic layers is what will always be displayed for that layer's portion of the legend even after a refresh is called. For example, if I have already rendered the map with a classified dynamic layer, say with 5 classes, and then instantiate the legend digit, the legend will correctly show the classification. If I then change the number of classes I want to use (say to 10) and redisplay the map with the new renderer definition, the map is updated with the generaterenderer request, but no legend request is made and the legend redisplays the original 5-class scheme it created for that layer at the startup of the digit.

Does that suggest anything in particular that isn't being done as it should?

cheers,
jtm
0 Kudos
JoanneMcGraw
Frequent Contributor
jgravois,

It's taken a while, but I have finally zeroed in on the problem but still don't know how to fix it or why it is happening. It's something to do with the use of the layerInfo array when instantiating the esri.digit.Legend.

I have taken the sample "Change the Attribute Field Used to Render Data" found at: http://help.arcgis.com/en/webapi/javascript/arcgis/samples/renderer_dynamic_layer_change_attribute/i... and made some changes to it to illustrate the problem I am having in my application. I am attaching the altered html within a zip file. Hopefully, anyone who is interested will be able to simply unzip the file in an HTTP-accessible location, load the esri.html it contains and have it run properly (after changing the proxyUrl path, of course).

[ATTACH=CONFIG]17968[/ATTACH]

Assuming you can load the page successfully, you will see the legend as it always was in the sample. Take note of the first class' values (-99 - 219570). Now, change the field to use for display to "POP2000". After the map and legend has updated, you can see the change in the first class' values (-99 - 160971).

Now, go into the esri.html contained in the zip and find the code that instantiates the esri.digit.Legend. Uncomment the layerInfo element that is currently commented out so that two layers are passed in the layerInfos array. Load up the page again and take note of that first class' values again (-99 - 219570). Now, choose field "POP2000" and, although the map changes, the legend does not. That first class' values are the same no matter what field you pick. It will never update and always show you that layer's legend as it was when the esri.digit.Legend was instantiated.

Interesting, too, by the way is if you move the new layerInfo element below the sample's existing layerInfo element, it will work properly.

So, to anyone who has a look at this, is there a problem with how the layerInfos are defined in the HTML or being treated in the Legend digit?

If there are problems reproducing what I detail above, please let me know. Any help with this is appreciated because I'm completely stuck at this point.

Cheers,
jtm
0 Kudos
JoanneMcGraw
Frequent Contributor
can you put together a sample with public data so i can check it out?


Has anyone had an opportunity to try the sample I put together? Did it work (or rather not work) as described?

Can anyone suggest a way to get the legend to display its layers in the desired order AND update the dynamic rendering for a layer that is listed later in the array of layerInfos?

Cheers,
jtm
0 Kudos
JohnGravois
Deactivated User
during a technical support incident Joanne and i noticed that the problem was isolated to situations in which other layers are provided prior to the DynamicMapService with a dynamic client side renderer in the array of layerInfos, or when layerInfos are not specified in the constructor for the legend widget at all.  i logged the following defect on her behalf:

[#NIM085566  When no layerInfos are passed to the legend widget, labels are not updated to reflect new class breaks when the symbology is updated. ]

please don't hesitate to contact support if you would like to have your name added to the list of customers affected by this issue.
0 Kudos