Select to view content in your preferred language

Table of Contents - Legend Widget for FlexViewer 2.x

122765
664
12-01-2010 07:30 AM
RobertScheitlin__GISP
MVP Emeritus
All,

Here is the next in my line of widgets for the FlexViewer 2.x.

The legend portion of this widget is the same code as my dynamic legend widget so,

IT IS FOR ARCGIS SERVER 10 OR GREATER ONLY

This is just a simple TOC Widget that includes my dynamic legend component.
This widget also includes my enhancement for map service transparency,
right click context menu for zoom to make layer visible, and my scale
dependent renderer for the TOC checkboxes.
Tags (2)
0 Kudos
664 Replies
MattiasEkström
Frequent Contributor
Robert,
I know you've been asked about legends for WMS layers before, and that's not your priority now.
I'm thought I could take a look at this my self, as a first step I would be happy just to be able to add a single image with a hard coded imageURL for each WMS layer.
Can you give me some hints how to accomplish this?
My guess so far is that I might start with something like:
}else if (m_layer is WMSLayer){

in the getLegendData function in TocMapLayerItem.as

but then I'm lost 😃
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Mattias,

   I looked into this once and just didn't have the time to commit to it. As the TOC Widget uses a tree and tree item renderers You can't just stick an image into it. I don't have any advice for you on this right now.
0 Kudos
MattiasEkström
Frequent Contributor
Robert,
I understand, thanks anyway for this great widget.
I found a way to add show meta data button for WMS layers that shows a modified details window with the legend image, I'll settle for that for now.
0 Kudos
HaroldBostic
Frequent Contributor
Hello Robert,

I'm sure you have covered this, so hopefully it will be easy to respond.  When I combine the TOC with the Selection Widget, Once the Selection widget is activated, all the FeatureLayers used in the Selection Widget get added to the TOC, preventing FeatureLayers from being added is an option for me, but I'd figured I'll check with you to see if there is a cleaner solution.

Thanks for your hard work


I modeled the implementation for excluding graphics layers to accomplish this, thanks
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Harold,

   Glad you got it working I had intended to respond but must have gotten side tracked. I don't use the selection widget so I could not respond without investigating Marks code.
0 Kudos
MattiasEkström
Frequent Contributor
Robert, did you ever got that proxy support code that Jeremy Moore mentioned in an earlier post?
What I can tell it isn't implemented yet, right?

Jeremy could you share some code?

I would like just that part of the code because I'm using my own customized version of this TOCwidget.

EDIT:
I think I found a solution my self, I've only tested this a little bit in my own application that only has DynamicLayers in the legend, but it seems to work...
I made just a few changes to the getLegendData function in TocMapLayerItem.as
  private function getLegendData(m_layer:*):void
  {
   if (_legendDataLoaded)
    return;
   _legendDataLoaded = true;
   
   if (m_layer.hasOwnProperty("url")){
    const url:String = m_layer["url"];
    if (url === null)
     return;
   }else{
    return;
   }
   
   var httpServ:HTTPService = new HTTPService();
   httpServ.requestTimeout = lTimeout;
   var lname:String;
   var lInfos:Array;
   if (m_layer is ArcGISTiledMapServiceLayer){
    if(m_layer.version >= 10.01){
     if(ArcGISTiledMapServiceLayer(m_layer).proxyURL){
      //If layer uses proxy (my addition for proxy support)
      httpServ.url = ArcGISTiledMapServiceLayer(m_layer).proxyURL + "?" + ArcGISTiledMapServiceLayer(m_layer).url + "/legend?f=json";
     }else{
      //if layer doesn't use proxy (original code)
      httpServ.url = ArcGISTiledMapServiceLayer(m_layer).url + "/legend?f=json";
     }     
     httpServ.resultFormat = "text";
     lname = ArcGISTiledMapServiceLayer(m_layer).id;
     lInfos = ArcGISTiledMapServiceLayer(m_layer).layerInfos;
     httpServ.addEventListener(ResultEvent.RESULT,function(event:ResultEvent):void{processLegend(event,lname,Number.NaN,lInfos,httpServ.url)});
     httpServ.send();
    }else{
     lname = ArcGISTiledMapServiceLayer(m_layer).id;
     ArcGISTiledMapServiceLayer(m_layer).addEventListener(DetailsEvent.GET_ALL_DETAILS_COMPLETE,function(event:DetailsEvent):void{getAllDetailsResult(event,lname)});
     ArcGISTiledMapServiceLayer(m_layer).addEventListener(FaultEvent.FAULT, function(event:Event):void{FlexGlobals.topLevelApplication.dispatchEvent(new Event("legendDataLoaded$"))});
     ArcGISTiledMapServiceLayer(m_layer).getAllDetails();
    }
   }else if (m_layer is ArcGISDynamicMapServiceLayer){
    if(m_layer.version >= 10.01){
     if(ArcGISDynamicMapServiceLayer(m_layer).proxyURL){
      //If layer uses proxy (my addition for proxy support)
      httpServ.url = ArcGISDynamicMapServiceLayer(m_layer).proxyURL + "?" + ArcGISDynamicMapServiceLayer(m_layer).url + "/legend?f=json";
     }else{
      //if layer doesn't use proxy (original code)
      httpServ.url = ArcGISDynamicMapServiceLayer(m_layer).url + "/legend?f=json";
     }
     httpServ.resultFormat = "text";
     lname = ArcGISDynamicMapServiceLayer(m_layer).id;
     lInfos = ArcGISDynamicMapServiceLayer(m_layer).layerInfos
     httpServ.addEventListener(ResultEvent.RESULT,function(event:ResultEvent):void{processLegend(event,lname,Number.NaN,lInfos,httpServ.url)});
     httpServ.send();
    }else{
     lname = ArcGISDynamicMapServiceLayer(m_layer).id;
     ArcGISDynamicMapServiceLayer(m_layer).addEventListener(DetailsEvent.GET_ALL_DETAILS_COMPLETE,function(event:DetailsEvent):void{getAllDetailsResult(event,lname)});
     ArcGISDynamicMapServiceLayer(m_layer).addEventListener(FaultEvent.FAULT, function(event:Event):void{FlexGlobals.topLevelApplication.dispatchEvent(new Event("legendDataLoaded$"))});
     ArcGISDynamicMapServiceLayer(m_layer).getAllDetails();
    }
   }else if (m_layer is KMLLayer)   {
    timeOutVar = setTimeout(getKMLLegend, 100, m_layer);
   }else if (m_layer is FeatureLayer){
    var FeatServId:Number = Number.NaN;
    var msName:String = FeatureLayer(m_layer).url.replace("FeatureServer","MapServer");
    if(msName.substring(msName.length - 9) != "MapServer"){
     if(FeatureLayer(m_layer).proxyURL){
      //If layer uses proxy (my addition for proxy support)
      httpServ.url = FeatureLayer(m_layer).proxyURL + "?" + msName.substring(0,msName.lastIndexOf("/")) + "/legend?f=json";
     }else{
      //if layer doesn't use proxy (original code)
      httpServ.url = msName.substring(0,msName.lastIndexOf("/")) + "/legend?f=json";
     }
     FeatServId = parseInt(msName.substring(msName.lastIndexOf("/")+ 1));
    }else{
     if(FeatureLayer(m_layer).proxyURL){
      //If layer uses proxy (my addition for proxy support)
      httpServ.url = FeatureLayer(m_layer).proxyURL + "?" + msName + "/legend?f=json";
     }else{
      //if layer doesn't use proxy (original code)
      httpServ.url = msName + "/legend?f=json";
     }
    }
    if(m_layer.layerDetails.version >= 10.01){
     httpServ.resultFormat = "text";
     lname = FeatureLayer(m_layer).id;
     httpServ.addEventListener(ResultEvent.RESULT,function(event:ResultEvent):void{processLegend(event,lname,FeatServId)});
     httpServ.send();
    } else {
     lname = FeatureLayer(m_layer).id;
     getFeatureResult(FeatureLayer(m_layer).layerDetails,lname);
    }

   }else{
    FlexGlobals.topLevelApplication.dispatchEvent(new Event("legendDataLoaded$"));
   }
  }
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Mattias,

   Thanks for the code. So here is a version of the function that supports tokens (secured services) and you proxy addition.

        private function getLegendData(m_layer:*):void
        {
            if (_legendDataLoaded)
                return;
            _legendDataLoaded = true;
            
            if (m_layer.hasOwnProperty("url")){
                const url:String = m_layer["url"];
                if (url === null)
                    return;
            }else{
                return;
            }
            
            var httpServ:HTTPService = new HTTPService();
            httpServ.requestTimeout = lTimeout;
            var lname:String;
            var lInfos:Array;
            var tURL:String;
            if (m_layer is ArcGISTiledMapServiceLayer){
                if(m_layer.version >= 10.01){
                    tURL = ArcGISTiledMapServiceLayer(m_layer).url;
                    if(tURL.indexOf("?token=") > 0){
                        httpServ.url = ArcGISTiledMapServiceLayer(m_layer).url.replace("?token=", "/legend?f=json&token=");
                    }else if(ArcGISTiledMapServiceLayer(m_layer).proxyURL){
                        //If layer uses proxy
                        httpServ.url = ArcGISTiledMapServiceLayer(m_layer).proxyURL + "?" + ArcGISTiledMapServiceLayer(m_layer).url + "/legend?f=json";
                    }else{
                        httpServ.url = ArcGISTiledMapServiceLayer(m_layer).url + "/legend?f=json";
                    }
                    httpServ.resultFormat = "text";
                    lname = ArcGISTiledMapServiceLayer(m_layer).id;
                    lInfos = ArcGISTiledMapServiceLayer(m_layer).layerInfos;
                    httpServ.addEventListener(ResultEvent.RESULT,function(event:ResultEvent):void{processLegend(event,lname,Number.NaN,lInfos,httpServ.url)});
                    httpServ.send();
                }else{
                    lname = ArcGISTiledMapServiceLayer(m_layer).id;
                    ArcGISTiledMapServiceLayer(m_layer).addEventListener(DetailsEvent.GET_ALL_DETAILS_COMPLETE,function(event:DetailsEvent):void{getAllDetailsResult(event,lname)});
                    ArcGISTiledMapServiceLayer(m_layer).addEventListener(FaultEvent.FAULT, function(event:Event):void{FlexGlobals.topLevelApplication.dispatchEvent(new Event("legendDataLoaded$"))});
                    ArcGISTiledMapServiceLayer(m_layer).getAllDetails();
                }
            }else if (m_layer is ArcGISDynamicMapServiceLayer){
                if(m_layer.version >= 10.01){
                    tURL  = ArcGISDynamicMapServiceLayer(m_layer).url;
                    if(tURL.indexOf("?token=") > 0){
                        httpServ.url = ArcGISDynamicMapServiceLayer(m_layer).url.replace("?token=", "/legend?f=json&token=");
                    }else if(ArcGISDynamicMapServiceLayer(m_layer).proxyURL){
                        //If layer uses proxy
                        httpServ.url = ArcGISDynamicMapServiceLayer(m_layer).proxyURL + "?" + ArcGISDynamicMapServiceLayer(m_layer).url + "/legend?f=json";
                    }else{
                        httpServ.url = ArcGISDynamicMapServiceLayer(m_layer).url + "/legend?f=json";
                    }
                    httpServ.resultFormat = "text";
                    lname = ArcGISDynamicMapServiceLayer(m_layer).id;
                    lInfos = ArcGISDynamicMapServiceLayer(m_layer).layerInfos
                    httpServ.addEventListener(ResultEvent.RESULT,function(event:ResultEvent):void{processLegend(event,lname,Number.NaN,lInfos,httpServ.url)});
                    httpServ.send();
                }else{
                    lname = ArcGISDynamicMapServiceLayer(m_layer).id;
                    ArcGISDynamicMapServiceLayer(m_layer).addEventListener(DetailsEvent.GET_ALL_DETAILS_COMPLETE,function(event:DetailsEvent):void{getAllDetailsResult(event,lname)});
                    ArcGISDynamicMapServiceLayer(m_layer).addEventListener(FaultEvent.FAULT, function(event:Event):void{FlexGlobals.topLevelApplication.dispatchEvent(new Event("legendDataLoaded$"))});
                    ArcGISDynamicMapServiceLayer(m_layer).getAllDetails();
                }
            }else if (m_layer is KMLLayer){
                timeOutVar = setTimeout(getKMLLegend, 100, m_layer);
            }else if (m_layer is FeatureLayer){
                var FeatServId:Number = Number.NaN;
                var msName:String = FeatureLayer(m_layer).url.replace("FeatureServer","MapServer");
                if(msName.substring(msName.length - 9) != "MapServer"){
                    tURL  = msName.substring(0,msName.lastIndexOf("/"));
                    if(tURL.indexOf("?token=") > 0){
                        httpServ.url = msName.substring(0,msName.lastIndexOf("/")).replace("?token=", "/legend?f=json&token=");
                    }else if(FeatureLayer(m_layer).proxyURL){
                        //If layer uses proxy
                        httpServ.url = FeatureLayer(m_layer).proxyURL + "?" + msName.substring(0,msName.lastIndexOf("/")) + "/legend?f=json";
                    }else{
                        httpServ.url = msName.substring(0,msName.lastIndexOf("/")) + "/legend?f=json";
                    }
                    FeatServId = parseInt(msName.substring(msName.lastIndexOf("/")+ 1));
                }else{
                    httpServ.url = msName + "/legend?f=json";
                }
                if(m_layer.layerDetails.version >= 10.01){
                    httpServ.resultFormat = "text";
                    lname = FeatureLayer(m_layer).id;
                    httpServ.addEventListener(ResultEvent.RESULT,function(event:ResultEvent):void{processLegend(event,lname,FeatServId)});
                    httpServ.send();
                }else{
                    lname = FeatureLayer(m_layer).id;
                    getFeatureResult(FeatureLayer(m_layer).layerDetails,lname);
                }
            }else{
                FlexGlobals.topLevelApplication.dispatchEvent(new Event("legendDataLoaded$"));
            }
        }
0 Kudos
AlexanderMena
Deactivated User
Hi, Robert,
thanks for the widget.

I am experiencing a problem with the widget:

The legend for the layers that have more than one full symbolism is not displayed in the widget.

I use FlexViewer version 2.3.1 and TOC version 2.3.7.2.
I read that can be for the Tree component Scroll adobe.
I wonder if this error was fixed for version 2.3.1 FlexView.

If it was resolved I would like the 2.3.x version of TOC where the solution or the way
to implement it in version 2.3.7.2 because I do not upgrade to FlexViewer version 2.5.

Could you give some hints to solve it??, thanks a lot.

Alexander Mena.
Procalculo.
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Alexander,

   Support is only offered for the latest version of my widgets. The code attached is what I believe to be the 2.3.9.2 version. You really have to watch for new releases, as bugs are constantly fixed and enhancements made to my widgets. All of the below happend for FlexViewer 2.3.1 version of the TOC widget since 2.3.7.2:

Version 2.3.9.2 - 1 August, 2011, 8:40 PM
* This probably will not happen ever again but I wanted to have a good stable Flex Viewer 2.3.1
  version of this widget available so I have added the compiled version with the memory leak fix
  and the follow-up fix for the disapearing labels.
* Uncompiled code is written for Flex Viewer 2.4 ONLY!

Version 2.3.9.1 - 19 July, 2011
* Fixed a item alignment issue in the TOC

Version 2.3.9 - 12 July, 2011
* Added exit code for people still using ArcGIS Server 9.3.1 or lower so that the Generating Legends
  message was not be stuck on the widget. (Lengend swatches will not be gerated for Server 9.3.1 or lower).

Version 2.3.8.6 - 6 July, 2011
* Added Ability to collapse ALL legend symbology
* Added new context menu for "expand all layers" and "collapse all layers"
* Changed the expand and contract icon for legends to the plus and minus (like in ArcMap).

Version 2.3.8.5 - 1 July, 2011
* Added Ability to collapse legend symbology is more than one symbol is present for a layer
* Added ability to have all collapsible legend symbology collapsed at startup based on
  TOCWidget.xml setting.

Version 2.3.8.4 - 23 June, 2011
* Slowed down mouse wheel scroll speed
* Added generic legend support for Dimension, Annotation, Raster Catalog, and Tiled Raster Basemaps
* I am not real happy with the Tiled Raster Basemaps but the way esri currently returns legend info
  is not real conducive to legend generation. Maybe 10.1 of server will fix this.

Version 2.3.8.3 - 21 June, 2011
* Fixed issue with excluding multiple sublayers of a dynamic map service.
* Added a busy indicator and message for large complicated legends.

Version 2.3.8.2 - 21 June, 2011
* More optimization of the layout to use less vertical and horizontal space.

Version 2.3.8.1 - 20 June, 2011
* Fixed Horizontal clipping issues when tree leafs were collapsed.

Version 2.3.8 - 11 June, 2011
* Fixed Horizontal and vertical scrolling issues.
* Enhanced layout of TOC swatches and checkboxes.
* Cleaned up lots of unused portions of the code.
* TOC Item label is gray when item is scale dependent.

Version 2.3.7.2 - 10 June, 2011
* Fixed ZoomToMakeVisible context menu when using cached/tiled base maps.
* Feature layers now only have one checkbox at the parent map service that show
  Scale dependency and has context menus.

Don't forget to click the top arrow (promote) as shown below:
0 Kudos
AlexanderMena
Deactivated User
Thank you Robert for you reply, but.

Where I find the lastest version without compiling for FlexViewer 2.3.1? I need the code to fix the scrolling.

I have customized the widget. I try to replicate the code for Scroll of the version 2.5 but remains the same.

<s:Scroller id="scr" width="100%" height="100%">
    <s:Group>
     <s:layout>
      <s:VerticalLayout gap="1"/>
     </s:layout>
     <s:HGroup id="boxMessage"
         width="100%"
         includeInLayout="false"
         visible="false"
         verticalAlign="middle"
         horizontalAlign="center">
      <mx:Image id="swfMessage"
          source="widgets/TOC/assets/images/loader.swf"/>
      <s:Label id="txtMessage"
         width="90%"
         text="{GeneratingLegendMsg}"/>
     </s:HGroup>
     <toccomp:TOC id="toc"
         width="100%"
         height="100%"
         labels="{[ZoomToMakeVisible,ExpandAll,CollapseAll]}"
         useesridescription="{UseNewEsriDescrption}"
         expanded="{expanded}"
         legendCollapsed="{legendCollapsed}"
         liveScrolling="false"
         variableRowHeight="true"
         tocMinWidth="{wTemplate.width - 45}"
         scroller="{scr}"
         loader="{boxMessage}"/>
    </s:Group>
   </s:Scroller>

Thank you.

Alexander Mena
Procalculo.
0 Kudos