文章目录

  • 前言
  • vis与vis-network认识
  • vis-network使用排坑
  • vis-network配置
  • 开发时注意的功能点
    • 1.性能问题
    • 2.是否有环路情况
    • 3.位置保存还是状态保持
    • 4.展开收缩
    • 5.分页器
    • 6.节点是否可拖动
    • 7.编辑拓扑关系
  • 总结

前言

我自己了解到的绘制拓扑图的开源库有vis和阿里的G6,G6在项目中没机会使用,只用到的vis,有时间再玩一下G6,G6好像比vis功能强大一些,下面主要说一下vis。

vis与vis-network认识

我接手拓扑项目时,项目中使用的是vis。现场反馈一个需求,说是要自定义线条的箭头。我在官网上看到可以进行自定义箭头,但是一使用就是报错,很是郁闷不理解。

在查阅大量资料后,发现有demo竟然没有完全引入vis,单独引入了vis框架中的一个vis-network,也可以成功绘制拓扑图。紧接着去研究vis与vis-network的区别,研究发现vis-network是vis框架中的一个功能组件,主要是用来绘制拓扑图,而且拓扑项目中也只使用到了vis框架中的绘制拓扑图功能。于是在项目中将vis更换成最新版本的vis-network,并进行自定义箭头的尝试,发现可以进行自定义箭头,满足项目的需求。

因此我建议如果项目中只使用到了绘制拓扑图能力时,只引入vis-network即可,这样引入的包体积减小,可使用的功能更多。

npm install vis-network@9.1.0  (安装的是 ^9.1.0 版本) 当时network的最新版本
// 这里最好使用ESModule的模块引入方式,这里我不修改了,有使用到自己研究修改
const vis = require("vis-network/dist/vis-network.min.js"); // vis-network 引入方式

vis-network使用排坑

  • 使用vis-network不要使用vis,首先是vis是多个功能板块的集合,项目中只会使用到其中的vis-network;还有虽然vis-network包含在vis中,但是有些功能在vis中无法使用,使用了就会报错。如线条的箭头图标改为image类型。
  • vis-network绘制出来后,激活拓扑图会自带outline,但是找不到哪个元素添加的outline,需添加以下代码:* { outline: none; }
  • nodes节点模块,使用title时,需自己手调样式,否则页面上不会展示。
    ::v-deep .vis-tooltip {position: absolute;visibility: visible;}
  • 可视化操作模块manipulation,在vis-network中使用会报错,目前不知道原因,可能是版本问题。在vis中可以使用,需要自己调样式,而且感觉这个可视化操作不怎么好用,用处不大。
  • 放大缩小按钮等需自己手调样式才会展示,都是拓扑图中自带的,只是因为样式问题没有显示出来。
  • 拓扑图分层级时,同层级从左往右的节点顺序:①当节点无x轴坐标时,与edges线条数组中的连接顺序有关。②当有x轴坐标时,以坐标值大小为准。

vis-network配置

配置有很多,直接写一个小案例放上配置吧。

<template><div id="mynetwork" ref="mynetwork"></div>
</template><script>
const vis = require("vis-network/dist/vis-network.min.js");
export default {name: 'HelloWorld',props: {msg: String},data() {return {nodes: null,edges: null,options: null,network: null,}},created() {this.nodes = new vis.DataSet([  // nodes是节点{id: 1, label: 'Node 1',level: 1},{id: 2, label: 'Node 2',level: 2},{id: 8, label: 'Node 8',level: 2},{id: 9, label: 'Node 9',level: 2},{id: 10, label: 'Node 10',level: 2},{id: 3, label: 'Node 3',level: 2},{id: 4, label: 'Node 4',level: 3},{id: 5, label: 'Node 5',level: 3},{id: 6, label: 'Node 6',level: 4},{id: 7, label: 'Node 7',level: 5},]);this.edges = new vis.DataSet([  // edges是线{from: 1, to: 2},  // 决定了节点从左往右的顺序{from: 1, to: 3},{from: 1, to: 8},{from: 1, to: 9},{from: 1, to: 10},{from: 2, to: 4},{from: 2, to: 5},{from: 5, to: 6},{from: 6, to: 7},]);},mounted() {this.init()},methods: {init() {const container = this.$refs.mynetwork;const data = {nodes: this.nodes,edges: this.edges}this.options = {autoResize: true, // 默认true,自动调整容器的大小height: '100%', // 默认值width: '100%',  // 默认值locale: 'cn',   // 选择语言,默认英文en,cn为汉语locales: {      // 语言格式化对象cn: {edit: '编辑',del: '删除',back: '返回',addNode: '添加节点',addEdge: '添加连线',editNode: '编辑节点',editEdge: '编辑连线',addDescription: '点击空白区域添加节点',edgeDescription: 'Click on a node and drag the edge to another node to connect them.',editEdgeDescription: 'Click on the control points and drag them to a node to connect to it.',createEdgeError: 'Cannot link edges to a cluster.',deleteClusterError: 'Clusters cannot be deleted.',editClusterError: 'Clusters cannot be edited.',},},// 配置模块configure: {enabled: false, // false时不会在界面上出现各种配置项 },// 节点模块nodes: {chosen: true, // 对选择节点做出反应color: {border: '#2B7CE9',background: '#97C2FD',highlight: {border: '#2B7CE9',background: '#FFEC8B'},hover: {border: '#2B7CE9',background: '#FFC125'}},font: {align: 'left',color: '#FFC125',size: 12// vadjust: 10, // 标签文本的垂直位置,值越大离节点越远},labelHighlightBold: false,// hidden: true, // 为true不会显示节点。但仍是物理模拟的一部分shape: 'image',image: {    // 路径问题要注意,一定要存储在静态文件夹中unselected: '/static/images/icon_normal.svg',selected: '/static/images/icon_selected.svg',},size: 25, // 节点大小physics: false, // 关闭物理引擎title: '哈哈哈', // 用户悬停在节点上时显示的标题,可以是HTML元素或包含纯文本或HTML的字符串widthConstraint: { // 节点的最小宽度与最大宽度// maximum: 100,}},// 边模块edges: {// label: '哈哈哈',physics: false,smooth: {enabled: true,type: 'curvedCCW', // 平滑曲线的类型forceDirection: 'horizontal' // 用于分层布局的配置项,可选值有: ['horizontal', 'vertical', 'none']},// arrows: {  // 这里可以用来自定义箭头,type为image类型即可// middle: { enabled: true, type: 'image', imageHeight: 12, imageWidth: 12, src: getOpticalRed() }// },},// 交互模块interaction: {hover: true, // 启用鼠标悬停hoverConnectedEdges: false, // 鼠标悬停在节点上时,与其连接的边不高亮显示hideEdgesOnDrag: false, // true时拖动视图时不会绘制边。这会加快拖动时的响应速度hideNodesOnDrag: false, // true时拖动视图时不会绘制节点navigationButtons: true,selectConnectedEdges: false, // 选中节点时,与其连接的边不高亮multiselect: false, // true时长时间单击(或触摸)以及控件单击将添加到选择中tooltipDelay: 100,},// 可视化操作: 没起作用,不知道是不是版本的问题manipulation: {enabled: false,initiallyActive: true,addNode: true,addEdge: true,// editNode: undefined,editEdge: true,deleteNode: true,deleteEdge: true,controlNodeStyle:{// all node options are valid.}},// 物理引擎physics: {enabled: true,barnesHut: {gravitationalConstant: -20000, // 斥力springLength: 20,   // 弹簧长度avoidOverlap: 1,},maxVelocity: 50,minVelocity: 1,stabilization: {iterations: 500, // 最大迭代次数enabled: true,// fit: true,fit: false,   // 值为false时,点击刷新后可回到刷新前的页面},},// 布局layout: {randomSeed: 2000,hierarchical: {enabled: true,levelSeparation: 100, // 层级之间的距离,太小的话箭头会盖住标签字nodeSpacing: 100,     // 节点之间的距离treeSpacing: 100,     // 树之间的距离 sortMethod: 'directed',},},}this.network = new vis.Network(container, data, this.options);setTimeout(() => {this.nodes.update({id: 9, label: '更新后的9'})},10000)}}
}
</script><style scoped lang="less">
#mynetwork {width: 80%;height: 60%;border: none;::v-deep .vis-navigation {position: absolute;z-index: 2;right: 12px;top: 47.8%;.vis-zoomIn,.vis-zoomOut {width: 24px;height: 24px;margin: 4px;cursor: pointer;border: 1px solid #c0c0c0;border-radius: 2px;border-radius: 2px;&:hover {border-color: #ccc;color: #4d4d4d;}}}::v-deep .vis-tooltip {position: absolute;visibility: visible;}
}
</style>

开发时注意的功能点

1.性能问题

拓扑图性能问题很严重,官网上明确说了最多只支持几千个节点的同时展示,我试了一下,展示的节点很多时,页面操作非常卡顿。

所以在前期设计时要格外考虑性能问题,后面因为性能问题重写了好几版代码结构,都是泪。

2.是否有环路情况

我做的项目在定位时是不考虑环路的情况的,所以当时做了树状图和星状图是用的一套数据。后面听说加了要支持环路的需求,那之前的设计根本没法玩了,要全部推倒。我也不负责此拓扑项目了,不清楚后续如何设计的,所以在前端设计时也要考虑好自己项目的定位与应用场景。

3.位置保存还是状态保持

所谓的位置保存就是将每个节点的x与y轴值传给后端进行数据库保存,每次渲染时节点都会出现在相同的位置。

状态保持是不进行位置保存,只是在前端进行维护一份位置数据,保证在用户关闭浏览器之前,每个节点的相对顺序是保持不变的。

当时主要考虑到进行位置保存时,节点的首次渲染与新增节点渲染处理逻辑较为复杂,尤其在树状图模式下,位置没有任何意义了,就使用了状态保持的处理逻辑。

4.展开收缩

当使用树状图时,层级很深时很难分析拓扑状态,最好是可以增加展示收缩节点功能,可以进行缩放与展开层级,此功能很好用,也可以解决一下性能问题,使页面上展示的节点数不至于很多,进行性能优化。展开收缩的实现也不难,就是初始做一个判断,在需要进行展开收缩的节点上绘制一个展开收缩按钮,并加上自己封装的展开收缩功能。

5.分页器

有展开收缩功能,那当然少不了左右翻页的分页器了,实现逻辑和展开收缩类型,很好实现。

6.节点是否可拖动

当节点可拖动时,要考虑到分页器的绘制了,分页器要始终绘制在最左侧和最右侧的节点旁边的。
好在节点拖动时拓扑图是不断重绘的(就是canvas的重绘),可以封装一个公共函数进行分页器的绘制。

7.编辑拓扑关系

只有展示拓扑关系的功能显示是不够的,还要具有可编辑性,具体的编辑功能还要看如何进行设计的,需要什么样的场景。

总结

还有太多的点就暂时不说了,只是说了一些拓扑绘制实现思路,没有说实现的详细代码,有兴趣的可以一起讨论如何用代码进行实现,我感觉我编写的代码需要优化,不怎么好,还是经验不足。

vis-network绘制拓扑图相关推荐

  1. html5拓扑图图入门,如何使用HTML5 Canvas动态的绘制拓扑图

    如何使用HTML5 Canvas动态的绘制拓扑图 使用HTML5 Canvas动态的绘制拓扑图: HTML5中引入新的元素canvas,其drawImage 方法允许在 canvas 中插入其他图像( ...

  2. vis.js网络拓扑图第一个demo,vis-network.min.js的下载

    在vis.js的中文文档里有个demo,复制粘贴出来跑跑,是可以运行的 地址:vis-network 入门 | Ame's blog 1.源码是这样的,粘贴出来就可以跑: //源码 <html& ...

  3. vis network(visjs)安装简单使用

    vis.js可视化的出发点之一是它们可以处理动态数据,并允许对数据进行操作.为了实现这一点,vis.js包括一个基于灵活键/值 DataSet并DataView处理非结构化JSON数据的功能. 数据集 ...

  4. Vue.js中使用vis network出现的点和线更新问题

    发现问题有一段时间,中文网一直没搜到结果,最终还是在github的已关闭issue里翻出了历史答案,简单翻译其中回答的部分内容,记录如下. 1.环境 前端工程vue.js,版本2.6.11. vis- ...

  5. vis.js网络拓扑图自定义图片

    1.首先看一下我做的效果图:  2.在官方demo中找有自定义图片的例子:Vis Network Examples 3.点击进去发现只有demo,没有源码,,,,于是f12自己找 4.只需要添加下面代 ...

  6. 二、vis network配置项

    配置项 往往默认的格式无法达到设计的效果,这时候就需要手动修改配置项以实现ui和交互 var options = {autoResize: true,height: '100%',width: '10 ...

  7. vue使用Vis.Network制作图谱

    //首先要加载VIS npm install vis --save//在main.js中引入配置项 import "vis/dist/vis.css"//在使用的页面引入该组件 i ...

  8. VISIO自动绘制 和手工绘制拓扑图

    明明白白画拓扑 网络拓扑是一个网络的物理或逻辑结构图,拥有一个详细且精确的网络拓扑图对于建设网络和维护网络都是有很大帮助的,布线方可以根据拓扑图安排布线提高网络设施的建设速度,而维护方也可以根据拓扑替 ...

  9. vis Network demo,源码开源 + (vue框架)

    前段时间用到了,感觉不错,写了一个开源的demo,大家有兴趣的可以看看https://github.com/xiaohu12685/Network_demo_vis. 大体样子就是这样,看功能就好,界 ...

最新文章

  1. 《Essential C++》读书笔记 之 泛型编程风格
  2. 谷歌让AI芯片学会“下崽”,下一代TPU就让AI自己设计
  3. mysql 查询字段中是否存在空格的_mysql查询字段中带空格的值的sql语句
  4. SAP Spartacus lock focus Directive的工作原理示意图
  5. 百度飞桨顶会论文复现(5):视频分类论文之《Representation Flow for Action Recognition》篇
  6. java 设置文本颜色_设置文本中的字体的颜色
  7. Python操作文件文档
  8. 【CSON原创】CSS的障眼法:利用border实现图片的翻转
  9. 2011最新笔记本、一体机显卡性能排行
  10. 金额转换成人民币大写
  11. Win11系统pin码忘记了怎么办?Win11忘记pin码解决方法
  12. LoadRunner 录制IE 8卡死
  13. Contiki之初步
  14. 我的世界服务器怎么设置自动拾取,自动拾取Auto Pickup Mod
  15. 猜一宋词名句 Java_古诗词名言名句大全之宋词名句集锦
  16. 线上插画培训班有用吗,教你选靠谱的插画课程
  17. 既然有MySQL了,为什么还要有MongoDB?
  18. 互联网日报 | 2月1日 星期一 | 苏宁宣布云网万店组织架构;威马汽车完成上市辅导;美团上线医疗健康品牌“百寿健康网”...
  19. linux otg 鼠标 节点,otg 的host功能,使用otg转host的线,连接鼠标。无效。
  20. 【arXiv2022】GroupTransNet: Group Transformer Network for RGB-D Salient Object Detection

热门文章

  1. poj 3013 Big Christmas Tree(最短路变形)
  2. 图像标注工具-LabelImg
  3. 概率统计Python计算:单个正态总体均值双侧假设的T检验
  4. 重磅!中国最赚钱的公司,要上市了!
  5. deamon tools dtsoft virtual cdrom device 失败 错误
  6. Android中的硬件加速
  7. 网线排线顺序及常规用法
  8. 《程序员》11年02期精彩内容:我的创业故事
  9. 计算网络节点模块内连通度(within modular degree)和模块间连通度(between modular degree)
  10. 2022焊工(初级)特种作业证考试题库及模拟考试