AdobeStock_455007340

Grouping Data With Flex 3 AdvancedDataGrid

Home » Grouping Data With Flex 3 AdvancedDataGrid

The enhancements to the data grids in Flex 3 have been eagerly anticipated, and are greatly appreciated – especially by us ColdFusion developers who spend so much time creating highly data-centric applications. I plan on providing examples of how to use the new data grids with ColdFusion, and here is the first.
AdvancedDataGrid supports group expanding and collapsing within grids, think of it as a grid with an embedded tree control. Multiple levels of grouping are supported (each level becomes a tree branch), but this example uses a single level for simplicity’s sake.
The example uses the default database tables that come with ColdFusion 8, and here is the simple CFC method which just returns several columns from two tables:




SELECT mediatype, artname, description, price
FROM media, art
WHERE media.mediaid=art.mediaid
ORDER BY mediatype, artname




I saved this component as art.cfc in a folder named test beneath the web root. You can save it wherever you like, but of course you’ll need to adjust the path in the MXML accordingly. Here is the MXML:






















points to the CFC. defines the grid and columns, in much the same way as regular does. But unlike , here the dataProvider is passed as a child tag so as to be able to specify additional information. can accept hierarchical data ready to be used for grouping, as well as flat data, in which case a GroupingCollection must be used so that Flex can regroup the data hierarchically. As ColdFusion queries are flat (non-hierarchical), a GroupingCollection is defined using . The GroupingCollection accepts one or more fields to be grouped on, and here a single field is specified using .
When using GroupingCollections like this, the data grid itself must explicitly be refreshed so that the changes are reflected in the displayed grid. According to the documentation, this example would do this as , but this does not seem to work. Instead, the refresh() method is specified in so that it is called when data is received. (Thanks to Mike Nimer for figuring this one out for me!).
And there you have it, a really simple data grid with expand/collapse grouping.

12 responses to “Grouping Data With Flex 3 AdvancedDataGrid”

  1. Steve Walker Avatar
    Steve Walker

    Ben,
    Thanks for this example. Here it is with live data from my blog (http://www.swphoto.net/advgrid/).

  2. Vegard Bakke Avatar
    Vegard Bakke

    Do you know whether it is possible to show data next to the "closed folders"?
    For example aggregated price/cost per mediatype. Also, display the number of sub items of a group in the AdvancedDataGrid could be of interest. Typical use would be accounting sheets, where you could drill down in the data. But then you’d need the summarised totals on the top level, not just the leaf nodes.
    So far I haven’t seen any documentation or examples showing this feature, which I’d thought would have been the main purpose for the AdvancedDataGrid control.

  3. Ben Forta Avatar
    Ben Forta

    Yes, that is indeed possible, and that’s the next example I plan on posting (as soon as I get a few moments to finish writing it, that is).
    — Ben

  4. Vegard Bakke Avatar
    Vegard Bakke

    Eeexcellet! I’ll keep a close eye on your blog, then.. 🙂

  5. Ben Forta Avatar
    Ben Forta
  6. Don Kerr Avatar
    Don Kerr

    As usual…Ben…thanks for the help. Spent a long trying to figure out why gc.refresh wouldn’t work! … then you explained why. I appreciate it very much.
    Don

  7. Patrick Whittingham Avatar
    Patrick Whittingham

    Ben –
    I noticed this example is for remoteobject. How does one use do grouping for httpservice? I totally think Flex 3 (datagrid) is awesome with its perfomance (7000+ rows brought back and rendered in 4 – 6 seconds) with httpservice.

  8. Don Kerr Avatar
    Don Kerr

    Patrick, check out how to convert your httpservice result to an ArrayCollection, then feed the ArrayCollection to the ADG GroupingCollection dataProvider.
    seeing passing data section here
    http://livedocs.adobe.com/flex/3/html/help.html?content=dpcontrols_6.html
    import mx.collections.ArrayCollection;
    [Bindable]
    public var myDP:ArrayCollection;

    <mx:GroupingCollection id="gc" source="{myDP}">
    I just don’t have any sample code on converting the httpservice result to an ArrayCollection. XML to XMLllistCollection, yes, but not an ArrayCollection. Sorry.
    Don

  9. Don Kerr Avatar
    Don Kerr

    not sure what you’re bringing back in your service, but here is an example of what I was referring to about reading httpservice data into an arrayCollection
    http://flexonblog.wordpress.com/2007/12/29/read-data-in-to-arraycollection-using-httpservice-result-property/
    forgive me that it is a php service example.:) I only have CF example going to a XMLlistCollection, but it is basically the same thing. (httpservice result to arraycollection to groupingCollection dataProvider ).
    I’m sure Ben has a better example.
    Don

  10. Don Kerr Avatar
    Don Kerr

    I decided to build a quick demo of bringing in xml data via HTTPSERVICE and using it as a dataProvider for
    1) Nested mx:Repeater via XMLListCollection,
    2) AdvancedDataGrid Hierarchy via HierarchicalData (XML hierarchical data)
    3) AdvancedDataGrid Grouping (flat data grouped – could be flat query result from CFC )
    http://www.fusionpage.com/flex/demos/bin/demos.html
    Don

  11. Don Kerr Avatar
    Don Kerr

    The httpservice example in the url of my previous post above, shows both heirarchical and grouping examples using httpservice
    Flex code is below..
    <?xml version="1.0" encoding="utf-8"?>
    <mx:Canvas width="100%" height="100%" creationComplete="initApp()" xmlns:mx="http://www.adobe.com/2006/mxml&quot; xmlns="*">
    <mx:Script>
    <![CDATA[
    import mx.collections.ArrayCollection;
    import mx.core.Application;
    import mx.rpc.events.ResultEvent;
    import mx.rpc.events.FaultEvent;
    import mx.controls.Alert;
    import mx.collections.HierarchicalData;
    [Bindable]
    private var panelLoopTree:ArrayCollection = new ArrayCollection();
    public function initApp(): void {
    srv.send();
    panelsDP.send();
    }
    private function readXML(event:ResultEvent):void
    {
    panelLoopTree=(event.result.myxml.panel);
    gc.refresh();
    }
    public function clicker(selectedLoopbtn:Object):void {
    //do something when button is clicked
    }
    ]]>
    </mx:Script>
    <mx:HTTPService id="srv" url="loops.xml" resultFormat="e4x"/>
    <mx:XMLListCollection id="xc" source="{srv.lastResult.panel}"/>
    <mx:HTTPService id="panelsDP"
    url="flat.xml" useProxy="false"
    showBusyCursor="true" result="readXML(event)"/>
    <mx:VBox width="260" height="95%" horizontalAlign="center" paddingLeft="5" paddingRight="5">
    <mx:Panel width="250" title="XML-httpService-mx:Repeater">
    <mx:Accordion width="230" height="100" id="ACCpanels">
    <mx:Repeater id="panelRepeat" dataProvider="{xc}">
    <mx:Canvas width="100%" height="100%" label="{String(panelRepeat.currentItem.@panelname)}">
    <mx:Tile width="220" paddingLeft="5"
    paddingRight="5" paddingTop="5"
    paddingBottom="5"
    direction="horizontal"
    x="0" y="0"
    tileHeight="20"
    tileWidth="100"
    id="tileLoops">
    <mx:Repeater id="loopRepeat" dataProvider="{panelRepeat.currentItem.loop}">
    <mx:Button
    width="100"
    label="{String(loopRepeat.currentItem.@loopname)}"
    click="clicker(event.currentTarget.getRepeaterItem());"
    >
    </mx:Button>
    </mx:Repeater>
    </mx:Tile>
    </mx:Canvas>
    </mx:Repeater>
    </mx:Accordion>
    </mx:Panel>
    <mx:Panel title="XML-httpService-ADG Hierarchy" width="250">
    <mx:AdvancedDataGrid width="230" height="100" id="adg1"
    dataProvider="{new HierarchicalData(xc)}">
    <mx:columns>
    <mx:AdvancedDataGridColumn headerText="panel" dataField="@panelname"/>
    <mx:AdvancedDataGridColumn headerText="loop" dataField="@loopname"/>
    </mx:columns>
    </mx:AdvancedDataGrid>
    </mx:Panel>
    <mx:Panel width="250" title="XML-httpService-ADG Grouping">
    <mx:AdvancedDataGrid width="230" height="100" initialize="gc.refresh();" id="adg2" >
    <mx:dataProvider>
    <mx:GroupingCollection id="gc" source="{panelLoopTree}">
    <mx:grouping>
    <mx:Grouping>
    <mx:GroupingField name="panelname"/>
    </mx:Grouping>
    </mx:grouping>
    </mx:GroupingCollection>
    </mx:dataProvider>
    <mx:columns>
    <mx:AdvancedDataGridColumn headerText="loop" dataField="loopname"/>
    </mx:columns>
    </mx:AdvancedDataGrid>
    </mx:Panel>
    </mx:VBox>
    </mx:Canvas>

  12. Joe S. Avatar
    Joe S.

    Ok,
    I’ve been having this refresh issue and it’s driving me crazy. I call a webservice on my main flex application page, but I can’t get my container to refresh unless I use a button … please help! The code is below to help anyone else with this issue (I deleted items from the code to make it more readable).
    By the way … Ben I’ve been reading your stuff for years but this is the first time I post.
    Joe S.
    <?xml version="1.0" encoding="utf-8"?>
    <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml&quot;
    xmlns:v="views.dashboard.*"
    layout="horizontal"
    creationComplete="init()">
    <mx:Script>
    <![CDATA[
    import mx.collections.SortField;
    import mx.collections.Sort;
    import mx.collections.ArrayCollection;
    import mx.rpc.events.ResultEvent;
    import mx.rpc.events.FaultEvent;
    [Bindable]
    public var selectedItem:Object;
    [Bindable]
    public var selectedSite:String = "";
    /* [Bindable]
    public var selectedType:String = "Select a Site"; */
    [Bindable]
    public var mselectedType:String = "Select Function";
    [Bindable]
    public var rselectedType:String = "Select Region";
    /* [Bindable]
    private var categories:ArrayCollection=new ArrayCollection(); */
    [Bindable]
    private var mcategories:ArrayCollection=new ArrayCollection();
    [Bindable]
    private var rcategories:ArrayCollection=new ArrayCollection();
    /* private function catHandler(event:ResultEvent):void{
    categories = event.result.catalog.category;
    var catObj:Object = new Object();
    catObj.name = "Select a Site";
    catObj.categoryID = 0;
    categories.addItemAt(catObj, 0);
    catCombo.selectedIndex = 0;
    } */
    private function mcatHandler(event:ResultEvent):void{
    mcategories = event.result.masteroptions.mcategory;
    var mcatObj:Object = new Object();
    mcatObj.mname = "Select Function";
    mcatObj.mcategoryID = 0;
    mcategories.addItemAt(mcatObj, 0);
    mcatCombo.selectedIndex = 0;
    }
    private function rcatHandler(event:ResultEvent):void{
    rcategories = event.result.regionoptions.rcategory;
    var rcatObj:Object = new Object();
    rcatObj.rname = "Select Region";
    rcatObj.rcategoryID = 0;
    rcategories.addItemAt(rcatObj, 0);
    rcatCombo.selectedIndex = 0;
    }
    //SITES
    private function salesRPCResult(event:ResultEvent):void{
    sales.dp = (event.result as ArrayCollection);
    }
    private function activityRPCResult(event:ResultEvent):void{
    activity.dp = (event.result as ArrayCollection);
    }
    private function demandRPCResult(event:ResultEvent):void{
    demand.dp = (event.result as ArrayCollection);
    }
    //SITE ADDITIONAL
    private function bldgIDRPCResult(event:ResultEvent):void{
    bldgID.dp = (event.result as ArrayCollection);
    }
    private function EVPRPCResult(event:ResultEvent):void{
    evpDetails.dp = (event.result as ArrayCollection);
    }
    private function bldgTypeRPCResult(event:ResultEvent):void{
    bldgType.dp = (event.result as ArrayCollection);
    }
    private function bldgRPCResult(event:ResultEvent):void{
    bldg.dp = (event.result as ArrayCollection);
    }
    private function showFault(event:FaultEvent):void{
    trace(event.fault.faultCode+":"+event.fault.faultString);
    }
    private function getFunctionData():void{
    //FUNCTIONAL
    dashboardWS.getFunctionRFTDetails.send();
    dashboardWS.getFunctionHLMCDetails.send();
    dashboardWS.getFunctionHLMCINTLDetails.send();
    }
    private function getRegionData():void{
    //REGIONAL
    dashboardWS.getRegionalUtilization.send();
    dashboardWS.getCapitalSpend.send();
    dashboardWS.getGlobalUtilizationUSINTLChart.send();
    //SUBREGIONAL
    dashboardWS.getSubRegionalUtilization.send();
    dashboardWS.getSubCapitalSpend.send();
    dashboardWS.getSubRegionalUtilizationChart.send();
    dashboardWS.getSubRegionalDemand.send();
    }
    private function getSiteData():void{
    //SITES
    dashboardWS.getSalesData.send();
    dashboardWS.getActivityData.send();
    dashboardWS.getDemandsupplyData.send();
    //SITE ADDITIONAL
    dashboardWS.getBldgIDData.send();
    dashboardWS.getEVPData.send();
    dashboardWS.getBldgTypeData.send();
    dashboardWS.getBldgData.send();
    }
    private function getData():void{
    //GLOBAL
    dashboardWS.getGlobalUtilization.send();
    dashboardWS.getGlobalUtilizationUSChart.send();
    dashboardWS.getGlobalUtilizationINTLChart.send();
    //SUMMARIES
    dashboardWS.getMasterDetails.send();
    dashboardWS.getFunctionDetails.send();
    /* OTHER
    dashboardWS.getMasterUtilization.send();
    dashboardWS.getMasterUtilizationNAMA.send();
    dashboardWS.getMasterUtilizationEU.send();
    dashboardWS.getMasterUtilizationAPLA.send(); */
    }
    private function init():void{
    // startDate.selectedDate = new Date(2006,3,1);
    // endDate.selectedDate = new Date(2006,4,1);
    // catRPC.send();
    mcatRPC.send();
    rcatRPC.send();
    getData();
    }
    private function sortByDateField(aSales:ArrayCollection, colName:String):ArrayCollection{
    var salesData:ArrayCollection = aSales;
    var sort:Sort = new Sort();
    sort.fields = new Array(new SortField(colName,true));
    salesData.sort = sort;
    salesData.refresh();
    return salesData;
    }
    /* private function setCat(event:Event):void{
    selectedType = ComboBox(event.currentTarget).selectedItem.categoryID;
    getData();
    } */
    private function msetCat(event:Event):void{
    mselectedType = ComboBox(event.currentTarget).selectedItem.mcategoryID;
    getFunctionData();
    }
    private function rsetCat(event:Event):void{
    rselectedType = ComboBox(event.currentTarget).selectedItem.rcategoryID;
    getRegionData();
    }
    private function setSite(event:Event):void{
    selectedSite = List(event.currentTarget).selectedItem.data;
    getSiteData();
    }
    ]]>
    </mx:Script>
    <mx:Model id="sitesUS">
    <states>
    <state label="Thousand Oaks" data="USTO"/>
    <state label="San Francisco" data="USSF"/>
    <state label="Fremont" data="USFM"/>
    <state label="Washington; Bothell" data="USWA-BOTHELL"/>
    <state label="Washington; Seattle" data="USWA-SEATTLE"/>
    <state label="Colorado; Boulder" data="USBO-BOULDER"/>
    <state label="Colorado; Longmont" data="USBO-LONGMONT"/>
    <state label="Rhode Island" data="USRI"/>
    <state label="Cambridge, MA" data="USAM"/>
    <state label="Puerto Rico" data="PRJU"/>
    <state label="Canada, Toronto" data="CA"/>
    <state label="Canada, Burnaby" data="CABN"/>
    </states>
    </mx:Model>
    <mx:Model id="sitesEUCEE">
    <states>
    <state label="Austria; CEE" data="ATVI"/>
    <state label="Bulgaria" data=""/>
    <state label="Czech" data="CZPR"/>
    <state label="Hungary" data="HUBU"/>
    <state label="Poland" data="PLWA"/>
    <state label="Romania" data=""/>
    <state label="Slovakia" data="SKPI"/>
    <state label="Slovenia" data="SLLJ"/>
    </states>
    </mx:Model>
    <mx:WebService
    id="dashboardWS"
    wsdl="http://ustositedev.amgen.com/afm/scripts/flex/aggregate.cfc?wsdl&quot;
    fault="showFault(event)">
    <!– SITES –>
    <mx:operation name="getSalesData" result="salesRPCResult(event)">
    <mx:request>
    <!– <startDate>2006,4,1</startDate>
    <endDate>2006,4,1</endDate> –>
    <category>{selectedSite}</category>
    </mx:request>
    </mx:operation>
    <mx:operation name="getActivityData" result="activityRPCResult(event)">
    <mx:request>
    <category>{selectedSite}</category>
    </mx:request>
    </mx:operation>
    <mx:operation name="getDemandsupplyData" result="demandRPCResult(event)">
    <mx:request>
    <category>{selectedSite}</category>
    </mx:request>
    </mx:operation>
    <!– SITE ADDITIONAL –>
    <mx:operation name="getBldgIDData" result="bldgIDRPCResult(event)">
    <mx:request>
    <category>{selectedSite}</category>
    </mx:request>
    </mx:operation>
    <mx:operation name="getEVPData" result="EVPRPCResult(event)">
    <mx:request>
    <category>{selectedSite}</category>
    </mx:request>
    </mx:operation>
    <mx:operation name="getBldgTypeData" result="bldgTypeRPCResult(event)">
    <mx:request>
    <category>{selectedSite}</category>
    </mx:request>
    </mx:operation>
    <mx:operation name="getBldgData" result="bldgRPCResult(event)">
    <mx:request>
    <category>{selectedSite}</category>
    </mx:request>
    </mx:operation>
    </mx:WebService>
    <mx:HTTPService id="mcatRPC"
    url="/afm/db/flex/master_options.xml"
    result="mcatHandler(event)"/>
    <mx:HTTPService id="rcatRPC"
    url="/afm/db/flex/region_options.xml"
    result="rcatHandler(event)"/>
    <mx:ApplicationControlBar dock="true">
    <mx:LinkBar dataProvider="{myNav}" disabledColor="0xffffff" separatorColor="0xffffff" />
    </mx:ApplicationControlBar>
    <mx:ViewStack id="myNav" height="100%" width="100%" creationPolicy="all">
    <mx:VBox id="allBox" label="Sites" width="100%" height="100%">
    <mx:HBox id="SiteContainer" width="100%" height="100%">
    <mx:Accordion id="accordion" borderStyle="solid" dropShadowEnabled="true" color="0x323232" width="15%" height="100%">
    <!– Define each panel using a VBox container. –>
    <mx:VBox label="US/Canada Sites" height="100%" width="100%">
    <mx:List id="sourceUS" width="100%" color="0x0050AA" dataProvider="{sitesUS.state}" height="100%"
    change="this.selectedItem=List(event.target).selectedItem; setSite(event);" />
    </mx:VBox>
    <mx:VBox label="Europe – CEE" height="100%" width="100%">
    <mx:List id="sourceEUCEE" width="100%" color="0x0050AA" dataProvider="{sitesEUCEE.state}" height="100%"
    change="this.selectedItem=List(event.target).selectedItem; setSite(event);" />
    </mx:VBox>
    </mx:Accordion>
    <mx:VBox id="allSiteContainer" width="100%" height="100%">
    <mx:HBox id="siteLinkBox" width="100%">
    <mx:LinkBar dataProvider="{newSiteContainer}" disabledColor="0xffffff" />
    <!–<mx:Spacer width="10"/>
    <mx:Label text="Selected State: {selectedItem.data}"/>–>
    <mx:Spacer width="100%"/>
    <mx:Text maxHeight="30">
    <mx:htmlText>
    <![CDATA[
    <font color="#EE1122"> Utilization > 90% </font> <font color="#ffffff">|</font> <font color="#EE1122"><b>Utilization > 100% </b></font>
    ]]>
    </mx:htmlText>
    </mx:Text>
    </mx:HBox>
    <mx:ViewStack id="newSiteContainer" height="100%" width="100%" creationPolicy="all">
    <mx:VBox id="vboxSiteContainer" label="Utilization and Activity" width="100%" height="100%">
    <v:Utilization id="sales" width="100%" height="100%" title="Utilization"
    maximize="this.currentState=’fullSales’" restore="this.currentState=”"/>
    <mx:HBox id="rightCharts" width="100%" height="100%" >
    <v:Activity id="activity" width="100%" height="100%" title="Site Activity"
    maximize="this.currentState=’fullType’" restore="this.currentState=”"/>
    <v:UtilizationYear id="demand" width="100%" height="100%" title=" Demand vs Capacity"
    maximize="this.currentState=’fullComp’" restore="this.currentState=”"/>
    </mx:HBox>
    </mx:VBox>
    <mx:VBox id="allSecondBox" label="Capacity Details" width="100%" height="100%">
    <v:BuildingDetails id="bldgID" title="Building Capacity Forecast Details" width="100%" height="100%"
    maximize="this.currentState=’fullBldg’" restore="this.currentState=”"/>
    <mx:HBox id="bottomCharts" width="100%" height="100%">
    <v:SiteEVP id="evpDetails" width="100%" height="100%" title="Current Seat Demand by EVP"
    maximize="this.currentState=’fullEVP’" restore="this.currentState=”"/>
    <v:BuildingType id="bldgType" width="100%" height="100%" title="Intended Capacity by Building Type"
    maximize="this.currentState=’fullBldgType’" restore="this.currentState=”"/>
    <v:Building id="bldg" width="100%" height="100%" title="Current Utilization by Building"
    maximize="this.currentState=’fullBldgUtilization’" restore="this.currentState=”"/>
    </mx:HBox>
    </mx:VBox>
    </mx:ViewStack>
    </mx:VBox>
    </mx:HBox>
    </mx:VBox>
    </mx:ViewStack>
    </mx:WindowedApplication>

    — OK THIS IS MY CONTAINER FILE CALLED
    — BuildingDetails.mxml

    <?xml version="1.0" encoding="utf-8"?>
    <v:MaxRestorePanel xmlns:mx="http://www.adobe.com/2006/mxml&quot;
    xmlns:v="views.*"
    layout="vertical">
    <mx:Script>
    <![CDATA[
    import mx.collections.ICollectionView;
    [Bindable]
    public var dp:ICollectionView = null;
    // import mx.collections.ArrayCollection;
    // import mx.collections.GroupingField;
    // import mx.collections.Grouping;
    // import mx.collections.GroupingCollection;
    // Callback function that hightlights in red less than 0
    public function myColStyleFunc0(data:Object,
    col:AdvancedDataGridColumn):Object
    {
    if(data["PREV_YR_ACTUAL"] < 0)
    return {color:0xFF0000};
    return null;
    }
    public function myColStyleFunc1(data:Object,
    col:AdvancedDataGridColumn):Object
    {
    if(data["CUR_YR_1"] < 0)
    return {color:0xFF0000};
    return null;
    }
    public function myColStyleFunc2(data:Object,
    col:AdvancedDataGridColumn):Object
    {
    if(data["CUR_YR_2"] < 0)
    return {color:0xFF0000};
    return null;
    }
    public function myColStyleFunc3(data:Object,
    col:AdvancedDataGridColumn):Object
    {
    if(data["CUR_YR_3"] < 0)
    return {color:0xFF0000};
    return null;
    }
    public function myColStyleFunc4(data:Object,
    col:AdvancedDataGridColumn):Object
    {
    if(data["CUR_YR_4"] < 0)
    return {color:0xFF0000};
    return null;
    }
    public function myColStyleFunc5(data:Object,
    col:AdvancedDataGridColumn):Object
    {
    if(data["CUR_YR_5"] < 0)
    return {color:0xFF0000};
    return null;
    }
    public function myColStyleFunc6(data:Object,
    col:AdvancedDataGridColumn):Object
    {
    if(data["CUR_YR_6"] < 0)
    return {color:0xFF0000};
    return null;
    }
    public function myColStyleFunc7(data:Object,
    col:AdvancedDataGridColumn):Object
    {
    if(data["CUR_YR_7"] < 0)
    return {color:0xFF0000};
    return null;
    }
    public function myColStyleFunc8(data:Object,
    col:AdvancedDataGridColumn):Object
    {
    if(data["CUR_YR_8"] < 0)
    return {color:0xFF0000};
    return null;
    }
    public function myColStyleFunc9(data:Object,
    col:AdvancedDataGridColumn):Object
    {
    if(data["CUR_YR_9"] < 0)
    return {color:0xFF0000};
    return null;
    }
    ]]>
    </mx:Script>
    <mx:NumberFormatter id="nf" useThousandsSeparator="true"/>
    <mx:AdvancedDataGrid creationComplete="myGroup.refresh()" width="100%" height="100%">
    <mx:dataProvider>
    <mx:GroupingCollection id="myGroup" source="{dp}">
    <mx:Grouping>
    <mx:GroupingField name="BL_TYPE">
    <mx:summaries>
    <mx:SummaryRow summaryPlacement="group">
    <mx:fields>
    <mx:SummaryField dataField="PREV_YR_ACTUAL" operation="SUM" />
    <mx:SummaryField dataField="CUR_YR_1" operation="SUM" />
    <mx:SummaryField dataField="CUR_YR_2" operation="SUM" />
    <mx:SummaryField dataField="CUR_YR_3" operation="SUM" />
    <mx:SummaryField dataField="CUR_YR_4" operation="SUM" />
    <mx:SummaryField dataField="CUR_YR_5" operation="SUM" />
    <mx:SummaryField dataField="CUR_YR_6" operation="SUM" />
    <mx:SummaryField dataField="CUR_YR_7" operation="SUM" />
    <mx:SummaryField dataField="CUR_YR_8" operation="SUM" />
    <mx:SummaryField dataField="CUR_YR_9" operation="SUM" />
    </mx:fields>
    </mx:SummaryRow>
    </mx:summaries>
    </mx:GroupingField>
    </mx:Grouping>
    </mx:GroupingCollection>
    </mx:dataProvider>
    <mx:columns>
    <mx:AdvancedDataGridColumn dataField="BL_ID" width="200" headerText="Bldg" editable="false"/>
    <mx:AdvancedDataGridColumn dataField="SUB_TYPE" headerText="Type" width="100" editable="false"/>
    <mx:AdvancedDataGridColumn dataField="PREV_YR_ACTUAL" headerText="2008" width="100" textAlign="right" editable="false" formatter="{nf}" styleFunction="myColStyleFunc0" />
    <mx:AdvancedDataGridColumn dataField="CUR_YR_1" headerText="2009" textAlign="right" width="100" editable="false" formatter="{nf}" styleFunction="myColStyleFunc1" />
    <mx:AdvancedDataGridColumn dataField="CUR_YR_2" headerText="2010" textAlign="right" width="100" editable="false" formatter="{nf}" styleFunction="myColStyleFunc2" />
    <mx:AdvancedDataGridColumn dataField="CUR_YR_3" headerText="2011" textAlign="right" width="100" editable="false" formatter="{nf}" styleFunction="myColStyleFunc3" />
    <mx:AdvancedDataGridColumn dataField="CUR_YR_4" headerText="2012" textAlign="right" width="100" editable="false" formatter="{nf}" styleFunction="myColStyleFunc4" />
    <mx:AdvancedDataGridColumn dataField="CUR_YR_5" headerText="2013" textAlign="right" width="100" editable="false" formatter="{nf}" styleFunction="myColStyleFunc5" />
    <mx:AdvancedDataGridColumn dataField="CUR_YR_6" headerText="2014" textAlign="right" width="100" editable="false" formatter="{nf}" styleFunction="myColStyleFunc6" />
    <mx:AdvancedDataGridColumn dataField="CUR_YR_7" headerText="2015" textAlign="right" width="100" editable="false" formatter="{nf}" styleFunction="myColStyleFunc7" />
    <mx:AdvancedDataGridColumn dataField="CUR_YR_8" headerText="2016" textAlign="right" width="100" editable="false" formatter="{nf}" styleFunction="myColStyleFunc8" />
    <mx:AdvancedDataGridColumn dataField="CUR_YR_9" headerText="2017" textAlign="right" width="100" editable="false" formatter="{nf}" styleFunction="myColStyleFunc9" />
    </mx:columns>
    </mx:AdvancedDataGrid>
    <mx:ControlBar id="controls">
    <mx:Button label="Pull Bldg Details" click="myGroup.refresh()"/>
    </mx:ControlBar>
    </v:MaxRestorePanel>

Leave a Reply