jtopo js插件绘制网络拓扑图

一、实现的功能

1、拓扑的基本绘制

2、拓扑放射性布局

3、多级拓扑的实现

4、下级拓扑节点的隐藏与展现

5、导出拓扑图

二、效果图展示

正常展示:

jtopo js插件绘制网络拓扑图_第1张图片

节点收缩展示:

jtopo js插件绘制网络拓扑图_第2张图片

三、引入库(稍作可以直接复用)

1、引入jQuery,jquery.js

2、引入jtopo插件jtopo-0.4.8.js

3、支持IE8,excanvas.js

四、前端代码

在实现节点隐藏于展示过程中,实现方法可能不够好,问题如下:

1、而且使用全局数组(用来存储隐藏的节点),重新展示后全局数组里面的数据无法删除,因为不敢保证所有节点同时展示与收缩,因此使用的是当重新展示后,把重新展示的节点对象用对应的数字替换数组中的位置,这样保证再次隐藏的时候数组能够重新添加。有的人可能会问既然可能会第二次隐藏,那为什么要把存在数组中的对应的展示的节点对象删除呢?那是为了防止当重复再节点上添加相同的节点。(改进思路,用拓扑对象的outLinks属性作为增删的校验)

2、判断节点点击展示或隐藏的方法待改进,我采用的是数字计数法,缺陷就是一次或两次有效(改进思路,暂无)

3、js代码:


HTML:


    


        

         

  
        

    

4、json格式:

{
    "crlr": 5,
    "degree": 360,
    "disitem": 360,
    "name": "asffa",
    "nodelist": [
        {
            "crlr": 5,
            "degree": 120,
            "disitem": null,
            "name": "210.27.48.30",
            "nodelist": [],
            "noder": null,
            "pt": {
                "x": 6.12421475744837E+16,
                "y": 1000
            },
            "rt": {
                "center": {
                    "x": 1000,
                    "y": 1000
                },
                "degree": 0,
                "r": 6.12421475744827E+16
            },
            "xdegree": -60
        }
    ],
    "noder": 6.12421475744827E+16,
    "pt": {
        "x": 1000,
        "y": 1000
    },
    "xdegree": 0
}

5、后台代码,拓扑对象坐标计算,使用的是弧度定位算法:

public class JtopNode {
    public String name = "";
    
     public class toppoint
     {
         public double x;
         public double y;
         /*public toppoint(double x,double y){
             this.x = x;
             this.y = y;
         }*/
     }

     class toprpt
     {
         public double r;
         public double degree;
         public toppoint center = new toppoint();
     }

     public class topnode
     {
         public List nodelist = new ArrayList();
         public topnode parentnode ;
         public String name = "asffa";

         public toprpt rt;//圆形坐标
         public toppoint pt;//坐标

         public double crlr = 5;//小球半径
         public double noder;//扇面半径

         public double disitem;//扇形间隔角

         public double degree;//扇面角度
         public double xdegree;//扇形底线夹角


     }

     toppoint rt2pt(toprpt rt)
     {
            double y1 = rt.r * Math.sin(rt.degree *Math.PI / 180);
            double x1 = rt.r * Math.cos(rt.degree * Math.PI / 180);
            toppoint tp = new toppoint();
            tp.x = rt.center.x+x1;
            tp.y = rt.center.y+y1;
            return tp;
     }

     void getnode_parm(topnode nd)
     {
         double disitem = nd.degree / (nd.nodelist.size());
         double minr = nd.crlr / Math.sin(0.5 * disitem * Math.PI / 180);
         nd.disitem = disitem;
         nd.noder = minr * 1.5 + nd.crlr * 3+80;
         if (nd.noder < 250)
         {
             nd.noder = 250;
         }
     }

     //得到直角坐标
     void getchildnode_pt(topnode nd)
     {
         if(nd.nodelist==null&&nd.nodelist.size()<1) return;
         for (int i = 0; i < nd.nodelist.size(); i++)
         {
             nd.nodelist.get(i).degree = 120.0;
             toprpt rt = new toprpt();
             rt.center = new toppoint();
             rt.center.x =  nd.pt.x;
             rt.center.y =  nd.pt.y;
             rt.r = nd.noder;
             rt.degree = nd.xdegree + nd.disitem * i;
             nd.nodelist.get(i).xdegree = rt.degree - nd.nodelist.get(i).degree / 2;// (rt.degree - nd.nodelist[i].degree / 2);

             nd.nodelist.get(i).rt = rt;
             nd.nodelist.get(i).pt = new toppoint();// = rt2pt(rt);
             toppoint    tp = rt2pt(rt);
             nd.nodelist.get(i).pt.x = tp.x;
             nd.nodelist.get(i).pt.y =     tp.y;    
             
             getnode_parm(nd.nodelist.get(i));
             
             getchildnode_pt(nd.nodelist.get(i));
         }
     }

   public void setrootnode_parm(topnode root)
     {
         root.degree = 360;
         root.xdegree = 0;
         root.pt = new toppoint();
         root.pt.x=1000.0;
         root.pt.y=1000.0;
         getnode_parm(root);
      //   drawitem(root, root.pt);
         getchildnode_pt(root);
     }
     
   public void parseXML(NmTopoRelation nmTopoRelation,TopoResult topoResult){
       System.out.println("topoID="+nmTopoRelation.getDevtypeId());
       System.out.println("topoIp="+nmTopoRelation.getDevIp());
       //创建XML解析对象
       xml x = new xml();
       //初始化,解析XML,得到子节点
       List interIpList = x.xmlRouters(nmTopoRelation.getDevtypeId());
       //得到子网所对应的所有IP
       List childLists =  x.xmlSubnets();
       
       String subIp = "";
       List ipList = new ArrayList();
       //获取所有二层节点IP
       for(NmTopoRelation parent:interIpList){
           if(parent.getDevIp() != null){
               ipList.add(parent.getDevIp());
           }
       }
       
       //核心ip就是路由ip,根据传进来的路由ip得到它所对应的所有子网ip,然后根据子网ip进行绘制
       //因为是子网,所有主机号为0,因此将核心ip的主机号剪掉,得到一个网络号,再利用网络号与扫描的ip进行匹配
       //对扫描到的ip进行网段匹配
       if(interIpList != null&&childLists != null){
           if(ipList.contains(nmTopoRelation.getDevIp()))
           {
               List tops = nmtp2Td(interIpList);
               for(topnode td:tops){
                   if(td.name.equals(nmTopoRelation.getDevIp())){
                       continue;
                   }
                   subIp = td.name.substring(0, td.name.lastIndexOf("."))+".";
                   List tops2 = nmtp2Td(childLists);
                   for(topnode td2:tops2){
                       if(td2.name.indexOf(subIp)<0){
                           continue;
                       }
                       if(td.name.equals(td2.name)){
                           continue;
                       }
                   td.nodelist.add(td2);
                   }
                   topoResult.getTnode().nodelist.add(td);
               }
           }
       }
       
       setrootnode_parm(topoResult.getTnode());
       
   }
   public List nmtp2Td(List nmlist){
       List tdlist = new ArrayList();
       topnode td = null;
       for(int i = 0; i < nmlist.size();i ++){
           td = new topnode();
           td.name = nmlist.get(i).getDevIp();
           tdlist.add(td);
       }
       return tdlist;
   }
}

6、以上后台代码只是实现了三层拓扑图,如果还有更多层,需要对这个方法 nmtp2Td() 稍作修改

接下来直接使用fastjson格式化一把传入js就搞定。祝你愉快!


你可能感兴趣的:(网络拓扑,jtopo,canvas)