@logicflow/core
Version:
LogicFlow, help you quickly create flowcharts
357 lines (356 loc) • 18.3 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 __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;
};
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;
};
import { jsx as _jsx } from "preact/jsx-runtime";
import { Component } from 'preact/compat';
import { StepDrag, formatAnchorConnectValidateData, targetNodeInfo, } from '../../util';
import { ElementState, EventType, ModelType } from '../../constant';
export var AdjustType;
(function (AdjustType) {
AdjustType["SOURCE"] = "SOURCE";
AdjustType["TARGET"] = "TARGET";
})(AdjustType || (AdjustType = {}));
var AdjustPoint = /** @class */ (function (_super) {
__extends(AdjustPoint, _super);
function AdjustPoint(props) {
var _this = _super.call(this) || this;
_this.handleMouseDown = function (ev) {
if (_this.stepDrag) {
_this.stepDrag.handleMouseDown(ev);
}
};
_this.onDragStart = function () {
var _a = _this.props, x = _a.x, y = _a.y, edgeModel = _a.edgeModel;
var startPoint = edgeModel.startPoint, endPoint = edgeModel.endPoint, pointsList = edgeModel.pointsList;
// 记录下原始路径信息,在调整中,如果放弃调整,进行路径还原
_this.oldEdge = {
startPoint: startPoint,
endPoint: endPoint,
pointsList: pointsList,
};
_this.setState({
endX: x,
endY: y,
dragging: true,
});
// 拖拽AdjustPoint时不修改edgeModel.isHitable,避免偶尔会出现边不能点击问题(https://github.com/didi/LogicFlow/issues/974)
// edgeModel.isHitable = false;
};
_this.onDragging = function (_a) {
var deltaX = _a.deltaX, deltaY = _a.deltaY;
var _b = _this.state, endX = _b.endX, endY = _b.endY;
var _c = _this.props, graphModel = _c.graphModel, type = _c.type;
var transformModel = graphModel.transformModel, editConfigModel = graphModel.editConfigModel;
var _d = __read(transformModel.moveCanvasPointByHtml([endX, endY], deltaX, deltaY), 2), x = _d[0], y = _d[1];
_this.setState({
endX: x,
endY: y,
dragging: true,
});
// 调整过程中实时更新路径
var edgeModel = _this.props.edgeModel;
var info = targetNodeInfo({
x: endX,
y: endY,
}, graphModel);
// 如果一定的坐标能够找到目标节点,预结算当前节点与目标节点的路径进行展示
if (info && info.node && _this.isAllowAdjust(info).pass) {
var startPoint = edgeModel.startPoint, endPoint = edgeModel.endPoint, sourceNode = edgeModel.sourceNode, targetNode = edgeModel.targetNode;
var params = type === AdjustType.SOURCE
? {
startPoint: {
x: info.anchor.x,
y: info.anchor.y,
},
endPoint: {
x: endPoint.x,
y: endPoint.y,
},
sourceNode: info.node,
targetNode: targetNode,
}
: {
startPoint: {
x: startPoint.x,
y: startPoint.y,
},
endPoint: {
x: info.anchor.x,
y: info.anchor.y,
},
sourceNode: sourceNode,
targetNode: info.node,
};
edgeModel.updateAfterAdjustStartAndEnd(params);
}
else {
// 如果没有找到目标节点,更新起终点为当前坐标
type === AdjustType.SOURCE
? edgeModel.updateStartPoint({ x: x, y: y })
: edgeModel.updateEndPoint({ x: x, y: y });
}
if (edgeModel.text.value && editConfigModel.adjustEdge) {
edgeModel.setText(Object.assign({}, edgeModel.text, edgeModel.textPosition));
}
};
_this.onDragEnd = function (_a) {
var _b, _c, _d;
var event = _a.event;
try {
// 将状态置为非拖拽状态
_this.setState({
dragging: false,
});
var _e = _this.props, graphModel = _e.graphModel, edgeModel = _e.edgeModel, type = _e.type;
// 拖拽AdjustPoint时不修改edgeModel.isHitable,避免偶尔会出现边不能点击问题(https://github.com/didi/LogicFlow/issues/974)
// edgeModel.isHitable = true;
var _f = _this.state, endX = _f.endX, endY = _f.endY, dragging = _f.dragging;
var info = targetNodeInfo({
x: endX,
y: endY,
}, graphModel);
// 没有dragging就结束边
if (!dragging)
return;
// 如果找到目标节点,删除老边,创建新边
var needRecoveryEdge = false;
var createEdgeInfo = void 0;
if (info && info.node) {
var _g = _this.isAllowAdjust(info), pass = _g.pass, msg = _g.msg, newTargetNode = _g.newTargetNode;
if (pass) {
var _h = edgeModel.getData(), text = _h.text, _j = _h.sourceAnchorId, sourceAnchorId = _j === void 0 ? '' : _j, _k = _h.targetAnchorId, targetAnchorId = _k === void 0 ? '' : _k, rest = __rest(_h, ["text", "sourceAnchorId", "targetAnchorId"]);
createEdgeInfo = __assign(__assign({ sourceAnchorId: sourceAnchorId, targetAnchorId: targetAnchorId }, rest), { text: (text === null || text === void 0 ? void 0 : text.value) || '' });
// 根据调整点是边的起点或重点,计算创建边需要的参数
if (type === AdjustType.SOURCE) {
var sourceNode = graphModel.getNodeModelById(info.node.id);
var targetNode = graphModel.getNodeModelById(edgeModel.targetNodeId);
var edgeInfo = (_b = graphModel.edgeGenerator) === null || _b === void 0 ? void 0 : _b.call(graphModel, sourceNode === null || sourceNode === void 0 ? void 0 : sourceNode.getData(), targetNode === null || targetNode === void 0 ? void 0 : targetNode.getData(), createEdgeInfo);
createEdgeInfo = __assign(__assign({}, edgeInfo), { sourceNodeId: info.node.id, sourceAnchorId: info.anchor.id, startPoint: {
x: info.anchor.x,
y: info.anchor.y,
}, targetNodeId: edgeModel.targetNodeId, endPoint: __assign({}, edgeModel.endPoint) });
// 找到的是原有的源节点上的原锚点时,还原边
if (edgeModel.sourceNodeId === info.node.id &&
edgeModel.sourceAnchorId === info.anchor.id) {
needRecoveryEdge = true;
}
}
else if (type === AdjustType.TARGET) {
var sourceNode = graphModel.getNodeModelById(edgeModel.sourceNodeId);
var targetNode = graphModel.getNodeModelById(info.node.id);
var edgeInfo = (_c = graphModel.edgeGenerator) === null || _c === void 0 ? void 0 : _c.call(graphModel, sourceNode === null || sourceNode === void 0 ? void 0 : sourceNode.getData(), targetNode === null || targetNode === void 0 ? void 0 : targetNode.getData(), createEdgeInfo);
createEdgeInfo = __assign(__assign({}, edgeInfo), { sourceNodeId: edgeModel.sourceNodeId, startPoint: __assign({}, edgeModel.startPoint), targetNodeId: info.node.id, targetAnchorId: info.anchor.id, endPoint: {
x: info.anchor.x,
y: info.anchor.y,
} });
// 找到的是原有的目标节点上的原锚点时,还原边
if (edgeModel.targetNodeId === info.node.id &&
edgeModel.targetAnchorId === info.anchor.id) {
needRecoveryEdge = true;
}
}
}
else {
// 如果没有通过校验,还原边并抛出CONNECTION_NOT_ALLOWED事件
needRecoveryEdge = true;
var nodeData = newTargetNode.getData();
graphModel.eventCenter.emit(EventType.CONNECTION_NOT_ALLOWED, {
data: nodeData,
msg: msg,
});
}
}
else {
// 如果没有找到目标节点,还原边
needRecoveryEdge = true;
}
if (!needRecoveryEdge) {
// 为了保证id不变必须要先删除老边,再创建新边,创建新边是会判断是否有重复的id
// 删除老边
var oldEdgeData = edgeModel.getData();
graphModel.deleteEdgeById(edgeModel.id);
// 创建新边
var edge = graphModel.addEdge(__assign({}, createEdgeInfo));
// 向外抛出事件
graphModel.eventCenter.emit(EventType.EDGE_EXCHANGE_NODE, {
data: {
newEdge: edge.getData(),
oldEdge: oldEdgeData,
},
});
}
else {
// 如果没有找到目标节点或者没有通过校验,还原边
_this.recoveryEdge();
}
(_d = _this.preTargetNode) === null || _d === void 0 ? void 0 : _d.setElementState(ElementState.DEFAULT);
}
finally {
var graphModel = _this.props.graphModel;
graphModel.eventCenter.emit(EventType.ADJUST_POINT_DRAGEND, {
e: event,
data: _this.stepDragData,
});
}
};
// 还原边
_this.recoveryEdge = function () {
var edgeModel = _this.props.edgeModel;
var _a = _this.oldEdge, startPoint = _a.startPoint, endPoint = _a.endPoint, pointsList = _a.pointsList;
edgeModel.updateStartPoint(startPoint);
edgeModel.updateEndPoint(endPoint);
// 折线和曲线还需要更新其pointsList
if (edgeModel.modelType !== ModelType.LINE_EDGE) {
edgeModel.pointsList = pointsList !== null && pointsList !== void 0 ? pointsList : [];
edgeModel.initPoints();
}
};
// 调整点的样式默认从主题中读取, 可以复写此方法进行更加个性化的自定义
// 目前仅支持圆形图标进行标识,可以从圆形的r和颜色上进行调整
_this.getAdjustPointStyle = function () {
var theme = _this.props.graphModel.theme;
var edgeAdjust = theme.edgeAdjust;
return edgeAdjust;
};
_this.state = {
dragging: false,
endX: 0,
endY: 0,
};
_this.targetRuleResults = new Map();
_this.sourceRuleResults = new Map();
var type = props.type, edgeModel = props.edgeModel, graphModel = props.graphModel;
var eventCenter = graphModel.eventCenter;
_this.stepDragData = {
type: type,
edgeData: edgeModel.getData(),
};
_this.stepDrag = new StepDrag({
onDragStart: _this.onDragStart,
onDragging: _this.onDragging,
onDragEnd: _this.onDragEnd,
eventType: 'ADJUST_POINT',
isStopPropagation: false,
eventCenter: eventCenter,
data: _this.stepDragData,
});
return _this;
}
AdjustPoint.prototype.isAllowAdjust = function (info) {
var _a = this.props, _b = _a.edgeModel, id = _b.id, sourceNode = _b.sourceNode, targetNode = _b.targetNode, sourceAnchorId = _b.sourceAnchorId, targetAnchorId = _b.targetAnchorId, type = _a.type;
// const newTargetNode = info.node;
var newSourceNode;
var newTargetNode;
var newSourceAnchor;
var newTargetAnchor;
// 如果调整的是连线起点
if (type === AdjustType.SOURCE) {
newSourceNode = info.node;
newTargetNode = targetNode;
newSourceAnchor = info.anchor;
newTargetAnchor = targetNode.getAnchorInfo(targetAnchorId);
}
else {
newSourceNode = sourceNode;
newTargetNode = info.node;
newTargetAnchor = info.anchor;
newSourceAnchor = sourceNode.getAnchorInfo(sourceAnchorId);
}
// 如果前一个接触的节点和此时接触的节点不相等,则将前一个节点状态重新设置为默认状态。
if (this.preTargetNode && this.preTargetNode !== info.node) {
this.preTargetNode.setElementState(ElementState.DEFAULT);
}
this.preTargetNode = info.node;
// #500 不允许锚点自己连自己, 在锚点一开始连接的时候, 不触发自己连接自己的校验。
if (newTargetAnchor.id === newSourceAnchor.id) {
return {
pass: false,
msg: '',
newTargetNode: newTargetNode,
};
}
var targetInfoId = "".concat(newSourceNode.id, "_").concat(newTargetNode.id, "_").concat(newSourceAnchor.id, "_").concat(newTargetAnchor.id);
// 查看鼠标是否进入过target,若有检验结果,表示进入过, 就不重复计算了。
if (!this.targetRuleResults.has(targetInfoId)) {
var sourceRuleResult = newSourceNode.isAllowConnectedAsSource(newTargetNode, newSourceAnchor, newTargetAnchor, id);
var targetRuleResult = newTargetNode.isAllowConnectedAsTarget(newSourceNode, newSourceAnchor, newTargetAnchor, id);
this.sourceRuleResults.set(targetInfoId, formatAnchorConnectValidateData(sourceRuleResult));
this.targetRuleResults.set(targetInfoId, formatAnchorConnectValidateData(targetRuleResult));
}
var _c = this.sourceRuleResults.get(targetInfoId), isSourcePass = _c.isAllPass, sourceMsg = _c.msg;
var _d = this.targetRuleResults.get(targetInfoId), isTargetPass = _d.isAllPass, targetMsg = _d.msg;
// 实时提示出即将连接的节点是否允许连接
var state = isSourcePass && isTargetPass
? ElementState.ALLOW_CONNECT
: ElementState.NOT_ALLOW_CONNECT;
if (type === AdjustType.SOURCE) {
newSourceNode.setElementState(state);
}
else {
newTargetNode.setElementState(state);
}
return {
pass: isSourcePass && isTargetPass,
msg: targetMsg || sourceMsg,
newTargetNode: newTargetNode,
};
};
AdjustPoint.prototype.render = function () {
var _a = this.props, x = _a.x, y = _a.y, getAdjustPointShape = _a.getAdjustPointShape, edgeModel = _a.edgeModel;
var dragging = this.state.dragging;
return (_jsx("g", { pointerEvents: dragging ? 'none' : '', onPointerDown: this.handleMouseDown, children: !dragging ? getAdjustPointShape(x, y, edgeModel) : '' }));
};
return AdjustPoint;
}(Component));
export { AdjustPoint };
export default AdjustPoint;