想了很久 G2 5.0 要做什么,怎么做,这里总一个汇总手稿。

G2 4.0

G2 5.0 稿子 - 图1
之前 G2 4.0 的发布内容

  • TypeScript(AntV 走出 ts 的第一步)
  • Canvas & SVG(以前也有,反而升级 G 之后,Bug 很多,不推荐使用 SVG)
  • 更新机制(更新并不能带来大幅度的性能提升)
  • 组件体系升级( 增加 slider、scrollbar,体验优化,信息优先级,但是因为技术原因,完成度 50%)
  • 更强大 View(彻底解决 scale 创建、同步问题,多 View 布局同步问题,自定义 controller,解耦一些逻辑)
  • 交互语法(交互语法第一个版本)
  • 细粒度动画(可自定义图形的动画,但是目前来看,很少开发者去使用)
  • 暗黑主题(3.5 也有)

但是同时也丢失了一些有点和特性:

  • DataSet 数据驱动
  • 精良的文档(普遍反馈的 3.x 文档更优)
  • html 类组件(label、legend、annotation)

G2 4.0 获得了一些新特性,但是也丢失了一些特性。而对于存量的布局问题,依然没有解决。

我们要做什么?

G2 优势(核心竞争力):

  • 图形语法:静态渲染,学术友好,数据分析友好
  • 强交互:动态,交互语法
  • 强扩展:业务灵活自定义

G2 = Layout(Geometry, Component) Interaction Animation
Geometry = Attribute Shape Coordinate
Component = Axis + Legend + Tooltip + Label + Annotation + Slider + Scrollbar + Timeline
Interaction = ?


所以:

  1. 一些从 3.x 遗留下来的布局、响应式问题,到 4.x 依然无解
  2. 组件自定义能力
    • legend、tooltip、annotation、label、toolbar…
  3. 交互:交互语法究竟是什么?
    1. 学术
    2. 业务(工业)
  4. 底层包工程、性能、质量
    • scale
    • coordinate
    • adjust
    • attr
  5. 新特性
    • 时序
    • 统计
    • 多种交互语法扩展
    • 分段 scale

具体怎么做?

介绍几个核心点的做法。

布局

目前的布局逻辑 auto padding,图形有 padding,位置给组件。

  1. 将组件放到 0, 0 位置,去自由渲染,得到每个组件的 width 和 height
  2. 得到组件的宽和之后,通过组件的 position 范围,以及布局逻辑,计算出对应的 x y 以及 auto padding
  3. done

问题

  1. 组件的信息响应式处理,这里的逻辑是矛盾的!

image.png
矛盾点:

  • 组件自由伸展,宽高作为组件的宽高
  • 上述优先级逻辑 又需要在 一个固定的宽高中执行

所以解法是:加了一个很晦涩的 verticalLimitLength 配置。表示可以自由伸展的最大范围。组件内部约束 和 组件外部约束 互相影响,让布局逻辑非常复杂。

  1. 两次计算(3.x 两次渲染)

先移动到 (0, 0) 位置,伸展开计算 width height,然后布局逻辑之后,获得 x y,移动到 (x, y) 位置。这里有两次

  1. 两次渲染的上下文环境并不完全一致,所以导致的布局问题

image.png

竞品调研

  • echarts
  1. 组件的 rotate 是确定的,而不是自动 auto 的
  2. ellipsis 一定是有确定的宽和高
  3. 其他情况,抽样隐藏逻辑
  4. 默认的 grid 逻辑是:绝对像素 / 百分比

也有不少的 bug:

image.png image.png image.png
  • highcharts
  1. rotation = 0 配置默认的旋转,布局
  2. 碰撞后,autoRotation 可自动旋转
  3. 旋转还不行就省略(x 轴省略,y 永不省略)

image.png

解法

布局的问题来源是组件 + 布局算法。

归纳一下:

  1. 在约束条件下,求解数所有组件的 x y width height
  2. 所有的组件在给定的绝对 width height 下处理好自己的响应式
  3. 响应式的过程有一个优先级
  • 组件

所有组件都有自己的 x y width height,以及 move 函数。

  1. type AxisLabelCfg = {
  2. rotate: number[];
  3. ellipsis: boolean;
  4. hide: boolean;
  5. overlapOrder: string[]; // ['rotate', 'hide']
  6. }
  • 布局

参考之前 SEEConf 的分享,使用约束布局的逻辑,将布局逻辑算术化。(牛逼吹出去了,但是其实还并没有实现!)

交互

问题:

  1. 目前的交互语法是基于一个交互阶段的封装,是否是最终解、最优解?
  2. 对于可视分析并不友好!(筛选、联动的是数据,而不是 event + action)
  3. 阻断扩展

解法:
G2 5.0 稿子 - 图8
在我们暂时无法判断什么是最优的时候,内置打个样,不阻断社区扩展,让社区去选择!(虽然目前 AntV 也没有什么社区)

自定义能力(组件)

增强外置 HTML 绘制能力。

tooltip

image.png image.png

现在 tooltip 有的自定义:

  1. formatter
  2. customItems
  3. customContent ❌
  4. tooltip:change ❌

legend

image.png image.png

现有图例的自定义:1、formatter 2、items ❌

  • 布局(位置、大小、边距、多行分页展示…)
  • 内容(缺省展示、tooltip 展示…)
  • 交互(高亮、数据过滤…)
  • 事件(目前有,需要规范下回调参数)
  • 自定义(目前需要全部重新自定义,无法基础已有的内容进行自定义,如:指标卡图例

annotation

image.png image.png

现有辅助标记有:

  1. 文本、线、dateRange、dataMarker、shape、html 等自定义
  2. 获取图表实例信息 ❌

言而总之:内置常见的,但是让开发者能够自己的开发,基于合理的机制,做出自己业务需要的效果。

  1. 生命周期事件
  2. 规范的获取实例数据 API
  3. 实例操作 API(筛选、高亮)

label

  • type
  • layout
  • 自定义

性能

渲染性能

  • scale 数据性能 ✅
  • label 碰撞检测性能 ✅
  • label 碰撞检测异步化
  • 数据处理异步化(不卡 UI)
  • G 层渲染性能

交互性能

  • G 事件拾取性能优化
  • G 层的按需渲染、分片渲染
  • G2 render、update 合并

统计图表的性能优化,手段其实很成熟,照着火焰图直接优化。对于核心的性能卡点,增加性能单测(scale)。大部分都是代码逻辑上没有考虑到而已。

  1. X 轴 category scale 在大数据的时候,ticks 很多,axis label,但是实际其实画布肯定都显示不出来,这个时候,完全可以先抽样 500,再去做 overlap 逻辑。
  2. category scale 映射枚举值为索引,大量循环使用 indexOf,只需要一个 o(1) 的缓存就可以将 o(n^2) 变成 o(n)。