[img]http://nealmi.iteye.com/upload/attachment/42222/0ec77e93-a323-3366-94e4-d71d22d3078c.jpg[/img]
iLog有個很不錯的,可是收錢,799美刀。你可以看這裏[url]http://visudemos.ilog.com/webdemos/orgchart/orgchart.html[/url]。
俺農村來的,比較窮,最終還是自己“創造”了一個。
其實算法還是很就簡單地,核心就是遞歸算法。
我寫的那個是隻能接受XML的。
核心代碼:
/**
* create nodes,
* calculate depth.
* */
private function _createSubNodes(data:ICollectionView, parentNode:IOrgChartNode):void{
for(var cursor:IViewCursor = data.createCursor(); !cursor.afterLast; cursor.moveNext()){
var node:IOrgChartNode = _createNode(cursor.current, parentNode);
if(_treeDataDesciptor.isBranch(cursor.current, data)
&& _treeDataDesciptor.getChildren(cursor.current, data).length != 0){
var __tmp:ICollectionView = _treeDataDesciptor.getChildren(cursor.current, data);
_createSubNodes(__tmp, node);
}
}
}
private var _maxX:Number=0;
/**
* Wrap data with IOrgChartNode
* */
private function _createNode(data:Object, parentNode:IOrgChartNode):IOrgChartNode{
var node:IOrgChartNode = new DefaultOrgChartNode();
node.addEventListener(MouseEvent.CLICK, nodeClick);
node.addEventListener(MouseEvent.MOUSE_OVER, nodeMouseOver);
node.addEventListener(MouseEvent.ROLL_OVER, nodeRollOver);
node.addEventListener(MouseEvent.MOUSE_OUT, nodeMouseOut);
node.parentNode = parentNode;
node.data = data;
node.width = hItemWidth;
node.height = hItemHeight;
//起始時,根節點在最左邊
if(parentNode == null){
node.x = 0;
node.y = 0;
//_maxX = node.width + _horizonalSpacing;
}else{
if(node.previousSibling == null){
//與父節點在同一中軸線上
//trace(node);
node.x = parentNode.x + (parentNode.width - node.width)/2;
_maxX = node.x + node.width;
}else{
node.x = _maxX + _horizonalSpacing;
_maxX = node.x + node.width;
}
//移動父節點
updateParentNodePosition(node.parentNode );
node.y = parentNode.y + parentNode.height + _verticalSpacing;
}
_nodes.addItem(node);
return node;
}
/**
* 遞歸移動所有父節點的位置。
* */
private function updateParentNodePosition(node:IOrgChartNode):void{
if(node != null){
var subs:ArrayCollection = node.subNodes;
var lastChild:IOrgChartNode = subs.getItemAt(subs.length - 1 ) as IOrgChartNode;
var firstChild:IOrgChartNode = subs.getItemAt(0) as IOrgChartNode;
node.x = firstChild.x + ( lastChild.x - firstChild.x + lastChild.width - node.width) / 2;
//遞歸更新直到根節點
updateParentNodePosition(node.parentNode);
}
}
基本就是一個遞歸右移父節點的算法。
然後把所有的節點統一的Render就OK了。