Files
railwaysystem/RuoYi-Vue/ruoyi-ui/node_modules1/@antv/g-canvas/esm/group.js
T
2026-09-10 15:40:10 +08:00

113 lines
4.7 KiB
JavaScript

import { __extends } from "tslib";
import { AbstractGroup } from '@antv/g-base';
import * as Shape from './shape';
import { applyAttrsToContext, drawChildren, refreshElement } from './util/draw';
import { each, max, min } from '@antv/util';
import { intersectRect } from './util/util';
var Group = /** @class */ (function (_super) {
__extends(Group, _super);
function Group() {
return _super !== null && _super.apply(this, arguments) || this;
}
/**
* 一些方法调用会引起画布变化
* @param {ChangeType} changeType 改变的类型
*/
Group.prototype.onCanvasChange = function (changeType) {
refreshElement(this, changeType);
};
Group.prototype.getShapeBase = function () {
return Shape;
};
Group.prototype.getGroupBase = function () {
return Group;
};
// 同 shape 中的方法重复了
Group.prototype._applyClip = function (context, clip) {
if (clip) {
context.save();
// 将 clip 的属性挂载到 context 上
applyAttrsToContext(context, clip);
// 绘制 clip 路径
clip.createPath(context);
context.restore();
// 裁剪
context.clip();
clip._afterDraw();
}
};
// 这个方法以前直接使用的 getCanvasBBox,由于 group 上没有缓存,所以每次重新计算,导致性能开销比较大
// 大概能够节省全局渲染 15-20% 的性能,如果不在这里加缓存优化后 10W 个节点无法达到 5-6 ms,大概能够 30-40ms
Group.prototype.cacheCanvasBBox = function () {
var children = this.cfg.children;
var xArr = [];
var yArr = [];
each(children, function (child) {
var bbox = child.cfg.cacheCanvasBBox;
// isInview 的判定是一旦图形或者分组渲染就要计算是否在视图内,
// 这个判定 10W 个图形下差不多能够节省 5-6 ms 的开销
if (bbox && child.cfg.isInView) {
xArr.push(bbox.minX, bbox.maxX);
yArr.push(bbox.minY, bbox.maxY);
}
});
var bbox = null;
if (xArr.length) {
var minX = min(xArr);
var maxX = max(xArr);
var minY = min(yArr);
var maxY = max(yArr);
bbox = {
minX: minX,
minY: minY,
x: minX,
y: minY,
maxX: maxX,
maxY: maxY,
width: maxX - minX,
height: maxY - minY,
};
var canvas = this.cfg.canvas;
if (canvas) {
var viewRange = canvas.getViewRange();
// 如果这个地方判定 isInView == false 设置 bbox 为 false 的话,拾取的性能会更高
// 但是目前 10W 图形的拾取在 2-5ms 内,这个优化意义不大,可以后期观察再看
this.set('isInView', intersectRect(bbox, viewRange));
}
}
else {
this.set('isInView', false);
}
this.set('cacheCanvasBBox', bbox);
};
Group.prototype.draw = function (context, region) {
var children = this.cfg.children;
var allowDraw = region ? this.cfg.refresh : true; // 局部刷新需要判定
// 这个地方需要判定,在 G6 的场景每个 group 都有 transform 的场景下性能会开销非常大
// 通过 refresh 的判定,可以不刷新没有发生过变化的分组,不在视窗内的分组等等
// 如果想进一步提升局部渲染性能,可以进一步优化 refresh 的判定,依然有潜力
if (children.length && allowDraw) {
context.save();
// group 上的矩阵和属性也会应用到上下文上
// 先将 attrs 应用到上下文中,再设置 clip。因为 clip 应该被当前元素的 matrix 所影响
applyAttrsToContext(context, this);
this._applyClip(context, this.getClip());
drawChildren(context, children, region);
context.restore();
this.cacheCanvasBBox();
}
// 这里的成本比较大,如果不绘制则不再
// this.set('cacheCanvasBBox', this.getCanvasBBox());
this.cfg.refresh = null;
// 绘制后,消除更新标记
this.set('hasChanged', false);
};
// 绘制时被跳过,一般发生在分组隐藏时
Group.prototype.skipDraw = function () {
this.set('cacheCanvasBBox', null);
this.set('hasChanged', false);
};
return Group;
}(AbstractGroup));
export default Group;
//# sourceMappingURL=group.js.map