Select to view content in your preferred language

Legend component rendering issue

2928
4
01-30-2012 01:10 PM
RoyceSimpson
Frequent Contributor
I've got a map object which has a dynamic map service layer (myLayer) in it that I'm using as to populate a legend. The legend.layers property is being set to that dynamic map service layer (legend.layers = [myLayer]).  In this app, the user is restricted to pick and only show one "layer" out of the 30+ "layers" within myLayer.  With the legend turned on, the user should see only the legend item for the single "layer" that they have turned on at any given time.

This is all working fine except that it seems that the legend component draws each legend item a little lower than the previous one in the myLayer TOC layer list, so if the user turns on the 35th layer in myLayer, the legend draws up with a vertical scroll bar that you have to scroll through a bunch of blank space to finally get to the desired legend item.

I've attached two screen shots.  noBlankSpace.jpg shows the legend when the user draws only the first "layer" in myLayer.  If the user picks, say... the 20th "layer" in myLayer to draw... it looks like what you see in lotsOfBlankSpace.jpg.  If the user picks the 30th "layer" in myLayer, they need to scroll down a window of blank space before they see the legend item.

There seems to be a direct correlation between how far down the the "layer" is in the published MXD TOC and how much blank space precedes the legend item to be drawn.

Not sure how to fix this but it's pretty tough on users to have to scroll through a bunch of dead air to see legend items.
0 Kudos
4 Replies
JHayes
by
Frequent Contributor
I think adding the code would help a little.

Joe
0 Kudos
by Anonymous User
Not applicable
Original User: ibespalov

Royce,

1 - If layer(s), included in Legend, has no any sublayers - no issue detected! ([ATTACH=CONFIG]11726[/ATTACH])

2 - If included in legend layer has sublayers - issue detected! ([ATTACH=CONFIG]11727[/ATTACH])

3 - Find deafault LegendSkin.mxml file (... arcgis_api_flex_2_5\ArcGIS_Flex\skins\src\com\esri\ags\skins), include skin in project. Looks like resolved, but must be tested with real application ([ATTACH=CONFIG]11728[/ATTACH])

In legend skin file add highlighted code:

function showHideLayers(isSubLayerVisible:Boolean, serviceGroups:Array, layer:Layer, leafLayerLegendInfo:LayerLegendInfo, numLeaf:Number):void
{
    var i:int;
    if (!isSubLayerVisible)
    {
        count++;
    }
    if (count == numLeaf) // all the layers with legends are not visible
    {
        for (i = 0; i < serviceGroups.length; i++)
 {
     serviceGroups.includeInLayout = serviceGroups.visible = false;
 }
    }
    else
    {
        for (i = 0; i < serviceGroups.length; i++)
 {
     serviceGroups.visible = serviceGroups.includeInLayout = true;
     for (var e:int = 0; e < serviceGroups.numElements; e++)
     {
         if (serviceGroups.getElementAt(e) is Label && Label(serviceGroups.getElementAt(e)).name == String(leafLayerLegendInfo.layerId))
  {
      if (isSubLayerVisible)
      {
          Label(serviceGroups.getElementAt(e)).visible = Label(serviceGroups.getElementAt(e)).includeInLayout = true;
   if (!subLayerInScaleRange(leafLayerLegendInfo))
   {
       if (hostComponent.respectCurrentMapScale)
       {
           Label(serviceGroups.getElementAt(e)).visible = Label(serviceGroups.getElementAt(e)).includeInLayout = false;
       }
       else
       {
           Label(serviceGroups.getElementAt(e)).alpha = 0.5;
       }
   }
      }
      else
      {
          Label(serviceGroups.getElementAt(e)).visible = Label(serviceGroups.getElementAt(e)).includeInLayout = false;
      }
  }
        
  if (serviceGroups.getElementAt(e) is DataGroup && DataGroup(serviceGroups.getElementAt(e)).name == String(leafLayerLegendInfo.layerId))
  {
      if (isSubLayerVisible)
      {
          DataGroup(serviceGroups.getElementAt(e)).visible = DataGroup(serviceGroups.getElementAt(e)).includeInLayout = true;
   if (!subLayerInScaleRange(leafLayerLegendInfo))
   {
       if (hostComponent.respectCurrentMapScale)
       {
           DataGroup(serviceGroups.getElementAt(e)).visible = DataGroup(serviceGroups.getElementAt(e)).includeInLayout = false;
       }
       else
       {
           DataGroup(serviceGroups.getElementAt(e)).alpha = 0.5;
       }
   }
                    }
                    else
                    {
                        DataGroup(serviceGroups.getElementAt(e)).visible = DataGroup(serviceGroups.getElementAt(e)).includeInLayout = false;
                    }
  }   
  // exclude Spacer if sublayer is not visible
  if (serviceGroups.getElementAt(e) is mx.controls.Spacer)
  {
      if (isSubLayerVisible)
      {
          mx.controls.Spacer(serviceGroups.getElementAt(e)).visible = mx.controls.Spacer(serviceGroups.getElementAt(e)).includeInLayout = true;
   if (!subLayerInScaleRange(leafLayerLegendInfo))
   {
       if (hostComponent.respectCurrentMapScale)
       {
           mx.controls.Spacer(serviceGroups.getElementAt(e)).visible = mx.controls.Spacer(serviceGroups.getElementAt(e)).includeInLayout = false;
       }
   }
      }
      else
      {
          mx.controls.Spacer(serviceGroups.getElementAt(e)).visible = mx.controls.Spacer(serviceGroups.getElementAt(e)).includeInLayout = false;
      }
                }
     }
        }
    }
    isLegendShown();
}


Did you tried to play with skin class?

P.S. ArcGIS API for FLEX 2.5 - Adobe flex SDK 4.5.1
0 Kudos
RoyceSimpson
Frequent Contributor
Thanks Ivan,
Yes, I have all my actual "map layers" in the mxd categorized within group layers.  I'll look into your solution ASAP.
-r
0 Kudos
by Anonymous User
Not applicable
Original User: simpsonr

Thanks Ivan,
Yes, I have all my actual "map layers" in the mxd categorized within group layers.  I'll look into your solution ASAP.
-r


Fixed.  Thanks Ivan for the tip on the LegendSkin class.  I was able to simplify on your suggestion by referencing a modified LegendSkin whereby I only need to comment out  the two lines that look like the following:  "serviceGroup.addElement(new Spacer());". 

Since I only ever allow the user to make one layer visible at a time from that map service... the above modification works.

Thanks again.
-r
0 Kudos