butterfly-dag
Version:
一个基于数据驱动的节点式编排组件库,让你有方便快捷定制可视化流程图表
1,939 lines (1,591 loc) • 388 kB
JavaScript
import _$d from 'lodash';
import d3Force from 'd3-force';
import dagre from 'dagre';
import { Matrix, SingularValueDecomposition } from 'ml-matrix';
import '@antv/matrix-util';
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) {
symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
}
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _typeof(obj) {
"@babel/helpers - typeof";
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
_typeof = function (obj) {
return typeof obj;
};
} else {
_typeof = function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
}
return _typeof(obj);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
return _assertThisInitialized(self);
}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _superPropBase(object, property) {
while (!Object.prototype.hasOwnProperty.call(object, property)) {
object = _getPrototypeOf(object);
if (object === null) break;
}
return object;
}
function _get(target, property, receiver) {
if (typeof Reflect !== "undefined" && Reflect.get) {
_get = Reflect.get;
} else {
_get = function _get(target, property, receiver) {
var base = _superPropBase(target, property);
if (!base) return;
var desc = Object.getOwnPropertyDescriptor(base, property);
if (desc.get) {
return desc.get.call(receiver);
}
return desc.value;
};
}
return _get(target, property, receiver || target);
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
}
function _iterableToArrayLimit(arr, i) {
var _i = arr && (typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]);
if (_i == null) return;
var _arr = [];
var _n = true;
var _d = false;
var _s, _e;
try {
for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
return arr2;
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _createForOfIteratorHelper(o, allowArrayLike) {
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
if (!it) {
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
if (it) o = it;
var i = 0;
var F = function () {};
return {
s: F,
n: function () {
if (i >= o.length) return {
done: true
};
return {
done: false,
value: o[i++]
};
},
e: function (e) {
throw e;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var normalCompletion = true,
didErr = false,
err;
return {
s: function () {
it = it.call(o);
},
n: function () {
var step = it.next();
normalCompletion = step.done;
return step;
},
e: function (e) {
didErr = true;
err = e;
},
f: function () {
try {
if (!normalCompletion && it.return != null) it.return();
} finally {
if (didErr) throw err;
}
}
};
}
var EventEmit3$4 = require('eventemitter3');
var Canvas = /*#__PURE__*/function (_EventEmit) {
_inherits(Canvas, _EventEmit);
var _super = _createSuper(Canvas);
function Canvas() {
_classCallCheck(this, Canvas);
// root 根节点
// layout 布局支持
// zoomable 是否可放大缩小
// moveable 是否可移动
// draggable 是否可拖动节点
// linkable 是否可连接线条
// disLinkable 是否可取消连线
// theme 主题配置
// global 公共配置
return _super.call(this);
} // 渲染节点
_createClass(Canvas, [{
key: "draw",
value: function draw() {} // 获取节点
}, {
key: "getNode",
value: function getNode() {} // 获取线条
}, {
key: "getEdge",
value: function getEdge() {} // 获取节点组
}, {
key: "getGroup",
value: function getGroup() {} // 添加节点
}, {
key: "addNode",
value: function addNode() {} // 批量添加节点
}, {
key: "addNodes",
value: function addNodes() {} // 添加线条
}, {
key: "addEdge",
value: function addEdge() {} // 批量添加线条
}, {
key: "addEdges",
value: function addEdges() {} // 批量添加节点组
}, {
key: "addGroups",
value: function addGroups() {} // 删除节点
}, {
key: "removeNode",
value: function removeNode() {} // 批量删除节点
}, {
key: "removeNodes",
value: function removeNodes() {} // 删除线条
}, {
key: "removeEdge",
value: function removeEdge() {} // 批量删除线条
}, {
key: "removeEdges",
value: function removeEdges() {} // 删除节点组
}, {
key: "removeGroup",
value: function removeGroup() {} // 获取相邻的线条
}, {
key: "getNeighborEdges",
value: function getNeighborEdges() {} // 获取相邻的节点
}, {
key: "getNeighborNodes",
value: function getNeighborNodes() {} // 获取无环血缘图
}, {
key: "getNeighborNodesAndEdgesByLevel",
value: function getNeighborNodesAndEdgesByLevel() {}
}, {
key: "getAdjcentTable",
value: function getAdjcentTable() {} // 需要改为内部方法
// 获取缩放值
}, {
key: "getZoom",
value: function getZoom() {} // 动态设置可缩放
}, {
key: "setZoomable",
value: function setZoomable() {} // 动态设置缩放值
}, {
key: "zoom",
value: function zoom() {} // 获取偏移值
}, {
key: "getOffset",
value: function getOffset() {} // 动态设置可移动
}, {
key: "setMoveable",
value: function setMoveable() {} // 动态设置移动
}, {
key: "move",
value: function move() {} // 获取中心点
}, {
key: "getOrigin",
value: function getOrigin() {} // 动态设置中心点
}, {
key: "setOrigin",
value: function setOrigin() {} // 获取数据结构
}, {
key: "getDataMap",
value: function getDataMap() {} // 设置网格模式
}, {
key: "setGirdMode",
value: function setGirdMode() {} // 设置网格线条
}, {
key: "setGuideLine",
value: function setGuideLine() {} // 设置辅助线
}, {
key: "justifyCoordinate",
value: function justifyCoordinate() {} // 设置框选模式
}, {
key: "setSelectMode",
value: function setSelectMode() {} // 设置某些联合值,即框选的元素
}, {
key: "getUnion",
value: function getUnion() {} // 设置所有联合值,即框选的元素
}, {
key: "getAllUnion",
value: function getAllUnion() {} // 添加联合值
}, {
key: "add2Union",
value: function add2Union() {} // 删除某些联合值
}, {
key: "removeUnion",
value: function removeUnion() {} // 删除所有联合值
}, {
key: "removeAllUnion",
value: function removeAllUnion() {} // 聚焦单个节点(看看需要合并不)
}, {
key: "focusNodeWithAnimate",
value: function focusNodeWithAnimate() {} // 聚焦某些节点
}, {
key: "focusNodesWithAnimate",
value: function focusNodesWithAnimate() {} // 画布坐标转换为终端坐标
}, {
key: "canvas2terminal",
value: function canvas2terminal() {} // 终端坐标转换为画布坐标
}, {
key: "terminal2canvas",
value: function terminal2canvas() {} // 保存为图片
}, {
key: "save2img",
value: function save2img() {} // ********* 需要优化的api *********
// 更新画布的大小
}, {
key: "updateRootResize",
value: function updateRootResize() {} // ********* 需要新增的api *********
// 单击的回调
}, {
key: "click",
value: function click() {} // 双击的回调
}, {
key: "doubleClick",
value: function doubleClick() {} // 右键的回调
}, {
key: "onContextmenu",
value: function onContextmenu() {} // 集成menu
// 生成/关闭缩略图
}]);
return Canvas;
}(EventEmit3$4);
var EventEmit3$3 = require('eventemitter3');
var Node = /*#__PURE__*/function (_EventEmit) {
_inherits(Node, _EventEmit);
var _super = _createSuper(Node);
function Node() {
_classCallCheck(this, Node);
// id 节点唯一标志
// top 坐标y
// left 坐标x
// group 存在于哪个节点组上
// dom 节点的dom元素
// draggable 该节点是否能拖动标志,可覆盖全局的
// options 数据的透传
// _on 节点发送事件
// _emit 节点发送事件
// _global 全局的配置
// 需要优化的
// scope scope相同可拉进group里面
// endpoints endpoint对象
// _endpointsData 真实的endpoint数据
// _isMoving 标识是否在移动做,兼容冒泡
return _super.call(this);
} // 渲染节点
_createClass(Node, [{
key: "draw",
value: function draw() {} // 获取锚点
}, {
key: "getEndpoint",
value: function getEndpoint() {} // 添加锚点
}, {
key: "addEndpoint",
value: function addEndpoint() {} // 删除锚点
}, {
key: "removeEndpoint",
value: function removeEndpoint() {} // 移动节点
}, {
key: "moveTo",
value: function moveTo() {} // 获取宽度
}, {
key: "getWidth",
value: function getWidth() {} // 获取高度
}, {
key: "getHeight",
value: function getHeight() {} // 设置该节点是否能拖动,能覆盖全局
}, {
key: "setDraggable",
value: function setDraggable() {} // remove的方法
}, {
key: "remove",
value: function remove() {} // 销毁的方法
}, {
key: "destroy",
value: function destroy() {} // ********* 需要新增的api *********
// focus回调
}, {
key: "focus",
value: function focus() {} // unFocus回调
}, {
key: "unFocus",
value: function unFocus() {} // 单击的回调
}, {
key: "click",
value: function click() {} // 双击的回调
}, {
key: "doubleClick",
value: function doubleClick() {} // 右键的回调
}, {
key: "onContextmenu",
value: function onContextmenu() {} // hover的回调
}, {
key: "hover",
value: function hover() {}
}]);
return Node;
}(EventEmit3$3);
var EventEmit3$2 = require('eventemitter3');
var Endpoint = /*#__PURE__*/function (_EventEmit) {
_inherits(Endpoint, _EventEmit);
var _super = _createSuper(Endpoint);
function Endpoint() {
_classCallCheck(this, Endpoint);
return _super.call(this);
}
return Endpoint;
}(EventEmit3$2);
var $$a = require('jquery');
var _$c = require('lodash');
var BaseEndpoint = /*#__PURE__*/function (_Endpoint) {
_inherits(BaseEndpoint, _Endpoint);
var _super = _createSuper(BaseEndpoint);
function BaseEndpoint(opts) {
var _this;
_classCallCheck(this, BaseEndpoint);
_this = _super.call(this, opts);
_this.id = opts.id;
_this.options = opts;
_this.orientation = opts.orientation;
_this.pos = opts.pos;
_this.type = opts.type;
_this.nodeType = _$c.get(opts, 'nodeType', 'node');
_this.nodeId = _$c.get(opts, '_node.id');
_this.root = opts.root;
_this.scope = opts.scope;
_this.expandArea = opts.expandArea;
_this.limitNum = opts.limitNum; // 已连接数
_this.connectedNum = 0;
_this.options = opts; // 鸭子辨识手动判断类型
_this.__type = 'endpoint'; // 假如锚点在节点上则有值
_this._node = opts._node;
_this._global = opts._global;
_this._on = opts._on;
_this._emit = opts._emit; // 相对坐标
_this._top = 0;
_this._left = 0; // 相对于画布的绝对坐标
_this._posTop = 0;
_this._posLeft = 0;
_this._width = 0;
_this._height = 0; // 拉线时候可连接的标志
_this._linkable = false;
_this._coordinateService = null;
_this.dom = null; // 判断自定义锚点
_this._isInitedDom = false;
if (opts.dom) {
_this.dom = opts.dom;
_this._isInitedDom = true;
}
return _this;
}
_createClass(BaseEndpoint, [{
key: "_init",
value: function _init(obj) {
this._coordinateService = obj._coordinateService;
if (obj.nodeType) {
this.nodeType = obj.nodeType;
} // 计算锚点起始值
if (!this._isInitedDom) {
this.dom = this.draw({
id: this.id,
orientation: this.orientation,
pos: this.pos,
dom: this.dom,
root: this.root,
type: this.type,
options: this.options
});
} else {
// 计算width,height,left,top
this._width = $$a(this.dom).outerWidth();
this._height = $$a(this.dom).outerHeight();
this._left = this._coordinateService._terminal2canvas('x', $$a(this.dom).offset().left + this._coordinateService.scrollLeft);
this._top = this._coordinateService._terminal2canvas('y', $$a(this.dom).offset().top + this._coordinateService.scrollTop);
this._posTop = this._top;
this._posLeft = this._left;
}
this.attachEvent();
}
}, {
key: "draw",
value: function draw(obj) {
var _dom = obj.dom;
if (!_dom) {
_dom = $$a('<div class="butterflie-circle-endpoint"></div>').attr('id', this.id);
} else {
_dom = $$a(_dom);
}
return _dom[0];
}
}, {
key: "updatePos",
value: function updatePos() {
var dom = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.dom;
var orientation = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.orientation;
var pos = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.pos;
if (this._isInitedDom) {
// 计算width,height,left,top
this._width = $$a(this.dom).outerWidth();
this._height = $$a(this.dom).outerHeight(); // 计算锚点起始值
this._left = this._coordinateService._terminal2canvas('x', $$a(this.dom).offset().left + this._coordinateService.scrollLeft);
this._top = this._coordinateService._terminal2canvas('y', $$a(this.dom).offset().top + this._coordinateService.scrollTop);
this._posLeft = this._left;
this._posTop = this._top;
} else {
var _currentNode = this._node;
var _currentDom = $$a(this._node.dom);
this.nodeType; // 分情况弄好方向和位置
var nodeW = _currentDom.outerWidth();
var nodeH = _currentDom.outerHeight();
var targetDom = null;
var targetDomW = 0;
var targetDomH = 0;
if (this.root) {
targetDom = _currentDom.find(this.root);
targetDomW = targetDom.width();
targetDomH = targetDom.height();
}
this._width = $$a(dom).outerWidth();
this._height = $$a(dom).outerHeight(); // 计算节点本身的偏移量
var eOffsetX = this._width / 2;
var eOffsetY = this._height / 2;
var _offsetTop = 0;
var _offsetLeft = 0;
var _orientation = orientation || this.orientation || [0, -1];
var _pos = pos || this.pos || [_orientation[0] === 0 ? 0.5 : 0, _orientation[1] === 0 ? 0.5 : 0];
var result = [0, 0];
var _ox = _orientation[0];
var _oy = _orientation[1];
var _px = _pos[0];
var _py = _pos[1];
if (_ox === 0) {
result[0] = !this.root ? nodeW * _px - eOffsetX : targetDomW * _px - eOffsetX;
} else if (_ox === -1) {
result[0] = 0 - eOffsetX;
} else if (_ox === 1) {
result[0] = !this.root ? nodeW - eOffsetX : targetDomW - eOffsetX;
}
if (_oy === 0) {
result[1] = !this.root ? nodeH * _py - eOffsetY : targetDomH * _py - eOffsetY;
} else if (_oy === -1) {
result[1] = 0 - eOffsetY;
} else if (_oy === 1) {
result[1] = !this.root ? nodeH - eOffsetY : targetDomH - eOffsetY;
} // 计算绝对定位
if (_currentNode && !this.root) {
_offsetTop += _currentNode.top;
_offsetLeft += _currentNode.left;
} else if (_currentNode && this.root) {
// 计算传入的dom距离跟节点
var nodeDomOffsets = _currentDom.offset();
var targetDomOffsets = targetDom.offset(); // 先计算目标节点和父节点得差值再加上父节点的offset
_offsetTop += targetDomOffsets.top - nodeDomOffsets.top + _currentNode.top;
_offsetLeft += targetDomOffsets.left - nodeDomOffsets.left + _currentNode.left;
}
this._top = result[1] + _offsetTop;
this._left = result[0] + _offsetLeft;
this._posTop = this._top;
this._posLeft = this._left;
if (_currentNode._group) {
var _groupPos = this._getGroupPos(_currentNode._group);
this._posTop += _groupPos.top;
this._posLeft += _groupPos.left;
}
$$a(dom).css('top', this._top).css('left', this._left);
this.updated && this.updated();
}
this.emit('InnerEvents', {
type: 'endpoint:updatePos',
point: this
});
}
}, {
key: "_getGroupPos",
value: function _getGroupPos(group) {
var targetGroup = group;
var top = 0;
var left = 0;
while (targetGroup) {
top += targetGroup.top;
left += targetGroup.left;
targetGroup = targetGroup._group;
}
return {
top: top,
left: left
};
}
}, {
key: "hasConnection",
value: function hasConnection() {
return this.connectedNum > 0;
}
}, {
key: "moveTo",
value: function moveTo(x, y) {
this._top = y;
this._left = x;
this._posTop = this._top;
this._posLeft = this._left;
if (!this._isInitedDom) {
$$a(this.dom).css('top', y).css('left', x);
if (_$c.get(this, '_node._group')) {
this._posTop += this._node._group.top;
this._posLeft += this._node._group.left;
}
}
}
}, {
key: "linkable",
value: function linkable() {
$$a(this.dom).addClass('linkable');
}
}, {
key: "unLinkable",
value: function unLinkable() {
$$a(this.dom).removeClass('linkable');
}
}, {
key: "hoverLinkable",
value: function hoverLinkable() {
$$a(this.dom).addClass('hover');
}
}, {
key: "unHoverLinkable",
value: function unHoverLinkable() {
$$a(this.dom).removeClass('hover');
}
}, {
key: "attachEvent",
value: function attachEvent() {
var _this2 = this;
$$a(this.dom).on('mousedown', function (e) {
var LEFT_KEY = 0;
if (e.button !== LEFT_KEY) {
return;
}
e.preventDefault();
e.stopPropagation();
_this2.emit('InnerEvents', {
type: 'endpoint:drag',
data: _this2
});
});
}
}, {
key: "emit",
value: function emit(type, data) {
_get(_getPrototypeOf(BaseEndpoint.prototype), "emit", this).call(this, type, data);
this._emit(type, data);
}
}, {
key: "destroy",
value: function destroy(isNotEvent) {
if (!isNotEvent) {
$$a(this.dom).off();
$$a(this.dom).remove();
this.removeAllListeners();
} else {
$$a(this.dom).detach();
}
}
}]);
return BaseEndpoint;
}(Endpoint);
var $$9 = require('jquery');
var _$b = require('lodash');
var BaseNode = /*#__PURE__*/function (_Node) {
_inherits(BaseNode, _Node);
var _super = _createSuper(BaseNode);
function BaseNode(opts) {
var _this;
_classCallCheck(this, BaseNode);
_this = _super.call(this, opts);
_this.id = opts.id;
_this.scope = opts.scope;
_this.group = opts.group;
_this.top = opts.top || 0;
_this.left = opts.left || 0;
_this.dom = opts.dom || null;
_this.draggable = opts.draggable;
_this.options = opts; // 鸭子辨识手动判断类型
_this.__type = 'node';
_this._on = opts._on;
_this._emit = opts._emit;
_this._global = opts._global; // endpoint 这部分需要考虑
_this.endpoints = [];
_this._endpointsData = opts.endpoints;
_this._endpointLimitNum = opts._endpointLimitNum; // 标识是否在移动做,兼容冒泡
_this._isMoving = false; // 长宽
_this.width = undefined;
_this.height = undefined;
_this._isForceUpdateSize = false;
return _this;
}
_createClass(BaseNode, [{
key: "draw",
value: function draw(obj) {
var _dom = obj.dom;
if (!_dom) {
_dom = $$9('<div></div>').attr('class', 'node').attr('id', obj.id);
}
var node = $$9(_dom);
if (obj.top !== undefined) {
node.css('top', "".concat(obj.top, "px"));
}
if (obj.left !== undefined) {
node.css('left', "".concat(obj.left, "px"));
}
this.updated && this.updated();
return node[0];
}
}, {
key: "focus",
value: function focus() {}
}, {
key: "unFocus",
value: function unFocus() {}
}, {
key: "addEndpoint",
value: function addEndpoint(obj, isInited) {
if (isInited) {
this.emit('InnerEvents', {
type: 'node:addEndpoint',
data: obj,
isInited: isInited
});
return obj;
} // 这部分可能还需要想一下
var EndpointClass = obj.Class || BaseEndpoint;
var endpoint = new EndpointClass(_$b.assign({
limitNum: obj.limitNum || this._endpointLimitNum,
_on: this._on,
_emit: this._emit,
_node: this,
_global: this.global
}, obj));
this.emit('InnerEvents', {
type: 'node:addEndpoint',
data: endpoint
});
this.endpoints.push(endpoint);
return endpoint;
}
}, {
key: "removeEndpoint",
value: function removeEndpoint(pointId) {
var rmEndpointIndex = _$b.findIndex(this.endpoints, function (point) {
return point.id === pointId;
});
if (rmEndpointIndex !== -1) {
var rmEndpoint = this.endpoints.splice(rmEndpointIndex, 1)[0];
this.emit('InnerEvents', {
type: 'node:removeEndpoint',
data: rmEndpoint
});
rmEndpoint.destroy();
return rmEndpoint;
}
}
}, {
key: "getEndpoint",
value: function getEndpoint(pointId, type) {
return _$b.find(this.endpoints, function (point) {
if (!point.type || point.type === 'onlyConnect') {
return pointId === point.id;
} else {
return pointId === point.id && (type && type === point.type || !type);
}
});
}
}, {
key: "_init",
value: function _init() {
var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (this._isInited) {
return;
} // 这里可以抽象下,和constructor对比
if (obj.left) {
this.left = obj.left;
}
if (obj.top) {
this.top = obj.top;
}
if (obj._isDeleteGroup) {
this.group = undefined;
this._group = undefined;
} else {
obj.group && (this.group = obj.group);
}
delete obj._isDeleteGroup;
this._isInited = true;
if (obj.dom) {
this.dom = obj.dom;
obj.left && $$9(this.dom).css('left', "".concat(obj.left, "px"));
obj.top && $$9(this.dom).css('top', "".concat(obj.top, "px"));
} else {
this.dom = this.draw(_$b.assign({
id: this.id,
top: this.top,
left: this.left,
dom: this.dom,
options: this.options
}, obj));
}
if (!this._hasEventListener) {
this._addEventListener();
this._hasEventListener = true;
}
} // drag的时候移动的api
}, {
key: "_moveTo",
value: function _moveTo(x, y) {
var _this2 = this;
// 自身移动
$$9(this.dom).css('top', y).css('left', x); // 所在的点移动
this.endpoints.forEach(function (item) {
item.moveTo(x - _this2.left + item._left, y - _this2.top + item._top);
});
this.top = y;
this.left = x;
}
}, {
key: "moveTo",
value: function moveTo(x, y, isNotEventEmit) {
this.emit('InnerEvents', {
type: 'node:move',
node: this,
x: x,
y: y,
isNotEventEmit: isNotEventEmit
});
}
}, {
key: "getWidth",
value: function getWidth(useCache) {
if (!useCache || !this.width || this._isForceUpdateSize) {
this.width = $$9(this.dom).outerWidth();
this._isForceUpdateSize = false;
}
return this.width;
}
}, {
key: "getHeight",
value: function getHeight(useCache) {
if (!useCache || !this.height || this._isForceUpdateSize) {
this.height = $$9(this.dom).outerHeight();
this._isForceUpdateSize = false;
}
return this.height;
}
}, {
key: "_createEndpoint",
value: function _createEndpoint(isInited) {
var _this3 = this;
if (isInited) {
this.endpoints.forEach(function (item) {
return _this3.addEndpoint(item, isInited);
});
} else if (this._endpointsData) {
this._endpointsData.map(function (item) {
return _this3.addEndpoint(item);
});
}
}
}, {
key: "_addEventListener",
value: function _addEventListener() {
var _this4 = this;
// todo 做事件代理的形式
$$9(this.dom).on('mousedown', function (e) {
var LEFT_KEY = 0;
if (e.button !== LEFT_KEY) {
return;
}
if (!['SELECT', 'INPUT', 'RADIO', 'CHECKBOX', 'TEXTAREA'].includes(e.target.nodeName)) {
e.preventDefault();
}
if (_this4.draggable) {
_this4._isMoving = true;
_this4.emit('InnerEvents', {
type: 'node:dragBegin',
data: _this4
});
} else {
// 单纯为了抛错事件给canvas,为了让canvas的dragtype不为空,不会触发canvas:click事件
_this4.emit('InnerEvents', {
type: 'node:mouseDown',
data: _this4
});
}
});
$$9(this.dom).on('click', function (e) {
e.preventDefault();
e.stopPropagation();
_this4.emit('system.node.click', {
node: _this4
});
_this4.emit('events', {
type: 'node:click',
node: _this4
});
});
this.setDraggable(this.draggable);
}
}, {
key: "setDraggable",
value: function setDraggable(draggable) {
this.draggable = draggable;
}
}, {
key: "remove",
value: function remove() {
this.emit('InnerEvents', {
type: 'node:delete',
data: this
});
}
}, {
key: "emit",
value: function emit(type, data) {
_get(_getPrototypeOf(BaseNode.prototype), "emit", this).call(this, type, data);
this._emit(type, data);
}
}, {
key: "on",
value: function on(type, callback) {
_get(_getPrototypeOf(BaseNode.prototype), "on", this).call(this, type, callback);
this._on(type, callback);
}
}, {
key: "destroy",
value: function destroy(isNotEvent) {
if (!isNotEvent) {
this.endpoints.forEach(function (item) {
!item._isInitedDom && item.destroy();
});
$$9(this.dom).remove();
this.removeAllListeners();
this._hasEventListener = false;
} else {
this.endpoints.forEach(function (item) {
!item._isInitedDom && item.destroy(isNotEvent);
});
$$9(this.dom).detach();
}
this._isInited = false;
}
}]);
return BaseNode;
}(Node);
var ARROW_TYPE = {
default1: {
type: 'pathString',
content: 'M0 0 L-3 3 L2 0 L-3 -3 Z'
},
"default": {
type: 'pathString',
content: 'M5 0 L0 -2 Q 1.0 0 0 2 Z'
},
length: 5 //自定义
// arrow1: {
// type: 'svg',
// content: require('../../static/arrow/arrow1.svg')
// },
// arrow2: {
// type: 'svg',
// content: require('../../static/arrow/arrow2.svg')
// },
// arrow3: {
// type: 'svg',
// content: require('../../static/arrow/arrow3.svg')
// },
}; // 计算线条某个位置的斜率
function calcSlope(opts) {
var shapeType = _$d.get(opts, 'shapeType');
var dom = _$d.get(opts, 'dom');
var arrowPosition = _$d.get(opts, 'arrowPosition', 0.5);
var path = _$d.get(opts, 'path');
var coordinates = path.split(' ');
var x = 0;
var y = 0;
if (shapeType === 'BezierTest' || shapeType === 'AdvancedBezierTest') {
var p0 = {
x: coordinates[8],
y: coordinates[9]
};
var p1 = {
x: coordinates[1],
y: coordinates[2]
};
if (arrowPosition !== 1) {
p0 = dom.getPointAtLength(dom.getTotalLength() * arrowPosition + 0.001);
p1 = dom.getPointAtLength(dom.getTotalLength() * arrowPosition);
} else {
p0 = dom.getPointAtLength(dom.getTotalLength() * arrowPosition);
p1 = dom.getPointAtLength(dom.getTotalLength() * arrowPosition - 0.001);
}
x = p1.x - p0.x;
y = p1.y - p0.y;
} else if (shapeType === 'Straight') {
var _p = {
x: coordinates[1],
y: coordinates[2]
};
var _p2 = {
x: coordinates[4],
y: coordinates[5]
};
x = _p2.x - _p.x;
y = _p2.y - _p.y;
} else {
var _p3 = 0;
var _p4 = 1;
if (arrowPosition !== 1) {
_p3 = dom.getPointAtLength(dom.getTotalLength() * arrowPosition);
_p4 = dom.getPointAtLength(dom.getTotalLength() * arrowPosition + 0.001);
} else {
_p3 = dom.getPointAtLength(dom.getTotalLength() * arrowPosition - 0.001);
_p4 = dom.getPointAtLength(dom.getTotalLength() * arrowPosition);
}
x = _p4.x - _p3.x;
y = _p4.y - _p3.y;
}
return {
x: x,
y: y
};
}
var registerArrow = function registerArrow(arrows) {
arrows.forEach(function (item) {
ARROW_TYPE[item.key] = {
type: item.type,
content: item.content,
width: item.width,
height: item.height
};
});
};
var Arrow = {
calcSlope: calcSlope,
ARROW_TYPE: ARROW_TYPE,
registerArrow: registerArrow
};
var MINDIST = 20;
var TOL = 0.1;
var TOLxTOL = 0.01;
// this.x = x;
// this.y = y;
// }
var LEFT = 'Left';
var RIGHT = 'Right';
var TOP = 'Top';
var BOTTOM = 'Bottom'; // 曼哈顿折线路由算法
function _route(conn, fromPt, fromDir, toPt, toDir) {
// 防止图上节点隐藏NaN的死循环问题
fromPt.x = fromPt.x || 0;
fromPt.y = fromPt.y || 0;
toPt.x = toPt.x || 0;
toPt.y = toPt.y || 0;
var xDiff = fromPt.x - toPt.x;
var yDiff = fromPt.y - toPt.y;
var point;
var dir;
var pos;
conn.push({
x: fromPt.x,
y: fromPt.y
});
if (xDiff * xDiff < TOLxTOL && yDiff * yDiff < TOLxTOL) {
// conn.push({x: toPt.x, y: toPt.y});
return;
}
if (fromDir === LEFT) {
if (xDiff > 0 && yDiff * yDiff < TOL && toDir === RIGHT) {
point = toPt;
dir = toDir;
} else {
if (xDiff < 0) {
point = {
x: fromPt.x - MINDIST,
y: fromPt.y
};
} else if (yDiff > 0 && toDir === BOTTOM || yDiff < 0 && toDir === TOP) {
point = {
x: toPt.x,
y: fromPt.y
};
} else if (fromDir === toDir) {
pos = Math.min(fromPt.x, toPt.x) - MINDIST;
point = {
x: pos,
y: fromPt.y
};
} else {
point = {
x: fromPt.x - xDiff / 2,
y: fromPt.y
};
}
if (yDiff > 0) {
dir = TOP;
} else {
dir = BOTTOM;
}
}
} else if (fromDir === RIGHT) {
if (xDiff < 0 && yDiff * yDiff < TOL && toDir === LEFT) {
point = toPt;
dir = toDir;
} else {
if (xDiff > 0) {
point = {
x: fromPt.x + MINDIST,
y: fromPt.y
};
} else if (yDiff > 0 && toDir === BOTTOM || yDiff < 0 && toDir === TOP) {
point = {
x: toPt.x,
y: fromPt.y
};
} else if (fromDir === toDir) {
pos = Math.max(fromPt.x, toPt.x) + MINDIST;
point = {
x: pos,
y: fromPt.y
};
} else {
point = {
x: fromPt.x - xDiff / 2,
y: fromPt.y
};
}
if (yDiff > 0) {
dir = TOP;
} else {
dir = BOTTOM;
}
}
} else if (fromDir === BOTTOM) {
if (xDiff * xDiff < TOL && yDiff < 0 && toDir === TOP) {
point = toPt;
dir = toDir;
} else {
if (yDiff > 0) {
point = {
x: fromPt.x,
y: fromPt.y + MINDIST
};
} else if (xDiff > 0 && toDir === RIGHT || xDiff < 0 && toDir === LEFT) {
point = {
x: fromPt.x,
y: toPt.y
};
} else if (fromDir === toDir) {
pos = Math.max(fromPt.y, toPt.y) + MINDIST;
point = {
x: fromPt.x,
y: pos
};
} else {
point = {
x: fromPt.x,
y: fromPt.y - yDiff / 2
};
}
if (xDiff > 0) {
dir = LEFT;
} else {
dir = RIGHT;
}
}
} else if (fromDir === TOP) {
if (xDiff * xDiff < TOL && yDiff > 0 && toDir === BOTTOM) {
point = toPt;
dir = toDir;
} else {
if (yDiff < 0) {
point = {
x: fromPt.x,
y: fromPt.y - MINDIST
};
} else if (xDiff > 0 && toDir === RIGHT || xDiff < 0 && toDir === LEFT) {
point = {
x: fromPt.x,
y: toPt.y
};
} else if (fromDir === toDir) {
pos = Math.min(fromPt.y, toPt.y) - MINDIST;
point = {
x: fromPt.x,
y: pos
};
} else {
point = {
x: fromPt.x,
y: fromPt.y - yDiff / 2
};
}
if (xDiff > 0) {
dir = LEFT;
} else {
dir = RIGHT;
}
}
}
_route(conn, point, dir, toPt, toDir);
}
function _calcOrientation(beginX, beginY, endX, endY, orientationLimit) {
var _calcWithLimit = function _calcWithLimit(rank) {
if (orientationLimit) {
var _loop = function _loop(i) {
var isInLimit = _$d.some(orientationLimit, function (limit) {
return limit === rank[i];
});
if (isInLimit) {
return {
v: rank[i]
};
}
};
for (var i = 0; i < rank.length; i++) {
var _ret = _loop(i);
if (_typeof(_ret) === "object") return _ret.v;
}
return rank[0];
} else {
return rank[0];
}
}; // 计算orientation
var posX = endX - beginX;
var posY = endY - beginY;
var orientation = null; // 斜率
var k = Math.abs(posY / posX);
if (posX === 0 || posY === 0) {
if (posX === 0) {
orientation = posY >= 0 ? _calcWithLimit(['Top', 'Left', 'Right', 'Bottom']) : orientation;
orientation = posY < 0 ? _calcWithLimit(['Bottom', 'Left', 'Right', 'Top']) : orientation;
}
if (posY === 0) {
orientation = posX >= 0 ? _calcWithLimit(['Right', 'Top', 'Bottom', 'Left']) : orientation;
orientation = posX < 0 ? _calcWithLimit(['Left', 'Top', 'Bottom', 'Right']) : orientation;
}
} else if (posX > 0 && posY > 0) {
if (k > 1) {
orientation = _calcWithLimit(['Top', 'Left', 'Right', 'Bottom']); // orientation = [0, -1];
} else {
orientation = _calcWithLimit(['Left', 'Top', 'Bottom', 'Right']); // orientation = [-1, 0];
}
} else if (posX < 0 && posY > 0) {
if (k > 1) {
orientation = _calcWithLimit(['Top', 'Right', 'Left', 'Bottom']); // orientation = [0, -1];
} else {
orientation = _calcWithLimit(['Right', 'Top', 'Bottom', 'Left']); // orientation = [1, 0];
}
} else if (posX < 0 && posY < 0) {
if (k > 1) {
orientation = _calcWithLimit(['Bottom', 'Right', 'Left', 'Top']); // orientation = [0, 1];
} else {
orientation = _calcWithLimit(['Right', 'Bottom', 'Top', 'Left']); // orientation = [1, 0];
}
} else {
if (k > 1) {
orientation = _calcWithLimit(['Bottom', 'Left', 'Right', 'Top']); // orientation = [0, 1];
} else {
orientation = _calcWithLimit(['Left', 'Bottom', 'Top', 'Right']); // orientation = [-1, 0];
}
}
switch (orientation) {
case 'Left':
return [-1, 0];
case 'Right':
return [1, 0];
case 'Top':
return [0, -1];
case 'Bottom':
return [0, 1];
}
}
function _findControlPoint(point, sourcePoint, targetPoint, _so, _to) {
// 曲率,可配置的
var majorAnchor = 10; // 偏移,定死的
var minorAnchor = 10;
var result = []; // 特殊处理完全水平和垂直的情况
if (sourcePoint.pos[0] === targetPoint.pos[0] && _so[1] !== _to[1] && _so[0] === 0 && _to[0] === 0) {
result = [point[0], point[1] + majorAnchor * _so[1]];
return result;
}
if (sourcePoint.pos[1] === targetPoint.pos[1] && _so[0] !== _to[0] && _so[1] === 0 && _to[1] === 0) {
result = [point[0] + majorAnchor * _so[0], point[1]];
return result;
} // 平常情况
var perpendicular = _so[0] !== _to[0] || _so[1] === _to[1];
if (!perpendicular) {
if (_so[0] === 0) {
result.push(sourcePoint.pos[0] < targetPoint.pos[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
} else {
result.push(point[0] - majorAnchor * _so[0]);
}
if (_so[1] === 0) {
result.push(sourcePoint.pos[1] < targetPoint.pos[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
} else {
result.push(point[1] - majorAnchor * _to[1]);
}
} else {
if (_to[0] === 0) {
result.push(targetPoint.pos[0] < sourcePoint.pos[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
} else {
result.push(point[0] + majorAnchor * _to[0]);
}
if (_to[1] === 0) {
result.push(targetPoint.pos[1] < sourcePoint.pos[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
} else {
result.push(point[1] + majorAnchor * _so[1]);
}
}
return result;
} //二阶贝塞尔曲线
function _findSecondControlPoint(sourcePoint, targetPoint, _so, _to, shapeType) {
//中点
var midX = (sourcePoint.pos[0] + targetPoint.pos[0]) / 2;
var midY = (sourcePoint.pos[1] + targetPoint.pos[1]) / 2; //四分之一点的位置
var quarterX = midX - (midX - sourcePoint.pos[0]) / 2;
var quarterY = midY - (midY - sourcePoint.pos[1]) / 2; //四分之三位置
var threeQuarterX = midX + (midX - sourcePoint.pos[0]) / 2;
var threeQuarterY = midY + (midY - sourcePoint.pos[1]) / 2;
var basicPointX = midX;
var basicPointY = midY;
if (shapeType === "Bezier2-1") {
basicPointX = midX;
basicPointY = midY;
} else if (shapeType === "Bezier2-2") {
basicPointX = quarterX;
basicPointY = quarterY;
} else if (shapeType === "Bezier2-3") {
basicPointX = threeQuarterX;
basicPointY = threeQuarterY;
}
var ctrlPoint;
var offset;
var _width = Math.abs(sourcePoint.pos[0] - sourcePoint.pos[0]);
var _height = Math.abs(sourcePoint.pos[1] - targetPoint.pos[1]);
var dist = Math.sqrt(_width * _width + _height * _height); //正常情况
var midK = (targetPoint.pos[1] - sourcePoint.pos[1]) / (targetPoint.pos[0] - sourcePoint.pos[0]);
if (midK === 0) {
if (sourcePoint.pos[0] < targetPoint.pos[0] && _so[0] === 1 && _to[0] === -1 || sourcePoint.pos[0] > targetPoint.pos[0] && _so[0] === -1 && _to[0] === 1 || sourcePoint.pos[1] < targetPoint.pos[1] && _so[1] === 1 && _to[1] === -1 || sourcePoint.pos[1] > targetPoint.pos[1] && _so[1] === -1 && _to[1] === 1) {
return ctrlPoint = [midX, midY];
}
}
var k = -1 / midK;
var b = basicPointY - k * basicPointX;
offset = Math.sqrt(3) * dist / 6;
var t;
var _sum0 = _so[0] + _to[0];
var _sum1 = _so[1] + _to[1];
if (targetPoint.pos[0] < sourcePoint.pos[0] && targetPoint.pos[1] < sourcePoint.pos[1] && (_sum0 === 0 && _sum1 === 0 || _sum0 === 1 && _sum1 === -1)) {
t = 1;
} else if (targetPoint.pos[0] > sourcePoint.pos[0] && targetPoint.pos[1] < sourcePoint.pos[1] && _sum0 === 1 && _sum1 === 1) {
t = 1;
} else if (targetPoint.pos[0] < sourcePoint.pos[0] && targetPoint.pos[1] > sourcePoint.pos[1] && (_sum0 === 0 && _sum1 === 0 || _sum0 === 1 && _sum1 === 1)) {
t = 1;
} else if (targetPoint.pos[0] > sourcePoint.pos[0] && targetPoint.pos[1] > sourcePoint.pos[1] && _sum0 === 1 && _sum1 === -1) {
t = 1;
} else {
t = -1;
}
ctrlPoint = [basicPointX + offset * t, k * (basicPointX + offset * t) + b]; //特殊情况:
var percent = 0.25;
var minorDist = 100;
offset = dist * percent + minorDist;
var so_offsetX = 0;
var so_offsetY = 0;
var to_offsetX = 0;
var to_offsetY = 0;
if (_so[0] === -1 && targetPoint.pos[0] > sourcePoint.pos[0] || _so[0] === 1 && targetPoint.pos[0] < sourcePoint.pos[0] || _so[1] === 1 && targetPoint.pos[1] < sourcePoint.pos[1] || _so[1] === -1 && targetPoint.pos[1] > sourcePoint.pos[1]) {
if (_so[0] !== 0) {
so_offsetX = offset * _so[0];
}
if (_so[1] !== 0) {
so_offsetY = offset * _so[1];
}
return ctrlPoint = [sourcePoint.pos[0] + so_offsetX, sourcePoint.pos[1] + so_offsetY];
}
if (_so[0] === _to[0] && _so[1] === _to[1] || _so[0] !== 0 && targetPoint.pos[1] < sourcePoint.pos[1] && _to[1] === -1 || _so[0] !== 0 && targetPoint.pos[1] > sourcePoint.pos[1] && _to[1] === 1 || _so[1] !== 0 && targetPoint.pos[0] < sourcePoint.pos[0] && _to[0] === -1 || _so[1] !== 0 && targetPoint.pos[0] > sourcePoint.pos[0] && _to[0] === 1) {
if (_to[0] !== 0) {
to_offsetX = offset * _to[0];
} else if (_to[1] !== 0) {
to_offsetY = offset * _to[1];
}
ctrlPoint = [targetPoint.pos[0] + to_offsetX, targetPoint.pos[1] + to_offsetY];
}
return ctrlPoint;
}
function _findManhattanPoint(points, pos) {
var result = undefined;
var gap = Infinity;
for (var i = 0; i < points.length - 1; i++) {
var _dir = points[i].x === points[i + 1].x ? 'vertical' : 'horizontal';
var _from = points[i];
var _to = points[i + 1];
if (_dir === 'vertical') {
if (gap > Math.abs(pos.x - _from.x)) {
gap = Math.abs(pos.x - _from.x);
result = {
from: _from,
to: _to,
direction: _dir,
index: i
};
}
} else {
if (gap > Math.abs(pos.y - _from.y)) {
gap = Math.abs(pos.y - _from.y);
result = {
from: _from,
to: _to,
direction: _dir,
index: i
};
}
}
}
return result;
}
var drawAdvancedBezier = function drawAdvancedBezier(sourcePoint, targetPoint) {
if (!sourcePoint.orientation) {
sourcePoint.orientation = _calcOrientation(targetPoint.pos[0], targetPoint.pos[1], sourcePoint.pos[0], sourcePoint.pos[1]);
}
if (!targetPoint.orientation) {
targetPoint.orientation = _calcOrientation(sourcePoint.pos[0], sourcePoint.pos[1], targetPoint.pos[0], targetPoint.pos[1]);
} // 控制点
var _width = Math.abs(sourcePoint.pos[0] - targetPoint.pos[0]);
var _height = Math.abs(sourcePoint.pos[1] - targetPoint.pos[1]);
var _so = sourcePoint.orientation;
var _to = targetPoint.orientation;
var dist = Math.sqrt(_width * _width + _height * _height); // 控制点百分比,可转配置
var percent = 0.25; // 偏差量,可转配置
var minorDist = 30;
var so_offsetX = 0;
var so_offsetY = 0;
if (_so[0] !== 0) {
so_offsetX = (dist * percent + minorDist) * _so[0];
} else if (_so[1] !== 0) {
so_offsetY = (dist * percent + minorDist) * _so[1];
}
var to_offsetX = 0;
var to_offsetY = 0;
if (_to[0] !== 0) {
to_offsetX = (dist * percent + minorDist) * _to[0];
} else if (_to[1] !== 0) {
to_offsetY = (dist * percent + minorDist) * _to[1];
}
var sourceCtrlPoint = [sourcePoint.pos[0] + so_offsetX, sourcePoint.pos[1] + so_offsetY];
var targetCtrlPoint = [targetPoint.pos[0] + to_offsetX, targetPoint.pos[1] + to_offsetY]; // 起始点
var result = ['M', sourcePoint.pos[0], sourcePoint.pos[1]]; // let result = ['M', targetPoint.pos[0], targetPoint.pos[1]];
// 两个控制点
result = result.concat(['C', sourceCtrlPoint[0], sourceCtrlPoint[1]], targetCtrlPoint[0], targetCtrlPoint[1]); // result = result.concat(['C', targetCtrlPoint[0], targetCtrlPoint[1], sourceCtrlPoint[0], sourceCtrlPoint[1]]);
// 结束点
result = result.concat([targetPoint.pos[0], targetPoint.pos[1]]); // result = result.concat([sourcePoint.pos[0], sourcePoint.pos[1]]);
return result.join(' ');
};
function drawBezier(sourcePoint, targetPoint) {
if (!sourcePoint.orientation) {
sourcePoint.orientation = _calcOrientation(targetPoint.pos[0], targetPoint.pos[1], sourcePoint.pos[0], sourcePoint.pos[1]);
}
if (!targetPoint.orientation) {
targetPoint.orientation = _calcOrientation(sourcePoint.pos[0], sourcePoint.pos[1], targetPoint.pos[0], targetPoint.pos[1]);
} // 控制点
var _width = Math.abs(sourcePoint.pos[0] - targetPoint.pos[0]);
var _height = Math.abs(sourcePoint.pos[1] - targetPoint.pos[1]);
var _sx = sourcePoint.pos[0] < targetPoint.pos[0] ? _width : 0;
var _sy = sourcePoint.pos[1] < targetPoint.pos[1] ? _height : 0;
var _tx = sourcePoint.pos[0] < targetPoint.pos[0] ? 0 : _width;
var _ty = sourcePoint.pos[1] < targetPoint.pos[1] ? 0 : _height;
var _so = sourcePoint.orientation;
var _to = targetPoint.orientation;
var sourceCtrlPoint = _findControlPoint([_sx, _sy], sourcePoint, targetPoint, _so, _to);
var targetCtrlPoint = _findControlPoint([_tx, _ty], targetPoint, sourcePoint, _to, _so);
var offsetX = sourcePoint.pos[0] < targetPoint.pos[0] ? sourcePoint.pos[0] : targetPoint.pos[0];
var offsetY = sourcePoint.pos[1] < targetPoint.pos[1] ? sour