• Vis.js – 基于浏览器的动态 JavaScript 可视化库


    Vis.js – 基于浏览器的动态 JavaScript 可视化库

    一、总结

    一句话总结:Vis.js 是一个动态的,基于浏览器的可视化库。该库被设计为易于使用,能处理大量的动态数据。该库由以下几部分组成:一是数据集和数据视图,基于灵活的键/值数据集,可以添加,更新和删除项目,订阅数据集变化;二是时间轴,用于显示不同类型的时间轴数据,在时间轴上项目可以交互移动,缩放和操纵;三是图形,使用节点和边显示一个交互式图形或网络。

    1、vis库由哪些部分组成?

    数据视图
    时间轴
    图形

    一是数据集和数据视图,基于灵活的键/值数据集,可以添加,更新和删除项目,订阅数据集变化;

    二是时间轴,用于显示不同类型的时间轴数据,在时间轴上项目可以交互移动,缩放和操纵;

    三是图形,使用节点和边显示一个交互式图形或网络。

    二、Vis.js – 基于浏览器的动态 JavaScript 可视化库

    Vis.js 是一个动态的,基于浏览器的可视化库。该库被设计为易于使用,能处理大量的动态数据。该库由以下几部分组成:一是数据集和数据视图,基于灵活的键/值数据集,可以添加,更新和删除项目,订阅数据集变化;二是时间轴,用于显示不同类型的时间轴数据,在时间轴上项目可以交互移动,缩放和操纵;三是图形,使用节点和边显示一个交互式图形或网络。

     

      时间轴效果可以看这里的 Demo,示例代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <!doctype html>
    <html>
    <head>
    <title>Timeline | Basic demo</title>
    <script src="http://visjs.org/dist/vis.js"></script>
    <link href="http://visjs.org/dist/vis.css" rel="stylesheet" type="text/css" />
     
    <style type="text/css">
    body, html {
    font-family: sans-serif;
    }
    </style>
    </head>
    <body>
    <div id="mytimeline"></div>
     
    <script type="text/javascript">
    var container = document.getElementById('mytimeline');
    var data = [
    {id: 1, content: 'item 1', start: '2013-04-20'},
    {id: 2, content: 'item 2', start: '2013-04-14'},
    {id: 3, content: 'item 3', start: '2013-04-18'},
    {id: 4, content: 'item 4', start: '2013-04-16', end: '2013-04-19'},
    {id: 5, content: 'item 5', start: '2013-04-25'},
    {id: 6, content: 'item 6', start: '2013-04-27'}
    ];
    var options = {};
    var timeline = new vis.Timeline(container, data, options);
    </script>
    </body>
    </html>

      

    立即下载 插件主页

     
    参考: Vis.js – 基于浏览器的动态 JavaScript 可视化库 - 梦想步行者 - CSDN博客
    https://blog.csdn.net/baby_fmm/article/details/25773581
     
     
     

    三、vis.js 小记

     
    简述

    vis.js 基于浏览器的动态可视化库。该库被设计为易于使用,处理大量的动态数据,并支持对数据的操作和交互。该库由组件DataSet,Timeline,Network,Graph2d和Graph3d组成

    文档地址:http://visjs.org/

    小demo(双击折叠展开/隐藏子节点以及位置自定义)

    这里写图片描述

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>visjs关系图-双击折叠展开子节点(隐藏显示子节点)</title>
    </head>
    
    <body>
    <div id="mynetwork" style=" 100%;height: 100%;border: 1px solid lightgray;margin:0 auto;" >0</div>
    </body>
    
    <script type="text/javascript" src="http://visjs.org/dist/vis.js"></script>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"></script>
    <link href="http://visjs.org/dist/vis.min.css" rel="stylesheet" type="text/css"/>
    <script>
    
        var container = document.getElementById('mynetwork');
        var network = null;
        var newNodeArr = [];
        var options;
        var nodesArr = [];
        var edgesArr = [];
        var nodes_data;
        var edges_data;
        var connectedNum = '子节点数:';
    
        $(function (){
    
    //        $('#mynetwork').bind("contextmenu", function(e){ return false; }); // 右键
            // 高度响应式
            clientHeight = document.documentElement.clientHeight;
            clientWidth = document.documentElement.clientWidth;
            $('#mynetwork').css('height',clientHeight-70);
            $('#mynetwork').css('width',clientWidth-180);
    
            var _mydata = {
                "nodes":[
                    {"id":0,"assistId":0,"label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":0,"hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-674","y":"-716","hidden":false},
                    {"id":1,"assistId":1,"name":"网路","label":"网路","image":"http://visjs.org/examples/network/img/refresh-cl/System-Firewall-2-icon.png","shape":"image","pid":1,"hostType":"2","size":22,"isOurDraw":"false","x":"-86","y":"-287","hidden":false},
                    {"id":"1_0","assistId":"1_0","name":"网路","label":"网路","image":"http://visjs.org/examples/network/img/refresh-cl/System-Firewall-2-icon.png","shape":"image","pid":null,"hostType":"2","hostStatus":"1","size":22,"isOurDraw":"false","x":"-75","y":"51","hidden":false},
                    {"id":"1_0_0","assistId":"1_0_0","name":"网路","label":"网路","image":"http://visjs.org/examples/network/img/refresh-cl/System-Firewall-2-icon.png","shape":"image","pid":"1_0","hostType":"2","hostStatus":"1","size":22,"isOurDraw":"false","x":"-54","y":"455","hidden":false},
                    {"id":"1_0_0_0","assistId":"1_0_0_0","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"94","y":"340","hidden":false},
                    {"id":"1_0_0_1","assistId":"1_0_0_1","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-133","y":"641","hidden":false},
                    {"id":"1_0_0_2","assistId":"1_0_0_2","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-167","y":"439","hidden":false},
                    {"id":"1_0_0_3","assistId":"1_0_0_3","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"170","y":"447","hidden":false},
                    {"id":"1_0_0_4","assistId":"1_0_0_4","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"66","y":"435","hidden":false},
                    {"id":"1_0_0_5","assistId":"1_0_0_5","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-224","y":"576","hidden":false},
                    {"id":"1_0_0_6","assistId":"1_0_0_6","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-143","y":"540","hidden":false},
                    {"id":"1_0_0_7","assistId":"1_0_0_7","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-233","y":"374","hidden":false},
                    {"id":"1_0_0_8","assistId":"1_0_0_8","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-120","y":"348","hidden":false},
                    {"id":"1_0_0_9","assistId":"1_0_0_9","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-249","y":"476","hidden":false},
                    {"id":"1_0_0_10","assistId":"1_0_0_10","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"43","y":"532","hidden":false},
                    {"id":"1_0_0_11","assistId":"1_0_0_11","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-30","y":"662","hidden":false},
                    {"id":"1_0_0_12","assistId":"1_0_0_12","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"134","y":"533","hidden":false},
                    {"id":"1_0_0_13","assistId":"1_0_0_13","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-49","y":"576","hidden":false},
                    {"id":"1_0_0_14","assistId":"1_0_0_14","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-6","y":"333","hidden":false},
                    {"id":"1_0_0_15","assistId":"1_0_0_15","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"67","y":"622","hidden":false},
                    {"id":"1_0_1","assistId":"1_0_1","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-24","y":"-123","hidden":false},
                    {"id":"1_0_2","assistId":"1_0_2","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-191","y":"92","hidden":false},
                    {"id":"1_0_3","assistId":"1_0_3","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-227","y":"156","hidden":false},
                    {"id":"1_0_4","assistId":"1_0_4","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-280","y":"75","hidden":false},
                    {"id":"1_0_5","assistId":"1_0_5","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"129","y":"64","hidden":false},
                    {"id":"1_0_6","assistId":"1_0_6","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-169","y":"-25","hidden":false},
                    {"id":"1_0_7","assistId":"1_0_7","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-133","y":"160","hidden":false},
                    {"id":"1_0_8","assistId":"1_0_8","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-183","y":"-108","hidden":false},
                    {"id":"1_0_9","assistId":"1_0_9","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"66","y":"137","hidden":false},
                    {"id":"1_0_10","assistId":"1_0_10","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"101","y":"-35","hidden":false},
                    {"id":"1_0_11","assistId":"1_0_11","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"4","y":"-33","hidden":false},
                    {"id":"1_0_12","assistId":"1_0_12","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-33","y":"154","hidden":false},
                    {"id":"1_0_13","assistId":"1_0_13","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"39","y":"47","hidden":false},
                    {"id":"1_0_14","assistId":"1_0_14","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-126","y":"-127","hidden":false},
                    {"id":"1_0_15","assistId":"1_0_15","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":"1_0","hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-256","y":"-30","hidden":false},
                    {"id":"1_1","assistId":"1_1","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":null,"hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"93","y":"-399","hidden":false},
                    {"id":"1_2","assistId":"1_2","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":null,"hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-267","y":"-365","hidden":false},
                    {"id":"1_3","assistId":"1_3","label":"设备","image":"http://visjs.org/examples/network/img/refresh-cl/Hardware-Laptop-1-icon.png","shape":"image","pid":null,"hostType":"1","hostStatus":"1","size":15,"isOurDraw":"false","x":"-99","y":"-483","hidden":false}
                ],
                "edges":[
                    {"id":"1_0","from":1,"to":"1_0","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0","from":"1_0","to":"1_0_0","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_0","from":"1_0_0","to":"1_0_0_0","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_1","from":"1_0_0","to":"1_0_0_1","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_2","from":"1_0_0","to":"1_0_0_2","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_3","from":"1_0_0","to":"1_0_0_3","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_4","from":"1_0_0","to":"1_0_0_4","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_5","from":"1_0_0","to":"1_0_0_5","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_6","from":"1_0_0","to":"1_0_0_6","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_7","from":"1_0_0","to":"1_0_0_7","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_8","from":"1_0_0","to":"1_0_0_8","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_9","from":"1_0_0","to":"1_0_0_9","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_10","from":"1_0_0","to":"1_0_0_10","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_11","from":"1_0_0","to":"1_0_0_11","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_12","from":"1_0_0","to":"1_0_0_12","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_13","from":"1_0_0","to":"1_0_0_13","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_14","from":"1_0_0","to":"1_0_0_14","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_0_15","from":"1_0_0","to":"1_0_0_15","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_1","from":"1_0","to":"1_0_1","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_2","from":"1_0","to":"1_0_2","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_3","from":"1_0","to":"1_0_3","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_4","from":"1_0","to":"1_0_4","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_5","from":"1_0","to":"1_0_5","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_6","from":"1_0","to":"1_0_6","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_7","from":"1_0","to":"1_0_7","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_8","from":"1_0","to":"1_0_8","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_9","from":"1_0","to":"1_0_9","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_10","from":"1_0","to":"1_0_10","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_11","from":"1_0","to":"1_0_11","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_12","from":"1_0","to":"1_0_12","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_13","from":"1_0","to":"1_0_13","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_14","from":"1_0","to":"1_0_14","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_0_15","from":"1_0","to":"1_0_15","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_1","from":1,"to":"1_1","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_2","from":1,"to":"1_2","color":{"color":"#ccc"},"hidden":false},
                    {"id":"1_3","from":1,"to":"1_3","color":{"color":"#ccc"},"hidden":false}
                ]
            };
            draw(_mydata);
        });
    
    
        function draw(data){
            var  options = {
                nodes : {
                    font:{
                        color: "#888",
                        size: 10
                    }
                },
                edges: {
                    smooth: false, //是否显示方向箭头
                    color: "#333" // 线条颜色
                },
                layout: {
                    improvedLayout:false
                },
                interaction: {
                    navigationButtons: true, // 如果为真,则在网络画布上绘制导航按钮。这些是HTML按钮,可以使用CSS完全自定义。
                    keyboard: {
                        enabled: true,
                        speed: {
                            x: -1,
                            y: -1,
                            zoom: 0.02
                        },
                        bindToWindow: true
                    } // 启用键盘快捷键
                },
                physics: {
                    stabilization: false,
                    barnesHut: {
                        centralGravity: 8, // 中心重力吸引器将整个网络拉回中心
                        springLength: 80, // 边缘被建模为弹簧。这个弹簧长度是弹簧的剩余长度
                        gravitationalConstant: -80000, // 重力吸引。我们喜欢排斥 所以价值是负数。如果你想要排斥力更强,减小值(所以-10000,-50000)。
                        avoidOverlap: 0.2, // 接受范围:[0 .. 1]。当大于0时,会考虑节点的大小。该距离将由重力模型的节点的包围圆的半径计算。值1是最大重叠避免。
                        damping: 0.3,
                        springConstant: 0.5
                    },
                    minVelocity: 16 // 一旦达到所有节点的最小速度,我们假设网络已经稳定,仿真停止。
                }
            };
    
            network = new vis.Network(container, data, options);
            nodes_data = network.body.data.nodes;
            edges_data = network.body.data.edges;
    
            //动画稳定后的处理事件
            var stabilizedTimer;
            network.on("stabilized", function (params) { // 会调用两次?
                window.clearTimeout(stabilizedTimer);
                stabilizedTimer = setTimeout(function(){
                    exportNetworkPosition(network);
                    options.physics.enabled = false; // 关闭物理系统
                    network.setOptions(options);
                },200);
            });
    
            // 右键
            network.on("oncontext",function(params){});
    
            //选中节点
            network.on("selectNode", function (params) {});
    
            //单击节点
            network.on("click", function (params) {});
    
            //双击节点 隐藏或者显示子节点
            network.on("doubleClick", function (params) {
                if ( params.nodes.length != 0) { // 双击的是节点
                    var _node = params.nodes[0];
                    var _nodeName = nodes_data._data[_node].name;
                    var _allChild = getAllChilds(network,_node,[]);
                    if(_allChild.length > 0 ){ // 存在子节点
                        if( nodes_data._data[_allChild[_allChild.length-1]].hidden == false){
                            nodes_data.update([{id:_node,label:_nodeName + "  "+connectedNum+_allChild.length}]);
                            for(var i=0;i<_allChild.length;i++){
                                nodes_data.update([{id:_allChild[i], hidden:true}]);
                                edges_data.update([{id:_allChild[i], hidden:true}]);
                            }
                        }else{
                            nodes_data.update([{id:_node, label:_nodeName}]);
                            for(var j=0;j<_allChild.length;j++){
                                nodes_data.update([{id:_allChild[j], hidden:false}]);
                                edges_data.update([{id:_allChild[j], hidden:false}]);
                            }
                        }
                    }
                }
            });
    
            //拖动节点
            network.on("dragging", function (params) {//拖动进行中事件
                if (params.nodes.length != 0 ) {
                    nodeMoveFun(params);
                }
            });
    
            //拖动结束后
            network.on("dragEnd", function (params) {
                if (params.nodes.length != 0 ) {
                    var arr = nodeMoveFun(params);
                    exportNetworkPosition(network,arr);
                }
            });
    
            // 缩放
            network.on("zoom", function (params) {});
        }
    
        /*
         *获取所有子节点
         * network :图形对象
         * _thisNode :单击的节点(父节点)
         * _Allnodes :用来装子节点ID的数组
         * */
        function getAllChilds(network,_thisNode,_Allnodes){
            var _nodes = network.getConnectedNodes(_thisNode,"to");
            if(_nodes.length > 0){
                for(var i=0;i<_nodes.length;i++){
                    getAllChilds(network,_nodes[i],_Allnodes);
                    _Allnodes.push(_nodes[i]);
                }
            }
            return _Allnodes
        };
    
        // 节点移动
        function nodeMoveFun(params){
            var click_node_id = params.nodes[0];
            var allsubidsarr = getAllChilds(network,click_node_id,[]); // 获取所有的子节点
    
            if(allsubidsarr){ // 如果存在子节点
                var positionThis = network.getPositions(click_node_id);
                var clickNodePosition = positionThis[click_node_id]; // 记录拖动后,被拖动节点的位置
                var position = JSON.parse(localStorage.getItem("position"));
                var startNodeX,startNodeY; // 记录被拖动节点的子节点,拖动前的位置
                var numNetx,numNety; // 记录被拖动节点移动的相对距离
                var positionObj={}; // 记录移动的节点位置信息, 用于返回
    
                positionObj[click_node_id] =  {x:clickNodePosition.x, y:clickNodePosition.y}; // 记录被拖动节点位置信息
                numNetx = clickNodePosition.x - position[click_node_id].x; // 拖动的距离
                numNety = clickNodePosition.y - position[click_node_id].y;
    
                for(var j =0;j<allsubidsarr.length;j++){
                    if(position[allsubidsarr[j]]) {
                        startNodeX = position[allsubidsarr[j]].x; // 子节点开始的位置
                        startNodeY = position[allsubidsarr[j]].y;
                        network.moveNode(allsubidsarr[j], (startNodeX + numNetx), (startNodeY + numNety)); // 在视图上移动子节点
                        positionObj[allsubidsarr[j]] =  {x:(startNodeX + numNetx), y:(startNodeY + numNety)}; // 记录子节点位置信息
                    }
                }
            }
            return positionObj;
        };
    
        /*
         *节点位置设置
         * network :图形对象
         * arr :本次移动的节点位置信息
         * */
        function exportNetworkPosition(network,arr){
            if(arr){ // 折叠过后  getPositions() 获取的位置信息里不包含隐藏的节点位置信息,这时候调用上次存储的全部节点位置,并修改这次移动的节点位置,最后保存
                var localtionPosition = JSON.parse(localStorage.getItem("position"));
                for(let index in arr ){
                    localtionPosition[index] = {
                        x:arr[index].x,
                        y:arr[index].y
                    }
                }
                setLocal(localtionPosition);
    
            }else{
                var position = network.getPositions();
                setLocal(position);
            }
        };
        //处理本地存储,这里仅仅只能作为高级浏览器使用,ie9以下不能处理
        function setLocal(position) {
            localStorage.removeItem("position");
            localStorage.setItem("position",JSON.stringify(position));
        }
    </script>
    </html>
    添加节点以及添加连线的方法
    1. 简单的添加两个节点,以及一条连线(除此之外 nodes 和 edges 还支持 updateremove 操作)
    network.body.data.nodes.add([{id: "addNode01",label: "add01",level: 5},{id: "addNode02",label: "add02",level: 5}]);
    network.body.data.edges.add([{id: "addEdge01",from: "addNode01",to: "addNode02"}]);

    这里写图片描述
    2. 比较复杂的在线编辑,在 option 中启用 manipulation 配置:addNode、editNode、deleteNode、addEdge、editEdge 和 deleteEdge。

    var options = {
                autoResize: true, // Default:true  如果为true,则网络将自动检测其容器何时调整大小,并相应地重新绘制自己。如果为false,则可以在使用函数redraw()和setSize()调整容器的容器大小后强制重新绘制网络。
                clickToUse: false, // Default:false  将网络配置clickToUse为时,只有在激活时才会对鼠标和触摸事件做出反应。激活时,网络周围会显示蓝色阴影边框。通过点击该网络将网络设置为活动状态,然后通过点击网络外部或按ESC键将其更改为非活动状态。
                 "100%", // 画布的宽度。可以百分比或像素
                height: "100%",
                locale: "cn", // 选择区域设置。默认情况下,该语言是英语。
                locales: locales, // 语言环境 默认情况下 'en', 'de', 'es', 'it', 'nl' 'pt-br', 'ru' 的支持。
                configure: {
                    enabled: false, // 打开或关闭配置界面。
                    filter:  function(option, path){
                        return path.indexOf('physics') !== -1
                    }, // 如果布尔值为true,则给出所有选项,false将不显示任何值。 如果提供了字符串,则允许以下任意组合:节点,边,布局,交互,操纵,物理,选择,渲染器。随意想出一个有趣的分开的字符。最后,当提供一个字符串数组时,任何前面提到的字段都被接​​受。当提供一个函数时,你会收到两个参数。选项对象中的选项和选项的路径。如果它返回true,则选项将显示在配置程序中。
    //              container:  undefined,
                    showButton: true // 在配置器底部显示生成选项按钮。
                },
                nodes : {
                    font:{
                        color: "#eee",
                        size: 10
                    }
                },
                edges: {
                    smooth: {
                        enabled: true,
                        type: 'cubicBezier', // 'dynamic', 'continuous', 'discrete','diagonalCross', 'horizontal', 'vertical', 'curvedCW', 'curvedCCW', 'cubicBezier'
                        forceDirection: 'vertical', //'horizontal', 'vertical', 'none' 该选项仅用于cubicBezier曲线。
                        roundness: 0.7 // 0 .. 1.0
                    },
                    color: "#737373" // 线条颜色
                },
                layout: { // 自动层级布局
                    improvedLayout:false,
                    hierarchical: {
                        enabled:true, //切换分层布局系统
                        levelSeparation: 260,//不同级别之间的距离。
                        nodeSpacing:260,// 自由轴上节点之间的最小距离,这仅适用于初始布局。如果启用物理,则节点距离将存在有效的节点距离。
                        treeSpacing:260,//不同树木之间的距离(独立网络)
                        blockShifting: false, // 每个节点都会检查空白,并尽可能地将它的分支与它一起移动,并在任何级别上考虑nodeSpacing
                        edgeMinimization: false, // 每个节点将尝试沿其自由轴移动以减少其边缘的总长度
                        parentCentralization: false, // 如果为true,则布局算法完成后,父节点将再次居中。
                        direction:'UD', // UD, DU, LR, RL
                        sortMethod: 'directed' // directed hubsize
                    }
                },
    
                manipulation: {
                    enabled: true,
                    addNode: function(data,callback){
                        document.getElementById('node-type').value = "1";
                        document.getElementById('node-label').value = "";
                        document.getElementById('saveButton').onclick = saveData.bind(this, data, callback);
                        document.getElementById('cancelButton').onclick = clearPopUp.bind();
                        document.getElementById('network-popUp').style.display = 'block';
                    },
                    editNode: function(data,callback){
                            document.getElementById('node-label').value = deviceName;
                            document.getElementById('saveButton').onclick = saveEditData.bind(this, data, callback);
                            document.getElementById('cancelButton').onclick = cancelEdit.bind(this,callback);
                            document.getElementById('network-popUp').style.display = 'block';
                        }
                    },
                    deleteNode: function(data,callback){
                            // do something
                            if(isDo){
                                callback(data); // 操作成功
                            }else{
                                callback(null); // 操作失败
                            }
                    },
                    addEdge: function (data, callback) {
                            // do something
                            if(isDo){
                                callback(data); // 操作成功
                            }else{
                                callback(null); // 操作失败
                            }
                    },
                    editEdge: false, // 关系不可编辑
                    deleteEdge: function(data,callback){
                            // do something
                            if(isDo){
                                callback(data); // 操作成功
                            }else{
                                callback(null); // 操作失败
                            }
                    }
                },
                interaction: {
                    hover: true,
                    navigationButtons: true, // 如果为真,则在网络画布上绘制导航按钮。这些是HTML按钮,可以使用CSS完全自定义。
                    keyboard: {
                        enabled: true,
                        speed: {
                            x: -1,
                            y: -1,
                            zoom: 0.02
                        },
                        bindToWindow: false
                    } // 启用键盘快捷键
                },
                physics: { // 采用分层布局系统,关闭物理布局
                    enabled: false,
                    stabilization: false,
                    barnesHut: {
                        centralGravity: 8, // 中心重力吸引器将整个网络拉回中心
                        springLength: 80, // 边缘被建模为弹簧。这个弹簧长度是弹簧的剩余长度
                        gravitationalConstant: -80000, // 重力吸引。我们喜欢排斥 所以价值是负数。如果你想要排斥力更强,减小值(所以-10000,-50000)。
                        avoidOverlap: 0.2, // 接受范围:[0 .. 1]。当大于0时,会考虑节点的大小。该距离将由重力模型的节点的包围圆的半径计算。值1是最大重叠避免。
                        damping: 0.3,
                        springConstant: 0.5
                    },
                    minVelocity: 16 // 一旦达到所有节点的最小速度,我们假设网络已经稳定,仿真停止。
    //              stabilization: {//如果开启,下面注释掉的监听图形绘制过程的函数才会生效
    //               enabled:true,
    //               iterations:2000,
    //               updateInterval:25
    //              }
                }
            };
    查询设备
        /**
         * 查找设备 
         * @param name 设备名称/SN/MAC
         */
        function findDevice(name){
            var nodes = network.body.data.nodes._data;
            for(var i in nodes){
                if(nodes[i].label== name || nodes[i].hostSn == name || nodes[i].hostMac == name){ // 具体需要可在此配置
                    network.focus(nodes[i].id,{
                        scale:2
                    });
                    return
                }
            }
            layer.msg("查找的设备不存在!", {icon: 5});
        }

     
     
    参考:vis.js 小记 - river、的博客 - CSDN博客
    https://blog.csdn.net/qq_39759115/article/details/78594831
     
     
     
  • 相关阅读:
    restframework 使用OrderingFilter实现排序
    restframework 使用django_filters 实现过滤
    Serializer 嵌套使用
    docker 运行scrpyd
    flutter-lol云顶之弈助手app
    微信小程序上传多张图片,后端只保存了最后一张的Bug
    ettercap局域网arp欺骗,轻松窃密
    GoLang邮件发送Demo(继上篇msmtp)
    Mac下命令行发邮件【搭配php(shell_exec...)等脚本语言,轻松发邮件,告别各种依赖库】
    我的第一个RN应用(漂亮的首页和笑话列表)
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/9863258.html
Copyright © 2020-2023  润新知