我前一段时间写过一篇文章《「AntV」怎样用SVG & X6制作客户旅程时光轴》,分享了怎样通过使用SVG和X6制作客户旅程时光轴,得到了很多伙伴们的喜欢。
一些小伙伴找我要到了演示Demo的源代码,可是即使在有演示Demo源代码,在这基础之上再进行二次开发时却遇到了很多障碍。
软件/工具是知识和经验凝结的产物,在开发上遇到的很多障碍、往往是相关知识、开发经验或者能力方面有欠缺,所以我打算在演示Demo源代码基础之上,通过接下来的《「AntV X6」从0到1实现客户旅程时光轴组件》一系列文章,将我使用SVG和X6的相关知识和经验对大家进行分享,希望能帮到有同样需求的朋友。
《「AntV X6」从0到1实现客户旅程时光轴组件》会以系列文章的形式,有步骤、有重点地分享我使用AntV X6进行客户旅程时光轴组件实现相关的知识和经验,目前该系列文章会有如下6篇:
- 「AntV X6」从0到1实现客户旅程时光轴组件01-先导篇
- 「AntV X6」从0到1实现客户旅程时光轴组件02-画布篇
- 「AntV X6」从0到1实现客户旅程时光轴组件03-节点篇
- 「AntV X6」从0到1实现客户旅程时光轴组件04-连线篇
- 「AntV X6」从0到1实现客户旅程时光轴组件05-布局篇
- 「AntV X6」从0到1实现客户旅程时光轴组件06-动画篇
系列文章将会以“项目驱动”的方式进行技术知识和开发经验的分享,贯穿整个系列文章的客户旅程时光轴Demo如下:
回顾之前的文章,我们知道了一个客户旅程时光轴图由以下5个核心要素组成——
点(节点,Node):旅程图中那些一个个的圆圈,被称为“节点”;边(连线,Edge):两个节点中的连线,被称为“边”;标签(Label):节点下的说明文字,被称为“标签”;布局(Layout):各个节点位置坐标的排列,被称为“布局”;动画(Animation):在旅程时光轴图中,有一个从第一个节点一直到最后一个节点的描边动画。
以下是《「AntV X6」从0到1实现客户旅程时光轴组件05-布局篇》文章正文。
布局
AntV X6提供了一个@antv/layout包——里面提供了包括grid布局、dagre布局、force布局等等布局算法供我们使用——我们往往会通过使用各个布局算法,将布局的结果作为我们节点的位置坐标。
在一篇名称为《可视化图布局算法浅析》的文章中总结了图可视化场景下常用的布局算法——
-
几何布局:grid(网格布局算法),circle(环形布局算法),concentric(同心圆布局算法),radial(辐射状布局算法),avsdf(邻接点最小度优先算法,Adjacent Vertex with Smallest Degree First);
-
层级布局:dagre(有向无环图树布局算法,Directed Acyclic Graph and Trees),breadthfirst(广度优先布局算法),elk(Eclipse布局算法,Eclipse Layout Kernel),klay(K层布局算法,K Lay);
-
力导布局:fcose(最快复合弹簧内置布局算法,Fast Compound Spring Embedder),cola(约束布局,Constraint-based Layout),cise(环形弹簧内置布局算法,Circular Spring Embedder),elk2(Eclipse布局算法,Eclipse Layout Kernel),euler(欧拉布局算法),spread(扩展布局算法),fruchterman(Fruchterman-Reingold布局算法),combo(混合布局算法);
-
其他布局:mds(高维数据降维布局算法,Multi Dimensional Scaling),random(随机布局算法)。
在当前的客户旅程时光轴Demo中,我们是结合了Dagre布局和网格布局进行布局实现的——先使用Dagre算法进行一次布局计算,再使用网格布局处理一次。
Dagre布局
Dagre布局算法是“层次布局”的一个成熟算法实现,X6的@antv/layout布局包中就有Dagre布局的实现。
在 Dagre算法中定义了几个基本概念:
(1)rankDir:图的延展方向,分为由上到下(tb)、由下到上(bt)、由左到右(lr)、由右到左(rl)四种。
(2)rank:沿着图的延展方向划分的层级,每个顶点都存在于某个层级上,一个层级上可能有多个顶点。
(3)level:在每个 rank 中针对每一个节点划分的级。不同 rank 中的 level 互不影响。
关于Dagre布局更详细的内容,我写过一篇文章《Dagre算法简介以及在流程图自动布局中的应用》,感兴趣的可以去看看。
Dagre布局的使用很简单,实现如下——
const dagreLayout = new DagreLayout({
type: 'dagre',
rankdir: 'LR',
// align: 'UR', // 居中对齐
ranksep: 36,
nodesep: 20,
});
dagreLayout.updateCfg({
begin: begin,
ranker: 'longest-path', // 'tight-tree' 'longest-path' 'network-simplex'
});
let dagreModel = dagreLayout.layout(data as any);
graph.fromJSON(dagreModel);
经过Dagre布局之后,我们能得到从左往右的布局的一个旅程图,效果如下——
但是项目上,我们有一个需求是一行展示固定个数(比如一行6个),超出则换行显示(比如这里的客户旅程A和C)——
这时候我们需要在Dagre算法基础之上,再使用网格布局处理一次。
网格布局
网格布局是一种几何布局,我们可以通过把旅程节点划分到各个行和列中,然后根据节点所在的行和列、计算出节点实际所处的坐标。
在客户旅程项目中,跟正常网格布局稍微不一样的地方是,这里的旅程节点需要折行显示——
在这里我们做了如下处理:
- 对于奇数行,节点y坐标相同,x坐标值是节点的列号(columnNumber)进行计算;
- 对于偶数行,节点y坐标相同,x坐标值需要在上述步骤1的基础之上进行位置兑换。
在接下来的系列文章中,我们继续从“节点”、“连线”、“标签”、“布局”、“动画”这5个要素出发,通过结合下面的客户旅程时光轴图Demo案例,进行更详细的分解和讲述,希望能帮助到有需要的朋友: