绘制人物关系图

来源:互联网 发布:公用端口号是多少 编辑:程序博客网 时间:2024/04/28 09:54



<!DOCTYPE html>
<html>
<head>
<script type="text/javascript"src="http://mbostock.github.com/d3/d3.v2.js?2.9.1"></script>
<style type="text/css">
.link { stroke: green; stroke-linejoin:bevel;}
 
.link_error{
    stroke:red;
    stroke-linejoin:bevel;
}
 
.nodetext {
 
    font: 12px sans-serif;
    -webkit-user-select:none;
    -moze-user-select:none;
    stroke-linejoin:bevel;
     
}
 
#container{
    width:800px;
    height:600px;
    border:1px solid gray;
    border-radius:5px;
    position:relative;
    margin:20px;
}
</style>
</head>
<body>
    <div id='container'></div>
<script type="text/javascript">
 
function Topology(ele){
    typeof(ele)=='string'&& (ele=document.getElementById(ele));
    var w=ele.clientWidth,
        h=ele.clientHeight,
        self=this;
    this.force = d3.layout.force().gravity(.05).distance(200).charge(-800).size([w, h]);
    this.nodes=this.force.nodes();
    this.links=this.force.links();
    this.clickFn=function(){};
    this.vis = d3.select(ele).append("svg:svg")
                 .attr("width", w).attr("height", h).attr("pointer-events","all");
 
    this.force.on("tick", function(x) {
      self.vis.selectAll("g.node")
          .attr("transform", function(d) { return"translate(" + d.x + ","+ d.y + ")"; });
 
      self.vis.selectAll("line.link")
          .attr("x1", function(d) { returnd.source.x; })
          .attr("y1", function(d) { returnd.source.y; })
          .attr("x2", function(d) { returnd.target.x; })
          .attr("y2", function(d) { returnd.target.y; });
    });
}
 
 
Topology.prototype.doZoom=function(){
    d3.select(this).select('g').attr("transform","translate("+ d3.event.translate + ")"+" scale(" + d3.event.scale + ")");
 
}
 
 
//增加节点
Topology.prototype.addNode=function(node){
    this.nodes.push(node);
}
 
Topology.prototype.addNodes=function(nodes){
    if(Object.prototype.toString.call(nodes)=='[object Array]' ){
        var self=this;
        nodes.forEach(function(node){
            self.addNode(node);
        });
 
    }
}
 
//增加连线
Topology.prototype.addLink=function(source,target){
    this.links.push({source:this.findNode(source),target:this.findNode(target)});
}
 
//增加多个连线
Topology.prototype.addLinks=function(links){
    if(Object.prototype.toString.call(links)=='[object Array]' ){
        var self=this;
        links.forEach(function(link){
            self.addLink(link['source'],link['target']);
        });
    }
}
 
 
//删除节点
Topology.prototype.removeNode=function(id){
    var i=0,
        n=this.findNode(id),
        links=this.links;
    while( i < links.length){
        links[i]['source']==n || links[i]['target'] ==n ? links.splice(i,1) : ++i;
    }
    this.nodes.splice(this.findNodeIndex(id),1);
}
 
//删除节点下的子节点,同时清除link信息
Topology.prototype.removeChildNodes=function(id){
    var node=this.findNode(id),
        nodes=this.nodes;
        links=this.links,
        self=this;
 
    var linksToDelete=[],
        childNodes=[];
     
    links.forEach(function(link,index){
        link['source']==node
            && linksToDelete.push(index)
            && childNodes.push(link['target']);
    });
 
    linksToDelete.reverse().forEach(function(index){
        links.splice(index,1);
    });
 
    var remove=function(node){
        var length=links.length;
        for(var i=length-1;i>=0;i--){
            if(links[i]['source'] == node ){
               var target=links[i]['target'];
               links.splice(i,1);
               nodes.splice(self.findNodeIndex(node.id),1);
               remove(target);
                
            }
        }
    }
 
    childNodes.forEach(function(node){
        remove(node);
    });
 
    //清除没有连线的节点
    for(var i=nodes.length-1;i>=0;i--){
        var haveFoundNode=false;
        for(var j=0,l=links.length;j<l;j++){
            ( links[j]['source']==nodes[i] || links[j]['target']==nodes[i] ) && (haveFoundNode=true)
        }
        !haveFoundNode && nodes.splice(i,1);
    }
}
 
 
 
//查找节点
Topology.prototype.findNode=function(id){
    var nodes=this.nodes;
    for(var i in nodes){
        if(nodes[i]['id']==id ) returnnodes[i];
    }
    returnnull;
}
 
 
//查找节点所在索引号
Topology.prototype.findNodeIndex=function(id){
    var nodes=this.nodes;
    for(var i in nodes){
        if(nodes[i]['id']==id ) returni;
    }
    return-1;
}
 
//节点点击事件
Topology.prototype.setNodeClickFn=function(callback){
    this.clickFn=callback;
}
 
//更新拓扑图状态信息
Topology.prototype.update=function(){
  var link = this.vis.selectAll("line.link")
      .data(this.links, function(d) { returnd.source.id + "-"+ d.target.id; })
      .attr("class", function(d){
            returnd['source']['status'] && d['target']['status'] ? 'link':'link link_error';
      });
 
  link.enter().insert("svg:line","g.node")
      .attr("class", function(d){
         returnd['source']['status'] && d['target']['status'] ? 'link':'link link_error';
      });
 
  link.exit().remove();
 
  var node = this.vis.selectAll("g.node")
      .data(this.nodes, function(d) { returnd.id;});
 
  var nodeEnter = node.enter().append("svg:g")
      .attr("class","node")
      .call(this.force.drag);
 
  //增加图片,可以根据需要来修改
  var self=this;
  nodeEnter.append("svg:image")
      .attr("class","circle")
      .attr("xlink:href", function(d){
         //根据类型来使用图片
         returnd.expand ? "http://ww2.sinaimg.cn/large/412e82dbjw1dsbny7igx2j.jpg": "http://ww4.sinaimg.cn/large/412e82dbjw1dsbnxezrrpj.jpg";
      })
      .attr("x","-32px")
      .attr("y","-32px")
      .attr("width","64px")
      .attr("height","64px")
      .on('click',function(d){ d.expand && self.clickFn(d);})
 
  nodeEnter.append("svg:text")
      .attr("class","nodetext")
      .attr("dx",15)
      .attr("dy", -35)
      .text(function(d) { returnd.id });
 
   
  node.exit().remove();
 
  this.force.start();
}
 
 
 
 
var topology=newTopology('container');
 
var nodes=[
    {id:'10.4.42.1',type:'router',status:1},
    {id:'10.4.43.1',type:'switch',status:1,expand:true},
    {id:'10.4.44.1',type:'switch',status:1},
    {id:'10.4.45.1',type:'switch',status:0}
 
];
 
var childNodes=[
    {id:'10.4.43.2',type:'switch',status:1},
    {id:'10.4.43.3',type:'switch',status:1}
 
];
 
var links=[
    {source:'10.4.42.1',target:'10.4.43.1'},
    {source:'10.4.42.1',target:'10.4.44.1'},
    {source:'10.4.42.1',target:'10.4.45.1'}
];
 
var childLinks=[
    {source:'10.4.43.1',target:'10.4.43.2'},
    {source:'10.4.43.1',target:'10.4.43.3'},
    {source:'10.4.43.2',target:'10.4.43.3'}
]
 
 
topology.addNodes(nodes);
topology.addLinks(links);
//可展开节点的点击事件
topology.setNodeClickFn(function(node){
    if(!node['_expanded']){
        expandNode(node.id);
        node['_expanded']=true;
    }else{
        collapseNode(node.id);
        node['_expanded']=false;
    }
});
topology.update();
 
 
function expandNode(id){
    topology.addNodes(childNodes);
    topology.addLinks(childLinks);
    topology.update();
}
 
function collapseNode(id){
    topology.removeChildNodes(id);
    topology.update();
}
 
</script>
</body>
</html>
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电脑开机桌面文件都没了怎么办 qq飞车手游队长换了微信群怎么办 qq飞车手游登录授权失败怎么办 安装时提示安装包发现错误怎么办 苹果6p升级系统验证失败怎么办 w10开不了机无限重启怎么办 微信朋友圈里的表情图打不开怎么办 金立手机微信启动录音被拒绝怎么办 微信帐号解封后漂流瓶不能用怎么办 微信怎么在电脑上登不上去怎么办 玩旧版60级魔兽经常花屏怎么办? 我的世界手机版物品栏不见了怎么办 苹果手机掉进水里出现花屏该怎么办 球球大作战还没进去停止运行怎么办 ps3 e3硬破芯片坏了怎么办 电话打开后页面上没有东西怎么办 WPS在电脑安装后卸载不了怎么办 ps总要以管理员的身份打开怎么办 3d关的慢保存慢怎么办 无法与服务器建立可靠的连接怎么办 被抵押的房子开发商不解押怎么办 手机系统语言是英文没有中文怎么办 w7主机网插口灯不亮了没网怎么办 电脑用了5年变得很卡了怎么办 苹果6s系统占12g怎么办 百度网盘下载的压缩包打不开怎么办 三星手机微信安装包解析错误怎么办 下身流出来的东西有异味很重怎么办 鞋脚底总有一股酸臭的味道怎么办 腋窝总是有股酸臭的味道应该怎么办 房间里总是有灰尘的味道怎么办 香水喷多了衣服味道太呛怎么办 香水喷在衣服上变黄了怎么办 84喷在白衣服上变红怎么办 夏季高温多肉山地玫瑰砍头了怎么办 海水缸爆藻有些石头不出绿藻怎么办 不小心把b原来的壁纸删了怎么办 注册简历时没有固定电话必填怎么办 申诉找回微信账号密码验证码怎么办 激活淘宝时显示注册账号过多怎么办 科学上网之后电脑上不了网怎么办