美文网首页
用vis实现网络拓扑图

用vis实现网络拓扑图

作者: 江湖小盛 | 来源:发表于2022-07-02 22:45 被阅读0次

    需求背景:

    1、实现一个网络拓扑图的可视化界面
    2、能和后台数据进行动态绑定渲染
    3、实现交互功能(拖拽、放大缩小、悬停提示等)

    安装&使用

    在项目中引入 vis有以下两种方式:NPM 引入和CDN 引入。

    1、在项目中使用 NPM 包引入
    step1: 安装vis到项目

    npm install vis --save
    

    step2: 在js文件或者vue文件中引入vis

    import vis from vis
    

    2、在 HTML 中使用 CDN 引入

     <script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
    

    快速入门

    创建一个vis 的拓扑图图仅需要下面几个步骤:
    1、创建关系图的 HTML 容器
    2、数据准备
    3、获取容器
    4、初始化拓扑图

    step1: 创建容器
    需要在 HTML 中创建一个用于容纳 vis绘制的图的容器,并且为容器设置宽高, vis 在绘制时会在该容器下追加 canvas 标签,然后将图绘制在其中。

    <style type="text/css">
        #mynetwork {
            width: 600px;
            height: 400px;
       }
        </style>
    
    <div id="mynetwork"></div>
    

    step2: 数据准备
    引入vis 的数据源为 JSON 格式的对象。该对象中需要有节点(nodes)和边(edges)字段,分别用数组表示:

       // 创建节点数据数组
        var nodesData= 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" }
        ]);
    
        // 创建边数据数组
        var edgesData= new vis.DataSet([
            { from: 1, to: 3 },
            { from: 1, to: 2 },
            { from: 2, to: 4 },
            { from: 2, to: 5 },
            { from: 3, to: 3 }
        ]);
    
       // 将数据赋值给vis 数据格式化器
        var data = {
          nodes: new vis.DataSet(nodesData),
          edges: new vis.DataSet(edgesData)
        };
        var options = {};
    

    注意:

    • nodes 数组中包含节点对象。每个节点对象中唯一的、必要的 id 以标识不同的节点.
    • edges 数组中包含边对象。from和 to是每条边的必要属性,分别代表了该边的起始点 id 与 目标点 id
    • options中可以定制化配置节点和边

    step3: 获取容器

    var container = document.getElementById('mynetwork');
    

    step4: 初始化拓扑图

    var network = new vis.Network(container, data, options);
    

    节点部分配置

    1、节点形状、大小、缩放

    nodes: {
      shape:  'dot',
      size: 20,
      scaling: {
         min: 10,
         max: 5,
         label:true
       },
    }
    

    注意:定义节点的外观。有两种类型的节点

    • 一类是标签在节点内部: ellipse, circle, database, box, text
    • 另一类是标签在节点下面: image, circularImage, diamond, dot, star, triangle, triangleDown, hexagon, square和 icon。
    • size 配置只适用于标签在节点下面的形状。
    • scaling 配置 标签在节点内部的,只有在启用标签缩放时才会有效
    • 使用缩放时,将忽略大小选项

    下图是节点形状汇总:


    节点形状.png

    2、节点部分样式配置

    nodes: {
      font: { // 设置字体
         color: '#000',
         size: 16,
      },
      borderWidth: 1, // 节点边框的宽度
      borderWidthSelected: 3, , // 节点被选中时边框的宽度
      color: {
        border: '#2B7CE9',  // 节点边框颜色
        background: '#97C2FC',  // 节点背景色
        hover: { // 节点鼠标滑过时状态颜色
            border: 'blue',
            background: '#D2E5FF'
         }
     },
     shadow: true,  // 节点阴影
     fixed: false,  // 拖拽节点是否可移动,true,不可移动。
    }
    

    边部分配置

    1、边的箭头配置

    edges: {
      arrows: {
        to: { // 指向目标点的箭头
            enabled: true,
            type: "arrow"
         },
        from: { // 指向起始点的箭头
            enabled: true,
            type: "arrow"
         }
      },
    }
    

    2、边的线条配置

    edges: {
      smooth: {
         enabled: true, // 打开和关闭平滑曲线
         type: "cubicbezier", // 线条类型
         roundness: 0.2 // 线条平滑度
         forceDirection:'horizontal' // 用于分层布局的配置项
       },
       hoverWidth: 2 //悬停于线条上的宽度
    }
    

    注意:

    • type可能的选项: dynamic, continuous, discrete, diagonalCross, straightCross, horizontal, vertical, curvedCW, curvedCCW, cubicBezier。
    • forceDirection选项仅用于cubicbezier曲线

    布局配置

    layout: {
        improvedLayout: true,  // 关系图将使用‘’Kamada Kawai‘’算法进行初始布局
        clusterThreshold: 150, // 集群阈值
        hierarchical: { // 层次布局
          enabled: true,
          direction: 'UD',        // UD, DU, LR, RL
          sortMethod: 'hubsize',  // hubsize, directed
          shakeTowards: 'leaves'  // roots, leaves
        }
      }
    

    交互配置

    interaction:{
        dragNodes:true,
        dragView: true,
        hover: true,
        hoverConnectedEdges: true,
        zoomView: true
      }
    

    简易demo

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <title>Network</title>
      <script type="text/javascript" src="./js/vis-network.min.js"></script>
      <style type="text/css">
        #mynetwork {
           width: 600px;
           height: 600px;
           border: 1px solid lightgray;
        }
      </style>
    </head>
    
    <body>
      <div id="mynetwork"></div>
      <script type="text/javascript"> 
    
      var nodesData = [
        { id: 0, label: "Node 0"},
        { 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" },
        { id: 6, label: "Node 6" },
        { id: 7, label: "Node 7" },
        { id: 8, label: "Node 8" },
        { id: 9, label: "Node 9" },
        { id: 10, label: "Node 10" },
        { id: 11, label: "Node 11" },
        { id: 12, label: "Node 12" },
        { id: 13, label: "Node 13" },
        { id: 14, label: "Node 14" },
      ]
    
      var edgesData = [
        { from: 0, to: 1, label: '数值:1' },
        { from: 0, to: 6, label: '数值:1' },
        { from: 0, to: 13, label: '数值:1' },
        { from: 0, to: 11, label: '数值:1' },
        { from: 1, to: 2, label: '数值:1' },
        { from: 2, to: 3, label: '数值:1' },
        { from: 2, to: 4, label: '数值:1' },
        { from: 3, to: 5, label: '数值:1' },
        { from: 1, to: 10, label: '数值:1' },
        { from: 1, to: 7, label: '数值:1' },
        { from: 2, to: 8, label: '数值:1' },
        { from: 2, to: 9, label: '数值:1' },
        { from: 3, to: 14, label: '数值:1' },
        { from: 1, to: 12, label: '数值:1' }
      ]
    
        // 获取容器
        var container = document.getElementById('mynetwork');
    
        // 将数据赋值给vis 数据格式化器
        var data = {
          nodes: new vis.DataSet(nodesData),
          edges: new vis.DataSet(edgesData)
        };
        
        var options = { 
          // 节点配置
          nodes: {
            shape: 'dot',
            font: {
              color: '#000',
              size: 16,
            },
            borderWidth: 1,
            borderWidthSelected: 3,
            color: {
              border: '#2B7CE9',
              background: '#97C2FC',
              hover: {
                border: 'blue',
                background: '#D2E5FF'
              }
            },
            shadow: true,
            fixed: false, 
            scaling: {
              min: 10,
              max: 5,
              label: true
            },
            // size: 30
          },
          // 边配置
          edges: {
            arrows: {
              to: {
                enabled: true,
                type: "arrow"
              }
            },
            smooth: {
              enabled: true,
              type: "curvedCW",
              roundness: 0.2
            },
            hoverWidth: 2
          },  
          interaction: {
            hover: true,
            hoverConnectedEdges: true,
          },
          // 布局
          layout: {
            improvedLayout: true,
            hierarchical: { 
              direction: "LR",
              sortMethod: 'directed', // directed hubsize
              shakeTowards: 'roots', // roots leaves  
            }
          },
        };
    
        // 初始化关系图
        var network = new vis.Network(container, data, options);
    
      </script>
    </body>
    
    </html>
    
    demo.png

    相关文章

      网友评论

          本文标题:用vis实现网络拓扑图

          本文链接:https://www.haomeiwen.com/subject/pgdfbrtx.html