Print Widget and Renderers with Functions

7358
17
05-10-2013 09:54 AM
DanielTrone
New Contributor
I am using the print widget and have noticed an unusual issue.

When I use a function-formula in the renderer instead of a simple variable, the legend does not display normally, but instead displays only the symbols used for that area and the label 'Override' (see attachment).  Is this a bug? (Also see code snippet below).

Secondly, also when I am using a function formula in the renderer, and when I use a defaultSymbol instead of setting the first parameter of ClassBreaksRenderer to false, the print process will fail.

Thirdly, when I use a renderer with a simple variable, and no default symbol, it works, but my transparency is always opaque. (At least in the first situation, with the Override labels, the transparency is correct).

<CODE>
  if (themevar === 'PCT_OTH_R') {
   renderer = new esri.renderer.ClassBreaksRenderer(false, function (graphic) {
    return ((graphic.attributes.OTHER_NH / graphic.attributes.POP0711) * 100);
   });
   renderer.addBreak({
    minValue: 0,
    maxValue: 2,
    symbol: new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([239, 237, 245, 0.5])),
    label: "< 2%"
   });
   renderer.addBreak({
    minValue: 2,
    maxValue: 5,
    symbol: new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([188, 189, 220, 0.5])),
    label: "2% to 5%"
   });
   renderer.addBreak({
    minValue: 5,
    maxValue: Infinity,
    symbol: new esri.symbol.SimpleFillSymbol().setColor(new dojo.Color([117, 107, 177, 0.5])),
    label: "> 5%"
   });
   $('#titleleg').html('PCT Other');
  }
</CODE>

Here is a link to the working application to see the print behavior in action.

http://dola.colorado.gov/gis-cms/sites/default/files/html/acs0711_11.html

And here is the fiddle (sorry its so long, but still 1/5 size of original project).
http://jsfiddle.net/DanielTrone/e2yse/
0 Kudos
17 Replies
JohnGravois
Frequent Contributor
based on my reading of the export webmap spec and a look at your own request, this is happening because you are currently passing a collection of graphics whose symbology is defined feature by feature, rather than in a class breaks renderer (defined within drawingInfo).

if you're able to further whittle down your fiddle to use a single layer (and actually give an opportunity to redefine symbology based on population and race), it would be easier to see what your options are.
0 Kudos
DanielTrone
New Contributor
Thanks for taking the time to look at this problem.


I have significantly cleaned up the fiddle down to only the essential elements. http://jsfiddle.net/DanielTrone/e2yse/1/

Note how the legend works for 'Median HH Income' (simple variable instead of a function, no default symbol) and how it doesnt work at all for 'Per Capita Income' (uses a default symbol).

Also note how 'Age less than 18' has the Override label text (uses a function instead of a simple variable).

And note how the transparency is wrong on 'Median HH Income', but correct on 'Age less than 18'.
0 Kudos
JohnGravois
Frequent Contributor
i took your code and wrote up a really simplified sample where the symbology is actually passed to ArcGIS Server with a class breaks renderer defined for the layer (instead of defining symbols feature by feature).

the only difference between my app and yours is that I am referencing a hardcoded featureLayer and you are pulling your layer from a webmap.

i didn't realize till just now, but your own web_map_json defines the layer as a "featureCollection".  i wonder why the hosted feature service ends up acting like a graphics layer?

"id" : "TractACSv4_4105",
   "opacity" : 1,
   "minScale" : 0,
   "maxScale" : 0,
   "featureCollection" : {
    "layers" : [{
      "layerDefinition" : {
       "name" : "TractACSv4",
0 Kudos
DanielTrone
New Contributor
I'm not sure I understand what's wrong (regarding feature collection vs graphics layer) and what I can do to fix it.

Also, have you noticed that if you replace 'false' with 'defaultSymbol' on the class breaks renderer, the Print operation fails? (might that have something to do with the first problem?)
0 Kudos
JohnGravois
Frequent Contributor
i took the time to adapt my simplified sample to pull your webmap and im still not seeing the same behavior as in your own application

http://jsfiddle.net/jagravois/A6cuH/1/

with regard to passing a default symbol in a class breaks renderer in the webmap json, i think im seeing the same thing you are, and will work on putting together something even more straightforward to show the problem.
0 Kudos
DanielTrone
New Contributor
MED_AGE may not be the best example to use, because it is used directly in the Class Breaks Renderer. (though note how the transparency is messed up anyway).

I took your fiddle and changed the Variable to AGE65PLUS, and used a calculated value in as the second parameter in the Class Breaks Renderer.  You should be able to see the legend problem here.  (Legend says Override 1, Override 2.  Transparency is correct, though).

http://jsfiddle.net/DanielTrone/xrGPh/2/
0 Kudos
JohnGravois
Frequent Contributor
thanks for pointing that out.  now i FINALLY understand what is going on. 

in this situation you are calculating a new value to use for your class breaks renderer on the fly without designating a new attribute column to store the value you calculated. (i think you already know this)

the collection of graphics have to be sent to the server feature by feature, with a symbol defined (not renderer, which supports a label), rather than having a true class breaks renderer defined for the feature layer.  If the field was present on the server we could just describe the renderer as class breaks and let ArcGIS Server draw things up on the fly).

i tested actually adding a new field to the graphics layer based on this value instead of relying on a function within the renderer, but this doesn't work either (because when we send the new print request we now assume a field is present in the service that isn't actually there).

function addNewAttribute() {
     var myLayer = app.map.getLayer("CountyACSv4_5756");
  myLayer.fields.push({"alias": "PERCENTOLD",
                      "editable": false,
       "length" : null,
       "nullable" : true,
                            "name" : "PERCENTOLD",
       "type" : "esriFieldTypeString"
       });
  dojo.forEach(myLayer.graphics, function (graphic) {
    graphic.attributes.PERCENTOLD = (graphic.attributes.AGE65PLUS / graphic.attributes.POP0711 * 100);
  });
   }


unfortunately, i don't know how of a good way to work around this problem (other than ensuring that you have fields present in the data for values you need to render by.)
0 Kudos
DanielTrone
New Contributor
As far as not being able to include a legend for calculated values - that's too bad.  I may have to restructure the data to work around this limitation - but as it was, I was already running up against the 256 column limit in shapefiles.  (The American Community Survey is a huge, huge dataset).

One last point, however,  what's going on with the layer transparency in the printouts? 

1.) In my fiddle,  http://jsfiddle.net/DanielTrone/xrGPh/2/  the transparency displays correctly in the printout; the basemap can be seen underneath the data layer.

2.) In your fiddle, http://jsfiddle.net/jagravois/A6cuH/  where we use the MED_AGE statistic directly, the transparency of the layer in the printout does not respect the transparency defined in the class breaks renderer.  It is completely opaque.

Any idea what's happening here, so I can seek to get the correct behavoir (transparency of example 1, with legend of example 2).
0 Kudos
JohnGravois
Frequent Contributor
sorry for the delayed reply.  i did some more testing and confirmed that this is a REST problem (as opposed to a problem in the JS API).  it seems that currently ArcGIS Server does not honor transparency defined as an alpha value within a RGB color symbol for feature service layers.

you can see this problem by removing the .TXT extension from the attached .webmap file (which has identical contents to the webmap JSON we pass to ArcGIS Server when printing) and dragging and dropping itdirectly into ArcMap.

"symbol" : {
    "color" : [0, 255, 0, 128], //128 (or 50% transparency) is replaced by 255
    "outline" : {
        "color" : [0, 0, 0, 128],  //128 (or 50% transparency) is replaced by 255
        "width" : 2,
        "type" : "esriSLS",
        "style" : "esriSLSSolid"
    },
    "type" : "esriSFS",
    "style" : "esriSFSSolid"
},

even though an alpha transparency of 128 is specified for the symbol fill color, the layer is completely opaque in ArcMap

[ATTACH=CONFIG]25482[/ATTACH]

since your sample app passes a collection of graphics instead of a feature service layer, you get around this limitation (but encounter another). 

ive asked the developers to update the Export Web Map Spec to acknowledge the limitation i found.  sorry for the inconvenience.
0 Kudos