UNPKG

@antv/x6

Version:

JavaScript diagramming library that uses SVG and HTML for rendering.

628 lines 26.2 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; }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Snapline = void 0; var util_1 = require("../../util"); var geometry_1 = require("../../geometry"); var view_1 = require("../../view/view"); var Snapline = /** @class */ (function (_super) { __extends(Snapline, _super); function Snapline(options) { var _this = _super.call(this) || this; var graph = options.graph, others = __rest(options, ["graph"]); _this.graph = graph; _this.options = __assign({ tolerance: 10 }, others); _this.render(); _this.parseFilter(); if (!_this.disabled) { _this.startListening(); } return _this; } Object.defineProperty(Snapline.prototype, "model", { get: function () { return this.graph.model; }, enumerable: false, configurable: true }); Object.defineProperty(Snapline.prototype, "containerClassName", { get: function () { return this.prefixClassName('widget-snapline'); }, enumerable: false, configurable: true }); Object.defineProperty(Snapline.prototype, "verticalClassName", { get: function () { return this.containerClassName + "-vertical"; }, enumerable: false, configurable: true }); Object.defineProperty(Snapline.prototype, "horizontalClassName", { get: function () { return this.containerClassName + "-horizontal"; }, enumerable: false, configurable: true }); Object.defineProperty(Snapline.prototype, "disabled", { get: function () { return (this.options.enabled !== true || this.graph.options.snapline.enabled !== true); }, enumerable: false, configurable: true }); Snapline.prototype.enable = function () { if (this.disabled) { this.options.enabled = true; this.graph.options.snapline.enabled = true; this.startListening(); } }; Snapline.prototype.disable = function () { if (!this.disabled) { this.options.enabled = false; this.graph.options.snapline.enabled = false; this.stopListening(); } }; Snapline.prototype.setFilter = function (filter) { this.options.filter = filter; this.parseFilter(); }; Snapline.prototype.render = function () { this.container = document.createElement('div'); this.$container = this.$(this.container); this.$horizontal = this.$(document.createElement('div')).addClass(this.horizontalClassName); this.$vertical = this.$(document.createElement('div')).addClass(this.verticalClassName); this.$container .hide() .addClass(this.containerClassName) .append([this.$horizontal, this.$vertical]); if (this.options.className) { this.$container.addClass(this.options.className); } }; Snapline.prototype.startListening = function () { this.stopListening(); this.graph.on('node:mousedown', this.captureCursorOffset, this); this.graph.on('node:mousemove', this.snapOnMoving, this); this.model.on('batch:stop', this.onBatchStop, this); this.delegateDocumentEvents({ mouseup: 'hide', touchend: 'hide', }); }; Snapline.prototype.stopListening = function () { this.graph.off('node:mousedown', this.captureCursorOffset, this); this.graph.off('node:mousemove', this.snapOnMoving, this); this.model.off('batch:stop', this.onBatchStop, this); this.undelegateDocumentEvents(); }; Snapline.prototype.parseFilter = function () { var _this = this; this.filterShapes = {}; this.filterCells = {}; this.filterFunction = null; var filter = this.options.filter; if (Array.isArray(filter)) { filter.forEach(function (item) { if (typeof item === 'string') { _this.filterShapes[item] = true; } else { _this.filterCells[item.id] = true; } }); } else if (typeof filter === 'function') { this.filterFunction = filter; } }; Snapline.prototype.onBatchStop = function (_a) { var name = _a.name, data = _a.data; if (name === 'resize') { this.snapOnResizing(data.cell, data); } }; Snapline.prototype.captureCursorOffset = function (_a) { var view = _a.view, x = _a.x, y = _a.y; var targetView = view.getDelegatedView(); if (targetView && this.isNodeMovable(targetView)) { var pos = view.cell.getPosition(); this.offset = { x: x - pos.x, y: y - pos.y, }; } }; Snapline.prototype.isNodeMovable = function (view) { return view && view.cell.isNode() && view.can('nodeMovable'); }; Snapline.prototype.snapOnResizing = function (node, options) { var _this = this; if (this.options.resizing && !options.snapped && options.ui && options.direction && options.trueDirection) { var view = this.graph.renderer.findViewByCell(node); if (view && view.cell.isNode()) { var nodeBbox = node.getBBox(); var nodeBBoxRotated_1 = nodeBbox.bbox(node.getAngle()); var nodeTopLeft = nodeBBoxRotated_1.getTopLeft(); var nodeBottomRight_1 = nodeBBoxRotated_1.getBottomRight(); var angle = geometry_1.Angle.normalize(node.getAngle()); var tolerance_1 = this.options.tolerance || 0; var verticalLeft_1; var verticalTop_1; var verticalHeight_1; var horizontalTop_1; var horizontalLeft_1; var horizontalWidth_1; var snapOrigin_1 = { vertical: 0, horizontal: 0, }; var direction = options.direction; var trueDirection = options.trueDirection; var relativeDirection = options.relativeDirection; if (trueDirection.indexOf('right') !== -1) { snapOrigin_1.vertical = nodeBottomRight_1.x; } else { snapOrigin_1.vertical = nodeTopLeft.x; } if (trueDirection.indexOf('bottom') !== -1) { snapOrigin_1.horizontal = nodeBottomRight_1.y; } else { snapOrigin_1.horizontal = nodeTopLeft.y; } this.model.getNodes().some(function (cell) { if (_this.isIgnored(node, cell)) { return false; } var snapBBox = cell.getBBox().bbox(cell.getAngle()); var snapTopLeft = snapBBox.getTopLeft(); var snapBottomRight = snapBBox.getBottomRight(); var groups = { vertical: [snapTopLeft.x, snapBottomRight.x], horizontal: [snapTopLeft.y, snapBottomRight.y], }; var distances = {}; Object.keys(groups).forEach(function (k) { var key = k; var list = groups[key] .map(function (value) { return ({ position: value, distance: Math.abs(value - snapOrigin_1[key]), }); }) .filter(function (item) { return item.distance <= tolerance_1; }); distances[key] = util_1.ArrayExt.sortBy(list, function (item) { return item.distance; }); }); if (verticalLeft_1 == null && distances.vertical.length > 0) { verticalLeft_1 = distances.vertical[0].position; verticalTop_1 = Math.min(nodeBBoxRotated_1.y, snapBBox.y); verticalHeight_1 = Math.max(nodeBottomRight_1.y, snapBottomRight.y) - verticalTop_1; } if (horizontalTop_1 == null && distances.horizontal.length > 0) { horizontalTop_1 = distances.horizontal[0].position; horizontalLeft_1 = Math.min(nodeBBoxRotated_1.x, snapBBox.x); horizontalWidth_1 = Math.max(nodeBottomRight_1.x, snapBottomRight.x) - horizontalLeft_1; } return verticalLeft_1 != null && horizontalTop_1 != null; }); this.hide(); var dx = 0; var dy = 0; if (horizontalTop_1 != null || verticalLeft_1 != null) { if (verticalLeft_1 != null) { dx = trueDirection.indexOf('right') !== -1 ? verticalLeft_1 - nodeBottomRight_1.x : nodeTopLeft.x - verticalLeft_1; } if (horizontalTop_1 != null) { dy = trueDirection.indexOf('bottom') !== -1 ? horizontalTop_1 - nodeBottomRight_1.y : nodeTopLeft.y - horizontalTop_1; } } var dWidth = 0; var dHeight = 0; if (angle % 90 === 0) { if (angle === 90 || angle === 270) { dWidth = dy; dHeight = dx; } else { dWidth = dx; dHeight = dy; } } else { var quadrant = angle >= 0 && angle < 90 ? 1 : angle >= 90 && angle < 180 ? 4 : angle >= 180 && angle < 270 ? 3 : 2; if (horizontalTop_1 != null && verticalLeft_1 != null) { if (dx < dy) { dy = 0; horizontalTop_1 = undefined; } else { dx = 0; verticalLeft_1 = undefined; } } var rad = geometry_1.Angle.toRad(angle % 90); if (dx) { dWidth = quadrant === 3 ? dx / Math.cos(rad) : dx / Math.sin(rad); } if (dy) { dHeight = quadrant === 3 ? dy / Math.cos(rad) : dy / Math.sin(rad); } var quadrant13 = quadrant === 1 || quadrant === 3; switch (relativeDirection) { case 'top': case 'bottom': dHeight = dy ? dy / (quadrant13 ? Math.cos(rad) : Math.sin(rad)) : dx / (quadrant13 ? Math.sin(rad) : Math.cos(rad)); break; case 'left': case 'right': dWidth = dx ? dx / (quadrant13 ? Math.cos(rad) : Math.sin(rad)) : dy / (quadrant13 ? Math.sin(rad) : Math.cos(rad)); break; default: break; } } switch (relativeDirection) { case 'top': case 'bottom': dWidth = 0; break; case 'left': case 'right': dHeight = 0; break; default: break; } var gridSize = this.graph.getGridSize(); var newWidth = Math.max(nodeBbox.width + dWidth, gridSize); var newHeight = Math.max(nodeBbox.height + dHeight, gridSize); if (options.minWidth && options.minWidth > gridSize) { newWidth = Math.max(newWidth, options.minWidth); } if (options.minHeight && options.minHeight > gridSize) { newHeight = Math.max(newHeight, options.minHeight); } if (options.maxWidth) { newWidth = Math.min(newWidth, options.maxWidth); } if (options.maxHeight) { newHeight = Math.min(newHeight, options.maxHeight); } if (options.preserveAspectRatio) { if (dHeight < dWidth) { newHeight = newWidth * (nodeBbox.height / nodeBbox.width); } else { newWidth = newHeight * (nodeBbox.width / nodeBbox.height); } } if (newWidth !== nodeBbox.width || newHeight !== nodeBbox.height) { node.resize(newWidth, newHeight, { direction: direction, relativeDirection: relativeDirection, trueDirection: trueDirection, snapped: true, snaplines: this.cid, restrict: this.graph.hook.getRestrictArea(view), }); if (verticalHeight_1) { verticalHeight_1 += newHeight - nodeBbox.height; } if (horizontalWidth_1) { horizontalWidth_1 += newWidth - nodeBbox.width; } } var newRotatedBBox = node.getBBox().bbox(angle); if (verticalLeft_1 && Math.abs(newRotatedBBox.x - verticalLeft_1) > 1 && Math.abs(newRotatedBBox.width + newRotatedBBox.x - verticalLeft_1) > 1) { verticalLeft_1 = undefined; } if (horizontalTop_1 && Math.abs(newRotatedBBox.y - horizontalTop_1) > 1 && Math.abs(newRotatedBBox.height + newRotatedBBox.y - horizontalTop_1) > 1) { horizontalTop_1 = undefined; } this.update({ verticalLeft: verticalLeft_1, verticalTop: verticalTop_1, verticalHeight: verticalHeight_1, horizontalTop: horizontalTop_1, horizontalLeft: horizontalLeft_1, horizontalWidth: horizontalWidth_1, }); } } }; Snapline.prototype.snapOnMoving = function (_a) { var _this = this; var view = _a.view, e = _a.e, x = _a.x, y = _a.y; var targetView = view.getEventData(e).delegatedView || view; if (!this.isNodeMovable(targetView)) { return; } var node = targetView.cell; var size = node.getSize(); var position = node.getPosition(); var cellBBox = new geometry_1.Rectangle(x - this.offset.x, y - this.offset.y, size.width, size.height); var angle = node.getAngle(); var nodeCenter = cellBBox.getCenter(); var nodeBBoxRotated = cellBBox.bbox(angle); var nodeTopLeft = nodeBBoxRotated.getTopLeft(); var nodeBottomRight = nodeBBoxRotated.getBottomRight(); var distance = this.options.tolerance || 0; var verticalLeft; var verticalTop; var verticalHeight; var horizontalTop; var horizontalLeft; var horizontalWidth; var verticalFix = 0; var horizontalFix = 0; this.model.getNodes().some(function (targetNode) { if (_this.isIgnored(node, targetNode)) { return false; } var snapBBox = targetNode.getBBox().bbox(targetNode.getAngle()); var snapCenter = snapBBox.getCenter(); var snapTopLeft = snapBBox.getTopLeft(); var snapBottomRight = snapBBox.getBottomRight(); if (verticalLeft == null) { if (Math.abs(snapCenter.x - nodeCenter.x) < distance) { verticalLeft = snapCenter.x; verticalFix = 0.5; } else if (Math.abs(snapTopLeft.x - nodeTopLeft.x) < distance) { verticalLeft = snapTopLeft.x; verticalFix = 0; } else if (Math.abs(snapTopLeft.x - nodeBottomRight.x) < distance) { verticalLeft = snapTopLeft.x; verticalFix = 1; } else if (Math.abs(snapBottomRight.x - nodeBottomRight.x) < distance) { verticalLeft = snapBottomRight.x; verticalFix = 1; } else if (Math.abs(snapBottomRight.x - nodeTopLeft.x) < distance) { verticalLeft = snapBottomRight.x; } if (verticalLeft != null) { verticalTop = Math.min(nodeBBoxRotated.y, snapBBox.y); verticalHeight = Math.max(nodeBottomRight.y, snapBottomRight.y) - verticalTop; } } if (horizontalTop == null) { if (Math.abs(snapCenter.y - nodeCenter.y) < distance) { horizontalTop = snapCenter.y; horizontalFix = 0.5; } else if (Math.abs(snapTopLeft.y - nodeTopLeft.y) < distance) { horizontalTop = snapTopLeft.y; } else if (Math.abs(snapTopLeft.y - nodeBottomRight.y) < distance) { horizontalTop = snapTopLeft.y; horizontalFix = 1; } else if (Math.abs(snapBottomRight.y - nodeBottomRight.y) < distance) { horizontalTop = snapBottomRight.y; horizontalFix = 1; } else if (Math.abs(snapBottomRight.y - nodeTopLeft.y) < distance) { horizontalTop = snapBottomRight.y; } if (horizontalTop != null) { horizontalLeft = Math.min(nodeBBoxRotated.x, snapBBox.x); horizontalWidth = Math.max(nodeBottomRight.x, snapBottomRight.x) - horizontalLeft; } } return verticalLeft != null && horizontalTop != null; }); this.hide(); if (horizontalTop != null || verticalLeft != null) { if (horizontalTop != null) { nodeBBoxRotated.y = horizontalTop - horizontalFix * nodeBBoxRotated.height; } if (verticalLeft != null) { nodeBBoxRotated.x = verticalLeft - verticalFix * nodeBBoxRotated.width; } var newCenter = nodeBBoxRotated.getCenter(); var newX = newCenter.x - cellBBox.width / 2; var newY = newCenter.y - cellBBox.height / 2; var dx = newX - position.x; var dy = newY - position.y; if (dx !== 0 || dy !== 0) { node.translate(dx, dy, { snapped: true, restrict: this.graph.hook.getRestrictArea(targetView), }); if (horizontalWidth) { horizontalWidth += dx; } if (verticalHeight) { verticalHeight += dy; } } this.update({ verticalLeft: verticalLeft, verticalTop: verticalTop, verticalHeight: verticalHeight, horizontalTop: horizontalTop, horizontalLeft: horizontalLeft, horizontalWidth: horizontalWidth, }); } }; Snapline.prototype.isIgnored = function (snapNode, targetNode) { return (targetNode.id === snapNode.id || targetNode.isDescendantOf(snapNode) || this.filterShapes[targetNode.shape] || this.filterCells[targetNode.id] || (this.filterFunction && util_1.FunctionExt.call(this.filterFunction, this.graph, targetNode))); }; Snapline.prototype.update = function (metadata) { var ctm = this.graph.matrix(); var sx = ctm.a; var sy = ctm.d; var tx = ctm.e; var ty = ctm.f; var sharp = this.options.sharp; var hasScroller = this.graph.scroller.widget != null; if (metadata.horizontalTop) { this.$horizontal .css({ top: metadata.horizontalTop * sy + ty, left: sharp ? metadata.horizontalLeft * sx + tx : hasScroller ? '-300%' : 0, width: sharp ? metadata.horizontalWidth * sx : hasScroller ? '700%' : '100%', }) .show(); } else { this.$horizontal.hide(); } if (metadata.verticalLeft) { this.$vertical .css({ left: metadata.verticalLeft * sx + tx, top: sharp ? metadata.verticalTop * sy + ty : hasScroller ? '-300%' : 0, height: sharp ? metadata.verticalHeight * sy : hasScroller ? '700%' : '100%', }) .show(); } else { this.$vertical.hide(); } this.show(); }; Snapline.prototype.resetTimer = function () { if (this.timer) { clearTimeout(this.timer); this.timer = null; } }; Snapline.prototype.show = function () { this.$container.show(); this.resetTimer(); if (this.container.parentNode == null) { this.graph.container.appendChild(this.container); } return this; }; Snapline.prototype.hide = function () { var _this = this; this.$container.hide(); this.resetTimer(); var clean = this.options.clean; var delay = typeof clean === 'number' ? clean : clean !== false ? 3000 : 0; if (delay > 0) { this.timer = window.setTimeout(function () { _this.unmount(); }, delay); } return this; }; Snapline.prototype.onRemove = function () { this.stopListening(); this.hide(); }; Snapline.prototype.dispose = function () { this.remove(); }; __decorate([ view_1.View.dispose() ], Snapline.prototype, "dispose", null); return Snapline; }(view_1.View)); exports.Snapline = Snapline; //# sourceMappingURL=index.js.map