Converting a business Analyst appllication to a widget.

3746
6
08-18-2011 01:47 PM
SeanCook
New Contributor
Hello all,

I was curious if anyone has had any success converting on of the BA server example applications into a widget.

I'm currently playing with the example linked below, and am not having success turning it into a functioning widget. I would appreciate any help along those lines. I've been trying to complete the task by copying off of another working widget and haven't had any luck yet. My code is below, and the original code is available at the link for anyone who could volunteer to take a look.

http://help.arcgis.com/en/businessanalyst/10.0/server/apis/flex/samples/index.html?sample=DriveTime

Is there any step by step available for doing this, or even a help page explicitly explaining how a widget and application differ?

Thanks in advance for any help!

Note: I cut out my imports because I had to reduce the number of characters.
<?xml version="1.0" encoding="utf-8"?>
<viewer:BaseWidget
 xmlns:esri="http://www.esri.com/2008/ags"
 xmlns:fx="http://ns.adobe.com/mxml/2009" 
 xmlns:s="library://ns.adobe.com/flex/spark" 
 xmlns:mx="library://ns.adobe.com/flex/mx" 
 widgetConfigLoaded="init()">
 
 <fx:Script>
  <![CDATA[

   //----------------------------------
   // Internal variables
   //----------------------------------
   
   // Bindable array for reports list
   [Bindable]private var _reports : Array;
   
   // drawn map point object
   private var _point : MapPoint;
   
   // Initial map extent.
   private var _initialExtent : Extent;
   
   
   
   //----------------------------------
   // Initializing
   //----------------------------------
   
   /**
    * Initialize the sample and activate the draw toolbar.
    */
   private function init():void 
   {
    
    
    drawToolbar.activate(DrawTool.MAPPOINT);
   }
   
   protected function report_openHandler(event:Event):void
   {
    map.addEventListener(MapMouseEvent.MAP_CLICK,mapClickHandler) 
    map.addLayer(myGraphicsLayer);
   }
   
   protected function report_closedHandler(event:Event):void
   {
    clear();
    //map.removeLayer(myGraphicsLayer); 
    map.removeEventListener(MapMouseEvent.MAP_CLICK,mapClickHandler) 
   }
   private function clear():void
   {
    myGraphicsLayer.clear();
   }
   
   private function mapClickHandler(event:MapMouseEvent):void
   {
    onDrawEnd(event.mapPoint);
   }
   
   
   //----------------------------------
   // Drawing
   //----------------------------------
   
   /**
    * Event handler for draw completing event;
    * capture the graphics from draw toolbar, 
    * add the graphics to the Map and create an object
    * based on the graphic drawn. 
    */
   private function onDrawEnd(event:DrawEvent):void  
   {                
    var graphic:Graphic = event.graphic;  
    
    // clear the previous drawing
    gLayer1.clear();                       
    gLayer1.add(graphic);             
    
    // Capture the point geometry from the draw toolbar.
    if(event.graphic.geometry is MapPoint)                
     _point = MapPoint(event.graphic.geometry);
    
    
    drawToolbar.deactivate();
    executeTask();
    
    map.extent = _initialExtent;
   }
   
   //----------------------------------
   // Executing the task
   //----------------------------------
   
   /**
    * Executes the task.
    */
   private function executeTask():void 
   {
    if(_point)
    {
     //create the parameters used by this task    
     var params : DriveTimeParameters = createParameters();
     
     
     //Get a static reference to a singleton instance of the BAServerClient class.
     //Instructions for how to create the BAServerClient class is provided at the top of this file.
     
     
     
     var client : BAServerClient = new BAServerClient();
     client.url = "http://nsesribap01vmsean:80/ArcGIS/baserver/REST/services/DefaultMap/BAServer";
     var task : DriveTimeTask  = new DriveTimeTask(client);
     task.execute(params, new mx.rpc.Responder(resultHandler, faultHandler));
    }
    else 
    {
     Alert.show("Store The point is not set.");
    }
   }
   
   /**
    * Creates parameters of the task. 
    */
   private function createParameters() : DriveTimeParameters 
   {
    //task output type
    var outputTypes : OutputTypes = new OutputTypes();
    outputTypes.getFeatureClass = true;
    outputTypes.getReport = true;
    
    var params : DriveTimeParameters = new DriveTimeParameters(outputTypes);
    
    //distance units
    params.distanceUnits = DriveTimeUnits.DRIVE_MINUTES;
    //radii
    params.radii = [3,5,10];
    //create stores
    var pointLayer : PointLayer = 
     new PointLayer([ new PointRecord("Store 1", "Redlands", "1", _point.y, _point.x)]);
    params.stores = pointLayer;
    //donut
    params.donut = false;
    //report options
    params.reportOptions = [
     new ReportOptions("PDF", "Market Profile", new BAReportHeader("Market Profile"))
    ];
    
    return params;
   }
   
   /**
    *  Result handler for the successful completion of the task execution. 
    */            
   private function resultHandler(event:BATaskCompletedEvent, token:Object=null):void 
   {
    var taskResultOutput : TaskResultOutput = event.result as TaskResultOutput;
    //draw the features on the map
    var fs : FeatureSet = taskResultOutput.recordSet;
    if (fs)
    {
     // add the resulting features to the map
     for (var i:Number = 0; i < fs.features.length; i++) 
     {
      var g : Graphic = fs.features;
      // set tooltip from attributes
      g.toolTip = fs.features.attributes["AREA_DESC2"];
      g.autoMoveToTop = false;
      gLayer.add(g);
     }
     
     zoomToExtent();
    }
    
    //print out the report information
    _reports = [];
    for each(var item : ReportInfo in taskResultOutput.reports)
    {
     var rep : Object = new Object();
     rep["templateName"] = item.templateName;
     rep["format"] = item.format;
     rep["url"] = item.url;
     rep["text"] = "Open Report"; 
     _reports.push(rep);    
    }

   }
   
   /**
    *  Generalized fault handler for an asynchronous failed task execution. 
    */   
   private function faultHandler(event:FaultEvent, token:Object=null):void 
   {
    var message:String = "An error occurred while executing the underlying Web Service request.";
    message += " Please try again later.";
    
    Alert.show(message, "Error");


   }
   
   /**
    * Event handler function for grid double click event
    * Handle opening the report when the 'Open Report' button is double clicked
    */
   private function onGridDoubleClick(e:ListEvent):void 
   {
    var url:String = e.itemRenderer.data.url;
    navigateToURL(new URLRequest(url), "_blank");
   }
   
   /**
    * Zoom to the resulting features extent
    */
   private function zoomToExtent() : void
   {
    var allGraphics : Array = gLayer.graphicProvider.source as Array;
    allGraphics = allGraphics.concat(gLayer1.graphicProvider.source as Array);
    
    map.extent = GraphicUtil.getGraphicsExtent(allGraphics).expand(1.25);
   }
  ]]>
 </fx:Script>
 <fx:Declarations>
  <!-- Control to user draw -->
  <esri:DrawTool id="drawToolbar"        
        map="{map}"
        markerSymbol="{sMarker}"
        drawEnd="onDrawEnd(event)" />
  <!-- Set the marker symbol for user draw -->
  <esri:SimpleMarkerSymbol id="sMarker" color="0xFFFF00" size="15" style="circle">            
   <esri:SimpleLineSymbol color="0x000000" width="2"/>        
  </esri:SimpleMarkerSymbol>
  
  <!-- Set renderer for Drive Time output feature class -->
  <esri:SimpleFillSymbol id="bFill" alpha="0.5" color="0x0000FF"/>
  <esri:SimpleFillSymbol id="gFill" alpha="0.5" color="0x00FF00"/>
  <esri:SimpleFillSymbol id="rFill" alpha="0.5" color="0xFF0000"/>
  <esri:UniqueValueRenderer id="uniqueValueRenderer" attribute="RING">
   <esri:UniqueValueInfo value="1" symbol="{rFill}"/>
   <esri:UniqueValueInfo value="2" symbol="{gFill}"/>
   <esri:UniqueValueInfo value="3" symbol="{bFill}"/>
  </esri:UniqueValueRenderer>        
 </fx:Declarations>
 

 <viewer:WidgetTemplate id= "report"
         width="305" 
         height="100" 
         open="report_openHandler(event)"
         closed="report_closedHandler(event)"/>
 
 <mx:VDividedBox width="100%" height="100%">
  <!-- Map control -->
  <esri:Map id="map">        
   <esri:extent>            
    <esri:Extent xmin="-117.352" ymin="33.955" xmax="-117.023" ymax="34.167">                
     <esri:SpatialReference wkid="4326"/>            
    </esri:Extent>        
   </esri:extent>        
   <esri:ArcGISTiledMapServiceLayer url="http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"/>        
   <!-- Graphics Layer to draw resulting features-->
   <esri:GraphicsLayer id="gLayer" renderer="{uniqueValueRenderer}" />
   <!-- Graphics Layer to draw user input-->
   <esri:GraphicsLayer id="gLayer1"/>
  </esri:Map>
  <s:VGroup width="100%" height="30%">
   <s:Label text="Reports" fontWeight="bold"/>
   <!-- Grid to display the list of reports -->
   <mx:DataGrid 
    dataProvider="{_reports}" doubleClickEnabled="true" itemDoubleClick="onGridDoubleClick(event)"
    scroll="true" width="100%" height="90%" textAlign="center">
    <mx:columns>
     <mx:DataGridColumn dataField="templateName" headerText="Template Name"/>
     <mx:DataGridColumn headerText="URL" color="0x0000FF" dataField="text"/>
     <mx:DataGridColumn dataField="format" headerText="Format"/>
     <mx:DataGridColumn dataField="url" visible="false"/>
    </mx:columns>
   </mx:DataGrid>            
  </s:VGroup>
 </mx:VDividedBox>      
</viewer:BaseWidget>

0 Kudos
6 Replies
PrashanthSukumaran
New Contributor II
Hi Sean,

What error are you seeing exactly?

The sample you found is using the BAServer Flex API.  You need to have a valid Business Analyst  Server License. 

It does explain what code to add if you have already secured(which is a good thing to do) your map services and the DefaultMap service.

The widget framework is part of the ArcGIS Viewer for Flex.  This url http://help.arcgis.com/en/webapps/flexviewer/ will tell you all you need to do with widgets and the sample viewer framework.   Check out the quick links on this page.

The sample flex viewer is based on ArcGIS API for Flex version 2.4 which is written in Flex 4 and has support for Flex 4.5.

I see that you have added the esri:Map in the widget which means the map will be visible within the widget itself. I don't know if that is what you want. As far as the arcgis flex viewer goes, the widget has functionality that writes to the MAP that is available as part of the Viewer itself.  Just try running on the the sample flex viewer apps and also download the source code for the Sample Flex Viewer. 

The basic idea of the Widget framework is that it is extendable.  You don't have the touch any of the Sample Flex Viewer code, all you need to do is write a widget following the guidelines and configure it in the config.xml and it is visible.  http://help.arcgis.com/en/webapps/flexviewer/help/index.html#/Create_your_own_widget/01m300000010000...

The Business Analyst Server Flex API 2.0.1 is awesome.  Check it out and also compare it with the BA Server REST API. 

If you don't have a Business Analyst Server license ie., ba server hosted in your corporate environment you can try the Business Analyst Online Flex API  and samples are available for that as well.

http://resources.arcgis.com/content/business-analyst-online/apis/flex

Hope this helps
0 Kudos
MehakSujan
New Contributor
Hi Sean,

To answer your question on the difference between a widget and an application, a widget in the Flex Viewer is basically a native Flex module which is a binary file (SWF format) that can be dynamically loaded and unloaded in a Flex application and that cannot exist separate from an application. This saves memory and time when starting up the main application. For more details on modules, you can refer to the Adobe docs at http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf69084-7f22.html.

For more information on the ArcGIS Viewer for Flex widget framework, you can look at the ArcGIS Viewer for Flex documentation at http://help.arcgis.com/en/webapps/flexviewer/help/index.html. To understand what a widget in the Flex Viewer is, you can look at http://help.arcgis.com/en/webapps/flexviewer/help/01m3/01m30000001v000000.htm and to get more information on how to create your own widget and also how to get a hold of the main map in the Flex Viewer application, you can refer to http://help.arcgis.com/en/webapps/flexviewer/help/01m3/01m300000010000000.htm.

Prashanth also already provided a lot of useful information and resources to you but if you have any more questions, feel free to ask.

Hope these help!

Thanks,
Mehak
0 Kudos
PrashanthSukumaran
New Contributor II
I used the bookmark widget as a starting template.  I have attached a very basic widget similar to the sample you mentioned.  This widget will work with ArcGIS Flex Viewer 2.4.
0 Kudos
cristiBJ
New Contributor III
Did this work? The above sample widget did not help much.  I am doing the same, trying to implement the BAO drive time report to a widget in Flex Viewer 2.4. The drive time report works, but the polygons do not draw.

I have trouble working with uniquevaluerenderer, I will post a new thread to ask.
0 Kudos
PrashanthSukumaran
New Contributor II
Did this work? The above sample widget did not help much.  I am doing the same, trying to implement the BAO drive time report to a widget in Flex Viewer 2.4. The drive time report works, but the polygons do not draw.

I have trouble working with uniquevaluerenderer, I will post a new thread to ask.



Hello Cristie,

Sean wanted to convert an interactive sample of a drive time which is what i have attached.  You can generate the report either for a ring, drive time, donut, polygons or any of the standard geographies. 

There are samples available that show you exactly how it can be done.  You can modify the attached widget to enable what you want.  It is pretty simple using the BA Flex API. 

The BAClientFactory.as has Sean urls 

private static var _BAServerURL:String = "http://nsesribap01vmsean:80/ArcGIS/baserver/REST/services/DefaultMap/BAServer";  Change the url to your own or to

private static var _BAServerURL:String = "http://baserver.esri.com/ArcGIS/baserver/REST/services/RedlandsDemoMap/BAServer";

If it does not work let me know what error you are seeing.
0 Kudos
SeanCook
New Contributor
Prashanth, you're an absolute life saver. Thank you so much. This really got me going, and I was able to start playing with it and get some more mods going...inputting drive times, changing the report name, having it clear on command, etc. You really helped out!
0 Kudos