基于jquery.jsPlumb编写拓扑图
要求:实现公司组织结构拓扑关系,可展开,可收拢;动态数据展示;叶子节点可点击;
实现办法:
1 国内还有一个插件也比较简单,但是该插件只能全部展开,并不能收拢,放弃了该办法;
2 最后选择了这个插件,因为相关资料很少,所以每步都是自己摸索出来的;
对数据的要求:因为该插件的每个节点都是一个具有独立不同id的div模块,所以json数据要求有一个id属性,并且所有的id都要不一样;
实现的原理:
1 先定位所有的节点(这个还简单点,只要依次遍历数据就行);
2 添加拓扑关系;(这个地方比较复杂,尤其是点击节点时,其他节点收缩,直接点展开,里面的循环量特别大,几乎都是在一个大循环里面套用了很多的子循环)
1 html部分(注意事项,里面的图片自己设置)
2 test.js
var tree_json=[ { "id": "1", "text": "国核院", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "2", "text": "土木工程部", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "3", "text": "科室一", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "4", "text": "u110", "iconCls": "icon-man" }, { "id": "5", "text": "u120", "iconCls": "icon-man" }, { "id": "51", "text": "u120", "iconCls": "icon-man" } ] }, { "id": "6", "text": "财务", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "7", "text": "u111", "iconCls": "icon-man" }, { "id": "71", "text": "u111", "iconCls": "icon-man" } ] } ] }, { "id": "8", "text": "建筑工程部", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "9", "text": "科室一", "iconCls": "icon-org", "state": "closed", }, { "id": "11", "text": "财务", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "12", "text": "u114", "iconCls": "icon-man" } ] } ] }, { "id": "13", "text": "综合室", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "14", "text": "u113", "iconCls": "icon-man" }, { "id": "141", "text": "u113", "iconCls": "icon-man" } ] }, { "id": "15", "text": "重庆公司", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "16", "text": "土木工程部", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "17", "text": "科室一", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "18", "text": "u115", "iconCls": "icon-man" } ] }, { "id": "19", "text": "财务", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "20", "text": "张文涛", "iconCls": "icon-man" } ] } ] }, { "id": "21", "text": "建筑工程部", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "24", "text": "财务", "iconCls": "icon-org", "state": "closed", "children": [ { "id": "25", "text": "李小进", "iconCls": "icon-man" } ] } ] } ] } ] } ]; $.ajax({ url: 'scripts/text.json', type: 'GET', dataType: 'json', data: {}, }) .done(function() { console.log("success"); myjson=tree_json; showTopo(); }) .fail(function() { console.log("error"); }) .always(function() { console.log("complete"); }); function showTopo(){ $("#top_server").css({"left":"50%","top":"5%"}); $(document).on({ mouseover:function(){$(this).css({"background-color":"#79deff","box-shadow":"#909090 0px 0px 10px", "-webkit-box-shadow": "#909090 0px 0px 10px","-moz-box-shadow": "#909090 0px 0px 10px"});}, mouseout:function(){$(this).css({"background-color":"","box-shadow":"", "-webkit-box-shadow": "","-moz-box-shadow": ""});}, click:function(){alert($(this).text());} },".instanceNode_leaf"); var company=myjson[0]["children"]; //初始化 公司数组 var companyNumber=company.length; // var company_department_arr=[]; //获取部门数组 var company_department_sec_arr=[]; //获取科室数组 //元素的摆放 先摆放公司 部门 科室 员工 if(tree_json[0].hasOwnProperty("children")){ elementLocation(company,companyNumber); } //开始定义连线和点击事件 jsPlumb.ready(function() { jsPlumb.draggable("top_server"); //定义可拖拽 var hoverPaintStyle = { lineWidth:2,strokeStyle:"#dedede" }; //鼠标经过时线宽度和颜色 jsPlumb.importDefaults({ DragOptions : { cursor: 'pointer'}, //拖动时鼠标停留在该元素上显示指针,通过css控制 EndpointStyles : { width:10, height:10,cursor: 'pointer'},//连接点的默认颜色 Connector : "Straight", //设置连线为直线 Endpoint : "Rectangle",//连接点的默认形状 Anchor : "Top",//连接点的默认位置 MaxConnections:1000,//同上 ConnectionsDetachable:false, HoverPaintStyle:hoverPaintStyle }); var defaults = { paintStyle:{ fillStyle:"#B4B9C5" },//设置连接点的颜色 connectorStyle:{ strokeStyle:"#B4B9C5", lineWidth:2 },//连线颜色、粗细 connector:[ "Flowchart", { stub:[10, 20], gap:5, cornerRadius:2} ], isSource:true, isTarget:true, endpoint:"Blank" }; var rootnode={ endpoint:["Image", { src:"images/sub.png" }],//设置连接点的形状为圆形 paintStyle:{ fillStyle:"#B4B9C5" },//设置连接点的颜色 connectorStyle:{ strokeStyle:"green", lineWidth:2 },//连线颜色、粗细 //connector:["Straight",{gap:5}], connector:[ "Flowchart", { stub:[10, 20], gap:10, cornerRadius:2} ], cssClass:"cursorEndpoint" }; var s1=jsPlumb.addEndpoint("top_server", {anchor:"Bottom"},rootnode);//根节点设置 //添加拓扑关系 for(var i=0;i0){ var s2_root=jsPlumb.addEndpoint("instance_"+company[i].id, {anchor:"Bottom"},rootnode); //把四个公司设置成根节点 //对公司绑定click事件 s2_root.bind("click", function(endpoint) { if(endpoint.getParameter("img")&&endpoint.getParameter("img")=="add"){ endpoint.setParameter("img","sub"); endpoint.setImage("images/sub.png"); for(var k=0;k -1) { jsPlumb.repaintEverything(); } }); //添加部门拓扑关系,也就是连接公司到部门,遍历部门 for(var i1=0;i1 -1) { jsPlumb.repaintEverything(); } }); //添加科室拓扑关系,也就是连接部门到科室; for(var i2=0;i2 -1) { jsPlumb.repaintEverything(); } }); for(var i3=0;i3 0){ jsPlumb.select({source:"instance_"+company[i].id}).setVisible(false); jsPlumb.select({source:"instance_"+company[i].id}).get(0).endpoints[0].setParameter("img","add"); jsPlumb.select({source:"instance_"+company[i].id}).get(0).endpoints[0].setImage("images/add.png"); } } }else{ endpoint.setParameter("img","add"); endpoint.setImage("images/add.png"); jsPlumb.hide("top_server"); for(var i=0;i -1) { jsPlumb.repaintEverything(); } }); $(window).resize(function(){ jsPlumb.repaintEverything(); }); }); } /* * 元素摆放位置--对称分布 */ function elementLocation(nodeArr,nodeNumber){ if(nodeNumber%2==1){//总节点数是奇数 //var num=parseInt(nodeNumber/2); for(var i=0;i parseInt(nodeNumber/2)){ leftLoc=50+10*(i-parseInt(nodeNumber/2)); }else{ leftLoc=50; } if(nodeArr[i].hasOwnProperty("children")){ var html=" "; $("body").append(html); var companyLoc=leftLoc; //在本例中表示公司横向定位,做这个是方便公司下面的部门定位; var companyDepartArr=nodeArr[i].children; var companyDepartArrLength=companyDepartArr.length; companyDepartLocation(companyLoc,companyDepartArr,companyDepartArrLength); //部门定位 } else{ var html=""+nodeArr[i].text+""; $("body").append(html); } } }else if(nodeNumber%2==0){//总节点数是偶数 //var num=parseInt(nodeNumber/2); for(var i=0;i"+nodeArr[i].text+"parseInt(nodeNumber/2)){ leftLoc=50+5+10*(i-parseInt(nodeNumber/2)); } if(nodeArr[i].hasOwnProperty("children")){ var html=" "; $("body").append(html); var companyLoc = leftLoc; var companyDepartArr=nodeArr[i].children; var companyDepartArrLength=companyDepartArr.length; companyDepartLocation(companyLoc,companyDepartArr,companyDepartArrLength); //部门定位 } else { var html=""+nodeArr[i].text+""; $("body").append(html); } } } } //部门定位 function companyDepartLocation(nodeLoc,nodeArr,nodeNumber){ if(nodeNumber%2==1){ for(var j=0;j"+nodeArr[i].text+"parseInt(nodeNumber/2)){ leftLoc=nodeLoc+5*j; } else{ leftLoc=nodeLoc; } if(department.hasOwnProperty("children")){ var html=" "; $("body").append(html); var departmentOrgnize=department.children; var departmentOrgnizeLength=departmentOrgnize.length; var departmentOrgnizeLoc=leftLoc; departmentOrgnizeLocation(departmentOrgnizeLoc,departmentOrgnize,departmentOrgnizeLength); //组织定位 } else{ var html=""+department.text+""; $("body").append(html); } } }else if(nodeNumber%2==0){ for(var j=0;j"+department.text+"parseInt(nodeNumber/2)){ leftLoc=nodeLoc+5+5*(j-parseInt(nodeNumber/2)); } if(department.hasOwnProperty("children")){ var html=" "; $("body").append(html); var departmentOrgnize=department.children; var departmentOrgnizeLength=departmentOrgnize.length; var departmentOrgnizeLoc=leftLoc; departmentOrgnizeLocation(departmentOrgnizeLoc,departmentOrgnize,departmentOrgnizeLength); //组织定位 } else { var html=""+department.text+""; $("body").append(html); } } } } //组织定位 function departmentOrgnizeLocation(nodeLoc,nodeArr,nodeNumber){ if(nodeNumber%2==1){ for(var j=0;j"+department.text+"parseInt(nodeNumber/2)){ leftLoc=nodeLoc+5*(j-parseInt(nodeNumber/2)); }else{ leftLoc=nodeLoc; } if(orgnize.hasOwnProperty("children")){ var html=" "; $("body").append(html); var staffArr=orgnize.children; var staffLength=staffArr.length; var staffLoc=leftLoc; staffLocation(staffLoc,staffArr,staffLength); //员工定位 } else { var html=""+orgnize.text+""; $("body").append(html); } } } else if(nodeNumber%2==0){ for(var j=0;j"+orgnize.text+"parseInt(nodeNumber/2)){ leftLoc=nodeLoc+5+5*(j-parseInt(nodeNumber/2)); } if(orgnize.hasOwnProperty("children")){ var html=" "; $("body").append(html); var staffArr=orgnize.children; var staffLength=staffArr.length; var staffLoc=leftLoc; staffLocation(staffLoc,staffArr,staffLength); //员工定位 } else { var html=""+orgnize.text+""; $("body").append(html); } } } } //员工定位 function staffLocation(nodeLoc,nodeArr,nodeNumber){ if(nodeNumber%2==1){ for(var j=0;j"+orgnize.text+"parseInt(nodeNumber/2)){ leftLoc=nodeLoc+5*(j-parseInt(nodeNumber/2)); }else{ leftLoc=nodeLoc; } if(staff.hasOwnProperty("children")){ var html=" "; $("body").append(html); } else { var html=""+staff.text+""; $("body").append(html); } } } else if(nodeNumber%2==0){ for(var j=0;j"+staff.text+"parseInt(nodeNumber/2)){ leftLoc=nodeLoc+5+5*(j-parseInt(nodeNumber/2)); } if(staff.hasOwnProperty("children")){ var html=" "; $("body").append(html); } else { var html=""+staff.text+""; $("body").append(html); } } } }"+staff.text+"
3、最后的效果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。