简介

详细设计中需要讲清楚下面的这些内容:

  • G2 的组成部分
  • 数据流转
  • 交互的设计
  • 扩展的方式

组成部分

类结构

详细设计 - 图1

  • 这次变化最大的是增加了 Element 这一层,Element 的详细设计参看这里:[Element 的设计]
  • Stat 是统计相关的类,2.x 提供的统计类在 4.x 中会回归,不过功能上会受限,不再将布局相关的在这里实现

    数据流转

    主要考虑几个数据流:

  • 初始化

  • 数据整体更新
  • 交互中的图形变化,交互完成后的数据变化

初始化

详细设计 - 图2 在 g2 之前的版本中,初始化和数据整体更新的流程本质上一样,仅仅在后者需要把之前的图形清理掉。 详细设计 - 图3 在 g2 4.0 中,数据更新是否走更新流程还需要进行设计,这会增加很多成本,包括:

  • 新数据和之前图形的匹配
  • 组件的更新机制
  • 图形和组件的动画机制

如果不走整体刷新的方案,则流程会变化成: 详细设计 - 图4 交互中的图形变化,不会去更新原始数据,而仅仅修改图形的属性。当然也可以通过更新数据重新走一遍数据更新流程来实现,但是这种方式成本非常大,如果不更新原始数据,会导致图形超出数据范围的情况发生。
交互结束后的数据变化,可以走数据整体更新的逻辑,通常来说大多是过滤。

交互的设计

g2 2.x 和 3.x 中的交互仅包括:

  • active/highlight
  • selected
  • tooltip
  • legend 筛选

这些交互逻辑基本全部写死在代码的内部,扩展性和适应性有很大问题,在 4.0 中,所有的这些交互都会写成 interaction,以一种可插拔的方式提供给用户,这里面最需要解决的问题:

  • 交互不应干扰图表元素和组件的渲染
  • 所有的交互都是平等的,G2 本身不内嵌任何交互

这样会精简 G2 主流程的代码,同时也会使得交互变得更加透明可控,交互详细的写法参看 交互的写法

扩展的设计

由于 G2 定位的变化,仅仅 shape 的扩展已经不能满足用户的需求,在 4.0 中我们将提供:

  • 交互的扩展
  • 因为引入 Element 对 shape 的扩展进行改造
  • 组件的扩展,对 Axis,Tooltip,Legend,annotation, label 进行扩展
  • 动画的扩展机制,需要同时考虑图表的图形元素和组件的图形元素的动画
  • 映射过程中的扩展:scale, coord 的扩展

交互的扩展

交互的扩展牵扯的内容非常多,在独立章节中讨论,参考 交互的写法

自定义 Shape 的改造

自定义 shape 需要进行以下改造:

  • 将单个 shape(canvas) 改造成 group
  • 能够对状态进行响应,例如 active, selected, dark 等
  • 能够通过继承复写现有的 shape

基本的设计理念将与 G6 一致,只是更加简单一些,最终的 API 可能是这样:

  1. G2.registerShape('interval', 'my-interval', {
  2. draw(cfg, group) {
  3. },
  4. setState(name, value, element) {
  5. }
  6. }, 'rect');
  7. chart.interval().position('x*y').shape('my-interval');

组件的扩展

目前来看,label, annotation(guide) 的扩展需求最为旺盛,而 axis, legend, tooltip 更多的是内容格式化需求,组件的扩展目前的设计比较简单,基于现有组件进行扩展,然后注册到组件的命名空间上即可:

  1. const Component = require('@antv/component');
  2. const Axis = Component.Axis;
  3. class MyAxis extends Axis.Line {
  4. }
  5. // 注册到命名空间
  6. Axis.MyAxis = MyAxis;
  7. // 使用
  8. chart.axis('xxx', {
  9. type: 'myAxis',
  10. ...
  11. });
  • 优点:简单、容易理解;
  • 缺点:理解要继承的类的结构和能扩展的方法,类设计时需要考虑用户的扩展需求

动画的扩展机制

暂时还没想好,2.x ,3.x 的扩展机制第三方用户并没有太多使用,需要把更多动画进行拆解,让用户更容易的定制动画。

映射过程中的扩展

scale 的扩展可以实现很多 G2 没有提供的功能:

  • 非均匀度量
  • 对称度量
  • 自己定义的周期性(周、月、年)的度量

scale 本质上在 2.x 开始用户就可以去扩展,只是没有在 api 中开放出来,直接在度量定义中复写其中的 scale 和 invert 方法即可:

  1. chart.scale('field', {
  2. type: 'linear',
  3. scale(value) {},
  4. invert(value) {}
  5. });
  • 这种方案扩展的 scale 每个图表上都需要写一遍,无法复用,所以更好的方案同组件的扩展一致
  1. const Scale = require('@antv/scale');
  2. const Custom extends Scale.Linear {
  3. scale(value) {},
  4. invert(value) {}
  5. }
  6. // 使用时
  7. chart.scale('xxx', {type: 'custom'});

总结

本章节,对 G2 4.0 的详细设计进行了粗略的介绍,这里面每个小结都需要进行细化,这些设计决定了用户可以理解的信息,也决定了用户使用 G2 的体验,欢迎大家参与讨论,让 G2 真正的成为易用、无限可能的图形语法、交互语法、动画语法。