@logicflow/extension
Version:
LogicFlow Extensions
283 lines (282 loc) • 14.8 kB
JavaScript
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;
;