View 是 G2 的画布容器,里面会包含 Geometry,组件,交互,事件等;而 Chart 是继承 View,直接暴露给开发者的便捷使用入口。
从几个点去做 View 的详细设计:
- 类图结构
 - 组件、几何图形的关系
 - 数据处理
 - 事件
 - 布局
 - 生命周期
 
1. 类图结构
整体上 Chart 继承自 View,功能上 Chart 和 View 区别不大。区别点包括:
- Chart 需要接受 dom / selector string 作为参数,然后创建 G.Canvas,生成三层 Group
 - Chart 需要处理容器变化的时候,自适应 / 手动适应图形(ChangeSize)
 
类图如下:

View 主要职责:
- 子 view、子组件、子几何图形的管理
 - 生命周期(initial、render、clear、destroy)
 - 设置配置的 API(比如数据、组件配置等、scale 配置)
 - 布局
 - 一些获取信息的 get API
 - 事件
 
2. 生命周期职责
目前整理是四个周期:initial、render、clear、destroy。各个周期的职责和内容包括:
- initial
 
- 处理 region
 - 绑定事件
 - 一些默认的初始配置
 
- render
 
- 递归 views 渲染
- 数据处理(filter)
 - 创建 coordinate
 - 构建画布(通过配置生成组件和 Geometry,geometry 数据处理(initial 阶段)完成)
- component
- axes
 - legend
 
 - geometry
 
 - component
 - 布局(layout 执行)
 
 - 绘制(canvan.draw)
 
- clear
 
clear 和 destroy 区别在于,clear 之后可以通过 initial、render 方法再次使用。
- 清空 views、components、geometries
 - 取消绑定事件
 - 配置复原
 
- destroy
 
理论上,只能在动态渲染中,动态增删 view 会用到。
- clear
 - 从 parent 中移除,销毁自己
 
生命周期的流程图如下:
3. 组件、Geometry 关系
View 管理子 view,子组件、子图形。
每个 view 中可以嵌套多个子 view,且可以包含多个组件和图形,具体这些组件和图形是什么,view 不会具体去关心。
至于说组件放到 View,还是放到顶层 Chart,由 controller 去控制和决定,View Chart 本身 API 不感知这个逻辑。
另外,对于组件 Components,还需要告诉 view 他的层级、方位。这些信息仅仅用于后续去生成实例、布局。
addComponent(component: Component, layer: LAYER = LAYER.MID, direction: DIRECTION = DIRECTION.BOTTOM): void
4. 数据处理
View 负责数据的 API 有两个(后续不排除会增加):
- view.data
 - view.filter
 
view 中的 data 是原始的数据,经过 filter 处理之后,会传给 Geometry 按照图形语法的方式,进行数据到图形的映射流程。
所以 view 这层提供的数据处理非常简单,目前仅仅只有过滤,可以通过扩展 view api 来扩展数据处理能力。
筛选器结构:
export type FilterCondition = (value: any, datum: Datum) => boolean;
5. 事件
View 在事件上会做两个事情:
- 监听他管理的 components、geometries 的事件。比如 legend:itemchange,interval:mouseover 等
 - 事件冒泡。也就是 chart 上可以监听到所有 components、geometries 的所有事件
 
name:event 组件事件名的逻辑,会直接包到底层 G 模块中。暂不知道如何实现?
6. 布局
布局:是对 view 中的 Views、Components、Geometries,根据配置(Region、Direction 等信息)计算出他们实际的位置和大小,并保证无遮挡、裁剪等问题。
Layout 是一个单纯的函数(简化概念):
export type Layout = (view: View) => void;
用户可以通过 view.setLayout 来指定自己的 layout 逻辑。G2 会内置一套处理 axis、legend、Geometry、分面 的布局逻辑。
- 根据子 view 的配置 range,可以计算出子 view 的位置大小;
 - 根据 view 的大小位置,以及 legend 的 direction,计算出 legend 的位置 x,y;
 - 根据 axis 内容不遮挡原则,计算出 yaxis 的 width,xaxis 的 height;
 - 剩余的位置给 Geometry,确定 Geometry 的 位置大小,然后可以反向计算出 yaxis 的 height、xaxis 的 width;以及他们的位置 x,y 信息;
 - 递归计算子 views 的布局;
 
开发者可以基于 G2 的 layout,追加自己的一些调整逻辑。或者完全自定义。
