@antv/x6
Version:
JavaScript diagramming library that uses SVG and HTML for rendering.
628 lines • 26.2 kB
JavaScript
"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