Vue 使用 vis-network 绘制网络关系图

1、Vis-network

visjs 提供了一个网络视图模块,提供给我们绘制网络之间的各个点、线之间的关系,这个的话就比较类似于echarts的地图,在地图上打点画线的逻辑,区别在于使用visjs可以拖动节点的位置、以及visjs里面还有对物理引擎等的引入。

网络是一种可视化,用于显示由节点和边组成的网络和网络。可视化易于使用,并支持自定义形状、样式、颜色、大小、图像等。网络可视化可在任何现代浏览器上流畅运行,最多可容纳数千个节点和边。为了处理大量节点,Network 支持集群。

官网地址:https://visjs.org/index.html

2、vis-network 网络视图模块的基本使用

首先先安装依赖

npm install vis-network

安装之后在vue当中导入vis-network模块

  require("vis-network/dist/dist/vis-network.min.css");
  const vis = require("vis-network/dist/vis-network.min");

之后就是直接进行使用该模块进行绘制网络视图了。
在这里插入图片描述
查看基本的网络图的效果
在这里插入图片描述
这里的话这种代码的篇幅还是有点太长了,就不贴源码了,可在下方gitee当中查看(/src/components/vis/index.js)。其中options配置可以在对应的官方文档当中查看对应的配置是代表什么意思。

代码见 https://gitee.com/modify_lzq/web-lzq-echarts.git
官网英文文档 https://visjs.github.io/vis-network/docs/network/
中文文档 https://ame.cool/pages/a7d858/

3、vis-network 节点展示类型

在节点设置当中提供了一个节点的外观配置(shape)有两种类型的节点。

  • 一类是标签在节点内部: ellipse(椭圆), circle(圆), database(数据库), box(盒子), text(文本)
  • 另一类是标签在节点下面: image(图片), circularImage(圆图), diamond(菱形), dot(圆点), star(星型), triangle(三角形), triangleDown(倒三角), hexagon(六边形), square(正方形)和 icon(图标)。

这里就只对image对象进行说明:首先我们导入两张图片进来

  import iconA from './image/iconA.png'
  import iconB from './image/iconB.png'

在节点配置形状的时候,有一个image配置:当形状设置为image或circularImage时,此选项应为图像的URL。如果找不到图像,可以使用brokenimage选项。

但是这种只适用于整个关系图上的所有节点都是同意图标,但是我们如果要对图标进行区分呢?

我们可以给节点新增一个image属性,这样在进行渲染节点的时候会使用该属性作为节点的image图像。

let nodes = [{id: 1, x: 10, y: 10, label: '1', image: iconA }]

但是这样设置的话,在这个nodes节点对象当中每一个节点都应该加上这个image属性,否则会报错image must be defined for node type 'image' 必须为节点类型“图像”定义图像
在这里插入图片描述

4、vis-network 边颜色展示

对于边来说,我们可以在配置文档当中看到,可以对边的颜色进行设置,其中包含了:未选中或悬停在边上时的颜色、选中边时的颜色、鼠标悬停在边缘上时的颜色、颜色继承、边的不透明度。

            color: {
              color: "#000",
              highlight: "#000",
              hover: "#000",
              inherit: "from",
              opacity: 1,
            },

对于这些来说,我们可以直接在options下的edges下进行配置,这样的话还是和上面的节点展示一样,所有的线都是一样的,如何给他设置不一样的颜色以及其他的样式呢?在前面给节点设置不同的图片的时候,其实就可以看出一点端倪了,我们直接给他的节点对象加image属性,那么边对象能不能直接加color属性呢?

	let edges = [{id: 1, from: 1, to: 2, color:'red'}, 
				 {id: 2, from: 3, to: 2, color: {color:'red', highlight:'blue' } }]

本着举一反三的态度,我们来试一试。可以看到,效果出来了,由此我们可以发现当对于同一元素需要设置不同的样式或者配置时,我们可以通过修改其数据对象进行配置

5、vis-network 边类型展示

在边进行显示的时候,提供了一个smooth.type属性,可能的选项: dynamic(动态曲线), continuous(连续), discrete(离散), diagonalCross(对角交叉), straightCross(直线交叉), horizontal(水平), vertical(垂直), curvedCW(顺时针曲线), curvedCCW(逆时针曲线), cubicBezier(贝塞尔曲线)。

这里我们主要要解决的是,当边的起始节点一致是存在多条边,但是只会在页面上绘制一条线的问题,在前文的基础上,看到这里其实或多或少的知道怎么去设置了。这里我们在options里面设置边的类型为直线,之后我们只需要判断那些边是重复(这里就不做判断了)。之后直接给重复的边的形状换成其他曲线类型即可。

	let edges = [{ id: 4, from: 1, to: 3, smooth: { type: "discrete" }}]

设置完成后查看效果:

在这里插入图片描述

5、自动布局

在不知道节点的具体位置的时候,我们可以使用vis提供的引擎进行自动布局。

        physics: {
          barnesHut: {
            // 引力常数   节点之间的引力强度。负值表示排斥力,正值表示吸引力。更大的值会增加节点之间的相互吸引或排斥的强烈程度
            gravitationalConstant: -10000,
            // 弹簧常数   节点链接之间的弹性力强度。该值越大,节点之间的连接线就会变得更紧密和更有张力
            springConstant: 0.01,
            // 弹簧长度   节点链接的自然长度。当链接的实际长度小于这个值时,会产生收缩力;当实际长度大于这个值时,会产生拉伸力。这个值指定了通过控制节点之间连接线的张力来调整布局的紧密程度。
            springLength: 100,
            // 中心引力   整个图的中心位置对节点的吸引力或排斥力的影响程度。较大的值会将节点聚焦到图的中心,较小的值会让节点更倾向于分散到整个布局
            centralGravity: 0.1
          }
        },

在这里插入图片描述

  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
可以通过以下步骤来实现: 1. 安装 vis-networkvis-util: ```bash npm install vis-network vis-util --save ``` 2. 在 Vue 组件中引入 vis-network: ```javascript import { Network } from 'vis-network/standalone/esm/vis-network' import 'vis-network/styles/vis-network.min.css' ``` 3. 在 Vue 组件中创建一个容器来放置 vis-network: ```html <div ref="networkContainer" style="height: 500px;"></div> ``` 4. 在 Vue 组件中初始化 vis-network,并设置节点和边: ```javascript mounted() { const container = this.$refs.networkContainer const data = { nodes: [ { id: 1, label: 'Node 1' }, { id: 2, label: 'Node 2' }, { id: 3, label: 'Node 3' } ], edges: [] } const options = {} this.network = new Network(container, data, options) } ``` 5. 监听节点拖拽事件,获取节点位置: ```javascript this.network.on('dragEnd', (event) => { const nodeId = event.nodes[0] const nodePosition = this.network.getPositions([nodeId])[nodeId] console.log(nodePosition) }) ``` 6. 监听边创建事件,获取边的起始节点和结束节点: ```javascript this.network.on('beforeDrawing', (ctx) => { this.network.getSelectedEdges().forEach(edgeId => { const edge = this.network.body.edges[edgeId] const fromNode = this.network.body.nodes[edge.from] const toNode = this.network.body.nodes[edge.to] const fromPosition = fromNode.getCenterPosition() const toPosition = toNode.getCenterPosition() console.log(fromPosition, toPosition) }) }) ``` 7. 监听鼠标事件,创建连线: ```javascript let fromNodeId = null this.network.on('click', (event) => { if (event.nodes.length > 0) { fromNodeId = event.nodes[0] } }) this.network.on('doubleClick', (event) => { if (event.nodes.length > 0) { const toNodeId = event.nodes[0] const edgeId = this.network.addEdge(fromNodeId, toNodeId) this.network.selectEdges([edgeId]) fromNodeId = null } }) ``` 这样就可以实现动态拖拽连线了。完整的代码示例可以参考以下链接: https://codesandbox.io/s/vue-vis-network-dynamic-draggable-edges-7m2yf?file=/src/components/Network.vue
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Modify_QmQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值