I encountered a problem where data will be coming as flat array collection and each record will have ID, name and Id of its parent. We need to create hierarchical array collection to supply to Tree. This was a night mare as I dint find any solution for my problem online :(.
We will be writing class TreeNodeH (Hierarchical Tree Node) and TreeCreator class which can be used as a utility class to create a tree out of flat array collection.
Here my flat array collection was having three fields ZZCUST_VEND (ID),ZZNAME (name),ZZHCUST_VEND(PID) and sample data would be like
var flatArrayCollection:ArrayCollection = new ArrayCollection([
{ZZCUST_VEND:"1", ZZNAME:"A", ZZHCUST_VEND:"0"},
{ZZCUST_VEND:"2", ZZNAME:"B", ZZHCUST_VEND:"0"},
{ZZCUST_VEND:"3", ZZNAME:"C", ZZHCUST_VEND:"0"},
{ZZCUST_VEND:"4", ZZNAME:"D", ZZHCUST_VEND:"0"},
{ZZCUST_VEND:"5", ZZNAME:"A1", ZZHCUST_VEND:"1"},
{ZZCUST_VEND:"6", ZZNAME:"B1", ZZHCUST_VEND:"2"},
{ZZCUST_VEND:"7", ZZNAME:"C1", ZZHCUST_VEND:"3"},
{ZZCUST_VEND:"8", ZZNAME:"A11", ZZHCUST_VEND:"5"},
{ZZCUST_VEND:"9", ZZNAME:"B11", ZZHCUST_VEND:"6"},
{ZZCUST_VEND:"10", ZZNAME:"C11", ZZHCUST_VEND:"7"},
{ZZCUST_VEND:"11", ZZNAME:"D1", ZZHCUST_VEND:"4"},
{ZZCUST_VEND:"12", ZZNAME:"D11", ZZHCUST_VEND:"11"},
{ZZCUST_VEND:"13", ZZNAME:"E", ZZHCUST_VEND:"0"},
{ZZCUST_VEND:"14", ZZNAME:"E1", ZZHCUST_VEND:"13"},
{ZZCUST_VEND:"15", ZZNAME:"C12", ZZHCUST_VEND:"7"},
]);
<---------------------------------TreeNodeH in package components----------------------------------------------------------------->
package components
{
import mx.collections.ArrayCollection;
public class TreeNodeH
{
public var id:String;
public var name:String;
public var pid:String;
public var children:ArrayCollection;
public function addChild(node:TreeNodeH):void
{
if(this.children == null)
{
this.children = new ArrayCollection();
}
children.addItem(node);
}
public function TreeNodeH()
{
}
}
}
<------------------------TreeCreator Class------------------------------>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TREE UTILITY CLASS //
// USED TO CREATES HIERARCHICAL COLLECTION OUT OF FLAT ARRAY COLLECTION WHERE EACH RECORD HAS (ID,NAME,PID). // //
// Akhil Mittal //
// //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package util
{
import mx.collections.ArrayCollection;
public class TreeCreator
{
public function TreeCreator()
{
}
/*
This function is used to insert a child node (childNode) under its parent node (node).
*/
public static function insertchildForNode(node:TreeNodeH, childNode:Object):void
{
if(node.children == null)
node.children = new ArrayCollection();
var newChild:TreeNodeH = new TreeNodeH();
newChild.id = childNode.idTab; //Id for every record in collection is idTab.
newChild.name = childNode.nameTab; //Name for every record is nameTab.
//newChild.parentId and node.id will be same.
newChild.pid = childNode.parentIDTab; //Parent ID will be parentIDTab
node.children.addItem(newChild);
}
/*
This function is used to create a hierarchical collection out of Flat Array collection.
*/
public static function createHierarchicalArrayCollection(flatArrayCollection:ArrayCollection):TreeNodeH
{
//First create a root node, but it wont be shown ultimately.
var top:TreeNodeH = new TreeNodeH();
top.name = "root";
top.id = "0"; //ID for the root will be 0 so that all the nodes with zero PID would be added under this.
top.pid = "-1";
//Now for every node find its parent and add the current node to the parent.
var parentNode:TreeNodeH = new TreeNodeH();
for(var i:int = 0; i<flatArrayCollection.length;i++)
{
var currentRecord:Object = flatArrayCollection.getItemAt(i) as Object;
//Find its proper parent reference
if(currentRecord.parentIDTab == "0")
parentNode = top;
else
parentNode = searchTreeForParentNode(currentRecord.parentIDTab,top);
//If parent is found then add this node to parent.
if(parentNode != null)
insertchildForNode(parentNode,currentRecord);
}
//Top is the root of that created tree.
return top;
}
/*
This function is used to search parent node for the node having PID as parentID. This is classic Breadth First Search
and will start from the top node (rootNode).
*/
public static function searchTreeForParentNode(parentID:String,rootNode:TreeNodeH):TreeNodeH
{
var openList:ArrayCollection = new ArrayCollection();
openList.addItem(rootNode);
var index:int = 0;
while (openList.length != 0)
{
var node:TreeNodeH = openList.getItemAt(index) as TreeNodeH;
if(parentID == node.id)
{
return node;
}
var nodeChildsList:ArrayCollection = node.children;
if(nodeChildsList != null)
{
var nLength:int = nodeChildsList.length;
for(var i:int=0; i<nLength;i++)
{
var currentItem:TreeNodeH = nodeChildsList.getItemAt(i) as TreeNodeH;
openList.addItem(currentItem);
}
}
index++;
}
//Node Not found.
return null;
}
}
}
Application can use this like:
[Bindable]
public var hierarchicalArrayCollection:ArrayCollection = new ArrayCollection();
var rootNode:TreeNodeH = TreeCreator.createHierarchicalArrayCollection(flatArrayCollection);
hierarchicalArrayCollection.addItem(rootNode);
<mx:Tree height="100%" width="100%" showRoot="true" allowMultipleSelection="true"/>
+