Displaying grouped data

Grouped data is flat data that you arrange in a hierarchy for display in the AdvancedDataGrid control. To group your data, you specify one or more data fields that collect the data into the hierarchy.

To populate the AdvancedDataGrid control with grouped data, create an instance of the GroupingCollection2 class from your flat data, and then pass that GroupingCollection2 instance to the data provider of the AdvancedDataGrid control. When you create the instance of the GroupingCollection2 from your flat data, you specify the fields for the data that are used to create the hierarchy.
Note: In the previous release of Flex, you used the GroupingCollection class with the AdvancedDataGrid control. The GroupingCollection2 class is new for Flex 4 and provides better performance than GroupingCollection.

Most of the examples in this section use the following flat data to create an instance of the GroupingCollection2 class:

[Bindable]
private var dpFlat:ArrayCollection = new ArrayCollection([
  {Region:"Southwest", Territory:"Arizona", 
      Territory_Rep:"Barbara Jennings", Actual:38865, Estimate:40000}, 
  {Region:"Southwest", Territory:"Arizona", 
      Territory_Rep:"Dana Binn", Actual:29885, Estimate:30000},  
  {Region:"Southwest", Territory:"Central California", 
      Territory_Rep:"Joe Smith", Actual:29134, Estimate:30000},  
  {Region:"Southwest", Territory:"Nevada", 
      Territory_Rep:"Bethany Pittman", Actual:52888, Estimate:45000},  
  {Region:"Southwest", Territory:"Northern California", 
      Territory_Rep:"Lauren Ipsum", Actual:38805, Estimate:40000}, 
  {Region:"Southwest", Territory:"Northern California", 
      Territory_Rep:"T.R. Smith", Actual:55498, Estimate:40000},  
  {Region:"Southwest", Territory:"Southern California", 
      Territory_Rep:"Alice Treu", Actual:44985, Estimate:45000}, 
  {Region:"Southwest", Territory:"Southern California", 
      Territory_Rep:"Jane Grove", Actual:44913, Estimate:45000}
]);

The following image shows an AdvancedDataGrid control that uses this data as input. This example specifies two fields that are used to group the data: Region and Territory. The first column of the AdvancedDataGrid control is associated with the Region field, so the navigation tree uses the Region field to define the labels for the leaf nodes of the tree.

The following code implements this example:

<?xml version="1.0"?>
<!-- dpcontrols/adg/SimpleGroupADGMXML.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
                  
            include "SimpleFlatData.as"
        ]]>
    </fx:Script>

    <mx:AdvancedDataGrid id="myADG" 
        width="100%" height="100%" 
        initialize="gc.refresh();">        
        <mx:dataProvider>
            <mx:GroupingCollection2 id="gc" source="{dpFlat}">
                <mx:grouping>
                    <mx:Grouping label="Region">
                        <mx:GroupingField name="Region"/>
                        <mx:GroupingField name="Territory"/>
                    </mx:Grouping>
                </mx:grouping>
            </mx:GroupingCollection2>
        </mx:dataProvider>        
        
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="Region"/>
            <mx:AdvancedDataGridColumn dataField="Territory"/>
            <mx:AdvancedDataGridColumn dataField="Territory_Rep"
                headerText="Territory Rep"/>
            <mx:AdvancedDataGridColumn dataField="Actual"/>
            <mx:AdvancedDataGridColumn dataField="Estimate"/>
        </mx:columns>
   </mx:AdvancedDataGrid>
</s:Application>

The executing SWF file for the previous example is shown below:

The GroupingCollection2 instance reformats the data based on these fields so that internally it is represented by the GroupingCollection2 instance, as the following example shows:

[{GroupLabel:"Southwest", children:[
    {GroupLabel:"Arizona", children:[
      {Region:"Southwest", Territory:"Arizona", 
        Territory_Rep:"Barbara Jennings", Actual:38865, Estimate:40000}, 
      {Region:"Southwest", Territory:"Arizona", 
        Territory_Rep:"Dana Binn", Actual:29885, Estimate:30000}]}  
    {GroupLabel:"Central California", children:[
      {Region:"Southwest", Territory:"Central California", 
        Territory_Rep:"Joe Smith", Actual:29134, Estimate:30000}]}
    {GroupLabel:"Nevada", children:[
      {Region:"Southwest", Territory:"Nevada",  
        Territory_Rep:"Bethany Pittman", Actual:52888, Estimate:45000}]}
    {GroupLabel:"Northern California", children:[
      {Region:"Southwest", Territory:"Northern California", 
        Territory_Rep:"Lauren Ipsum", Actual:38805, Estimate:40000}, 
      {Region:"Southwest", Territory:"Northern California", 
        Territory_Rep:"T.R. Smith", Actual:55498, Estimate:40000}]}
    {GroupLabel:"Southern California", children:[
      {Region:"Southwest", Territory:"Southern California", 
        Territory_Rep:"Alice Treu", Actual:44985, Estimate:45000}, 
      {Region:"Southwest", Territory:"Southern California", 
        Territory_Rep:"Jane Grove", Actual:44913, Estimate:45000}]}
]}]

Notice that the representation consists of a data hierarchy based on the Region and Territory fields of the flat data. The GroupingCollection2 instance still contains the original rows of the input flat data, but those rows are now arranged in a hierarchy based on the grouping fields.

Using synchronous or asynchronous refresh with the AdvancedDataGrid control

The GroupingCollection2.refresh() method applies the settings of the GroupingCollection2 class to the data. You must call this method any time you modify the GroupingCollection2 class, such as by setting the grouping, source, or summaries properties of the GroupingCollection2 class. You also call the GroupingCollection2.refresh() method when you modify a GroupingField of the GroupingCollection2 class, such as by changing the caseInsensitive, compareFunction, or groupingFunction properties.

Notice that in the previous example, the AdvancedDataGrid control calls the GroupingCollection2.refresh() method in response to the initialize event of the AdvancedDataGrid control.

The GroupingCollection2.refresh() method has the following signature:
public function refresh(async:Boolean = false, dispatchCollectionEvents:Boolean = false):Boolean

Set the async parameter to false, the default value, for synchronous refresh of the groups and any group summaries. Set it to true for asynchronous refresh.

For synchronous refresh, all groups and summaries are updated together before the method returns. That means your application cannot perform other processing operations for the duration of the call. It also prevents the user from interacting with the control until the refresh completes. Synchronous refresh is optimized for small data sets. Because a synchronous refresh updates all groups and summaries together, it has better performance than an asynchronous refresh. However, for large data sets, users might notice that the application pauses for the duration of the refresh.

In asynchronous refresh, all groups and summaries are updated individually. The refresh() method returns before the groups and summaries are updated so that your application can continue execution. Also, the control is updated during the refresh so that the user can continue to interact with it. For example, in asynchronous refresh, if the displayItemsExpanded property is true, the navigation tree is updated as new groups are created.

The overhead of updating groups and summaries individually, rather than all at once, makes an asynchronous refresh take longer than a synchronous one. However, for large data sets, your application continues to operate during the refresh.

The dispatchCollectionEvents parameter configures the dispatching of events in synchronous mode. If false, the default value, then no events are dispatched during the refresh. This setting provides the best performance for creating groups and summaries. If true, then events are dispatched as groups and summaries are calculated to update the control. However, the navigation tree is not updated as new groups are created.

For an asynchronous refresh, the dispatchCollectionEvents parameter is always set to true.

Using the default MXML property of the GroupingCollection2 class

The grouping property is the default MXML property of the GroupingCollection2 class, so you can rewrite the previous example as follows:

<?xml version="1.0"?>
<!-- dpcontrols/adg/SimpleGroupADGMXMLDefaultProp.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
                  
            include "SimpleFlatData.as"
        ]]>
    </fx:Script>

    <mx:AdvancedDataGrid id="myADG" 
        width="100%" height="100%" 
        initialize="gc.refresh();">        
        <mx:dataProvider> 
            <mx:GroupingCollection2 id="gc" source="{dpFlat}">
                    <mx:Grouping label="Region">
                        <mx:GroupingField name="Region"/>
                        <mx:GroupingField name="Territory"/>
                    </mx:Grouping>
            </mx:GroupingCollection2>
        </mx:dataProvider>        
        
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="Region"/>
            <mx:AdvancedDataGridColumn dataField="Territory"/>
            <mx:AdvancedDataGridColumn dataField="Territory_Rep"
                headerText="Territory Rep"/>
            <mx:AdvancedDataGridColumn dataField="Actual"/>
            <mx:AdvancedDataGridColumn dataField="Estimate"/>
        </mx:columns>
   </mx:AdvancedDataGrid>
</s:Application>

The executing SWF file for the previous example is shown below:

Setting the name of the GroupLabel field

By default, GroupLabel is the field name for the data items added to the flat data to create the hierarchy. For an example of the data structure created by the GroupingCollection2 class that uses the default field name, see Displaying grouped data.

Use the Grouping.label property to specify a different name so that you can create a different group label for each level of the generated hierarchy. You should always set the Grouping.label property for the top level in your hierarchy. That property is required to sort the nodes of the navigation tree.

Creating a column for the GroupLabel field

The AdvancedDataGrid control uses the GroupLabel field to define the labels for the branch nodes of the navigation tree. One option when displaying grouped data is to create a column for the top-level data items that the grouping fields create. For example, you group your flat data by the Region and Territory fields. These fields appear as the labels for the branch nodes of the navigation tree, so you omit separate columns for those fields, as the following example shows:

The following code creates this example. Notice that this example includes an AdvancedDataGridColumn instance for the GroupLabel field, and no column definitions for the Region and Territory fields.

<?xml version="1.0"?>
<!-- dpcontrols/adg/SimpleGroupADGGroupLabelMXML.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
                  
            include "SimpleFlatData.as";
        ]]>
    </fx:Script>

    <mx:AdvancedDataGrid id="myADG" 
        width="100%" height="100%"
        defaultLeafIcon="{null}" 
        initialize="gc.refresh();">        
        <mx:dataProvider>
            <mx:GroupingCollection2 id="gc" source="{dpFlat}">
                <mx:Grouping>
                    <mx:GroupingField name="Region"/>
                    <mx:GroupingField name="Territory"/>
                </mx:Grouping>
            </mx:GroupingCollection2>
        </mx:dataProvider>        
        
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="GroupLabel" 
                headerText="Region/Territory"/>
            <mx:AdvancedDataGridColumn dataField="Territory_Rep"
                headerText="Territory Rep"/>
            <mx:AdvancedDataGridColumn dataField="Actual"/>
            <mx:AdvancedDataGridColumn dataField="Estimate"/>
        </mx:columns>
   </mx:AdvancedDataGrid>
</s:Application>

The executing SWF file for the previous example is shown below:

Creating groups in ActionScript

The example in the previous section created the groups in MXML. However, you could let the user define the grouping at run time. The following example creates the groups in ActionScript by using an event handler:

<?xml version="1.0"?>
<!-- dpcontrols/adg/SimpleGroupADG.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script>
      <![CDATA[   
        import mx.collections.GroupingField;
        import mx.collections.Grouping;
        import mx.collections.GroupingCollection2;
        import mx.collections.ArrayCollection;
                  
        include "SimpleFlatData.as";

        [Bindable]
        public var myGColl:GroupingCollection2 = new GroupingCollection2();
        
        private var myGrp:Grouping = new Grouping();

        private function initDG():void {     

            // Initialize the GroupingCollection2 instance.
            myGColl.source = dpFlat;
                        
            // The Grouping instance defines the grouping fields
            // in the collection, and the order of the groups 
            // in the hierarchy.
            myGrp.fields = 
              [new GroupingField("Region"), new GroupingField("Territory")];
            myGrp.label = "Region";  
            
            // The grouping property contains a Grouping instance.
            myGColl.grouping = myGrp;

            // Specify the GroupedCollection as the data provider for 
            // the AdvancedDataGrid control.
            myADG.dataProvider=myGColl;
            
            // Refresh the display.
            myGColl.refresh();
        }        
      ]]>
    </fx:Script>

    <mx:AdvancedDataGrid id="myADG" 
        width="100%" height="100%" 
        creationComplete="initDG();">
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="Region"/>
            <mx:AdvancedDataGridColumn dataField="Territory"/>
            <mx:AdvancedDataGridColumn dataField="Territory_Rep"
                headerText="Territory Rep"/>
            <mx:AdvancedDataGridColumn dataField="Actual"/>
            <mx:AdvancedDataGridColumn dataField="Estimate"/>
        </mx:columns>
   </mx:AdvancedDataGrid>
</s:Application>

The executing SWF file for the previous example is shown below:

Creating summary rows

Summary data provides a way for you to extract information from your data for display in the AdvancedDataGrid control. For example, you can add summary data that contains the average value of a field across all rows of your data, that contains the maximum field value, the minimum field value, or that contains other types of summaries.

Note: Summary data is not supported for hierarchical data represented by the HierarchicalData class. You can only create summary data for data represented by the GroupingCollection2 class.

You create summary data about your groups by using the summaries property of the GroupingField class. You can display the summary data in an existing row of the AdvancedDataGrid control, or display it in a separate row.

The following example shows an AdvancedDataGrid control that displays two summary fields, Min Actual and Max Actual:

The Min Actual and Max Actual fields in the top row correspond to summaries for all rows in the group, and the Min Actual and Max Actual fields for each Territory correspond to summaries for all rows in the territory subgroup.

The following code creates this control:

<?xml version="1.0"?>
<!-- dpcontrols/adg/SummaryGroupADG.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
                  
            include "SimpleFlatData.as"
      ]]>
    </fx:Script>

    <mx:AdvancedDataGrid id="myADG" 
        width="100%" height="100%" 
        initialize="gc.refresh();">        
        <mx:dataProvider>
            <mx:GroupingCollection2 id="gc" source="{dpFlat}">
                <mx:Grouping label="Region">
                    <mx:GroupingField name="Region">
                        <mx:summaries>
                          <mx:SummaryRow summaryPlacement="group">
                            <mx:fields>
                                <mx:SummaryField2 dataField="Actual" 
                                    label="Min Actual" summaryOperation="MIN"/>
                                <mx:SummaryField2 dataField="Actual" 
                                    label="Max Actual" summaryOperation="MAX"/>
                            </mx:fields>
                          </mx:SummaryRow>
                        </mx:summaries>
                    </mx:GroupingField>
                    <mx:GroupingField name="Territory">
                        <mx:summaries>
                          <mx:SummaryRow summaryPlacement="group">
                            <mx:fields>
                                <mx:SummaryField2 dataField="Actual" 
                                    label="Min Actual" summaryOperation="MIN"/>
                                <mx:SummaryField2 dataField="Actual" 
                                    label="Max Actual" summaryOperation="MAX"/>
                            </mx:fields>
                          </mx:SummaryRow>
                        </mx:summaries>
                    </mx:GroupingField>
                </mx:Grouping>
            </mx:GroupingCollection2>
        </mx:dataProvider>        
        
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="Region"/>
            <mx:AdvancedDataGridColumn dataField="Territory_Rep"
                headerText="Territory Rep"/>
            <mx:AdvancedDataGridColumn dataField="Actual"/>
            <mx:AdvancedDataGridColumn dataField="Estimate"/>
            <mx:AdvancedDataGridColumn dataField="Min Actual"/>
            <mx:AdvancedDataGridColumn dataField="Max Actual"/>
        </mx:columns>
   </mx:AdvancedDataGrid>
</s:Application>

The executing SWF file for the previous example is shown below:

Notice in this example that you use the GroupingField.summaries property to specify the SummaryRow instance. The SummaryRow instance contains all the information about a data summary. In this example, you use the summaryPlacement property to add the summary data to the grouped data. Optionally, you can add new rows to contain the summary data.

Each SummaryRow instance specifies one or more SummaryField2 instances that create the data summary. In this example, you use the dataField property to specify that the summaries are determined by the data in the Actual data field, the label property to specify the name of the data field created to hold the summary data, and the summaryOperation property to specify how to create the summary for numeric fields. You can specify one of the following values: SUM, MIN, MAX, AVG, or COUNT.
Note: In the previous release of Flex, you used the SummaryField class to create summary data. The SummaryField2 class is new for Flex 4 and provides better performance than SummaryField.

Internally, the GroupingCollection2 class represents the grouped data, with the new summary data fields, as the following example shows:

[{GroupLabel:"Southwest", Max Actual:55498, Min Actual:29134, children:[
  {GroupLabel:"Arizona", Max Actual:38865, Min Actual:29885, children:[
    {Region:"Southwest", Territory:"Arizona", 
      Territory_Rep:"Barbara Jennings", Actual:38865, Estimate:40000}, 
    {Region:"Southwest", Territory:"Arizona", 
      Territory_Rep:"Dana Binn", Actual:29885, Estimate:30000}]}  
  {GroupLabel:"Central California", Max Actual:29134, Min Actual:29134, children:[
    {Region:"Southwest", Territory:"Central California", 
      Territory_Rep:"Joe Smith", Actual:29134, Estimate:30000}]}
  {GroupLabel:"Nevada", Max Actual:52888, Min Actual:52888, children:[
    {Region:"Southwest", Territory:"Nevada",  
      Territory_Rep:"Bethany Pittman", Actual:52888, Estimate:45000}]}
  {GroupLabel:"Northern California", Max Actual:55498, Min Actual:38805, children:[
    {Region:"Southwest", Territory:"Northern California", 
      Territory_Rep:"Lauren Ipsum", Actual:38805, Estimate:40000}, 
    {Region:"Southwest", Territory:"Northern California", 
      Territory_Rep:"T.R. Smith", Actual:55498, Estimate:40000}]}
  {GroupLabel:"Southern California", Max Actual:44985, Min Actual:44913, children:[
    {Region:"Southwest", Territory:"Southern California", 
      Territory_Rep:"Alice Treu", Actual:44985, Estimate:45000}, 
    {Region:"Southwest", Territory:"Southern California", 
      Territory_Rep:"Jane Grove", Actual:44913, Estimate:45000}]}
]}]

Using the default properties of the GroupingField and SummaryRow classes

The GroupingField.summaries property is the default property for the GroupingField class, and the SummaryRow.fields property is the default property for the SummaryRow class; therefore, you can omit those properties in your code and rewrite the previous example, as the following example shows:

<?xml version="1.0"?>
<!-- dpcontrols/adg/SummaryGroupADGDefProp.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
                  
            include "SimpleFlatData.as"
      ]]>
    </fx:Script>

    <mx:AdvancedDataGrid id="myADG" 
        width="100%" height="100%" 
        initialize="gc.refresh();">        
        <mx:dataProvider>
            <mx:GroupingCollection2 id="gc" source="{dpFlat}">
                <mx:Grouping label="Region">
                    <mx:GroupingField name="Region">
                          <mx:SummaryRow summaryPlacement="group">
                                <mx:SummaryField2 summaryOperation="MIN" 
                                    dataField="Actual" label="Min Actual"/>
                                <mx:SummaryField2 summaryOperation="MAX" 
                                    dataField="Actual" label="Max Actual"/>
                          </mx:SummaryRow>
                    </mx:GroupingField>
                    <mx:GroupingField name="Territory">
                          <mx:SummaryRow summaryPlacement="group">
                                <mx:SummaryField2 summaryOperation="MIN" 
                                    dataField="Actual" label="Min Actual"/>
                                <mx:SummaryField2 summaryOperation="MAX" 
                                    dataField="Actual" label="Max Actual"/>
                          </mx:SummaryRow>
                    </mx:GroupingField>
                </mx:Grouping>
            </mx:GroupingCollection2>
        </mx:dataProvider>        
        
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="Region"/>
            <mx:AdvancedDataGridColumn dataField="Territory_Rep"
                headerText="Territory Rep"/>
            <mx:AdvancedDataGridColumn dataField="Actual"/>
            <mx:AdvancedDataGridColumn dataField="Estimate"/>
            <mx:AdvancedDataGridColumn dataField="Min Actual"/>
            <mx:AdvancedDataGridColumn dataField="Max Actual"/>
        </mx:columns>
   </mx:AdvancedDataGrid>
</s:Application>

The executing SWF file for the previous example is shown below:

Specifying the display location of the summary data in the AdvancedDataGrid control

The SummaryRow class contains the summaryPlacement property that determines where the summary data appears in the AdvancedDataGrid control. The following table describes the values of the summaryPlacement property:

Value of summaryPlacement property

Description

first

Creates a summary row as the first row in the group.

last

Creates a summary row as the last row in the group.

group

Adds the summary data to the row corresponding to the group.

The previous example named SummaryGroupADG.mxml shows an example of summary data added to the group by specifying group as the value of the summaryPlacement property. The following example shows the same grouped data but with the summaryPlacement property set to last:

You can specify multiple values to the summaryPlacement property, separated by a space; for example, a value of last group specifies to show the summary at the group level and as the last row of the group.

Internally, the GroupingCollection2 represents the grouped data, with the new summary data fields, as the following example shows:

[{GroupLabel:"Southwest", children:[
  {GroupLabel:"Arizona", children:[
    {Region:"Southwest", Territory:"Arizona", 
      Territory_Rep:"Barbara Jennings", Actual:38865, Estimate:40000}, 
    {Region:"Southwest", Territory:"Arizona", 
      Territory_Rep:"Dana Binn", Actual:29885, Estimate:30000},  
    {Max Actual:38865, Min Actual:29885}]}   
  {GroupLabel:"Central California", children:[
    {Region:"Southwest", Territory:"Central California", 
      Territory_Rep:"Joe Smith", Actual:29134, Estimate:30000},
    {Max Actual:29134, Min Actual:29134}]}
  {GroupLabel:"Nevada", children:[
    {Region:"Southwest", Territory:"Nevada",  
      Territory_Rep:"Bethany Pittman", Actual:52888, Estimate:45000},
    {Max Actual:52888, Min Actual:52888}]}
  {GroupLabel:"Northern California", children:[
    {Region:"Southwest", Territory:"Northern California", 
      Territory_Rep:"Lauren Ipsum", Actual:38805, Estimate:40000}, 
    {Region:"Southwest", Territory:"Northern California", 
      Territory_Rep:"T.R. Smith", Actual:55498, Estimate:40000},
    {Max Actual:55498, Min Actual:38805}]}
  {GroupLabel:"Southern California", children:[
    {Region:"Southwest", Territory:"Southern California", 
      Territory_Rep:"Alice Treu", Actual:44985, Estimate:45000}, 
    {Region:"Southwest", Territory:"Southern California", 
      Territory_Rep:"Jane Grove", Actual:44913, Estimate:45000},
    {Max Actual:44985, Min Actual:44913}]}
  {Max Actual:55498, Min Actual:29134}    
]}]

Notice that a new row is added to the entire group to hold the summary data, and a new row is added to each subgroup to hold its summary data.

Creating multiple summaries

You can specify multiple SummaryRow instances in a single GroupingField instance. In the following example, you create summary data to define the following fields: Min Actual, Max Actual, Min Estimate, and Max Estimate for the Region group.

<?xml version="1.0"?>
<!-- dpcontrols/adg/SummaryGroupADGMultipleSummaries.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
                  
            include "SimpleFlatData.as"
      ]]>
    </fx:Script>

    <mx:AdvancedDataGrid id="myADG" 
        width="100%" height="100%" 
        initialize="gc.refresh();">        
        <mx:dataProvider>
            <mx:GroupingCollection2 id="gc" source="{dpFlat}">
                <mx:Grouping label="Region">
                    <mx:GroupingField name="Region">
                          <mx:SummaryRow summaryPlacement="group">
                                <mx:SummaryField2 summaryOperation="MIN" 
                                   dataField="Actual" label="Min Actual"/>
                                <mx:SummaryField2 summaryOperation="MAX" 
                                   dataField="Actual" label="Max Actual"/>
                          </mx:SummaryRow>
                          <mx:SummaryRow summaryPlacement="group">
                                <mx:SummaryField2 summaryOperation="MIN" 
                                   dataField="Estimate" label="Min Estimate"/>
                                <mx:SummaryField2 summaryOperation="MAX" 
                                   dataField="Estimate" label="Max Estimate"/>
                          </mx:SummaryRow>
                    </mx:GroupingField>
                    <mx:GroupingField name="Territory"/>
                </mx:Grouping>
            </mx:GroupingCollection2>
        </mx:dataProvider>        
        
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="Region"/>
            <mx:AdvancedDataGridColumn dataField="Territory_Rep"
                headerText="Territory Rep"/>
            <mx:AdvancedDataGridColumn dataField="Actual"/>
            <mx:AdvancedDataGridColumn dataField="Estimate"/>
            <mx:AdvancedDataGridColumn dataField="Min Actual"/>
            <mx:AdvancedDataGridColumn dataField="Max Actual"/>
            <mx:AdvancedDataGridColumn dataField="Min Estimate"/>
            <mx:AdvancedDataGridColumn dataField="Max Estimate"/>
        </mx:columns>
   </mx:AdvancedDataGrid>
</s:Application>

The executing SWF file for the previous example is shown below:

Creating a custom summary function

Use the SummaryRow.summaryObjectFunction property and the SummaryField2.summaryOperation property to add custom summary logic to your application. Your custom summary can perform many types of actions, but the result of the summary calculation must be of type Number.

The SummaryRow.summaryObjectFunction property defines a callback function that defines an instance of the SummaryObject class that collects the summary data. The AdvancedDataGrid control adds the SummaryObject instance to the data provider to display the summary data in the control. Therefore, you define within the SummaryObject instance the properties to display. In the following example, the callback function adds a property named Territory_Rep. This field appears in the Territory Rep column of the control for the summary row.

The SummaryField2.summaryOperation property takes an object that implements the mx.collections.ISummaryCalculator interface. That interface defines the following groups of methods:
  • Implement the summaryCalculationBegin(), calculateSummary(), and returnSummary() methods to compute a summary of the values.

  • Implement the summaryOfSummaryCalculationBegin(), calculateSummaryOfSummary(), and returnSummaryOfSummary() methods to compute a summary of summary values.

The following definition for the class MySummaryCalculator implements the ISummaryCalculator interface to create a class to summarize a field in every other row of a group:
package myComponents
{
    // dpcontrols/adg/myComponents/MySummaryCalculator.as
    import mx.collections.ISummaryCalculator;
    import mx.collections.SummaryField2;
    
    public class MySummaryCalculator implements ISummaryCalculator
    {
        public function MySummaryCalculator() {
        }
        
        // Define the summary object.
        protected var summObj:Object = new Object();
        // Define a var to hold the record count.
        protected var count:int;
        
        public function summaryCalculationBegin(field:SummaryField2):Object {
            // Initialize the variables.
            summObj.oddCount = 0;
            count = 1;
            return summObj;
        }
        
        public function calculateSummary(data:Object, field:SummaryField2, rowData:Object):void {
            // Only add the current value for every other row.
            if (count % 2 != 0)
            {                
                summObj.oddCount = summObj.oddCount + rowData[field.dataField];
            }
            count++;
        }
        
        public function returnSummary(data:Object, field:SummaryField2):Number {
            // Return the summary value.
            return summObj.oddCount;
        }
        
        // Implement these methods if you are creating a summary of summaries.
        public function summaryOfSummaryCalculationBegin(value:Object, field:SummaryField2):Object {
            return null;
        }
        
        public function calculateSummaryOfSummary(value:Object, newValue:Object, field:SummaryField2):void {
        }
        
        public function returnSummaryOfSummary(value:Object, field:SummaryField2):Number {
            return 0;
        }
    }
}

Notice that this class implements the summaryOfSummaryCalculationBegin(), calculateSummaryOfSummary(), and returnSummaryOfSummary() methods but leaves the implementation empty.

The following example implements callback functions for the summaryObjectFunction and use the MySummaryCalculator class to calculate a summary of the actual sales revenue for every other row of each territory:

<?xml version="1.0"?>
<!-- dpcontrols/adg/SummaryGroupADGCustomSummary.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <fx:Script>
        <![CDATA[
            import mx.collections.IViewCursor;
            import mx.collections.SummaryObject;
            import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
            import mx.collections.ArrayCollection;
            
            import myComponents.MySummaryCalculator;
                  
            include "SimpleFlatData.as" 
        
            // Callback function to create 
            // the SummaryObject used to hold the summary data.
            private function summObjFunc():SummaryObject {
            
                // Define the object containing the summary data.
                var obj:SummaryObject = new SummaryObject();
                // Add a field containing a value for the Territory_Rep column.
                obj.Territory_Rep = "Alternating Reps";
                
                return obj;
            }            
      ]]>
    </fx:Script>

    <mx:AdvancedDataGrid id="myADG" 
        width="100%" height="100%" 
        initialize="gc.refresh();">        
        <mx:dataProvider>
            <mx:GroupingCollection2 id="gc" source="{dpFlat}">
                <mx:Grouping label="Region">
                   <mx:GroupingField name="Region"/>
                   <mx:GroupingField name="Territory">
                      <mx:summaries>
                         <mx:SummaryRow summaryObjectFunction="summObjFunc" 
                            summaryPlacement="first">
                            <mx:fields>
                               <mx:SummaryField2 dataField="Actual" 
                                    summaryOperation="{new myComponents.MySummaryCalculator()}"/>
                            </mx:fields>
                         </mx:SummaryRow>
                      </mx:summaries>
                   </mx:GroupingField>
                </mx:Grouping>
            </mx:GroupingCollection2>
        </mx:dataProvider>        
        
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="Region"/>
            <mx:AdvancedDataGridColumn dataField="Territory_Rep"
                headerText="Territory Rep"/>
            <mx:AdvancedDataGridColumn dataField="Actual"/>
            <mx:AdvancedDataGridColumn dataField="Estimate"/>
        </mx:columns>
   </mx:AdvancedDataGrid>
</s:Application>

The executing SWF file for the previous example is shown below: