接到一个临时任务:
终端里面要加入企业图谱的功能,用于更直观的展示与查询企业相关的维度信息,(当然最主要的原因还是竞品做了这个功能...[摊手.jpg])
看完产品的需求文档之后还是应该研究一下竞品(看看是从哪抄来的),毕竟产品的需求一般都不包含清晰完整的交互细节。
对标的竞品长这样:
ok,知道从哪抄的就好办了,打开控制台大致看一下他们的技术实现,然后search一下网上的实现类似图谱的方案,基于低学习成本的策略,最终选择相对比较灵活的D3js的tree布局方式来实现。
接下来是对照着D3的官方文档和实例,手把手撸出来一个demon,实现基础的布局、动画、展开折叠等效果。
个人觉得d3的api还是十分强大的,特别是布局(layout)的api,例如tree,pack等,面对产品经理的特殊展示需求(不知道从哪个犄角旮旯里抄过来的),直接调用d3的布局api,往往能节省很多的时间,当然d3只是对数据进行处理,生成一份布局好的数据格式,你可以用任何dom结构来呈现它,不局限于svg或者canvas。
例如上次看到一个产品让我们组的一个同事做一个环形布局,去描述用户画像(大概就是用户的访问路径),如果直接用普通的dom布局需要考虑的细节会特别多,兼容性可能也比较难搞,这个时候如果可以用d3的
这个布局,肯定能够事半功倍。
言归正传,用上了d3的tree布局,整个的框架就有了,下面要解决的就是交互相关的问题,想要达到可以和竞品媲美的交互体验,还有很大的提升空间。
因为整个图谱是可以无限展开的(如果库表里有数据的情况下),又考虑到接口的承受能力,默认只会展示两层的数据,每次点击新节点的加号执行展开操作,都需要重新请求数据,拿过来拼接数据、处理数据,然后布局绘图。折叠同样也需要重组数据重绘,不同的是把数据隐藏起来,下次再展开的时候不用再去请求接口数据,有效减轻服务器带宽的压力。
最后的效果是这个样子的:
最后一个比较棘手的问题,应该就是重绘之后的视野移动了,需要将当前点击的节点移动到视野中央,但是我们只知道点击之前点击的位置,点击之后树的结构和节点数量发生了变化,如果按照变化之前的位置去移动,必定会造成移动位置的不准确和视野偏移。为此还吃了个bug,所以印象十分深刻。
为了解决这个问题,我能想到的办法就是为每个节点生成唯一的id,点击记录下来当前的id,然后等绘制完成或者数据处理完成(d3计算完位置)之后,再次查询到记录id的当前位置,将该节点移动到视野的正中央,如此这般,基本实现了竞品所有的交互功能。
除此之外,还有两个points需要提一下:
其一是链接线的绘制,我这里是自定义的线,默认的好像是贝赛尔曲线,我这里运用svg的基础画线方式Path(M,H, S,L,V,A,Q,C这样的基础属性)。
其二是节点上的rect长度的计算,因为d3自身是基于节点point的计算,不会把节点上的文字的长度计算进去,不加处理的话会造成节点和rect的重叠问题。所以我们需要在绘制图像之前根据当前layer的最长文字长度来确定下一层级节点的开始位置,我是写了一个方法来专门计算当前层级最大的长度,来保证整个布局不会出现重叠现象的。
由于公司内网网关的原因,暂时未能贴出代码,有需要的话可以联系或者评论。