效果如下:
html中加入如下代碼:
<style type="text/css"> .OrgBox{ font-size:12px; padding:5px 5px 5px 5px; clear:left; float:left; text-align:center; position:absolute; } .OrgBox div{ color:#FFA500; font-weight:800; } </style> <script language="javascript" type="text/javascript"> paintContactOrganization(arr); </script>
js代碼:
function offset(node){ var x = node.offsetLeft; var y = node.offsetTop; var w = node.offsetWidth; var h = node.offsetHeight; var parent = node.offsetParent; while (parent != null){ x += parent.offsetLeft; y += parent.offsetTop; parent = parent.offsetParent; } if(w==0){ w+=parseInt(node.currentStyle.width); w+=parseInt(node.currentStyle.paddingRight); w+=parseInt(node.currentStyle.paddingLeft); w+=parseInt(node.currentStyle.borderWidth) * 2; } if(h==0){ h+=parseInt(node.currentStyle.height); h+=parseInt(node.currentStyle.paddingTop); h+=parseInt(node.currentStyle.paddingBottom); h+=parseInt(node.currentStyle.borderWidth) * 2; } return {x: x, y: y, w: w, h: h}; } function OrgNode(){ this.Text=null; this.Link=null; this.Description=null; this.BoxWidth=null; this.BoxHeight=null; this.parentNode=null; this.NodeGroupId=null; //同一層的級別序號,從零開始 this.NodeOrderId=null; //同一級中的序號,從零開始 this.TopLine=null; this.BottomLine=null; this.Depth=null; this.Top=null; this.Left=null; this.Type=null; this.Nodes=[]; this.customParam=[]; //節點自定義參數 var This=this; this.Nodes.Add=function(OrgNode_){ OrgNode_.parentNode=This; This.Nodes[This.Nodes.length]=OrgNode_; } this.Box=null; this.Templet=null; this.Id="OrgNode_"+ GetRandomId(20); this.inIt= function(){ if(this.inIted==true)return; var tempDiv=document.createElement("DIV"); document.body.appendChild(tempDiv); var tempHTML=this.Templet; tempHTML=tempHTML.replace("{Id}", this.Id); tempHTML=tempHTML.replace("{Text}", this.Text); tempHTML=(this.Link==null)?tempHTML.replace("{Link}", "JavaScript:void(0)"):tempHTML.replace("{Link}", this.Link); tempHTML=tempHTML.replace("{Description}", this.Description); for(var Param_ in this.customParam){ tempHTML=tempHTML.replace("{"+ Param_ +"}", this.customParam[Param_]); } tempDiv.innerHTML=tempHTML; this.Box=document.getElementById(this.Id); if(this.BoxWidth!=null){ if(offset(this.Box).w < this.BoxWidth){ this.Box.style.width=this.BoxWidth +"px"; if(offset(this.Box).w > this.BoxWidth){ this.Box.style.width=(this.BoxWidth - (offset(this.Box).w - this.BoxWidth)) +"px"; } } } if(this.BoxHeight!=null){ if(offset(this.Box).h < this.BoxHeight){ this.Box.style.height=this.BoxHeight +"px"; if(offset(this.Box).h > this.BoxHeight){ this.Box.style.height=(this.BoxHeight - (offset(this.Box).h - this.BoxHeight)) +"px"; } } } this.Width=offset(this.Box).w; this.Height=offset(this.Box).h; this.inIted=true; } function GetRandomId(n_){ var litter="abcdefghijklmnopqrstuvwxyz" litter+=litter.toUpperCase() litter+="1234567890"; var idRnd=""; for(var i=1; i<=n_; i++){ idRnd+=litter.substr((0 + Math.round(Math.random() * (litter.length - 0))), 1) } return idRnd; } } function OrgShow(OrgNode_){ this.LineSize=2; this.LineColor="#000000"; this.IntervalWidth=100; this.IntervalHeight=50; this.Top=0; this.Left=0; this.Depth=0; this.Nodes=[]; this.DepthGroup=[]; //this.DepthGroup[n].Nodes 層深節點集合 //this.DepthGroup[n].NodeGroups[m] 層深節點按上層分類集合 this.DepthGroup[n].NodeGroups[m][k]層深節點 var This=this; this.BoxWidth=null; this.BoxHeight=null; this.BoxTemplet=null; this.ShowType=null; this.Run=function(){ BoxInit(OrgNode_); GetDepth(OrgNode_); SetDepthsHeight()//設置層深高度 //*************************** for(var n=1; n<=this.Depth; n++){//設置頂距離 var tempTop=this.Top + GetDepthHeightToRoot(n); var tempNodes=this.DepthGroup[n].Nodes; for(var m=0; m<tempNodes.length; m++){ tempNodes[m].Top=tempTop; } } //*************************** for(var n=this.Depth; n>=1; n--){//設置左距離 var DepthNodes=this.DepthGroup[n].Nodes; if(n==this.Depth){ for(var m=0; m<DepthNodes.length; m++){ if(m==0){ DepthNodes[m].Left=0; }else{ DepthNodes[m].Left=DepthNodes[m-1].Left + DepthNodes[m-1].Width + this.IntervalWidth; } } }else{ for(var m=0; m<DepthNodes.length; m++){ if(DepthNodes[m].Nodes.length!=0){ var tempNodeLeft_=DepthNodes[m].Nodes[0].Left + (GetGroupWidthByNode(DepthNodes[m].Nodes[0]) / 2); tempNodeLeft_-=(DepthNodes[m].Width / 2); DepthNodes[m].Left = tempNodeLeft_; } } for(var m=0; m<DepthNodes.length; m++){ if(DepthNodes[m].Left==null){ SetLeftByDepthNode(DepthNodes, m, "LTR"); } } } } SetDepthGroupWidth();//設置群組寬度 var MaxLeftValue=this.Nodes[0].Left; for(var n=1; n<this.Nodes.length; n++){//取得最小左距離 if(MaxLeftValue>this.Nodes[n].Left){ MaxLeftValue=this.Nodes[n].Left; } } MaxLeftValue=(-MaxLeftValue) + this.Left; for(var n=0; n<this.Nodes.length; n++){//重新設置距離 this.Nodes[n].Left+=MaxLeftValue; this.Nodes[n].Box.style.left=this.Nodes[n].Left + "px" this.Nodes[n].Box.style.top=this.Nodes[n].Top + "px" } //*************************** for(var n=1; n<=this.Depth; n++){//設置豎線條 var tempNodes=this.DepthGroup[n].Nodes; for(var m=0; m<tempNodes.length; m++){ if(n!=this.Depth){//設置底線條 if(tempNodes[m].Nodes.length!=0){ var tempLineLeft=tempNodes[m].Left + (tempNodes[m].Width / 2); var tempLineHeight=((this.IntervalHeight - this.LineSize) / 2); tempLineHeight+=(this.DepthGroup[n].Height - tempNodes[m].Height); var tempLineTop=tempNodes[m].Top + tempNodes[m].Height; var tempBottomLine=new CreateLine(2, tempLineTop, tempLineLeft, tempLineHeight, this.LineSize, this.LineColor, "LineBottom_"+ tempNodes[m].Id); tempNodes[m].BottomLine=tempBottomLine.Line; } } if(n!=1){//設置頂線條 var tempLineLeft=tempNodes[m].Left + (tempNodes[m].Width / 2); var tempLineHeight=((this.IntervalHeight - this.LineSize) / 2); var tempLineTop=tempNodes[m].Top - tempLineHeight; if(this.DepthGroup[tempNodes[m].Depth].NodeGroups[tempNodes[m].NodeGroupId].length==1){//如果只有一個節點 var tempBottomLineHeight=parseFloat(tempNodes[m].parentNode.BottomLine.style.height) + this.LineSize; tempNodes[m].parentNode.BottomLine.style.height=(tempLineHeight + tempBottomLineHeight)+"px"; }else{ var temptopLine=new CreateLine(2, tempLineTop, tempLineLeft, tempLineHeight, this.LineSize, this.LineColor, "LineTop_"+ tempNodes[m].Id); tempNodes[m].TopLine=temptopLine.Line; } } } } for(var n=2; n<=this.Depth; n++){//設置橫線條 var tempNodeGroups_=this.DepthGroup[n].NodeGroups; for(var m=0; m<tempNodeGroups_.length; m++){ if(tempNodeGroups_[m].length!=1){ var tempLineWidth=tempNodeGroups_[m].Width - (tempNodeGroups_[m][0].Width / 2) + this.LineSize; tempLineWidth-=(tempNodeGroups_[m][tempNodeGroups_[m].length-1].Width / 2); var tempLineTop=tempNodeGroups_[m][0].Top - ((this.IntervalHeight - this.LineSize) / 2) - this.LineSize; var tempLineLeft=tempNodeGroups_[m][0].Left + (tempNodeGroups_[m][0].Width / 2); var tempGroupLine=new CreateLine(1, tempLineTop, tempLineLeft, tempLineWidth, this.LineSize, this.LineColor, "LineGroup_"+ tempNodeGroups_[m][0].Id); } } } //************************************************************************************************* } function GetGroupWidthByNode(Node_){//根據群組中任一節點,取得群組寬度 var tempNodesGroup_=This.DepthGroup[Node_.Depth].NodeGroups[Node_.NodeGroupId]; var tempGroupWidth_=tempNodesGroup_[tempNodesGroup_.length-1].Left - tempNodesGroup_[0].Left; tempGroupWidth_+=tempNodesGroup_[tempNodesGroup_.length-1].Width return tempGroupWidth_; } function SetLeftByDepthNode(DepthNodes_, NodeId, Type){ if(Type=="LTR"&&NodeId==DepthNodes_.length-1){ SetLeftByDepthNode(DepthNodes_, NodeId, "RTL"); return; } if(Type=="RTL"&&NodeId==0){ SetLeftByDepthNode(DepthNodes_, NodeId, "LTR"); return; } var FindIndex=null; if(Type=="LTR"){ for(var r_=NodeId+1; r_<DepthNodes_.length; r_++){ if(DepthNodes_[r_].Left!=null){ FindIndex=r_; break; } } if(FindIndex==null){ SetLeftByDepthNode(DepthNodes_, NodeId, "RTL"); return; }else{ for(var r_=FindIndex-1; r_>=NodeId; r_--){ DepthNodes_[r_].Left=DepthNodes_[r_+1].Left - This.IntervalWidth - DepthNodes_[r_].Width; } } } if(Type=="RTL"){ for(var r_=NodeId-1; r_>=0; r_--){ if(DepthNodes_[r_].Left!=null){ FindIndex=r_; break; } } if(FindIndex==null){ SetLeftByDepthNode(DepthNodes_, NodeId, "LTR"); return; }else{ for(var r_=FindIndex+1; r_<=NodeId; r_++){ DepthNodes_[r_].Left=DepthNodes_[r_-1].Left + This.IntervalWidth + DepthNodes_[r_-1].Width; } } } } function GetDepthHeightToRoot(DepthId){//取得距離頂層的高度 var tempHeight_=0; for(var x_=DepthId; x_>=1; x_--){ tempHeight_+=This.DepthGroup[x_].Height; } tempHeight_+=This.IntervalHeight * (DepthId - 1); tempHeight_-=This.DepthGroup[DepthId].Height; return tempHeight_; } function SetLeftPosByChildNode(Node_, ChildNode_){//根據下級節點位置設置節點位置 var tempNodeGroups=This.DepthGroup[ChildNode_.Depth].NodeGroups[ChildNode_.NodeGroupId]; var tempNodeLeft; if(tempNodeGroups.length==1){ tempNodeLeft=((ChildNode_.Width / 2) + ChildNode_.Left) - (Node_.Width / 2); }else{ tempNodeLeft=GetFirstLeftPos(ChildNode_) + (tempNodeGroups.Width / 2) - (Node_.Width / 2); } Node_.Left=tempNodeLeft; } function GetFirstLeftPos(Node_){//根據節點位置取得同一級中首個節點位置 if(Node_.NodeOrderId==0){//Node_為首節點 return Node_.Left; } var tempWidth=0; for(var k_=0; k_<=Node_.NodeOrderId; k_++){ var tempGroupsNode=This.DepthGroup[Node_.Depth].NodeGroups[Node_.NodeGroupId][k_]; tempWidth+=tempGroupsNode.Width; } tempWidth+=(Node_.NodeOrderId * This.IntervalWidth); return ((Node_.Left - tempWidth) + (Node_.Width / 2)); } function ChildNodesWidth(OrgObj){//取得層寬 var ReWidth=0; for(var s_=0; s_<OrgObj.Nodes.length; s_++){ ReWidth+=OrgObj.Nodes[s_].Width; } ReWidth+=(OrgObj.Nodes.length-1) * This.IntervalWidth; return ReWidth; } function SetDepthGroupWidth(){//設置層深寬度 for(var n_=1; n_<=This.Depth; n_++){ var tempNodeGroups=This.DepthGroup[n_].NodeGroups; for(var m_=0; m_<tempNodeGroups.length; m_++){ tempNodeGroups[m_].Width=GetGroupWidthByNode(tempNodeGroups[m_][0]); } } } function SetDepthsHeight(){//設置層深高度 for(var n_=1; n_<=This.Depth; n_++){ var tempNodes_=This.DepthGroup[n_].Nodes; var MaxHeight=0; for(var m_=0; m_<tempNodes_.length; m_++){ if(tempNodes_[m_].Height>MaxHeight){ MaxHeight=tempNodes_[m_].Height; } } This.DepthGroup[n_].Height=MaxHeight; } } function GetDepth(OrgObj){//取得層深,層群集 This.Nodes[This.Nodes.length]=OrgObj; OrgObj.Depth=(This.Depth==0)?This.Depth+1:OrgObj.parentNode.Depth+1; This.Depth=(OrgObj.Depth>This.Depth)?OrgObj.Depth:This.Depth; if(typeof(This.DepthGroup[OrgObj.Depth])!="object"){ This.DepthGroup[OrgObj.Depth]=[]; This.DepthGroup[OrgObj.Depth].Nodes=[]; This.DepthGroup[OrgObj.Depth].NodeGroups=[]; } This.DepthGroup[OrgObj.Depth].Nodes[This.DepthGroup[OrgObj.Depth].Nodes.length]=OrgObj; if(OrgObj.Depth==1){ This.DepthGroup[OrgObj.Depth].NodeGroups[0]=[]; This.DepthGroup[OrgObj.Depth].NodeGroups[0][0]=OrgObj; OrgObj.NodeGroupId=0; OrgObj.NodeOrderId=0; }else{ if(This.DepthGroup[OrgObj.Depth].NodeGroups.length==0){ This.DepthGroup[OrgObj.Depth].NodeGroups[0]=[]; This.DepthGroup[OrgObj.Depth].NodeGroups[0][0]=OrgObj; OrgObj.NodeGroupId=0; OrgObj.NodeOrderId=0; }else{ var GroupsLength=This.DepthGroup[OrgObj.Depth].NodeGroups.length; var GroupNodesLength=This.DepthGroup[OrgObj.Depth].NodeGroups[GroupsLength-1].length; if(OrgObj.parentNode==This.DepthGroup[OrgObj.Depth].NodeGroups[GroupsLength-1][GroupNodesLength-1].parentNode){ This.DepthGroup[OrgObj.Depth].NodeGroups[GroupsLength-1][GroupNodesLength]=OrgObj; OrgObj.NodeGroupId=GroupsLength-1; OrgObj.NodeOrderId=GroupNodesLength; }else{ if(typeof(This.DepthGroup[OrgObj.Depth].NodeGroups[GroupsLength])!="object"){ This.DepthGroup[OrgObj.Depth].NodeGroups[GroupsLength]=[]; } GroupNodesLength=This.DepthGroup[OrgObj.Depth].NodeGroups[GroupsLength].length; This.DepthGroup[OrgObj.Depth].NodeGroups[GroupsLength][GroupNodesLength]=OrgObj; OrgObj.NodeGroupId=GroupsLength; OrgObj.NodeOrderId=GroupNodesLength; } } } if(OrgObj.Nodes.length!=0){ for(var n=0; n<OrgObj.Nodes.length; n++){ GetDepth(OrgObj.Nodes[n]); } } } function BoxInit(OrgObj_){//節點初始化 OrgObj_.Templet=GetBoxTemplet(); OrgObj_.BoxWidth=This.BoxWidth; OrgObj_.BoxHeight=This.BoxHeight; OrgObj_.inIt(); if(OrgObj_.Nodes.length!=0){ for(var n=0; n<OrgObj_.Nodes.length; n++){ BoxInit(OrgObj_.Nodes[n]); } } } function GetBoxTemplet(){//取得節點模板 if(This.BoxTemplet!=null)return This.BoxTemplet; var TempletStr="<div id=\"{Id}\" style=\"font-size:12px;padding:5px 5px 5px 5px;border:thin solid blue;background-color:lightgrey; clear:left;float:left;text-align:center;position:absolute;" if(This.ShowType==2)TempletStr+="writing-mode: tb-rl;"; TempletStr+="\" title=\"{Description}\" ><a target=\"_blank\" href=\"{Link}\">{Text}</a></div>"; return TempletStr; } function CreateLine(type_, top_, left_, long_, size_, color_, id_){ this.Type=type_; top_=top_+""; left_=left_+""; long_=long_+""; this.Top=(top_.substr(top_.length-2).toLowerCase()!="px")?top_+"px":top_; this.Left=(left_.substr(left_.length-2).toLowerCase()!="px")?left_+"px":left_; this.Long=(long_.substr(long_.length-2).toLowerCase()!="px")?long_+"px":long_; this.Size=(size_==undefined)?"1px":size_+""; this.Id=(id_==undefined)?null:id_; this.Size=(this.Size.substr(this.Size.length-2).toLowerCase()!="px")?this.Size+"px":this.Size; this.Color=(color_==undefined)?"#000000":color_; this.Line=document.createElement("DIV"); document.body.appendChild(this.Line); this.Line.innerText="x"; this.Line.style.position="absolute"; this.Line.style.top=this.Top; this.Line.style.left=this.Left; this.Line.style.overflow="hidden"; if(this.Type==1){ this.Line.style.borderTopColor=this.Color; this.Line.style.borderTopWidth=this.Size; this.Line.style.borderTopStyle="solid"; this.Line.style.width=this.Long; this.Line.style.height="0px"; }else{ this.Line.style.borderLeftColor=this.Color; this.Line.style.borderLeftWidth=this.Size; this.Line.style.borderLeftStyle="solid"; this.Line.style.height=this.Long; this.Line.style.width="0px"; } if(this.Id!=null)this.Line.id=this.Id; } }
function showXiaJiContact(contact){ var b=new OrgNode(); b.Text = "<img src=\""+contact.pic+"\" width=\"80px\" height=\"80px\"/><br/><a target=\"_blank\" href=\"index.php?module=Contacts&action=DetailView&record="+contact.id+"\">"+contact.lastname+"</a>";//這里是圖片及文字哦!!!! b.Description = contact.lastname; b.customParam.title= contact.department+" "+contact.title; b.customParam.accdiv = ''; var xiaji = contact.xiaji; for(var i=0;i<xiaji.length;i++){ b.Nodes.Add(showXiaJiContact(xiaji[i])); } return b; } function paintContactOrganization(accountArr){ var a=new OrgNode(); a.Text = "<a target=\"_blank\" href=\"index.php?module=Accounts&action=DetailView&record="+accountArr.id+"\">"+accountArr.name+"</a>"; a.Description=accountArr.name; a.customParam.title = ''; a.customParam.accdiv = "<a onclick=\"history.go(-1);return false;\" href=\"#\">客戶組織架構</a>"; var xiaji = accountArr.xiaji; for(var i=0;i<xiaji.length;i++){ a.Nodes.Add(showXiaJiContact(xiaji[i])); } var OrgShows=new OrgShow(a); OrgShows.Top=50; //設置頂距離 OrgShows.Left=50; //設置左距離 OrgShows.IntervalWidth=20; //設置節點間隔寬度 OrgShows.IntervalHeight=60; //設置節點間隔高度 OrgShows.ShowType=1; //設置節點展示方式 1橫向 2豎向 OrgShows.BoxHeight=30; //設置節點默認高度 //OrgShows.BoxWidth=100; //設置節點默認寬度 var TempletStr="<div id=\"{Id}\" style=\"font-size:13px;padding:15px 15px 15px 15px;border:15px thin outset #7f8183;border-radius:10px;background-color:#bae0e3; clear:left;float:left;text-align:center;position:absolute;" if(OrgShows.ShowType==2)TempletStr+="writing-mode: tb-rl;"; TempletStr+="\" title=\"{Description}\" ><div style=\"line-height:20px;\">{Text}</div><div style=\"line-height:20px;\">{title}</div><div style=\"line-height:20px;\">{accdiv}</div></div>"; OrgShows.BoxTemplet = TempletStr; OrgShows.Run(); }