用vis实现网络拓扑图

2022-07-02  本文已影响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 = {};

注意:

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
   },
}

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

下图是节点形状汇总:


节点形状.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 //悬停于线条上的宽度
}

注意:

布局配置

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
上一篇下一篇

猜你喜欢

热点阅读