vis.js学习笔记
vis.js包含了很多类型的图形,我这次主要是使用其network类型的可视化图形。
vis.js里面有很多技术点是可以深入挖掘的,比如布局算法、物理模拟效果等的实现,这都是我们可以借鉴学习的。
另外它的文档和在线配置生成工具很不错,我们可以学习并加入配置后台中。
学习过程必须有输出,我的输出计划是:
1、博客笔记
2、分享PPT
3、年末人员分布情况的可视化图形
节点(Node)
如何控制节点大小
如果用circle图形的话,节点默认是根据里面的文字来变更大小的,因此文字越长,图形越大,这其实是不利于可视化理解的。
因此我们一般采用dot这种shape,然后配合size属性控制大小。
另外,大小只是为了区分人员下属的多少,能体现差异性即可,不用按照人员数量比例来设置size,否则前面几级的节点图形会非常巨大,无法查看了(比如Boss的节点会非常非常大,把周围的线和图都遮住了)。这里应该有个趋势算法。
除此之外,vis.js还提供了scaling配置项来限定节点尺寸的最大值和最小值,通过scaling.min、scaling.max、value,就可以自动计算节点的大小了。我们程序中就是采用的这种方式。value值是后端直接计算后传给我们的,前端没有参与计算了。
如何收起某个节点
网上都是通过删除该节点下的子节点来实现的。
比如这篇文章:https://www.cnblogs.com/crystaltu/p/9177759.html
这个文章可能更好一些:
https://www.jianshu.com/p/b22727c8fe60
里面提到cluster可能也可以实现,待确认。
通过DataSet也可以删除,效率待确认:
1 | |
如何操纵和某个node/edge相关联的节点?
getConnectedNodes(nodeId or edgeId, [String direction])
getConnectedEdges(nodeId)
如何选中某个节点?
通过selectNodes()方法
network.selectNodes(childrenIds)
如何编辑节点?
https://visjs.github.io/vis-network/docs/network/index.html?keywords=editNode
vis有提供函数editNode(),直接触发编辑节点的操作,类似这样:
1 | |
图形形状
The shape defines what the node looks like. There are two types of nodes. One type has the label inside of it and the other type has the label underneath it.
The types with the label inside of it are: ellipse, circle, database, box, text.
The ones with the label outside of it are: image, circularImage, diamond, dot, star, triangle, triangleDown, hexagon, square and icon.
线条/边缘(edge)
如何设置箭头
API文档:https://visjs.github.io/vis-network/docs/network/edges.html?keywords=arrow#
1 | |
如何让线条变得圆润?
edges下面的smoth是控制线条圆润属性的配置
详见:https://visjs.github.io/vis-network/docs/network/edges.html
另外官方做了一个调试页面,可以调试选择适合自己的edge配置:
https://visjs.org/examples/network/edgeStyles/smooth.html
布局
布局算法
图布局力导引算法研究与实现:https://wenku.baidu.com/view/fc846f7a6edb6f1afe001f1b.html
可视化算法之布点算法:http://blog.sina.com.cn/s/blog_14d1518820102vxef.html
KK算法布局的停止条件:http://www.it1352.com/490778.html
(精)有向无环图的自动布局算法:https://blog.csdn.net/asd8705/article/details/43053639
(wiki)有向无环图:https://en.wikipedia.org/wiki/Directed_acyclic_graph
里面有介绍相关的算法,非常值得一读。
vis的布局,有如下几种方式:
1.通过layout布局
这样布局效率很高,但是默认布局出来是一个圆,且绝大多数人员都位于这个圆的边缘,当数据和关系比较多的时候,完全没法看。
2.通过物理引擎(physics)布局
这个详见官方文档里面关于physics的介绍,目前有barnesHut, repulsion, hierarchicalRepulsion, forceAtlas2Based这几种效果可以选择。
注意,物理效果布局,比较美观,但是性能巨差!以我们的项目为例:
edegs:6433
nodes:3496
layout布局:4秒
physics布局:20-30秒
如何让页面中心定位在某个节点上?
focus(nodeId, [Object options])
平移和缩放画布
通过network.moveTo()来实现:
1 | |
scale参数就是缩放的比例。
如何将网状结构改为树状结构?
将配置中的layout下面的hierarchical下面的enabled设置为true;然后将和enabled同一级的sortMethod设置为’directed’即可:
1 | |
几种物理布局的区别
BarnesHut
基于四叉树的重力模型,是默认的、最快的模型,也是推荐的模型
forceAtlas2Based
加强版BarnesHut
为什么我的布局不够均匀?
这里要理解一个单词:spring(弹簧)
physics-forceAtlas2Based-springLength这个配置的数值,会影响弹簧长度,进而影响布局是否均匀。
这个默认是100,我们可以直接用这个默认值。
这是布局均匀的配置:
1 | |
这是布局不均匀的配置:
1 | |
如何改为层级布局(树状布局)?
通过layout.hierrarchical来设置
http://visjs.org/docs/network/layout.html
如何在Canvas画布上画一些自定义的内容?
如果你想画的内容置于vis图形的下层,那么可以监听network的beforeDrawing事件,在它画图之前,先把你的图形画上去。
如果你想画的内容置于vis图形的上层,那么可以监听network的afterDrawing事件,在它画图之后,再把你的图形画上去。
比如我想在画图上画一些网格来辅助排版,就可以这样做:
1 | |
动画
如何实现动画效果?
选中某个后,通过修改node的坐标,使其飞过去,重新布局
physics配置讲解
1 | |
数据
数据结构
数据置于DataSet中,可以自动监控其变化,自动重新渲染页面。
如何保存每个节点上次展开的位置?
可以通过getPositions([nodeIds])这个方法获取指定节点在canvas画布中的x、y坐标。
如果不传入参数,就返回所有的节点的坐标。
1 | |
storePositions()可以给DataSet加入x、y坐标信息,但是没找到取出DataSet的方法,这个待研究。
如何导出所有节点的数据?
官方有个导入导出的demo:https://visjs.github.io/vis-network/examples/network/other/saveAndLoad.html
1 | |
看代码,是先通过network.getPositions()取到所有节点的id和坐标,然后通过network.getConnectedNodes(index)逐个获取node的数据,最后组装到一起返回的。
如何可视化编辑节点和线?
可以看官方的这2个demo:
https://visjs.github.io/vis-network/examples/network/other/manipulation.html
https://visjs.github.io/vis-network/examples/network/other/manipulationEditEdgeNoDrag.html
如何更新数据并自动画图?
通过DataSet实现,如下:
1 | |
如何动态修改配置?
只需要重新设置option参数即可,设置后立即生效:
1 | |
如何动态改变某个节点的属性?
1 | |
如何获取当前生效的配置信息?
1 | |
Cluster是什么?
集群,可以让与某个节点相关联的其他节点聚集到一堆。
可以通过这个来实现节点的展开和收起,不用通过增加/删除的方式来展示/隐藏节点了。
属于同一个cluster的node,他们拥有相同的cid属性,比如下面id为6~10的节点:
1 | |
看这个例子就清楚了:http://visjs.org/examples/network/other/clustering.html
其他
为什么我初始化非常慢?
物理效果中,有一个配置会严重影响加载速度:
1 | |
参考资料
如何搜索论文
Here is my workflow for getting papers:
- Search on Google Scholar for
<paper title>- Check all versions
- Check the university homepage of the author(s)
- Search for
"<paper title> pdf"on google search- Search the eBook section of my university library
一个可视化展示算法的网站:https://blog.csdn.net/huanglong8/article/details/55188649