UNPKG

@logicflow/extension

Version:
283 lines (282 loc) 14.8 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 __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DynamicGroupNode = void 0; var core_1 = require("@logicflow/core"); var lodash_es_1 = require("lodash-es"); var utils_1 = require("../tools/label/utils"); var DynamicGroupNode = /** @class */ (function (_super) { __extends(DynamicGroupNode, _super); function DynamicGroupNode() { var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this; _this.childrenPositionMap = new Map(); _this.onNodeRotate = function (_a) { var model = _a.model; var _b = _this.props, curGroup = _b.model, graphModel = _b.graphModel; var transformWithContainer = curGroup.transformWithContainer, isRestrict = curGroup.isRestrict; var childrenPositionMap = _this.childrenPositionMap; if (!transformWithContainer || isRestrict) { // isRestrict限制模式下,当前model resize时不能小于占地面积 // 由于parent:resize=>child:resize计算复杂,需要根据child:resize的判定结果来递归判断parent能否resize // 不符合目前 parent:resize成功后emit事件 -> 触发child:resize 的代码交互模式 // 因此isRestrict限制模式下不支持联动(parent:resize=>child:resize) // 由于transformWidthContainer是控制rotate+resize,为保持transformWidthContainer本来的含义 // parent:resize=>child:resize不支持,那么parent:rotate=>child:rotate也不支持 return; } // DONE: 目前操作是对分组内节点以节点中心旋转节点本身,而按照正常逻辑,应该是以分组中心,旋转节点(跟 Label 旋转操作逻辑一致) if (model.id === curGroup.id) { var center_1 = { x: curGroup.x, y: curGroup.y }; (0, lodash_es_1.forEach)(Array.from(curGroup.children), function (childId) { var child = graphModel.getNodeModelById(childId); if (child) { var point = { x: child.x, y: child.y }; if (childrenPositionMap.has(child.id)) { point = childrenPositionMap.get(child.id); } else { childrenPositionMap.set(child.id, point); } // 弧度转角度 var theta = model.rotate * (180 / Math.PI); if (theta < 0) theta += 360; var radian = theta * (Math.PI / 180); var newPoint = (0, utils_1.rotatePointAroundCenter)(point, center_1, radian); child.moveTo(newPoint.x, newPoint.y); child.rotate = model.rotate; } }); } }; _this.onNodeResize = function (_a) { var deltaX = _a.deltaX, deltaY = _a.deltaY, index = _a.index, model = _a.model, preData = _a.preData; var _b = _this.props, curGroup = _b.model, graphModel = _b.graphModel; var transformWithContainer = curGroup.transformWithContainer, isRestrict = curGroup.isRestrict; if (!transformWithContainer || isRestrict) { // isRestrict限制模式下,当前model resize时不能小于占地面积 // 由于parent:resize=>child:resize计算复杂,需要根据child:resize的判定结果来递归判断parent能否resize // 不符合目前 parent:resize成功后emit事件 -> 触发child:resize 的代码交互模式 // 因此isRestrict限制模式下不支持联动(parent:resize=>child:resize) return; } if (model.id === curGroup.id) { // node:resize是group已经改变width和height后的回调 // 因此这里一定得用preData(没resize改变width之前的值),而不是data/model var properties = preData.properties; var _c = properties || {}, groupWidth_1 = _c.width, groupHeight_1 = _c.height; (0, lodash_es_1.forEach)(Array.from(curGroup.children), function (childId) { var child = graphModel.getNodeModelById(childId); if (child) { // 根据比例去控制缩放dx和dy var childDx = (child.width / groupWidth_1) * deltaX; var childDy = (child.height / groupHeight_1) * deltaY; // child.rotate = model.rotate (0, core_1.handleResize)({ deltaX: childDx, deltaY: childDy, index: index, nodeModel: child, graphModel: graphModel, cancelCallback: function () { }, }); } }); } }; _this.onNodeMouseMove = function () { // console.log(data,deltaX,deltaY,'111') // const { model: curGroup, graphModel } = this.props // const { transformModel } = graphModel // const { SCALE_X, SCALE_Y } = transformModel // if (data.id === curGroup.id) { // const nodeIds = this.getNodesInGroup(curGroup, graphModel) // // https://github.com/didi/LogicFlow/issues/1914 // // 当调用lf.fitView()时,会改变整体的SCALE_X和SCALE_Y // // 由于group的mousemove是在drag.ts的this.onDragging()处理的,在onDragging()里面进行SCALE的处理 // // 而"node:mousemove"emit出来跟onDragging()是同时的,也就是emit出来的数据是没有经过SCALE处理的坐标 // // 因此这里需要增加SCALE的处理 // graphModel.moveNodes(nodeIds, deltaX / SCALE_X, deltaY / SCALE_Y, true) // } }; _this.graphRendered = function () { var model = _this.props.model; // 初始化时,如果 this.isCollapsed 为 true,则主动触发一次折叠操作 if (model.isCollapsed) { // https://github.com/didi/LogicFlow/issues/1918 // 当lf.render({nodes:[{分组节点}, {普通节点}]})时,由于是顺序遍历 // 会先触发分组Group节点的new Model => toggleCollapse() // => 此时在graphModel.elementsModelMap找不到它的children,因为还没初始化,因此无法正确折叠子元素 // -------------------- // 当lf.render({nodes:[{普通节点}, {分组节点}]})时, // 会先触发普通节点的new Model => graphModel.elementsModelMap.set(id, new Model()) // 然后再触发分组Group节点的new Model => toggleCollapse() => // 此时在graphModel.elementsModelMap能找到它的children了,因此可以正确折叠子元素 // -------------------- // 因此将整个初始化判断是否【主动触发一次折叠操作】放在"graph:rendered"全部渲染完成后再执行 model.toggleCollapse(true); } }; return _this; } DynamicGroupNode.prototype.componentDidMount = function () { _super.prototype.componentDidMount.call(this); var eventCenter = this.props.graphModel.eventCenter; // 在 group 旋转时,对组内的所有子节点也进行对应的旋转计算 eventCenter.on('node:rotate', this.onNodeRotate); // 在 group 缩放时,对组内的所有子节点也进行对应的缩放计算 eventCenter.on('node:resize', this.onNodeResize); // 在 group 移动时,对组内的所有子节点也进行对应的移动计算 eventCenter.on('node:mousemove', this.onNodeMouseMove); // 全部渲染完成后,判断是否【主动触发一次折叠操作】 eventCenter.on('graph:rendered', this.graphRendered); }; DynamicGroupNode.prototype.componentWillUnmount = function () { _super.prototype.componentWillUnmount.call(this); var eventCenter = this.props.graphModel.eventCenter; eventCenter.off('node:rotate', this.onNodeRotate); eventCenter.off('node:resize', this.onNodeResize); eventCenter.off('node:mousemove', this.onNodeMouseMove); eventCenter.off('graph:rendered', this.graphRendered); }; /** * 获取分组内的节点 * @param groupModel * @param graphModel */ DynamicGroupNode.prototype.getNodesInGroup = function (groupModel, graphModel) { var _this = this; var nodeIds = []; if (groupModel.isGroup) { (0, lodash_es_1.forEach)(Array.from(groupModel.children), function (nodeId) { nodeIds.push(nodeId); var nodeModel = graphModel.getNodeModelById(nodeId); if (nodeModel === null || nodeModel === void 0 ? void 0 : nodeModel.isGroup) { nodeIds = nodeIds.concat(_this.getNodesInGroup(nodeModel, graphModel)); } }); } return nodeIds; }; DynamicGroupNode.prototype.getResizeControl = function () { var _a = this.props.model, resizable = _a.resizable, isCollapsed = _a.isCollapsed; var showResizeControl = resizable && !isCollapsed; return showResizeControl ? _super.prototype.getResizeControl.call(this) : null; }; DynamicGroupNode.prototype.getAppendAreaShape = function () { // DONE: 此区域用于初始化 group container, 即元素拖拽进入感应区域 var model = this.props.model; var width = model.width, height = model.height, x = model.x, y = model.y, radius = model.radius, groupAddable = model.groupAddable; if (!groupAddable) return null; var _a = model.getNodeStyle().strokeWidth, strokeWidth = _a === void 0 ? 0 : _a; var style = model.getAddableOutlineStyle(); var newWidth = width + strokeWidth + 8; var newHeight = height + strokeWidth + 8; return (0, core_1.h)('rect', __assign(__assign({}, style), { width: newWidth, height: newHeight, x: x - newWidth / 2, y: y - newHeight / 2, rx: radius, ry: radius })); }; DynamicGroupNode.prototype.getCollapseIcon = function (sx, sy) { return "M ".concat(sx + 3, ",").concat(sy + 6, " ").concat(sx + 11, ",").concat(sy + 6, " M").concat(sx + 7, ",").concat(sy + 2, " ").concat(sx + 7, ",").concat(sy + 10); }; DynamicGroupNode.prototype.getExpandIcon = function (sx, sy) { return "M ".concat(sx + 3, ",").concat(sy + 6, " ").concat(sx + 11, ",").concat(sy + 6, " "); }; // 获取操作图标(收起或展开) DynamicGroupNode.prototype.getOperateIcon = function () { var model = this.props.model; var x = model.x, y = model.y, width = model.width, height = model.height; var sx = x - width / 2 + 10; var sy = y - height / 2 + 10; if (!model.collapsible) return null; var iconPath = (model === null || model === void 0 ? void 0 : model.isCollapsed) ? this.getCollapseIcon(sx, sy) : this.getExpandIcon(sx, sy); var operateIcon = (0, core_1.h)('path', { fill: 'none', stroke: '#818281', strokeWidth: 2, 'pointer-events': 'none', d: iconPath, }); return (0, core_1.h)('g', {}, [ (0, core_1.h)('rect', { height: 12, width: 14, rx: 2, ry: 2, strokeWidth: 1, fill: '#f4f5f6', stroke: '#cecece', cursor: 'pointer', x: sx, y: sy, onClick: function () { // DONE: 抛出折叠或展开事件 -> 在 toggleCollapse 方法中抛出 model.toggleCollapse(!model.isCollapsed); }, }), operateIcon, ]); }; DynamicGroupNode.prototype.getShape = function () { return (0, core_1.h)('g', {}, [ this.getAppendAreaShape(), _super.prototype.getShape.call(this), this.getOperateIcon(), ]); }; return DynamicGroupNode; }(core_1.RectNode)); exports.DynamicGroupNode = DynamicGroupNode; exports.default = DynamicGroupNode;