- Go backend (server/)
- Frontend (web/, server/static/)
- Database and deployment files
- Scripts and docs
Co-Authored-By: 狸花猫/Claude-Qwen3.6-Plus 🐾
113 lines
4.7 KiB
JavaScript
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
|