`

Flex 二叉树的实现及思路

    博客分类:
  • FLEX
 
阅读更多

效果图如下:



 

 

1、根据数据源的层级关系构造 树型的数据,并根据层次给每层数据赋于TREE_LEVEL数据

		protected function convertToTree(startData:Object,level:Number=0):void
		{
			if(startData != null)
			{
				level++ ;
				var children:Array = getChildrenNode(startData) ;
				startData.children = children ;
				for each(var data:Object in children)
				{
					convertToTree(data,level) ;
				}
				startData.TREE_LEVEL = level ;
			}
		}

 

2、根据数据,创建对应的节点,并把节点与数据进行绑定

		protected function mapDataToNode(startData:Object,startNode:BinaryTreeNode):void
		{
			if(startData == null || startNode == null)
			{
				return ;
			}
			var dataArray:Array = startData.children ;
			
			if(dataArray.length == 1 )
			{
				var newNode:BinaryTreeNode = createNode(startNode);
				
				newNode.data =  dataArray[0] ;
				startNode.children.itemUpdated(newNode,"data") ;
				mapDataToNode(dataArray[0],newNode) ;
			}
			if(dataArray.length == 2 )
			{
				var leftNode:BinaryTreeNode = createNode(startNode);
				var rightNode:BinaryTreeNode = createNode(startNode);
				
				leftNode.data =  dataArray[0] ;
				rightNode.data =  dataArray[1] ;
				startNode.children.itemUpdated(leftNode,"data") ;
				startNode.children.itemUpdated(rightNode,"data") ;
				mapDataToNode(dataArray[0],leftNode) ;
				mapDataToNode(dataArray[1],rightNode) ;
			}
		}

 3、获取最后一级的节点

		protected function getVirtualLast(last:Array,startNode:BinaryTreeNode):Array
		{
			if(startNode != null)
			{
				if(startNode.children && startNode.children.length == 0)
				{
					startNode.isLeaf = true ;
					last.push(startNode) ;
				}
				for each (var child:BinaryTreeNode in startNode.children)
				{
					getVirtualLast(last,child) ;
				}
			}
			return last ;
		}

 

 4、比较很容易的定位最后一级的位置

    如果是垂直排列,则

       Y坐标为(level - 1) * (VERTICAL_HEIGHT + lastNode.defaultHeight) + TOP_PADDING 

       如果前一个节点为它的兄弟节点,则 X坐标为preNode.vx + BROTHER_GAP + node.defaultWidth ;

                                                         否则X坐标为LEFT_PADDING

					if(_direction == "vertical")
				{
					lastNode.x = LEFT_PADDING ;
					
					lastNode.y = (level - 1) * (VERTICAL_HEIGHT + lastNode.defaultHeight) + TOP_PADDING ;
					for (var i:int=1;i<last.length;i++)
					{
						var node:BinaryTreeNode = last[i] as BinaryTreeNode ;
						var preNode:BinaryTreeNode = last[i-1] as BinaryTreeNode ;
						var nodeParent:BinaryTreeNode = node.superNode ;
						if(nodeParent == null)
						{
							return ;
						}
						if(ArrayUtil.arrayContainsValue(nodeParent.children.toArray(),preNode))
						{
							node.x = preNode.x + BROTHER_GAP + node.defaultWidth ;
						}
						else
						{
							node.x = preNode.x + GAP + node.defaultWidth ;
						}
						node.y = (node.level - 1) *  (VERTICAL_HEIGHT + node.defaultHeight) + TOP_PADDING ;
					}
				}

 

       5、根据最后一层的位置,推算出其他层的位置

       先对最后一层,按level进行排序,先推算最底层的父节点

       如果父节点有两个小孩,则父节点的  X坐标为 parentNode.x = ((parentNode.children[0] as BinaryTreeNode).x + ((parentNode.children[1] as BinaryTreeNode).x)) / 2 ;;

         如果只有一个小孩,则父节点的  X坐标为parentNode.x = childNode.x;

         Y坐标为parentNode.y = childNode.y - childNode.defaultHeight - VERTICAL_HEIGHT ;

					var fixArray:Array = new Array() ;
			fixedArray.sortOn("level", Array.DESCENDING | Array.NUMERIC); 
			if(_direction == "vertical")
			{
				for(var i:int=0;i<fixedArray.length ; i++)
				{
					var childNode:BinaryTreeNode = fixedArray[i] as BinaryTreeNode ;
					var parentNode:BinaryTreeNode = childNode.superNode ;
					
					if(parentNode == null)
					{
						continue; //return ;
					}
					if(parentNode.children.length == 2)
					{
						parentNode.x = ((parentNode.children[0] as BinaryTreeNode).x + ((parentNode.children[1] as BinaryTreeNode).x)) / 2 ;
						//两个孩子 确定一个父,所以他兄弟 不需要再循环了
						i++ ;
					}
					else if(parentNode.children.length == 1)
					{
						parentNode.x = childNode.x;
					}
					parentNode.y = childNode.y - childNode.defaultHeight - VERTICAL_HEIGHT ;
					fixArray.push(parentNode) ;
				}
				if(fixArray.length > 0)
				{
					fixPostion(fixArray) ;
				}
			}

 

6、根据位置设置节点是在左边还是右边

 

			if(_direction == "vertical")
			{
				for each(var n:BinaryTreeNode in children)
				{
					if(n.data)
					{
						if(n.x < node.x)
						{
							n.position = "left" ;
						}
						if(n.x > node.x)
						{
							n.position = "right" ;
						}
						if(n.x == node.x)
						{
							n.position = "direct" ;
						}
						children.itemUpdated(n) ;
						validatePostion(n) ;
					}
				}
			}

 7、锁定线的位置

 

			var children:ArrayCollection = startNode.children ;
			var searchReuslt:Array = ArrayUtil.getItemsByField(children.toArray(),null,"data")  as Array;
			if(searchReuslt && searchReuslt.length == 1)
			{
				var node:BinaryTreeNode = (children[0].data == null ? children[1] : children[0]) as BinaryTreeNode ;
				if(node.line &&_canvas.contains(node.line))
				{
					_canvas.removeChild(node.line) ;
				}
				node.line = new BinaryTreeLine() ;
				if(_direction == "vertical")
				{
					node.line.position = BinaryTreeLine.POSITION_L ;
					node.line.height = VERTICAL_HEIGHT - Locker.LOCKER_HEIGHT ;
					node.line.width = 0 ;
					node.line.x = node.x + node.defaultWidth / 2 ;
					node.line.y = node.y - VERTICAL_HEIGHT + Locker.LOCKER_HEIGHT ;
					node.line.direction = "VERTICAL" ;
					node.direction = "VERTICAL" ;
				}
				else
				{
					node.line.position = BinaryTreeLine.POSITION_D ;
					node.line.width = HORIZONAL_WIDTH - Locker.LOCKER_HEIGHT ;
					node.line.height = 0 ;
					node.line.y = node.y + node.defaultHeight / 2 ;
					node.line.x = node.x - HORIZONAL_WIDTH + Locker.LOCKER_HEIGHT ;
					node.line.direction = "HORIZONAL" ;
					node.direction = "HORIZONAL" ;
				}
				
				if(lineField && lineField != "" && node.data)
				{
					node.line.text = node.data[lineField] ;
				}
				fixLinePosition(node) ;
			}

 

8、根据最大和最小的X  Y值设置 measuredWidth  measuredHeight 以便出现滚动条

并加入到舞台中。

 

			_canvas.x = 0 ;
			_canvas.y = 15 ;
			_canvas.measuredWidth = maxX - minX + startNode.defaultWidth + TOP_PADDING ;
			_canvas.measuredHeight = maxY - minY + startNode.defaultHeight + LEFT_PADDING ;
			_canvas.setActualSize(_canvas.measuredWidth,_canvas.measuredHeight) ;
			
			addChildrenToContainer(startNode) ;
			_canvas.addChild(startNode) ;

 

        

  • 大小: 6.1 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics