树是图中一种特殊的数据结构。其特殊的性质、优美的结构,使得树形图在我们日常中广泛使用。比如,世界杯淘汰赛的晋级图,就是一个典型的树形数据可视化的案例。

下面我们将与大家探讨,如何使用 G6 快速实现这幅图。
场景准备
数据准备
{"roots": [{"teamA": "法国","flagA": "https://gw.alipayobjects.com/zos/rmsportal/yHYaCVIPRwEmmjbNqJjW.jpg","teamB": "克罗地亚","flagB": "https://gw.alipayobjects.com/zos/rmsportal/LJoAlBjTxagRLoNgSVmU.jpg","scoreA": 4,"scoreB": 2,"children": [{"teamA": "法国","flagA": "https://gw.alipayobjects.com/zos/rmsportal/yHYaCVIPRwEmmjbNqJjW.jpg","teamB": "比利时","flagB": "https://gw.alipayobjects.com/zos/rmsportal/tUwmQwmljZAvTXtljXcV.jpg","scoreA": 1,"scoreB": 0,"children": [……
在开始绘制树形图之前,我们先设置好一个 dom,并配上底图:
<style>#mountNode {width: 760px;height: 744px;background: url(https://gw.alipayobjects.com/zos/rmsportal/OSujrQtOvnOJVzRLmfIP.png);}</style><div id='mountNode'></div>

自定义节点-竞赛卡片
我们先来注册一个 node ,给它取个名字,就叫”card”(卡片)好了。
G6.registerNode('card', {});
draw 是自定义图项的最小接口,我们需要通过操作绘图引擎 G 来生成竞赛卡片。

draw(item) {const group = item.getGraphicGroup();const model = item.getModel();const scoreTextStyle = {textAlign: 'center',fontWeight: 900,fontSize: 14,fill: '#000'};const teamNameTextStyle = {textAlign: 'center',fontSize: 12,fill: 'rgba(0, 0, 0, 0.45)'};const width = 134;const height = 60;const keyShape = group.addShape('rect', {attrs: {x: 0,y: 0,width,height,fill: '#fff',radius: 4,}});group.addShape('image', {attrs: {x: 8,y: 8,width: 40,height: 24,img: model.flagA}});group.addShape('image', {attrs: {x: 86,y: 8,width: 40,height: 24,img: model.flagB}});group.addShape('text', {attrs: {...teamNameTextStyle,x: 28,y: 52,text: model.teamA,}});group.addShape('text', {attrs: {...teamNameTextStyle,x: 106,y: 52,text: model.teamB,}});group.addShape('text', {attrs: {...scoreTextStyle,x: 67,y: 52,text: model.scoreA + ' : '+ model.scoreB,}});return keyShape;}
注意 :在自定义图形时,设置坐标时,我们只需要考虑自身坐标系,而不需要考虑世界坐标系。
根据 G6 对锚点的定义,设置锚点

anchor: [[0, 0.5], // 左中[1, 0.5], // 右中[0.5, 0], // 上中[0.5, 1] // 下中]
选择布局
G6 中内置了若干种树图布局,不难看出这是,一种竖直方向紧凑树的布局。

const layout = new G6.Layouts.CompactBoxTree({direction: 'V',});
选择合适的边
边路由是图可视化领域中的一个难点,为了屏蔽这部分的复杂度,我们沉淀一些常见的边路由图形,供大家使用。
require('@antv/g6/build/plugin.edge.polyline');
引入该插件,会在 G6 中注册 polyline (直角) , polyline-round (圆角折线)两种边路由:


绘制图
有了上面储备的原料,我们已经基本上能画出这幅对阵图了。

const tree = new G6.Tree({container: 'mountNode',width: 760,height: 744,fitView: 'cc',layout,});tree.node({shape: 'card'});tree.edge({shape: 'polyline-round',style: {stroke: 'white',lineWidth: 1,strokeOpacity: 1}});tree.read(data);
