渲染进 @antv/g DisplayObject #4211
pearmini posted onGitHub
渲染进 @antv/g Group 元素
G2 除了能把 options 渲染成一个真实的 Canvas 或者 SVG 元素之外,还可以把图表渲染进一个 g 中的 DisplayObject。
开始使用
// 底层的使用方式
import { Canvas, Group } from '@antv/g';
import { Renderer } from '@antv/g-canvas';
import { renderToMountedElement } from 'runtime';
// 创建一个 group 并且挂载
const canvas = new Canvas({
container: 'app',
renderer: new Renderer()
});
const g = new Group();
canvas.append(g);
// 把图表渲染进这个挂载好的 group
const context = { group: g };
renderToMountedElement(options);
// 上层的使用方式
import { Canvas, Group } from '@antv/g';
import { Renderer } from '@antv/g-canvas';
import { Chart } from '@antv/g2';
// 创建一个 group 并且挂载
const canvas = new Canvas({
container: 'app',
renderer: new Renderer()
});
const g = new Group();
canvas.append(g);
// 把图表渲染进这个挂载好的 group
const chart = new Chart({
container: g
});
// 声明可视化 ....
chart.render();
设计
- runtime 新增
renderToMountedElement
方法,该方法和render
有以下两点不同:
- context 参数中的 Canvas 替换成一个 Group 元素,并且 context 是必选的。同时 context 提供的 Group 元素是挂载好的,否者不能正常执行动画。
- 返回值从一个真实的 DOM 节点,变成了一个 G 的 Group。
import { Group } from '@anvt/g';
const context = {
group: new Group()
};
// 第一次渲染
renderToMountedElement(options, context);
// 第二次渲染
renderToMountedElement(newOptions, context);
这里新增 renderToMountedElement 而不是把该能力放入 render 里面的原因是:runtime 里面的方法是比较底层的,所以希望每个方法更干净一点,不要有这种分支判断。就像 React 里面的 render 和 renderToString 一样。上层 API 合成一个就好(对用户友好)。
- chart api 的 container 支持 g 中的 element。如果 container 类型是 g 里面的 DisplayObject,
chart.render
调用 runtime 的renderToMountedElement
方法;否者原有逻辑。
任务
- 第一个 PR:runtime 增加
renderToMountedElement
方法 - 第二个 PR:api 通过 render 方法提供 renderToMountedElement 的能力
基本规范
为了减少 CR 成本,请遵循以下的基本规范:
- 合理设计函数接口,让每个函数做的事情合理。
- 命名原则:尽量简洁,不要太长。
// Primitive // 根据上下文命名即可,不需要突出类型 const count = 1; const name = 'jim';
// Array
const fruits = ['apple', 'orange', 'pear']; // 复数
const X = [1, 2, 3]; // 首字母大写(X
)
const matrix = [[1, 2, 3], [4, 5, 6,]]; // 特定语意
// Object // 单数形式 const scale = { x: new ScaleLinear(), y: new ScaleOrdinal() }
// Set 或者 WeakSet,同 Array const marks = new Set();
// Map 或者 WeakMap // 根据 id 获得名字 const idName = new Map(); // 两个单词:第一个是 key,第二个是 value
// 特殊语意 const circle = new Circle(); const store = new Map(); store.set(circle, { fill: 'red' });
- 非循环情况不要用 let。
```js
// Bad
let a;
if (b === 1) {
a = 1;
} else if (b === 2) {
a = 2;
} else {
a = 3
}
// Good
function getA() {
if (b === 1) {
return 1;
} else if (b === 2) {
return 2;
} else {
return 3;
}
}
const a = getA();
- 使用可迭代容器的原生方法,这类方法不要使用 lodash 或者 antv/util 里的方法。
// Bad
import { map } from '@antv/util';
const A = [1, 2, 3];
const B = map(a, d => d * 2);
// Good
const A = [1, 2, 3];
const B = A.map(d => d * 2);
- 复用逻辑抽象成一个函数,不要出现直接 copy 代码的情况。