vis.js网络拓扑图鼠标悬停/点击弹框,获取到当前节点的详情信息

我项目中需要鼠标悬停在节点和线上时,分别显示对应的详情,并且有点击的操作事件,所以简单的效果图如下:

效果图

官方文档中也有自带的悬停:vis-network interaction(交互) | Ame's blog

官方文档中看到的event事件,,只要数据中有title属性,设置了tooltipDelay,鼠标悬停在线和节点上时,就会显示对应的title值,但是我要的不是这种效果,所以看了文档的event事件------

官方文档中看到的event事件vis-network 事件 | Ame's blog

看文档,只传了一个id,而且并不是每一个事件都有id,找了半天没有找到好的解决办法,后面我自己写了和方法,用id做点击和悬停时的比较,获取到当前节点的所有信息。这样就显示出来了,主要的几个操作点如下图:

数据

事件

 最后,完整代码如下:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>vis.js</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <script type="text/javascript" src="js/jquery-1.12.4.min.js"></script>
    <script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
    <!--<script type="text/javascript" src="js/vis-network.min.js"></script>-->
    <style type="text/css">
        #mynetwork {
            width: 600px;
            height: 600px;
            border: 1px solid lightgray;
        }
        *{padding: 0;margin: 0;}
        .menu{
            /*这个样式不写,右键弹框会一直显示在画布的左下角*/
            position: absolute;
            background: rgba(3,3,3,0.6);
            border-radius: 5px;
            left: -99999px;
            top: -999999px;
        }
        .menu ul{list-style: none}
        .menu ul li{
            padding: 5px 10px;
            color: #ffff;
            border-bottom: 1px solid #ffffff;
            font-size: 14px;
            cursor: pointer;
            list-style: none;
        }
        .menu ul li:hover{
            color: #659bc5;
        }
        .menu ul li:last-child{
            border-bottom: none;
            padding: 5px 10px 0 10px;
        }
    </style>
</head>
<body>
<div id="mynetwork"></div>
<!--菜单操作-->
<div id="menuOperation" class="menu" style="display: none;">
    <ul>
        <li><span class="glyphicon glyphicon-off" aria-hidden="true"></span> 下线</li>
        <li><span class="glyphicon glyphicon-road" aria-hidden="true"></span> 通行</li>
    </ul>
</div>
<!--节点悬停-->
<div class="menu" id="divHoverNode" style="display: none;">
    <!--<ul></ul>-->
</div>
<script type="text/javascript">
    // 创建节点数据数组
    var nodes = [
        {
            "id": 0,
            "name": "外部网络",
            "type": "Internet",
            "ip":"1.1.1.1",
            "port":"未知",
            "ignore":"false",
            "flag":"true"
        }, {
            "id": 1,
            "name": "交换机",
            "type": "switch",
            "ip":"192.168.30.125",
            "mac":"48:de:3d:e2:49:a8",
            "model":"H3C",
            "uptime":"2020-09-03 10:50:50",
            "port":"22",
            "ignore":"true",
            "flag":"true"
        }, {
            "id": 2,
            "name": "交换机",
            "type": "switch",
            "ip":"192.168.1.8",
            "mac":"cd:bd:3d:e2:55:55",
            "model":"pf",
            "uptime":"2020-09-03 10:50:50",
            "port":"33",
            "ignore":"true",
            "flag":"true"
        }, {
            "id": 3,
            "name": "计算机",
            "type": "computer",
            "ip":"192.168.1.8",
            "mac":"dv:bd:fd:e2:df:fd",
            "model":"pf",
            "uptime":"2020-09-03 10:50:50",
            "account":"xiaox",
            "location":"xianm",
            "port":"44",
            "ignore":"true",
            "flag":"true"
        }, {
            "id": 4,
            "name": "路由器",
            "type": "rooter",
            "ip":"192.168.1.8",
            "mac":"ds:bd:3d:e2:ds:55",
            "model":"pf",
            "uptime":"2020-09-03 10:50:50",
            "account":"xiaox",
            "location":"xianm",
            "port":"55",
            "ignore":"true",
            "flag":"true"
        }, {
            "id": 5,
            "name": "服务器",
            "type": "service",
            "ip":"192.168.1.8",
            "mac":"vf:eq:dd:e2:55:55",
            "model":"pf",
            "uptime":"2020-09-03 10:50:50",
            "account":"xiaox",
            "location":"xianm",
            "port":"66",
            "ignore":"true",
            "flag":"true"
        }, {
            "id":6,
            "name": "打印机",
            "type": "print",
            "ip":"192.168.1.8",
            "mac":"ss:bd:3d:ju:55:55",
            "model":"pf",
            "uptime":"2020-09-03 10:50:50",
            "account":"xiaox",
            "location":"xianm",
            "port":"77",
            "ignore":"true",
            "flag":"true"
        }, {
            "id": 7,
            "name": "手机",
            "type": "phone",
            "ip":"192.168.1.8",
            "mac":"ju:ju:3d:e2:55:uy",
            "model":"pf",
            "uptime":"2020-09-03 10:50:50",
            "account":"xiaox",
            "location":"xianm",
            "port":"88",
            "ignore":"true",
            "flag":"true"
        }
    ];
    // 创建边数据数组
    var edges = [
        { from: 0, to: 1,id:"0>1" },
        { from: 1, to: 2,id:"1>2" },
        { from: 1, to: 3,id:"1>3" },
        { from: 1, to: 4,id:"1>4" },
        { from: 1, to: 5,id:"1>5" },
        { from: 2, to: 6,id:"2>6" },
        { from: 2, to: 7,id:"2>7" }
    ];
    /**
     * 自定义图片
     */
    for (var i = 0;i < nodes.length;i++){
        if (nodes[i].type == 'Internet'){
            nodes[i].image = 'image/internet.png';
        }
        if (nodes[i].type == 'switch'){
            nodes[i].image = 'image/switch.png';
        }
        if (nodes[i].type == 'hub'){
            nodes[i].image = 'image/hub.png';
        }
        if (nodes[i].type == 'computer'){
            nodes[i].image = 'image/computer.png';
        }
        if (nodes[i].type == 'rooter'){
            nodes[i].image = 'image/rooter.png';
        }
        if (nodes[i].type == 'service'){
            nodes[i].image = 'image/service.png';
        }
        if (nodes[i].type == 'print'){
            nodes[i].image = 'image/print.png';
        }
        if (nodes[i].type == 'phone'){
            nodes[i].image = 'image/phone.png';
        }
    }
    // 获取容器
    var container = document.getElementById('mynetwork');

    // 将数据赋值给vis 数据格式化器
    var data = {
        nodes: nodes,
        edges: edges
    };
    console.log('nodes',data.nodes);

    var options = {
        nodes:{
            shape: 'image'//设置图片
            // image:"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1599645215703&di=0cb23e74736a6a1222f35b822f5bf833&imgtype=0&src=http%3A%2F%2Fa1.att.hudong.com%2F05%2F00%2F01300000194285122188000535877.jpg"
        },
        interaction:{
            hover:true,
            hoverConnectedEdges: true
        }
    };


    // 初始化关系图
    var network = new vis.Network(container, data, options);

    /**
     * 节点鼠标悬停(点击)获取到的信息
     * 因为hoverNode事件官方文档中给的信息悬停时只传了id值,想在鼠标悬停的时候显示该节点的信息拿不到值,所以遍历节点,相等的时候return改节点的信息
     * @param option-----鼠标悬停时取得的id
     * @returns {{flag, port, ip, name, ignore, id, type}|{flag, port, ip, name, ignore, model, id, type, mac, uptime}|{flag, port, ip, name, ignore, model, location, id, type, mac, account, uptime}|*}
     */
    function getNode(option) {
        for (var i = 0;i < nodes.length;i++){
            if (option == nodes[i].id){
                // console.log('i',nodes[i]);
                return nodes[i];
            }
        }
    }

    /**
     * 线悬停(点击)时两端节点的信息(与节点类似)
     * edges中加了id属性,代表线条指向,悬停时通过edges--id与nodes--id对比,将两端节点信息拼凑出来
     * @param option----鼠标悬停在线上时取得的id
     * @returns {Array}
     */
    function getEdge(option){
        var linkId = option;
        var linkIdFirst = linkId.substring(0,1);//截取第一位
        var linkIdLast = linkId.substring(linkId.length-1,linkId.length);//截取最后一位
        var dataList = [];//存放线条两边的节点nodes数据
        for (var j =0;j<nodes.length;j++){
            if (linkIdFirst == nodes[j].id || linkIdLast == nodes[j].id){
                dataList.push(nodes[j]);
            }
        }
        return dataList;
    }
    //todo  悬停在节点上--显示弹框
    network.on('hoverNode',function(properties){
        // console.log('悬停节点',properties);
        var hoveNodeList = getNode(properties.node);
        // console.log('hoveNodeList',hoveNodeList);
        var deviceType = hoveNodeList.type;
        var imgPathSrc = hoveNodeList.image;
        if (deviceType == "Internet" || deviceType == "hub"){
            var $ul = "<ul>"
                +"<li><img src=' "+imgPathSrc+" ' width='30px' height='25px'><span> "+hoveNodeList.name+" </span> </li>"
                +"</ul>";
            $("#divHoverNode").append($ul);
        }
        else if (deviceType == "switch"){
            var $ul = "<ul>"
                +"<li><img src=' "+imgPathSrc+" ' width='30px' height='25px'><span> 设备类型: "+hoveNodeList.name+" </span> </li>"
                +"<li>IP:"+ hoveNodeList.ip+"</li>"
                +"<li>MAC:"+ hoveNodeList.mac+"</li>"
                +"<li>设备型号:"+ hoveNodeList.model+"</li>"
                +"</ul>";
            $("#divHoverNode").append($ul);
        }else{
            var $ul = "<ul>"
                +"<li><img src=' "+imgPathSrc+" ' width='30px' height='25px'><span> 设备类型:"+hoveNodeList.name+" </span> </li>"
                +"<li>IP:"+ hoveNodeList.ip+"</li>"
                +"<li>MAC:"+ hoveNodeList.mac+"</li>"
                +"<li>账号:"+ hoveNodeList.account+"</li>"
                +"<li>所在位置:"+ hoveNodeList.location+"</li>"
                +"<li>最后登录时间:"+ hoveNodeList.uptime+"</li>"
                +"</ul>";
            $("#divHoverNode").append($ul);
        }
        $('#divHoverNode').css({
            'display': 'block',
            'left': properties.event.offsetX + 15,
            'top' : properties.event.offsetY + 15
        });
        $('#menuOperation').hide();
    });
    //todo  从节点移开---隐藏弹框
    network.on('blurNode',function(){
        $("#divHoverNode").hide();
        $("#divHoverNode").empty();//移除之后清空div
    });
    //todo  悬停在边上--显示弹框
    network.on('hoverEdge',function(properties){
        // console.log('悬停边',properties);
        var hoveEdgeList = getEdge(properties.edge);
        // console.log('hoveEdgeList',hoveEdgeList);
        var $ul = "<ul>"
            +"<li>名称:"+ hoveEdgeList[0].name+"->"+hoveEdgeList[1].name+"</li>"
            +"<li>端口号:"+ hoveEdgeList[0].ip+"->"+hoveEdgeList[1].ip+"</li>"
            +"</ul>";
        $("#divHoverNode").append($ul);
        $('#divHoverNode').css({
            'display': 'block',
            'left': properties.event.offsetX + 15,
            'top' : properties.event.offsetY + 15
        });
        $('#menuOperation').hide();
    });
    //todo  从边上移开---隐藏弹框
    network.on('blurEdge',function(properties){
        $("#divHoverNode").hide();
        $("#divHoverNode").empty();//移除之后清空div
    });
    //todo  点击的判断是否选中节点时候显示隐藏
    network.on('click',function(properties){
        var clickNodeList = getNode(properties.nodes[0]);
        // console.log('clickNodeList',clickNodeList);
        if (typeof(clickNodeList) == "undefined") {
            $('#menuOperation').hide();
        }else{
            $('#menuOperation').css({
                'display': 'block',
                'left': properties.event.center.x + 15,
                'top' : properties.event.center.y + 15
            });
            $("#divHoverNode").hide();
        }
    });

</script>
</body>

  • 11
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 27
    评论
vis.js是一个用于可视化网络、图表和数据的JavaScript库。它提供了许多功能,包括节点移动和位置设置。以下是vis.js节点移动相关的教程。 1. 开始使用vis.js 在开始使用vis.js之前,需要引入vis.js库和vis.css样式文件。可以从vis.js官方网站上下载最新版本的vis.js库和vis.css样式文件,然后将它们添加到HTML页面中。 ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vis.js Node Move Tutorial</title> <link rel="stylesheet" type="text/css" href="vis.css"> <script type="text/javascript" src="vis.js"></script> </head> <body> <div id="network"></div> <script type="text/javascript"> // your code here </script> </body> </html> ``` 2. 创建一个简单的网络 在vis.js中,可以使用vis.Network对象来创建网络。首先,需要创建一个HTML元素,用于显示网络。然后,可以创建一个vis.Network对象,将其绑定到该HTML元素,并设置节点和边的数据。 ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vis.js Node Move Tutorial</title> <link rel="stylesheet" type="text/css" href="vis.css"> <script type="text/javascript" src="vis.js"></script> </head> <body> <div id="network"></div> <script type="text/javascript"> // create an array with nodes var nodes = new vis.DataSet([ {id: 1, label: 'Node 1'}, {id: 2, label: 'Node 2'}, {id: 3, label: 'Node 3'}, {id: 4, label: 'Node 4'}, {id: 5, label: 'Node 5'} ]); // create an array with edges var edges = new vis.DataSet([ {from: 1, to: 2}, {from: 1, to: 3}, {from: 2, to: 4}, {from: 2, to: 5} ]); // create a network var container = document.getElementById('network'); var data = {nodes: nodes, edges: edges}; var options = {}; var network = new vis.Network(container, data, options); </script> </body> </html> ``` 3. 启用节点移动 要启用节点移动,需要在创建vis.Network对象时,将moveable选项设置为true。可以通过options对象来设置该选项。 ```javascript var options = {moveable: true}; var network = new vis.Network(container, data, options); ``` 现在,可以在网络中拖动节点并放置到新的位置。 4. 监听节点移动事件 如果希望在节点移动时执行一些代码,可以监听节点移动事件。可以通过vis.Network对象的on方法来注册事件处理程序。 ```javascript network.on('dragEnd', function(params) { console.log(params.nodes[0] + ' was moved to x:' + params.pointer.canvas.x + ', y:' + params.pointer.canvas.y); }); ``` 上面的代码将在节点移动结束时,将节点ID和新位置的坐标输出到控制台。 5. 限制节点移动范围 有时,希望限制节点移动的范围,以保持网络的视觉效果。可以通过设置节点位置的边界来实现。可以在options对象中设置nodes选项,将其设置为一个对象,该对象包含每个节点的初始位置和位置边界。 ```javascript var options = { moveable: true, nodes: { 1: {x: 100, y: 100, fixed: true, borderWidth: 1, shape: 'circle', color: {background:'red', border:'black'}}, 2: {x: 300, y: 100, borderWidth: 1, shape: 'circle', color: {background:'blue', border:'black'}, physics: false}, 3: {x: 100, y: 300, borderWidth: 1, shape: 'circle', color: {background:'green', border:'black'}, physics: false}, 4: {x: 300, y: 300, borderWidth: 1, shape: 'circle', color: {background:'yellow', border:'black'}, physics: false} } }; ``` 如上所示,节点1的位置已经被固定,而其他节点则没有被固定,并且可以在屏幕上移动。 6. 停用节点移动 要停用节点移动,设置moveable选项为false即可。 ```javascript var options = {moveable: false}; var network = new vis.Network(container, data, options); ``` 现在,节点将无法移动。 以上就是vis.js节点移动相关的教程。通过这些教程,您可以在vis.js中轻松地启用节点移动,监听节点移动事件,限制节点移动范围,并停用节点移动。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值