UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering.

532 lines 22.1 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TransformManager = void 0; var util_1 = require("../util"); var geometry_1 = require("../geometry"); var base_1 = require("./base"); var TransformManager = /** @class */ (function (_super) { __extends(TransformManager, _super); function TransformManager() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.widgets = new Map(); return _this; } Object.defineProperty(TransformManager.prototype, "container", { get: function () { return this.graph.view.container; }, enumerable: false, configurable: true }); Object.defineProperty(TransformManager.prototype, "viewport", { get: function () { return this.graph.view.viewport; }, enumerable: false, configurable: true }); Object.defineProperty(TransformManager.prototype, "isSelectionEnabled", { get: function () { return this.options.selecting.enabled === true; }, enumerable: false, configurable: true }); TransformManager.prototype.init = function () { this.startListening(); this.resize(); }; TransformManager.prototype.startListening = function () { this.graph.on('node:mouseup', this.onNodeMouseUp, this); this.graph.on('node:selected', this.onNodeSelected, this); this.graph.on('node:unselected', this.onNodeUnSelected, this); }; TransformManager.prototype.stopListening = function () { this.graph.off('node:mouseup', this.onNodeMouseUp, this); this.graph.off('node:selected', this.onNodeSelected, this); this.graph.off('node:unselected', this.onNodeUnSelected, this); }; TransformManager.prototype.onNodeMouseUp = function (_a) { var node = _a.node; if (!this.isSelectionEnabled) { var widget = this.graph.hook.createTransform(node, { clearAll: true }); if (widget) { this.widgets.set(node, widget); } } }; TransformManager.prototype.onNodeSelected = function (_a) { var node = _a.node; if (this.isSelectionEnabled) { var widget = this.graph.hook.createTransform(node, { clearAll: false }); if (widget) { this.widgets.set(node, widget); } } }; TransformManager.prototype.onNodeUnSelected = function (_a) { var node = _a.node; if (this.isSelectionEnabled) { var widget = this.widgets.get(node); if (widget) { widget.dispose(); } this.widgets.delete(node); } }; /** * Returns the current transformation matrix of the graph. */ TransformManager.prototype.getMatrix = function () { var transform = this.viewport.getAttribute('transform'); if (transform !== this.viewportTransformString) { // `getCTM`: top-left relative to the SVG element // `getScreenCTM`: top-left relative to the document this.viewportMatrix = this.viewport.getCTM(); this.viewportTransformString = transform; } // Clone the cached current transformation matrix. // If no matrix previously stored the identity matrix is returned. return util_1.Dom.createSVGMatrix(this.viewportMatrix); }; /** * Sets new transformation with the given `matrix` */ TransformManager.prototype.setMatrix = function (matrix) { var ctm = util_1.Dom.createSVGMatrix(matrix); var transform = util_1.Dom.matrixToTransformString(ctm); this.viewport.setAttribute('transform', transform); this.viewportMatrix = ctm; this.viewportTransformString = transform; }; TransformManager.prototype.resize = function (width, height) { var w = width === undefined ? this.options.width : width; var h = height === undefined ? this.options.height : height; this.options.width = w; this.options.height = h; if (typeof w === 'number') { w = Math.round(w); } if (typeof h === 'number') { h = Math.round(h); } this.container.style.width = w == null ? '' : w + "px"; this.container.style.height = h == null ? '' : h + "px"; var size = this.getComputedSize(); this.graph.trigger('resize', __assign({}, size)); return this; }; TransformManager.prototype.getComputedSize = function () { var w = this.options.width; var h = this.options.height; if (!util_1.NumberExt.isNumber(w)) { w = this.container.clientWidth; } if (!util_1.NumberExt.isNumber(h)) { h = this.container.clientHeight; } return { width: w, height: h }; }; TransformManager.prototype.getScale = function () { return util_1.Dom.matrixToScale(this.getMatrix()); }; TransformManager.prototype.scale = function (sx, sy, ox, oy) { if (sy === void 0) { sy = sx; } if (ox === void 0) { ox = 0; } if (oy === void 0) { oy = 0; } sx = this.clampScale(sx); // eslint-disable-line sy = this.clampScale(sy); // eslint-disable-line if (ox || oy) { var ts = this.getTranslation(); var tx = ts.tx - ox * (sx - 1); var ty = ts.ty - oy * (sy - 1); if (tx !== ts.tx || ty !== ts.ty) { this.translate(tx, ty); } } var matrix = this.getMatrix(); matrix.a = sx; matrix.d = sy; this.setMatrix(matrix); this.graph.trigger('scale', { sx: sx, sy: sy, ox: ox, oy: oy }); return this; }; TransformManager.prototype.clampScale = function (scale) { var range = this.graph.options.scaling; return util_1.NumberExt.clamp(scale, range.min || 0.01, range.max || 16); }; TransformManager.prototype.getZoom = function () { return this.getScale().sx; }; TransformManager.prototype.zoom = function (factor, options) { options = options || {}; // eslint-disable-line var sx = factor; var sy = factor; var scale = this.getScale(); var clientSize = this.getComputedSize(); var cx = clientSize.width / 2; var cy = clientSize.height / 2; if (!options.absolute) { sx += scale.sx; sy += scale.sy; } if (options.scaleGrid) { sx = Math.round(sx / options.scaleGrid) * options.scaleGrid; sy = Math.round(sy / options.scaleGrid) * options.scaleGrid; } if (options.maxScale) { sx = Math.min(options.maxScale, sx); sy = Math.min(options.maxScale, sy); } if (options.minScale) { sx = Math.max(options.minScale, sx); sy = Math.max(options.minScale, sy); } if (options.center) { cx = options.center.x; cy = options.center.y; } sx = this.clampScale(sx); sy = this.clampScale(sy); if (cx || cy) { var ts = this.getTranslation(); var tx = cx - (cx - ts.tx) * (sx / scale.sx); var ty = cy - (cy - ts.ty) * (sy / scale.sy); if (tx !== ts.tx || ty !== ts.ty) { this.translate(tx, ty); } } this.scale(sx, sy); return this; }; TransformManager.prototype.getRotation = function () { return util_1.Dom.matrixToRotation(this.getMatrix()); }; TransformManager.prototype.rotate = function (angle, cx, cy) { if (cx == null || cy == null) { var bbox = util_1.Dom.getBBox(this.graph.view.stage); cx = bbox.width / 2; // eslint-disable-line cy = bbox.height / 2; // eslint-disable-line } var ctm = this.getMatrix() .translate(cx, cy) .rotate(angle) .translate(-cx, -cy); this.setMatrix(ctm); return this; }; TransformManager.prototype.getTranslation = function () { return util_1.Dom.matrixToTranslation(this.getMatrix()); }; TransformManager.prototype.translate = function (tx, ty) { var matrix = this.getMatrix(); matrix.e = tx || 0; matrix.f = ty || 0; this.setMatrix(matrix); var ts = this.getTranslation(); this.options.x = ts.tx; this.options.y = ts.ty; this.graph.trigger('translate', __assign({}, ts)); return this; }; TransformManager.prototype.setOrigin = function (ox, oy) { return this.translate(ox || 0, oy || 0); }; TransformManager.prototype.fitToContent = function (gridWidth, gridHeight, padding, options) { if (typeof gridWidth === 'object') { var opts = gridWidth; gridWidth = opts.gridWidth || 1; // eslint-disable-line gridHeight = opts.gridHeight || 1; // eslint-disable-line padding = opts.padding || 0; // eslint-disable-line options = opts; // eslint-disable-line } else { gridWidth = gridWidth || 1; // eslint-disable-line gridHeight = gridHeight || 1; // eslint-disable-line padding = padding || 0; // eslint-disable-line if (options == null) { options = {}; // eslint-disable-line } } var paddings = util_1.NumberExt.normalizeSides(padding); var border = options.border || 0; var contentArea = options.contentArea ? geometry_1.Rectangle.create(options.contentArea) : this.getContentArea(options); if (border > 0) { contentArea.inflate(border); } var scale = this.getScale(); var translate = this.getTranslation(); var sx = scale.sx; var sy = scale.sy; contentArea.x *= sx; contentArea.y *= sy; contentArea.width *= sx; contentArea.height *= sy; var width = Math.max(Math.ceil((contentArea.width + contentArea.x) / gridWidth), 1) * gridWidth; var height = Math.max(Math.ceil((contentArea.height + contentArea.y) / gridHeight), 1) * gridHeight; var tx = 0; var ty = 0; if ((options.allowNewOrigin === 'negative' && contentArea.x < 0) || (options.allowNewOrigin === 'positive' && contentArea.x >= 0) || options.allowNewOrigin === 'any') { tx = Math.ceil(-contentArea.x / gridWidth) * gridWidth; tx += paddings.left; width += tx; } if ((options.allowNewOrigin === 'negative' && contentArea.y < 0) || (options.allowNewOrigin === 'positive' && contentArea.y >= 0) || options.allowNewOrigin === 'any') { ty = Math.ceil(-contentArea.y / gridHeight) * gridHeight; ty += paddings.top; height += ty; } width += paddings.right; height += paddings.bottom; // Make sure the resulting width and height are greater than minimum. width = Math.max(width, options.minWidth || 0); height = Math.max(height, options.minHeight || 0); // Make sure the resulting width and height are lesser than maximum. width = Math.min(width, options.maxWidth || Number.MAX_SAFE_INTEGER); height = Math.min(height, options.maxHeight || Number.MAX_SAFE_INTEGER); var size = this.getComputedSize(); var sizeChanged = width !== size.width || height !== size.height; var originChanged = tx !== translate.tx || ty !== translate.ty; // Change the dimensions only if there is a size discrepency or an origin change if (originChanged) { this.translate(tx, ty); } if (sizeChanged) { this.resize(width, height); } return new geometry_1.Rectangle(-tx / sx, -ty / sy, width / sx, height / sy); }; TransformManager.prototype.scaleContentToFit = function (options) { if (options === void 0) { options = {}; } this.scaleContentToFitImpl(options); }; TransformManager.prototype.scaleContentToFitImpl = function (options, translate) { if (options === void 0) { options = {}; } if (translate === void 0) { translate = true; } var contentBBox; var contentLocalOrigin; if (options.contentArea) { var contentArea = options.contentArea; contentBBox = this.graph.localToGraph(contentArea); contentLocalOrigin = geometry_1.Point.create(contentArea); } else { contentBBox = this.getContentBBox(options); contentLocalOrigin = this.graph.graphToLocal(contentBBox); } if (!contentBBox.width || !contentBBox.height) { return; } var padding = util_1.NumberExt.normalizeSides(options.padding); var minScale = options.minScale || 0; var maxScale = options.maxScale || Number.MAX_SAFE_INTEGER; var minScaleX = options.minScaleX || minScale; var maxScaleX = options.maxScaleX || maxScale; var minScaleY = options.minScaleY || minScale; var maxScaleY = options.maxScaleY || maxScale; var fittingBox; if (options.viewportArea) { fittingBox = options.viewportArea; } else { var computedSize = this.getComputedSize(); var currentTranslate = this.getTranslation(); fittingBox = { x: currentTranslate.tx, y: currentTranslate.ty, width: computedSize.width, height: computedSize.height, }; } fittingBox = geometry_1.Rectangle.create(fittingBox).moveAndExpand({ x: padding.left, y: padding.top, width: -padding.left - padding.right, height: -padding.top - padding.bottom, }); var currentScale = this.getScale(); var newSX = (fittingBox.width / contentBBox.width) * currentScale.sx; var newSY = (fittingBox.height / contentBBox.height) * currentScale.sy; if (options.preserveAspectRatio !== false) { newSX = newSY = Math.min(newSX, newSY); } // snap scale to a grid var gridSize = options.scaleGrid; if (gridSize) { newSX = gridSize * Math.floor(newSX / gridSize); newSY = gridSize * Math.floor(newSY / gridSize); } // scale min/max boundaries newSX = util_1.NumberExt.clamp(newSX, minScaleX, maxScaleX); newSY = util_1.NumberExt.clamp(newSY, minScaleY, maxScaleY); this.scale(newSX, newSY); if (translate) { var origin_1 = this.options; var newOX = fittingBox.x - contentLocalOrigin.x * newSX - origin_1.x; var newOY = fittingBox.y - contentLocalOrigin.y * newSY - origin_1.y; this.translate(newOX, newOY); } }; TransformManager.prototype.getContentArea = function (options) { if (options === void 0) { options = {}; } if (options.useCellGeometry) { return this.model.getAllCellsBBox() || new geometry_1.Rectangle(); } return util_1.Dom.getBBox(this.graph.view.stage); }; TransformManager.prototype.getContentBBox = function (options) { if (options === void 0) { options = {}; } return this.graph.localToGraph(this.getContentArea(options)); }; TransformManager.prototype.getGraphArea = function () { var rect = geometry_1.Rectangle.fromSize(this.getComputedSize()); return this.graph.graphToLocal(rect); }; TransformManager.prototype.zoomToRect = function (rect, options) { if (options === void 0) { options = {}; } var area = geometry_1.Rectangle.create(rect); var graph = this.graph; options.contentArea = area; if (options.viewportArea == null) { options.viewportArea = { x: graph.options.x, y: graph.options.y, width: this.options.width, height: this.options.height, }; } this.scaleContentToFitImpl(options, false); var center = area.getCenter(); this.centerPoint(center.x, center.y); return this; }; TransformManager.prototype.zoomToFit = function (options) { if (options === void 0) { options = {}; } return this.zoomToRect(this.getContentArea(options), options); }; TransformManager.prototype.centerPoint = function (x, y) { var clientSize = this.getComputedSize(); var scale = this.getScale(); var ts = this.getTranslation(); var cx = clientSize.width / 2; var cy = clientSize.height / 2; x = typeof x === 'number' ? x : cx; // eslint-disable-line y = typeof y === 'number' ? y : cy; // eslint-disable-line x = cx - x * scale.sx; // eslint-disable-line y = cy - y * scale.sy; // eslint-disable-line if (ts.tx !== x || ts.ty !== y) { this.translate(x, y); } }; TransformManager.prototype.centerContent = function (options) { var rect = this.graph.getContentArea(options); var center = rect.getCenter(); this.centerPoint(center.x, center.y); }; TransformManager.prototype.centerCell = function (cell) { return this.positionCell(cell, 'center'); }; TransformManager.prototype.positionPoint = function (point, x, y) { var clientSize = this.getComputedSize(); // eslint-disable-next-line x = util_1.NumberExt.normalizePercentage(x, Math.max(0, clientSize.width)); if (x < 0) { x = clientSize.width + x; // eslint-disable-line } // eslint-disable-next-line y = util_1.NumberExt.normalizePercentage(y, Math.max(0, clientSize.height)); if (y < 0) { y = clientSize.height + y; // eslint-disable-line } var ts = this.getTranslation(); var scale = this.getScale(); var dx = x - point.x * scale.sx; var dy = y - point.y * scale.sy; if (ts.tx !== dx || ts.ty !== dy) { this.translate(dx, dy); } }; TransformManager.prototype.positionRect = function (rect, pos) { var bbox = geometry_1.Rectangle.create(rect); switch (pos) { case 'center': return this.positionPoint(bbox.getCenter(), '50%', '50%'); case 'top': return this.positionPoint(bbox.getTopCenter(), '50%', 0); case 'top-right': return this.positionPoint(bbox.getTopRight(), '100%', 0); case 'right': return this.positionPoint(bbox.getRightMiddle(), '100%', '50%'); case 'bottom-right': return this.positionPoint(bbox.getBottomRight(), '100%', '100%'); case 'bottom': return this.positionPoint(bbox.getBottomCenter(), '50%', '100%'); case 'bottom-left': return this.positionPoint(bbox.getBottomLeft(), 0, '100%'); case 'left': return this.positionPoint(bbox.getLeftMiddle(), 0, '50%'); case 'top-left': return this.positionPoint(bbox.getTopLeft(), 0, 0); default: return this; } }; TransformManager.prototype.positionCell = function (cell, pos) { var bbox = cell.getBBox(); return this.positionRect(bbox, pos); }; TransformManager.prototype.positionContent = function (pos, options) { var rect = this.graph.getContentArea(options); return this.positionRect(rect, pos); }; TransformManager.prototype.dispose = function () { this.widgets.forEach(function (widget) { return widget.dispose(); }); this.widgets.clear(); this.stopListening(); }; __decorate([ TransformManager.dispose() ], TransformManager.prototype, "dispose", null); return TransformManager; }(base_1.Base)); exports.TransformManager = TransformManager; //# sourceMappingURL=transform.js.map