要实现的结果图大概如下:
            董事长
               |
            总经理
       ————————
       |               |
     副总经理1       副总经理2
……一直下去。
感觉就是一棵树,问题是怎么像这样显示,我就想不出好的办法,所以自己造了个车轮,代码在后面:现在要在每个项那支持增删查改,右键菜单怎么弄?
如果实在没能用右键菜单,那怎么才能知道用户当前选的是那个??   var FRAME_WIDTH = 800;//窗口的宽
var FRAME_HEIGHT = 600;//窗口的高
var NODE_ZX_DISTANCE = 40;//上下级节点间的高度
var NODE_WIDTH = 130;//节点的宽
var NODE_HEIGHT = 28;//节点的高
var LINE_WIDTH = 20;//线节点的宽
var LINE_HEIGHT = 20;//线节点的高
//--------------------------------------------------------------------
//画子节点
//参数:dep为当前节点,item为要填充数据的数组,xx为当前节点的横坐标,yy为当前节点的纵坐标
  function addChild(dep, item, xx, yy){
item[item.length] = {
x : xx
, y : yy
, width : NODE_WIDTH
, height : NODE_HEIGHT
, title :dep.name
};
};
//--------------------------------------------------------------------
//画横线
//参数:dep为当前节点,item为要填充数据的数组,xx为当前节点的横坐标,yy为当前节点的纵坐标,area为当前节点的"活动范围"
function drawStriping(dep, item, xx, yy, area){
var start = xx+NODE_WIDTH/2-area/2;
var startImage = start + area/(2*dep.child.length)+LINE_WIDTH;
var endImage = start + area/(2*dep.child.length)*(2*dep.child.length-1)-LINE_WIDTH;

//添加左边开始端的转角
item[item.length] = {
x : startImage-LINE_WIDTH
, y : yy+NODE_ZX_DISTANCE + NODE_HEIGHT-LINE_HEIGHT
, width : 20
, height : 20
, bodyStyle : 'background-image: url(lineEndLeft.gif);border: 0 none'
};

//添加右边结束端的转角
item[item.length] = {
x : endImage
, y : yy+NODE_ZX_DISTANCE + NODE_HEIGHT-LINE_HEIGHT
, width : 20
, height : 20
, bodyStyle : 'background-image: url(lineEndRight.gif);border: 0 none'
};

//普通直线
for(var st=startImage; st < endImage; st+=LINE_WIDTH){
item[item.length] = {
x : st
, y : yy+NODE_ZX_DISTANCE + NODE_HEIGHT-LINE_HEIGHT
, width : 20
, height : 20
, bodyStyle : 'background-image: url(Striping.gif);border: 0 none'
};
}

//画中间的交叉节点
item[item.length] = {
x : start + area/2 - LINE_WIDTH/2
, y : yy+NODE_ZX_DISTANCE + NODE_HEIGHT-LINE_HEIGHT
, width : 20
, height : 20
, bodyStyle : 'background-image: url(cross.gif);border: 0 none;opacity=0'
};
};

//--------------------------------------------------------------------
//画竖线
//参数:dep为当前节点,item为要填充数据的数组,xx为当前节点的横坐标,yy为当前节点的纵坐标
function drawVerticalLine(dep, item, xx, yy){
var sx = xx + NODE_WIDTH/2 - LINE_WIDTH/2;
var sy = yy + NODE_HEIGHT;
var ey = yy + NODE_ZX_DISTANCE + NODE_HEIGHT;
for(var yt=sy; yt < ey; yt+=LINE_HEIGHT){
item[item.length] = {
x : sx
, y : yt
, width : LINE_WIDTH
, height : LINE_HEIGHT
, bodyStyle : 'background-image: url(VerticalLine.gif);border: 0 none'
};
}
}
//--------------------------------------------------------------------
//构建树
//参数:dep为当前节点,item为要填充数据的数组,xx为当前节点的横坐标,yy为当前节点的纵坐标,area为当前节点的"活动范围"
function built(dep, item, xx, yy, area){
addChild(dep, item, xx, yy);//先将本节点画出来

if(dep.child.length > 0){//如果有子节点就要画子树
drawVerticalLine(dep, item, xx, yy);//先画竖线,反正这个走不了
if(dep.child.length > 1){//如果这棵子树有多个叶子,我们还要画横线
drawStriping(dep, item, xx, yy, area);
}
for(var i=0; i<dep.child.length; i++){//递归画子树
built(dep.child[i], item, (xx+NODE_WIDTH/2-area/2) + ((area/(2*dep.child.length))*(2*i+1)) - NODE_WIDTH/2, (yy + NODE_ZX_DISTANCE + NODE_HEIGHT), area/dep.child.length);
}
}
};
//--------------------------------------------------------------------
Ext.onReady(function(){
var dep7 = {
name : '副总经理小小助手'
, child:[
]
};
var dep6 = {
name : '副总经理小助手'
, child:[
dep7
]
};
var dep5 = {
name : '副总经理助手1'
, child:[
dep6
]
};


var dep3 = {
name : '副总经理1'
, child:[
]
};
var dep4 = {
name : '副总经理2'
, child:[
]
};
var dep2 = {
name : '总经理1'
, child:[
dep3
, dep4
]
};
var dep33 = {
name : '副总经理11'
, child:[
]
};
var dep44 = {
name : '副总经理22'
, child:[
dep5
]
};

var dep22 = {
name : '总经理2'
, child:[
dep33
, dep44
]
};
var dep1 = {
name : '董事会'
, child:[
dep22
,dep2
]
};

var dep = dep1;
var it = [
{
x : -10000
, y : 100
, width : NODE_WIDTH
, height : NODE_HEIGHT
}
];
built(dep, it, (FRAME_WIDTH-NODE_WIDTH)/2, 10, FRAME_WIDTH);//把树弄出来,放到it里面去

var panel = new Ext.Panel({
title:'组织结构图'
, layout : 'absolute'
, frame: false
, height : FRAME_HEIGHT
, width : FRAME_WIDTH
, applyTo : 'panel'
, defaults : {
bodyStyle : 'background-color:#FFFFFF;padding:15px'
}
, items : it
});
panel.on("activate", function(){
alert("asdf");
})
});