http://livedocs.adobe.com/flex/3/html/help.html?content=advdatagrid_06.html
Adobe Flex 3 Help
Hierarchical and grouped data display
The
Hierarchical data
The following code shows hierarchical data in the SimpleHierarchicalData.as file:
[Bindable] private var dpHierarchy:ArrayCollection = new ArrayCollection([ {Region:"Southwest", children: [ {Region:"Arizona", children: [ {Territory_Rep:"Barbara Jennings", Actual:38865, Estimate:40000}, {Territory_Rep:"Dana Binn", Actual:29885, Estimate:30000}]}, {Region:"Central California", children: [ {Territory_Rep:"Joe Smith", Actual:29134, Estimate:30000}]}, {Region:"Nevada", children: [ {Territory_Rep:"Bethany Pittman", Actual:52888, Estimate:45000}]}, {Region:"Northern California", children: [ {Territory_Rep:"Lauren Ipsum", Actual:38805, Estimate:40000}, {Territory_Rep:"T.R. Smith", Actual:55498, Estimate:40000}]}, {Region:"Southern California", children: [ {Territory_Rep:"Alice Treu", Actual:44985, Estimate:45000}, {Territory_Rep:"Jane Grove", Actual:44913, Estimate:45000}]} ]} ]);
Notice that the data contains a top-level object that contains a Region field and multiple second-level children. Each second-level child also contains a Region field and one or more additional children. The following example shows the AdvancedDataGrid control displaying this data:
The code for this example is in the section
To display flat data as a hierarchy, you group the rows of the flat data before passing the data to the
AdvancedDataGrid control. The following code contains a variation on the hierarchical data shown in the previous image, but arranges the data in a flat data structure:
[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} ]);
In this example, the data contains a single level of individual records with no inherent hierarchy. To group the data, you specify one or more data fields used to arrange the data in a hierarchy. The following example shows the AdvancedDataGrid control where the flat data has been grouped by the Region field of the data:
The code for this example is in the section
Setting the data provider with hierarchical data
To configure the
For more information on displaying hierarchical data, see
You can create an instance of the HierarchicalData class or an instance of the GroupingCollection class from any data that you can use as a data provider. However, the AdvancedDataGrid control modifies its internal representation of the data as follows:
- An Array is represented internally by the AdvancedDataGrid control as an instance of the
ArrayCollection class. - An ArrayCollection class is represented internally by the AdvancedDataGrid control as an instance of the ArrayCollection class.
- A String that contains valid XML text is represented internally by the AdvancedDataGrid control as an instance of the
XMLListCollection class. - An
XMLNode class or an XMLList class is represented internally by the AdvancedDataGrid control as an instance of the XMLListCollection class. - Any object that implements the
ICollectionView interface is represented internally by the AdvancedDataGrid control as an instance of the ICollectionView interface. - An object of any other data type is wrapped in an Array instance with the object as its sole entry.
For example, you use an Array to create an instance of the HierarchicalData class, and then pass that
HierarchicalData instance to the
Calling validateNow() after setting the data provider
In some situations, you may set the data provider of the AdvancedDataGrid control to hierarchical or grouped data, and then immediately try to perform an action based on the new data provider. This typically occurs when you set the
adg.dataProvider = groupedCollection; adg.expandAll();
In this example, the call to
In this situation, you must insert the
adg.dataProvider = groupedCollection; adg.validateNow(); adg.expandAll();
Do not insert the
Controlling the navigation tree of the AdvancedDataGrid control
The
In the following example, you populate the AdvancedDataGrid control with the hierarchal data structure shown in
The AdvancedDataGrid control in this example defines four columns to display the data: Region, Territory Rep, Actual, and Estimate.
<?xml version="1.0"?> <!-- dpcontrols/adg/SimpleHierarchicalADG.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; include "SimpleHierarchicalData.as"; ]]> </mx:Script> <mx:AdvancedDataGrid width="100%" height="100%"> <mx:dataProvider> <mx:HierarchicalData source="{dpHierarchy}"/> </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> </mx:Application>
The executing SWF file for the previous example is shown below:
The following image shows the AdvancedDataGrid control created by this example. The control displays a folder icon to represent branch nodes of the tree, and a file icon to represent leaf nodes. The first column of the control is associated with the Region field of the data provider, so the tree labels display the value of the Region field.
Notice that the leaf icon for the tree does not show a label. This is because the individual records for each territory representative do not contain a Region field.
While the tree is often positioned in the left-most column of the control, you can use the
<?xml version="1.0"?> <!-- dpcontrols/adg/HierarchicalADGCategoriesTreeColumn.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; include "HierarchicalDataCategori es.as"; ]]> </mx:Script> <mx:AdvancedDataGrid width="100%" height="100%" treeColumn="{rep}"> <mx:dataProvider> <mx:HierarchicalData source="{dpHierarchy}" childrenField="categories"/> </mx:dataProvider> <mx:columns> <mx:AdvancedDataGridColumn dataField="Region"/> <mx:AdvancedDataGridColumn id="rep" dataField="Territory_Rep" headerText="Territory Rep"/> <mx:AdvancedDataGridColumn dataField="Actual"/> <mx:AdvancedDataGridColumn dataField="Estimate"/> </mx:columns> </mx:AdvancedDataGrid> </mx:Application>
The executing SWF file for the previous example is shown below:
Setting navigation tree icons and labels
The navigation tree lets you control the icons and labels used for the branch and leaf nodes. For example, you can display a tree of labels with no icons, a tree with just folder icons, a tree with no labels at all, or a tree in its own column that is not associated with any data field.
The following table describes the style properties of the
Style property | Description |
---|---|
defaultLeafIcon | Specifies the leaf icon. |
disclosureClosedIcon | Specifies the icon that is displayed next to a closed branch node. The default icon is a black triangle. |
disclosureOpenIcon | Specifies the icon that is displayed next to an open branch node. The default icon is a black triangle. |
folderClosedIcon | Specifies the folder closed icon for a branch node. |
folderOpenIcon | Specifies the folder open icon for a branch node. |
The following example sets the default leaf icon to null to hide it, and uses custom icons for the folder open and closed icons:
<?xml version="1.0"?> <!-- dpcontrols/adg/SimpleHierarchicalADGTreeIcons.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; include "SimpleHierarchicalData.as"; ]]> </mx:Script> <mx:AdvancedDataGrid width="100%" height="100%" defaultLeafIcon="{null}" folderOpenIcon="@Embed(source='assets/folderOpenIcon.jpg')" folderClosedIcon="@Embed(source='assets/folderClosedIcon.jpg')"> <mx:dataProvider> <mx:HierarchicalData source="{dpHierarchy}"/> </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> </mx:Application>
The executing SWF file for the previous example is shown below:
You can also specify the styles by using the
<mx:Style> AdvancedDataGrid { defaultLeafIcon:ClassReference(null); folderOpenIcon:Embed(source='assets/folderOpenIcon.jpg'); folderClosedIcon:Embed(source='assets/folderClosedIcon.jpg'); } </mx:Style>
Using the groupIconFunction and groupLabelFunction properties
Use the
The following example uses the
<?xml version="1.0"?> <!-- dpcontrols/adg/SimpleHierarchicalADGGroupIcon.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; include "SimpleHierarchicalData.as"; // Embed the icon for the groups. [Bindable] [Embed(source="assets/topTreeIcon.png")] public var icn:Class; // Define the groupIconFunction callback function. public function myIconFunc(item:Object, depth:int):Class { if(depth == 1) // If this is the top-level of the tree, return the icon. return icn; else // If this is any other level, return null. return null; } ]]> </mx:Script> <mx:AdvancedDataGrid width="100%" height="100%" groupIconFunction="myIconFunc"> <mx:dataProvider> <mx:HierarchicalData source="{dpHierarchy}"/> </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> </mx:Application>
The executing SWF file for the previous example is shown below:
Creating a separate column for the navigation tree
In the examples in
You can also put the navigation tree in its own column, where the column is not associated with a data field, as the following example shows:
This example does not associate a data field with the column that contains the tree, so the tree icons appear with no label. This example also sets the
The following code implements this example. Notice that the first column is not associated with a data field. Because it is the first column in the data grid, the AdvancedDataGrid control automatically uses it to display the navigation tree.
<?xml version="1.0"?> <!-- dpcontrols/adg/SimpleHierarchicalADGTreeColumn.mxml --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; include "SimpleHierarchicalData.as"; ]]> </mx:Script> <mx:AdvancedDataGrid width="100%" height="100%" folderClosedIcon="{null}" folderOpenIcon="{null}" defaultLeafIcon="{null}"> <mx:dataProvider> <mx:HierarchicalData source="{dpHierarchy}"/> </mx:dataProvider> <mx:columns> <mx:AdvancedDataGridColumn headerText="" width="50"/> <mx:AdvancedDataGridColumn dataField="Region"/> <mx:AdvancedDataGridColumn dataField="Territory_Rep" headerText="Territory Rep"/> <mx:AdvancedDataGridColumn dataField="Actual"/> <mx:AdvancedDataGridColumn dataField="Estimate"/> </mx:columns> </mx:AdvancedDataGrid> </mx:Application>
The executing SWF file for the previous example is shown below:
Comments (8)
-
smgilson wrote:
You can get the source collection/object by -
// get the HierarchicalData used to create the HierarchicalCollection
var hd:IHierarchicalData = IHierarchicalCollectionView(adg.dataProvider).source;
//From the HierarchicalData, get the source collection/object var source:Object = hd.getRoot();
Stephen Gilson
Flex Doc Team
--------------------------------------------------------------------------------
Pigg Man wrote:
I have noticed that in the help in the section "Setting the data provider with hierarchical data Setting the data provider with hierarchical data" -> in the last sentence it says "If you read the data back from the AdvancedDataGrid.dataProvider property, it is returned as an ArrayCollection instance.". If you do XMLListCollection(MyAdvancedDatagrid.dataProvider) or ArrayCollection(MyAdvancedDatagrid.dataProvider) that this will throw an error because it's of type HierarchicalCollectionView or GroupCollection. Would be nice if there was a way to get the collection from the dataProvider without having to create a cursor and such..
If I do MyAdvancedDataGrid.dataProvider = new HierarchicalData(MyXMLListCollection;
How would I get that same xmllistcollection back by using MyAdvancedDataGrid.dataProvider ... A work around is to keep a copy of the xmllistcollection and use that... but if you do this code MyAdvancedDataGrid.dataProvider = new HierarchicalData(MyXMLListCollection.copy()); you can't because the collections are different from each other because your creating a copy of it.
--------------------------------------------------------------------------------
wrkoch wrote:
Please note that when using grouping, you must refresh the grid manually when the data provider is changed. It is reason you have to do
initialize=xx.refresh() in the first place.
From Adobe Support:
The groupings is somewhat computationally intensive. The engineers
didn't want every single change to the data to cause a grouping
recalculation so they force you to do tell the data to refresh itself.
You need to run the refresh() method if you change a collection's sort
or filter as well.
-
for an example of exactly how to format these help sections take a look at:
http://www.flex-blog.com/drag-and-drop-from-datagrid-or-advanceddatagrid-to-tree/
Adobe would be well served if it followed this format.
-
Here is an actual advanceddatagrid sample that works.
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" initialize="init()"
xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768" viewSourceURL="srcview/index.html">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.DataGrid;
import mx.events.DragEvent;
import mx.managers.DragManager;
[Bindable]
private var collection1:ArrayCollection;
[Bindable]
private var collection2:XML = <node name="Root">
<node name="Node One">
<item name="Item One"/>
<item name="Item Two"/>
</node>
<node name="Node Two">
<item name="Item Three"/>
</node>
</node>;
private function init():void
{
var obj:Object;
collection1 = new ArrayCollection();
obj = new Object();
obj.name = "Item Four";
collection1.addItem(obj);
obj = new Object();
obj.name = "Item Five";
collection1.addItem(obj);
obj = new Object();
obj.name = "Item Six";
collection1.addItem(obj);
obj = new Object();
obj.name = "Item Seven";
collection1.addItem(obj);
obj = new Object();
obj.name = "Item Eight";
collection1.addItem(obj);
// open all items in Tree control
this.validateNow();
tree.expandChildrenOf(collection2, true);
}
private function doDragDrop(event:DragEvent):void
{
var item:XML;
// cancel default
event.preventDefault();
// get the drag format (its always items in our case
// when you are dragging FROM a Tree its treeItems
var draggedFormat:String = event.dragSource.formats[0];
// Get the dragged items
var draggedItems:Array = event.dragSource.dataForFormat(draggedFormat) as Array;
// Calculate the index in the Tree where the items were dropped
var dropIndex:int = tree.calculateDropIndex(event);
// Set the selected index of the Tree to the dropIndex
tree.selectedIndex = dropIndex;
// Check if we are dropping on a node
// Add each dragged item to the Tree by apppending it
// as a child of the selected node in the Tree.
for each( var object:Object in draggedItems )
{
// create item
item = <item></item>;
// set the name
item.@name = object.name;
// use appendChild to add the item.
// (if selected item is an item then append to parent)
if( (tree.selectedItem as XML).name() == "node")
{
(tree.selectedItem as XML).appendChild(item);
}
else{
(tree.selectedItem as XML).parent().appendChild(item);
}
}
}
private function doDragEnter(event:DragEvent):void
{
// Cancel default behaviour
event.preventDefault();
// Tell the DragManager that the Tree will accent the DragDrop
DragManager.acceptDragDrop( Tree(event.target) );
// hide the "drop line" that is shown in Tree control
// when dropping in a Tree
tree.showDropFeedback(event);
}
private function doDragOver(event:DragEvent):void
{
// Show the default "drop line" in the Tree control
tree.showDropFeedback(event);
// Cancel default behavious
event.preventDefault();
}
private function doDragExit(event:DragEvent):void
{
// hide the "drop line" that is shown in Tree control
// when dropping in a Tree
tree.hideDropFeedback(event);
}
private function doDragComplete(event:DragEvent):void
{
// hide the "drop line" that is shown in Tree control
// when dropping in a Tree
tree.hideDropFeedback(event);
}
]]>
</fx:Script>
<s:HGroup width="400" height="250" paddingLeft="5" paddingTop="5">
<mx:DataGrid dragComplete="doDragComplete(event)"
id="grid" width="50%" height="100%"
dataProvider="{collection1}" dragEnabled="true"
dragMoveEnabled="true">
<mx:columns>
<mx:DataGridColumn headerText="Name" dataField="name"/>
</mx:columns>
</mx:DataGrid>
<mx:Tree id="tree" width="50%" height="100%"
dataProvider="{collection2}"
dropEnabled="true"
labelField="@name"
dragOver="doDragOver(event)"
dragDrop="doDragDrop(event)"
dragEnter="doDragEnter(event)"
dragExit="doDragExit(event)"/>
</s:HGroup>
</s:Application> -
"n this example, the data contains a single level of individual records with no inherent hierarchy. To group the data, you specify one or more data fields used to arrange the data in a hierarchy. The following example shows the AdvancedDataGrid control where the flat data has been grouped by the Region field of the data"
There is no example of code showing flat data{dpFlat} in a hierarchical manner...and I have no idea what the above sentence means. Can you provide an example ? -
@anang1976 ...
Just below that sentence is a figure, then a paragraph with a link to the example. You can see the example here:
http://livedocs.adobe.com/flex/3/html/advdatagrid_08.html#230324
Stephen -
I have tried using the defaultLeafIcon to set a custom icon and find that the icon itself doesn't seem to get mouse events.
Specifically, it cannot be used to drag an item, nor can it be the drop target. I have tried using the exact same icon in a plain old Tree control and it works just fine. Is this a bug in the ADG and/or what can one do to work around this? It is very confusing to end users that they cannot use the icon to drag since the icon of an item is more intuitive to grab than the label of the item. -
@SPGAnne ...
Can you please file a bug for this issue athttp://bugs.adobe.com/jira
Stephen -
Nice , I have doubt reagrding grouping .To group the data, you specify one or more data fields used to arrange the data in a hierarchy.Label name should display based on groupingfield name .Is it possible to change that
name like display "All Region" instead of "Region".
Moderator note: this type of issue can be answered more effectively in the user-to-user forums athttp://forums.adobe.com - You need to
sign in in order to post a comment.