123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- import { __extends } from "tslib";
- import Element from './element';
- import { isFunction, isObject, each, removeFromArray, upperFirst, isAllowCapture } from '../util/util';
- var SHAPE_MAP = {};
- var INDEX = '_INDEX';
- /**
- * 设置 canvas
- * @param {IElement} element 元素
- * @param {ICanvas} canvas 画布
- */
- function setCanvas(element, canvas) {
- element.set('canvas', canvas);
- if (element.isGroup()) {
- var children = element.get('children');
- if (children.length) {
- children.forEach(function (child) {
- setCanvas(child, canvas);
- });
- }
- }
- }
- /**
- * 设置 timeline
- * @param {IElement} element 元素
- * @param {Timeline} timeline 时间轴
- */
- function setTimeline(element, timeline) {
- element.set('timeline', timeline);
- if (element.isGroup()) {
- var children = element.get('children');
- if (children.length) {
- children.forEach(function (child) {
- setTimeline(child, timeline);
- });
- }
- }
- }
- function contains(container, element) {
- var children = container.getChildren();
- return children.indexOf(element) >= 0;
- }
- function removeChild(container, element, destroy) {
- if (destroy === void 0) { destroy = true; }
- // 不再调用 element.remove() 方法,会出现循环调用
- if (destroy) {
- element.destroy();
- }
- else {
- element.set('parent', null);
- element.set('canvas', null);
- }
- removeFromArray(container.getChildren(), element);
- }
- function getComparer(compare) {
- return function (left, right) {
- var result = compare(left, right);
- return result === 0 ? left[INDEX] - right[INDEX] : result;
- };
- }
- var Container = /** @class */ (function (_super) {
- __extends(Container, _super);
- function Container() {
- return _super !== null && _super.apply(this, arguments) || this;
- }
- Container.prototype.isCanvas = function () {
- return false;
- };
- // 根据子节点确定 BBox
- Container.prototype.getBBox = function () {
- // 所有的值可能在画布的可视区外
- var minX = Infinity;
- var maxX = -Infinity;
- var minY = Infinity;
- var maxY = -Infinity;
- // 将可见元素、图形以及不为空的图形分组筛选出来,用于包围盒合并
- var children = this.getChildren().filter(function (child) {
- return child.get('visible') && (!child.isGroup() || (child.isGroup() && child.getChildren().length > 0));
- });
- if (children.length > 0) {
- each(children, function (child) {
- var _a = child.getBBox(), childMinX = _a.minX, childMaxX = _a.maxX, childMinY = _a.minY, childMaxY = _a.maxY;
- if (childMinX < minX) {
- minX = childMinX;
- }
- if (childMaxX > maxX) {
- maxX = childMaxX;
- }
- if (childMinY < minY) {
- minY = childMinY;
- }
- if (childMaxY > maxY) {
- maxY = childMaxY;
- }
- });
- }
- else {
- minX = 0;
- maxX = 0;
- minY = 0;
- maxY = 0;
- }
- var box = {
- x: minX,
- y: minY,
- minX: minX,
- minY: minY,
- maxX: maxX,
- maxY: maxY,
- width: maxX - minX,
- height: maxY - minY,
- };
- return box;
- };
- // 获取画布的包围盒
- Container.prototype.getCanvasBBox = function () {
- var minX = Infinity;
- var maxX = -Infinity;
- var minY = Infinity;
- var maxY = -Infinity;
- // 将可见元素、图形以及不为空的图形分组筛选出来,用于包围盒合并
- var children = this.getChildren().filter(function (child) {
- return child.get('visible') && (!child.isGroup() || (child.isGroup() && child.getChildren().length > 0));
- });
- if (children.length > 0) {
- each(children, function (child) {
- var _a = child.getCanvasBBox(), childMinX = _a.minX, childMaxX = _a.maxX, childMinY = _a.minY, childMaxY = _a.maxY;
- if (childMinX < minX) {
- minX = childMinX;
- }
- if (childMaxX > maxX) {
- maxX = childMaxX;
- }
- if (childMinY < minY) {
- minY = childMinY;
- }
- if (childMaxY > maxY) {
- maxY = childMaxY;
- }
- });
- }
- else {
- minX = 0;
- maxX = 0;
- minY = 0;
- maxY = 0;
- }
- var box = {
- x: minX,
- y: minY,
- minX: minX,
- minY: minY,
- maxX: maxX,
- maxY: maxY,
- width: maxX - minX,
- height: maxY - minY,
- };
- return box;
- };
- Container.prototype.getDefaultCfg = function () {
- var cfg = _super.prototype.getDefaultCfg.call(this);
- cfg['children'] = [];
- return cfg;
- };
- Container.prototype.onAttrChange = function (name, value, originValue) {
- _super.prototype.onAttrChange.call(this, name, value, originValue);
- if (name === 'matrix') {
- var totalMatrix = this.getTotalMatrix();
- this._applyChildrenMarix(totalMatrix);
- }
- };
- // 不但应用到自己身上还要应用于子元素
- Container.prototype.applyMatrix = function (matrix) {
- var preTotalMatrix = this.getTotalMatrix();
- _super.prototype.applyMatrix.call(this, matrix);
- var totalMatrix = this.getTotalMatrix();
- // totalMatrix 没有发生变化时,这里仅考虑两者都为 null 时
- // 不继续向下传递矩阵
- if (totalMatrix === preTotalMatrix) {
- return;
- }
- this._applyChildrenMarix(totalMatrix);
- };
- // 在子元素上设置矩阵
- Container.prototype._applyChildrenMarix = function (totalMatrix) {
- var children = this.getChildren();
- each(children, function (child) {
- child.applyMatrix(totalMatrix);
- });
- };
- // 兼容老版本的接口
- Container.prototype.addShape = function () {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- var type = args[0];
- var cfg = args[1];
- if (isObject(type)) {
- cfg = type;
- }
- else {
- cfg['type'] = type;
- }
- var shapeType = SHAPE_MAP[cfg.type];
- if (!shapeType) {
- shapeType = upperFirst(cfg.type);
- SHAPE_MAP[cfg.type] = shapeType;
- }
- var ShapeBase = this.getShapeBase();
- var shape = new ShapeBase[shapeType](cfg);
- this.add(shape);
- return shape;
- };
- Container.prototype.addGroup = function () {
- var args = [];
- for (var _i = 0; _i < arguments.length; _i++) {
- args[_i] = arguments[_i];
- }
- var groupClass = args[0], cfg = args[1];
- var group;
- if (isFunction(groupClass)) {
- if (cfg) {
- group = new groupClass(cfg);
- }
- else {
- group = new groupClass({
- // canvas,
- parent: this,
- });
- }
- }
- else {
- var tmpCfg = groupClass || {};
- var TmpGroupClass = this.getGroupBase();
- group = new TmpGroupClass(tmpCfg);
- }
- this.add(group);
- return group;
- };
- Container.prototype.getCanvas = function () {
- var canvas;
- if (this.isCanvas()) {
- canvas = this;
- }
- else {
- canvas = this.get('canvas');
- }
- return canvas;
- };
- Container.prototype.getShape = function (x, y, ev) {
- // 如果不支持拾取,则直接返回
- if (!isAllowCapture(this)) {
- return null;
- }
- var children = this.getChildren();
- var shape;
- // 如果容器是 group
- if (!this.isCanvas()) {
- var v = [x, y, 1];
- // 将 x, y 转换成对应于 group 的局部坐标
- v = this.invertFromMatrix(v);
- if (!this.isClipped(v[0], v[1])) {
- shape = this._findShape(children, v[0], v[1], ev);
- }
- }
- else {
- shape = this._findShape(children, x, y, ev);
- }
- return shape;
- };
- Container.prototype._findShape = function (children, x, y, ev) {
- var shape = null;
- for (var i = children.length - 1; i >= 0; i--) {
- var child = children[i];
- if (isAllowCapture(child)) {
- if (child.isGroup()) {
- shape = child.getShape(x, y, ev);
- }
- else if (child.isHit(x, y)) {
- shape = child;
- }
- }
- if (shape) {
- break;
- }
- }
- return shape;
- };
- Container.prototype.add = function (element) {
- var canvas = this.getCanvas();
- var children = this.getChildren();
- var timeline = this.get('timeline');
- var preParent = element.getParent();
- if (preParent) {
- removeChild(preParent, element, false);
- }
- element.set('parent', this);
- if (canvas) {
- setCanvas(element, canvas);
- }
- if (timeline) {
- setTimeline(element, timeline);
- }
- children.push(element);
- element.onCanvasChange('add');
- this._applyElementMatrix(element);
- };
- // 将当前容器的矩阵应用到子元素
- Container.prototype._applyElementMatrix = function (element) {
- var totalMatrix = this.getTotalMatrix();
- // 添加图形或者分组时,需要把当前图元的矩阵设置进去
- if (totalMatrix) {
- element.applyMatrix(totalMatrix);
- }
- };
- Container.prototype.getChildren = function () {
- return this.get('children');
- };
- Container.prototype.sort = function () {
- var children = this.getChildren();
- // 稳定排序
- each(children, function (child, index) {
- child[INDEX] = index;
- return child;
- });
- children.sort(getComparer(function (obj1, obj2) {
- return obj1.get('zIndex') - obj2.get('zIndex');
- }));
- this.onCanvasChange('sort');
- };
- Container.prototype.clear = function () {
- this.set('clearing', true);
- if (this.destroyed) {
- return;
- }
- var children = this.getChildren();
- for (var i = children.length - 1; i >= 0; i--) {
- children[i].destroy(); // 销毁子元素
- }
- this.set('children', []);
- this.onCanvasChange('clear');
- this.set('clearing', false);
- };
- Container.prototype.destroy = function () {
- if (this.get('destroyed')) {
- return;
- }
- this.clear();
- _super.prototype.destroy.call(this);
- };
- /**
- * 获取第一个子元素
- * @return {IElement} 第一个元素
- */
- Container.prototype.getFirst = function () {
- return this.getChildByIndex(0);
- };
- /**
- * 获取最后一个子元素
- * @return {IElement} 元素
- */
- Container.prototype.getLast = function () {
- var children = this.getChildren();
- return this.getChildByIndex(children.length - 1);
- };
- /**
- * 根据索引获取子元素
- * @return {IElement} 第一个元素
- */
- Container.prototype.getChildByIndex = function (index) {
- var children = this.getChildren();
- return children[index];
- };
- /**
- * 子元素的数量
- * @return {number} 子元素数量
- */
- Container.prototype.getCount = function () {
- var children = this.getChildren();
- return children.length;
- };
- /**
- * 是否包含对应元素
- * @param {IElement} element 元素
- * @return {boolean}
- */
- Container.prototype.contain = function (element) {
- var children = this.getChildren();
- return children.indexOf(element) > -1;
- };
- /**
- * 移除对应子元素
- * @param {IElement} element 子元素
- * @param {boolean} destroy 是否销毁子元素,默认为 true
- */
- Container.prototype.removeChild = function (element, destroy) {
- if (destroy === void 0) { destroy = true; }
- if (this.contain(element)) {
- element.remove(destroy);
- }
- };
- /**
- * 查找所有匹配的元素
- * @param {ElementFilterFn} fn 匹配函数
- * @return {IElement[]} 元素数组
- */
- Container.prototype.findAll = function (fn) {
- var rst = [];
- var children = this.getChildren();
- each(children, function (element) {
- if (fn(element)) {
- rst.push(element);
- }
- if (element.isGroup()) {
- rst = rst.concat(element.findAll(fn));
- }
- });
- return rst;
- };
- /**
- * 查找元素,找到第一个返回
- * @param {ElementFilterFn} fn 匹配函数
- * @return {IElement|null} 元素,可以为空
- */
- Container.prototype.find = function (fn) {
- var rst = null;
- var children = this.getChildren();
- each(children, function (element) {
- if (fn(element)) {
- rst = element;
- }
- else if (element.isGroup()) {
- rst = element.find(fn);
- }
- if (rst) {
- return false;
- }
- });
- return rst;
- };
- /**
- * 根据 ID 查找元素
- * @param {string} id 元素 id
- * @return {IElement|null} 元素
- */
- Container.prototype.findById = function (id) {
- return this.find(function (element) {
- return element.get('id') === id;
- });
- };
- /**
- * 该方法即将废弃,不建议使用
- * 根据 className 查找元素
- * TODO: 该方式定义暂时只给 G6 3.3 以后的版本使用,待 G6 中的 findByClassName 方法移除后,G 也需要同步移除
- * @param {string} className 元素 className
- * @return {IElement | null} 元素
- */
- Container.prototype.findByClassName = function (className) {
- return this.find(function (element) {
- return element.get('className') === className;
- });
- };
- /**
- * 根据 name 查找元素列表
- * @param {string} name 元素名称
- * @return {IElement[]} 元素
- */
- Container.prototype.findAllByName = function (name) {
- return this.findAll(function (element) {
- return element.get('name') === name;
- });
- };
- return Container;
- }(Element));
- export default Container;
- //# sourceMappingURL=container.js.map
|