一个能根据特定指标值查看任意前几名节点的可视化小demo
(本文在较早之前在本人知乎账号为“张孝曼”的数据可视化专栏发表过:知乎链接,所以也可到本人知乎上的文章分享查看更多文章)
之前用d3js做了一个可视化小工程跟大家分享一下。
首先我自己构造了一份人书关系的数据,表示的是一个人借了哪些书,一本书又被哪些人借过,整体是个网络图的结构,因为是自己构造的,所以我偷懒直接把人写people1,people2作为编号,书写成book1,book2......采用d3里的力导引布局来做一个力学关系图。
整体展示效果图:
其中绿色结点是人,黄色结点表示书。做了个鼠标移到节点上时显示对应名称的交互,可以查看某一节点具体的名称。左上角有四个输入框,上面对应四种指标值,表征的是图数据结构里每个节点的度和中心度等。输入框输入的值是前几名,比方说你想查看邻居节点最多的前5个节点,只要在degree下面的输入框输入5,下面的图就会变成只含有前五的节点和节点外面两层的节点与边的图,最后再点击一下最右边的清除键,后面会解释这个操作的原因。
在degree输入框输入5的结果:
由此可知book7,book4,book6,book14,people24这5个结点的degree值最高。其他指标值的展示方法相同,最后点击一下清除键是因为一开始写代码的时候对隐藏其他节点和边只是设置了一个不透明度的改变,让其他元素不可见了,但它们还存在于画布上,所以后面用jquery的remove()函数把不可见的元素清除掉,用清除键触发,这个按键触发有点多余,但是我后来懒得改了,请读者见谅。
这个demo展示其实是具有一定的应用价值的,比如你以某些种类指标值大小作为一个关系网络里的节点是否关键的判断,那你可以用我展示的这种方式去查看最关键的节点,或者说仅仅是某一指标最高的节点。
代码实现:
下面我说说具体的代码实现吧,大神可能会觉得我代码写得不好或者这么简单的代码不需要讲,可以直接跳过下面部分。但是读我文章的可能有道友对我上面的功能实现感兴趣,我还是想讲讲代码实现,这样道友可以更快看懂我源码怎么写的,文章最后会附上源码地址。
生成力学图的套路都差不多,定义好需要用到的变量,力导引布局,再写好数据文件接口,然后在里面添加节点和边对象,绑定数据等等,最后绑定各种交互事件。理解了一套代码,以后只需要作为模板改改就好了。我主要想讲数据展示的功能实现,图生成我就不讲了。
拿degree指标来说:
我首先是定义一个数组degree_num来保存degree数据,并排序,因为degree是值越大越重要,所以对数组做降序排序。
然后在触发函数里写功能,这里触发函数是对id为2的输入框绑定的失去焦点后触发的函数。首先创建多个对象保存好所有的节点圆circle元素,文本text元素,和边元素,以及输入框输入的值。紧接着定义了一个Get_min_num函数,作用是获得top几里的最小的那个指标值在top几中的个数,比如说我想获得degree值前五名,假如前五名的指标值分别是7,6,5,4,4。那最小值个数就是2,两个4。因为第六名第七名可能也是4。我使用这个函数是为了确保就算4的个数不只是有前五名中的两个时,我也只高亮显示两个degree值是4的节点。我高亮的top5不是指指标值的前五(这样可能包含不止五个节点),而是只显示排在前面的5个节点。
首先是把第一层结点高亮,也就是degree值最高的五个节点,我设置了高亮后节点和文本的样式。实现思路是遍历每个text和circle节点元素,然后拿top5里最小的指标值来做比较,如果是7,6,5,4,4。那这个值就是4。指标值大于4的是要展示的,等于4的只展示先遍历到的两个节点,小于4的就是不展示的点了,同时还把top5节点的id保存在数组circle_highlight_id里。
接下来高亮外面两层结点和中间的边利用的是广度优先搜索的思想。通过前面保存的第一层节点的id获得第二层的节点以及中间的边。同理通过第二层节点id获得第三层结点和第二层边。
实现如下:
最后隐藏和清除不被高亮的其他节点和边。
其他的指标实现方法相同。在我源码中没有对里面大段的代码做函数封装,而是对应四个输入框的触发事件把以上代码写了四遍,导致代码有点臃肿,也是我偷懒没有在之后做这个工作,以后尽量克服,哈哈。
如果读过我这篇文章的道友有更好的实现思路或相关的算法,欢迎来告诉我,让我学习学习。
本文章工程源代码地址:点击打开链接