架构不在于技术复杂度多高,多么炫技!而是在可持续、稳定的迭代。好的架构让我们可以能够达成 1.01^365 的目标。
这篇思路,只是一个整体的模糊思路,会大概从 G、G2、G2Plot 甚至 G6 的角度去整体考虑。
记录思路,初步归档。
**
整体来看
G
定位是构建 UI 的一个框架。是 AntV 的基础!
- 🙇♂️ UI 的开发规范和模式统一,基于此构建 AntV 的 GUI(UI for G)。
- 🙇♂️ 高性能
- 分片渲染(渲染性能)
- 按需渲染(交互性能)
- canvas、🙇♂️ svg 必然支持,webgl 很好的支持?
- 事件
- 动画
- 原子组件增加 html 组件(html 才是最亲民的 UI)
GUI
定位是基于 G 的 ui 组件库,首先要统一的是 AntV G2 G6 的组件库。即时不统一,也应该放到一起来开发。
- 设计上能统一的,一定要统一 视觉
- 设计上不能统一,需要在开发模式上统一
- 统一仓库:积少成多,只有有了足够多的 UI,复杂的画布渲染才会非常简单
基于这些:
- 构建基于 canvas 的业务组件将会变得非常容易(交叉表是其中一个重要的业务组件)
- G2 G6 层的自定义 shape 变得相对容易,心智统一,可复用
- 其他一些创意性的想法
G2
图形语法、 统计语法、交互语法。图形语法、统计语法,我理解已经实践多次,交互语法尚有争议。
G2 存在的最大问题,还是:
- 各种叉乘出来的图表中,各种各样的布局体验问题。
- 组件层的代码维护问题(G 层如果解决,这里问题自动消失)
- auto padding 导致的二次渲染(图表渲染生命周期 和 auto padding 计算逻辑耦合)
- 自定义组件
解法(成本其实主要在 component 和布局,也就是下面要提到的 UI + Layout):
- component 走 GUI 模式
- 组件(legend、axis、slider、scrollbar、title…) 都是固定的宽高,约束布局。
- 如何 auto padding???
- 其他 scale、attr、geometry 均可不变
带来的收益:
G6
Graph = UI + Layout
实际上所有的画布都是 UI + Layout,在 G2 中 UI 是 legend、axis、geometry 等,而 layout 之前是 auto padding,现在的约束布局。和 UI 中的 geometry 注入了图形语法数据处理的逻辑。
而这一点,在 G6 中体现的更加明显。
布局算法社区上比较丰富,节点 UI 也不存在像 G2 的 geometry 注入了图形语法数据处理的逻辑,或者像 axis 注入了 scale 逻辑。所以理论上来说,G6 的代码逻辑上比 G2 会简单不少(没有深入研究,不知道对不对)。
正餐:G2 5.0 概要思路
G2 5.0 主要修正和解决的问题:
存量的无法解决的布局问题
- 两次渲染
- 收缩过程中自动旋转导致的问题
- 坐标做自动旋转、自动省略、抽样逻辑
- 生命周期的优化
- …
自定义扩展、规范(优化)
- tooltip、legend、label 等组件的自定义
- slider 等自定义控制范围
- 联动
- 动画自定义
- 交互自定义
工程架构,代码规范
- 不少错错得对的地方,子包不够独立、规范(可视化的子包,一定要做到社区可用的状态)
- scale、coordinate、attr、adjust
组件 component(单独提出来)
- 功能复杂、代码杂乱
- 非 GUI 开发方式,组件无法复用
性能
- 渲染性能
- 异步 label
- 大数据 scale 等性能
- …
新特性
- 统计语法加回来?
- date scale 升级
- render / update
那么主要分成为几个思路:
Scale
思路:重写 @万木、@逍为
- 定位和 d3-scale 保持一致,做数据映射、以及连续的 ticks 算法逻辑
- 可以自定义 ticks method 算发
- 分段 scale
- 高性能
- 工程优美,社区可用
- 去除 registerScale、field、getName、formatter 等逻辑,移动到 G2 层
- G2 层自己包装袋 field,formater 含义的结构
目标:社区可用,迭代稳定。具体设计见:https://www.yuque.com/antv/g2plot/cmvbdm
Coordinate
思路:梳理 @万木、@逍为
目前暂时没有发现太大问题:
- 工程优美,社区可用,仓库规范
- 平行坐标系(斜率图)
- 去除 register 类 API
布局 + 组件
思路:全新的布局思路 @逍为
这个是 G2 5.0 最重要的部分了,之前的版本,多多少少都会因为这个布局而重构,但是一直么有彻底解决问题。
过往的布局,都是 auto panding,隐含着一个响应式逻辑:
- 组件自由撑开,剩下的内容给 Geometry 图形
- 为了限制组件无限撑开,增加一个 max limit 限制(类似于 max-width、max-height)
- 而组件的 auto rotate、ellipsis、sampling 可以任意开启关闭,最后影响的是组件的 width、height
问题:
- 组件优先布局、图形次之,在布局上,没有一个上帝视角,导致布局逻辑是耦合在生命周期中,无法自定义
- 无法进行组件的信息优化:auto rotate、ellipsis、sampling、hide 策略都是在固定的 width、height 的情况下的,而不是宽高动态互相影响,增加开发复杂度,增加开发者使用复杂度
解法:
- 所有的组件具备有确定的 x y width height,也就是 bbox、组件在这个确定的范围进行自我布局(按照组件信息优化的结构)
- 增加布局算法,甚至可以直接使用社区的关系布局算法。可以使用之前 SEEConf 上吹的约束布局,前期实现留口子,简单实现
- 布局仅仅是算出 组件、图形的 bbox,而具体的组件内部布局由元素自己完成
- 组件有分成为参入布局 和 不参入布局。不参入布局组件:annotation、label 等。
详细设计:https://www.yuque.com/antv/g2plot/mlrbh8
交互
思路:架构重构 @逍为
架构是将软件能力一层一层包装,在灵活性 和 便捷性中间的取舍,不同的业务按照自己对 灵活性 和 便捷性 的要求,选择不同的层级。目前的交互语法直接阻断一套 json 配置作为标准的交互语法,至于好不好用,业务能否绕过,完全没有考虑。
期望达成在没有验证什么是交互语法之前,我们只给出官方实现、但是业务开发者可以自行参考和封装。
生命周期
思路:架构重构 @逍为
生命周期是串起来整个流程的逻辑,本质是 View + Geometry / Component 的树形结构的渲染,如果布局简化之后,可以优化为:
- 实例化组件、Geometry(如果存在则更新)
- 组件、Geometry 数据处理(增量处理)
- 布局
- 渲染
详细设计:https://www.yuque.com/antv/g2plot/az8bha
自定义能力
思路:架构重构 @逍为
- API 开放程度,开发是基于 API 去扩展
- 自定义 legend
- 自定义 tooltip
- 自定义 label
- 自定义交互
- …
- 自定义考虑能产出社区生态
各自分开设计。