UNPKG

4.83 kBJavaScriptView Raw
1import { __extends } from "tslib";
2import { AbstractGroup } from '@antv/g-base';
3import * as Shape from './shape';
4import { applyAttrsToContext, drawChildren, refreshElement } from './util/draw';
5import { each } from '@antv/util';
6import { intersectRect } from './util/util';
7var Group = /** @class */ (function (_super) {
8 __extends(Group, _super);
9 function Group() {
10 return _super !== null && _super.apply(this, arguments) || this;
11 }
12 /**
13 * 一些方法调用会引起画布变化
14 * @param {ChangeType} changeType 改变的类型
15 */
16 Group.prototype.onCanvasChange = function (changeType) {
17 refreshElement(this, changeType);
18 };
19 Group.prototype.getShapeBase = function () {
20 return Shape;
21 };
22 Group.prototype.getGroupBase = function () {
23 return Group;
24 };
25 // 同 shape 中的方法重复了
26 Group.prototype._applyClip = function (context, clip) {
27 if (clip) {
28 context.save();
29 // 将 clip 的属性挂载到 context 上
30 applyAttrsToContext(context, clip);
31 // 绘制 clip 路径
32 clip.createPath(context);
33 context.restore();
34 // 裁剪
35 context.clip();
36 clip._afterDraw();
37 }
38 };
39 // 这个方法以前直接使用的 getCanvasBBox,由于 group 上没有缓存,所以每次重新计算,导致性能开销比较大
40 // 大概能够节省全局渲染 15-20% 的性能,如果不在这里加缓存优化后 10W 个节点无法达到 5-6 ms,大概能够 30-40ms
41 Group.prototype.cacheCanvasBBox = function () {
42 var children = this.cfg.children;
43 var xArr = [];
44 var yArr = [];
45 each(children, function (child) {
46 var bbox = child.cfg.cacheCanvasBBox;
47 // isInview 的判定是一旦图形或者分组渲染就要计算是否在视图内,
48 // 这个判定 10W 个图形下差不多能够节省 5-6 ms 的开销
49 if (bbox && child.cfg.isInView) {
50 xArr.push(bbox.minX, bbox.maxX);
51 yArr.push(bbox.minY, bbox.maxY);
52 }
53 });
54 var bbox = null;
55 if (xArr.length) {
56 var minX = Math.min.apply(null, xArr);
57 var maxX = Math.max.apply(null, xArr);
58 var minY = Math.min.apply(null, yArr);
59 var maxY = Math.max.apply(null, yArr);
60 bbox = {
61 minX: minX,
62 minY: minY,
63 x: minX,
64 y: minY,
65 maxX: maxX,
66 maxY: maxY,
67 width: maxX - minX,
68 height: maxY - minY,
69 };
70 var canvas = this.cfg.canvas;
71 if (canvas) {
72 var viewRange = canvas.getViewRange();
73 // 如果这个地方判定 isInView == false 设置 bbox 为 false 的话,拾取的性能会更高
74 // 但是目前 10W 图形的拾取在 2-5ms 内,这个优化意义不大,可以后期观察再看
75 this.set('isInView', intersectRect(bbox, viewRange));
76 }
77 }
78 else {
79 this.set('isInView', false);
80 }
81 this.set('cacheCanvasBBox', bbox);
82 };
83 Group.prototype.draw = function (context, region) {
84 var children = this.cfg.children;
85 var allowDraw = region ? this.cfg.refresh : true; // 局部刷新需要判定
86 // 这个地方需要判定,在 G6 的场景每个 group 都有 transform 的场景下性能会开销非常大
87 // 通过 refresh 的判定,可以不刷新没有发生过变化的分组,不在视窗内的分组等等
88 // 如果想进一步提升局部渲染性能,可以进一步优化 refresh 的判定,依然有潜力
89 if (children.length && allowDraw) {
90 context.save();
91 // group 上的矩阵和属性也会应用到上下文上
92 // 先将 attrs 应用到上下文中,再设置 clip。因为 clip 应该被当前元素的 matrix 所影响
93 applyAttrsToContext(context, this);
94 this._applyClip(context, this.getClip());
95 drawChildren(context, children, region);
96 context.restore();
97 this.cacheCanvasBBox();
98 }
99 // 这里的成本比较大,如果不绘制则不再
100 // this.set('cacheCanvasBBox', this.getCanvasBBox());
101 this.cfg.refresh = null;
102 // 绘制后,消除更新标记
103 this.set('hasChanged', false);
104 };
105 // 绘制时被跳过,一般发生在分组隐藏时
106 Group.prototype.skipDraw = function () {
107 this.set('cacheCanvasBBox', null);
108 this.set('hasChanged', false);
109 };
110 return Group;
111}(AbstractGroup));
112export default Group;
113//# sourceMappingURL=group.js.map
\No newline at end of file