可视化引擎antv系列之分面Facet(二)

没想到这么快就要使用自定义分面Facet功能了,猝不及防。
概述 起因是开发进行到一半的时候,发现 我们实现的效果 和 产品小伙伴的想法很不一致。而引擎现有能力并不支持产品想要的效果。嗯,只能自力更生了。
什么是分面 分面(Facet)是指利用 G2 提供的 View 递归嵌套能力,将一份数据按照某个维度分隔成若干子集,然后创建一个图表的矩阵,将每一个数据子集绘制到图表矩阵的窗格中。
上面是官方文档里的解释,简单讲就是 根据一定的规则对画布进行分割,形成多个子 View,然后在子 View 中绘制对应的数据和图形。
G2本身也内置了几种分面类型,如常见的list,rect,tree等,使用方式也很简单:

chart.facet(type: string, cfg: FacetCfg) => View

具体参考官方文档使用
如何自定义分面 自定义分面主要包含三个核心要素:
  1. 分面子 View 的定位逻辑
  2. 自定义分面机制
  3. 实现自定义分面类
子 View 定位
定位实质就是 分割出画布上的一部分给子view容器。
分面的核心逻辑是将当前 View 大小,根据数据拆分成多个子 view。
G2 中 View 可以拥有多个子 view,形成无限的嵌套逻辑。
自定义分面机制
【可视化引擎antv系列之分面Facet(二)】G2 提供自定义分面能力,实现并注册一个自定义分面的机制,大概如下代码:
import { registerFacet, Facet } from '@antv/g2'; // 实现一个自定义分面,继承 G2 分面基类 class MyFacet extends Facet { // TODO 实现自己的分面逻辑 }// 注册自定义分面到 G2 中 registerFacet('my-facet', Facet); // 消费自己的自定义分面 const chart = new Chart({ /*...*/ }); chart.facet('my-facet', { /* facetConfig */ });

实现自定义分面
核心就是开发自定义分面类 MyFacet,有5 个抽象方法必须实现。
import { Datum, Facet, FacetCfg, FacetData, View } from '@antv/g2'; interface MyFacetCfg extends FacetCfg { // TODO }interface MyFacetData extends FacetData { // TODO }class MyFacet extends Facet { protected afterEachView(view: View, facet: MyFacetCfg) {}protected beforeEachView(view: View, facet: MyFacetCfg) {}protected generateFacets(data: Datum[]): MyFacetCfg[] { return []; }protected getXAxisOption(x: string, axes: any, option: object, facet: MyFacetCfg): object { return undefined; }protected getYAxisOption(y: string, axes: any, option: object, facet: MyFacetCfg): object { return undefined; } }

内置分面源码分析 ok,了解了分面相关的基本概念,我们来分析一下内置分面的逻辑。
内置分面实现和自定义分面实现逻辑并无不同,也是必须实现5个抽象方法,我们先看一下 list分面的实现。
可视化引擎antv系列之分面Facet(二)
文章图片

这就是list分面类全部的代码了,很简洁。
我们核心分析一下 生成分面定位的 generateFacets 方法实现:
可视化引擎antv系列之分面Facet(二)
文章图片

根据维度分割字段把数据划分成 几行几列的 子view,就是这么个逻辑。
可视化引擎antv系列之分面Facet(二)
文章图片

画布区域划分就是根据行数和列数 评分区域,分配给每个子view。
剩余的绘制逻辑就和 普通图形没有区别了
其他几个分面 和这个都大同小异,本质就是如何 划分区域的问题。

    推荐阅读