From 9dcbfd3254df68e886a99cf11070c058616f19ea Mon Sep 17 00:00:00 2001 From: letterletter <2602729371@qq.com> Date: Wed, 21 Apr 2021 17:26:04 +0800 Subject: [PATCH 1/5] s --- docs/en-US/group.md | 258 +++++++++++++++++++++++++++++++------------- 1 file changed, 181 insertions(+), 77 deletions(-) diff --git a/docs/en-US/group.md b/docs/en-US/group.md index b22ae616..e450029f 100644 --- a/docs/en-US/group.md +++ b/docs/en-US/group.md @@ -17,6 +17,8 @@ canvas.draw({ top: 100, left: 100, Class: AGroup // after setting the base class, the canvas will render based on the custom class. + ... + //the attribute below }], nodes: ... edges: ... @@ -28,119 +30,221 @@ canvas.addGroup({ // the attribute below }); ``` +
+ +**`The returned dom of the node must be set to position: absolute;`** + +
+
+ +## attribute + +### id _``_ (Require) +  unique id of node +### top _``_ (Require) +  y coordinate +### left _``_ (Require) +  x coordinate +### width _``_ (Option) +  group width +### height _``_ (Option) +  group height +### endpoints _``_ (Option) +  system endpoints configuration: system endpoints will be added when this configuration is present +### Class _``_ (Option) +  extended class +### scope _``_ (Option) +  scope: When the scope of the node is consistent with the scope of the group, it can be added to the group. You can join as you like without setting it by default -## attribute: +```js +// single scope +group.scope = 'xxx'; +// multiple scope, any one matched can be connected +group.scope = 'xxx1 xxx2 xxx3'; +``` + +### draggable _``_ (Option) +  the node group is draggable. the default value is true +### resize _``_ (Option) +  the size of the node group is resizable. the default value is true -| key | describe | type | default -| :------ | :------ | :------ | :------ -| id | unique id | string (Require) | - -| top | y coordinate | number (Require) | - -| left | x coordinate | number (Require) | - -| width | group width | number (Option) | - -| height | group height | number (Option) | - -| type | group type | string (Option) | normal (drag in and drag out), inner (can only be dragged in and not out) -| endpoints | endpoint data | array (Option) | - -| Class | extended class | Class (Option) | When the extended class is passed in, the node group will be rendered according to the draw method of the extended class, and the related methods of the extended class will also override the method of the parent class. -| scope | scope | boolean (Option) | When the scope of the node is consistent with the scope of the group, it can be added to the group. You can join as you like without setting it by default. + -`* The returned dom of the node must be set to position: absolute;` +### group _``_ (Option) +  the id of the parent group: For supporting group nesting, you need to set canvas.theme.group.includeGroups open + + -## API: +
+
-### custom group: +## Class extend API: + +```js +import {Group} from 'butterfly-dag'; + +Class YourGroup extends Group { + + /** + * callback after group mount + */ + mount() {} + + /** + * group draw function + * @param {obj} data - group data + * @return {dom} - group dom + */ + draw(obj) {} +} +``` + +
+
+ +## External Call API: + +### group.getWidth() + +*function*: get group width + +*return* + +* `number` the width of group ```js -/** - * group draw function - * @param {obj} data - group data - * @return {dom} - group dom - */ -draw = (obj) => {} - -/** - * callback after group mount - */ -mounted = () => {} - -/** - * @return {number} - get group width - */ getWidth = () => {} +``` + +### group.getHeight () + +*function*: get group height + +*return* -/** - * @return {number} - get group height - */ +* `number` the height of group + +```js getHeight = () => {} ``` -### add and delete members: +### group.addNode (node) + +*function*: add node to group + +*param* + +* `{obj} node` node data ```js -/** - * add node to group - * @param {obj} node - node data - */ addNode = (node) => {} +``` + +### group.addNodes (nodes) + +*function*: add multiple nodes to group -/** - * add multiple nodes to group - * @param {array} nodes - nodes array - */ +*param* + +* `{array} nodes`nodes array + +```js addNodes = (nodes) => {} +``` + +### group.removeNode (node) + +*function*: delete node from group + +*param* + +* `{obj} node`node data -/** - * delete node from group - * @param {obj} node - node data - */ +```js removeNode = (node) => {} +``` + +### group.removeNodes (nodes) + +*function*: delete nodes from group -/** - * group删除节点 - * @param {array} nodes - 节点数组 - */ +*param* + +* `{obj} nodes`nodes array + +```js removeNodes = (nodes) => {} ``` -### custom endpoint: +### group.addEndpoint (obj) + +*function*: add endpoint to group + +*params* + +* `{obj} param` endpoint data (this method must be executed after the node is mounted) +* `{string} param.id` endpoint id +* `{string} param.orientation` endpoint direction (it can control the direction of the edge linkin or linkout) +* `{string} param.scope` scope +* `{string} param.type` 'source' / 'target' / undefined,ednpoint is both source and target when undefined +* `{string} param.dom` any sub DOM in the node can be used as a custom endpoint ```js -/** - * @param {obj} data - endpoint data (this method must be executed after the node is mounted) - * @param {string} param.id - endpoint id - * @param {string} param.orientation - endpoint direction (it can control the direction of the edge linkin or linkout) - * @param {string} param.scope - scope - * @param {string} param.type - 'source' / 'target' / undefined,ednpoint is both source and target when undefined - * @param {string} param.dom - any sub DOM in the node can be used as a custom endpoint - */ addEndpoint = (obj) => {} +``` + +### group.getEndpoint (id) + +*function*: get endpoint by id + +*param* + +* `{string} pointId` endpoint id + +*return* -/** - * @param {string} pointId - endpoint id - * @param {string(Option)} type - endpoint type (Optional) - * @return {Endpoint} - Endpoint object - */ -getEndpoint = (id, type) => {} +* `{Endpoint}`Endpoint Object + +```js +getEndpoint = (id) => {} ``` -### move: +### group.moveTo (obj) + +*function*: move coordinates of the node group + +*params* + +* `{number} obj.x `move to x coordinate +* `{number} obj.y `move to y coordinate + ```js -/** - * @param {number} x - move to x - * @param {number} y - move to y - */ moveTo = (obj) => {} ``` -### event: +### group.emit (event, data) + +*function*: emit events,canvas or any elements can receive event from the node group + +*params* + +* `{string} event `emit event name +* `{number} data `emit event data ```js -/** - * emit events - */ emit = (string, obj) => {} +``` + +### group.on (string, callback) + +*function*: accept events, the group can accept events from canvas or any elements -/** - * accept events - */ +*params* + +* `{string} event ` accept event name +* `{function} data `accept event callback + +```js on = (string, callback) => {} ``` + From 2a944b4b4d833490da684f2d64c0083746352927 Mon Sep 17 00:00:00 2001 From: letterletter <2602729371@qq.com> Date: Wed, 21 Apr 2021 19:51:02 +0800 Subject: [PATCH 2/5] group change --- docs/en-US/group.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/en-US/group.md b/docs/en-US/group.md index e450029f..0863b1df 100644 --- a/docs/en-US/group.md +++ b/docs/en-US/group.md @@ -39,11 +39,11 @@ canvas.addGroup({ ## attribute -### id _``_ (Require) +### id _``_ (Require)   unique id of node -### top _``_ (Require) +### top _``_ (Require)   y coordinate -### left _``_ (Require) +### left _``_ (Require)   x coordinate ### width _``_ (Option)   group width @@ -78,7 +78,7 @@ group.scope = 'xxx1 xxx2 xxx3';

-## Class extend API: +## Extented Class API: ```js import {Group} from 'butterfly-dag'; @@ -110,7 +110,7 @@ Class YourGroup extends Group { *return* -* `number` the width of group +* `number` the width of the group ```js getWidth = () => {} @@ -122,7 +122,7 @@ getWidth = () => {} *return* -* `number` the height of group +* `number` the height of the group ```js getHeight = () => {} @@ -130,7 +130,7 @@ getHeight = () => {} ### group.addNode (node) -*function*: add node to group +*function*: add node to the group *param* @@ -142,7 +142,7 @@ addNode = (node) => {} ### group.addNodes (nodes) -*function*: add multiple nodes to group +*function*: add multiple nodes to the group *param* @@ -154,7 +154,7 @@ addNodes = (nodes) => {} ### group.removeNode (node) -*function*: delete node from group +*function*: delete node from the group *param* @@ -166,7 +166,7 @@ removeNode = (node) => {} ### group.removeNodes (nodes) -*function*: delete nodes from group +*function*: delete nodes from the group *param* @@ -178,7 +178,7 @@ removeNodes = (nodes) => {} ### group.addEndpoint (obj) -*function*: add endpoint to group +*function*: add endpoint to the group *params* From f043ce54dae62e105bf5f675215051f586bfb4f2 Mon Sep 17 00:00:00 2001 From: letterletter <2602729371@qq.com> Date: Thu, 22 Apr 2021 15:10:58 +0800 Subject: [PATCH 3/5] save group --- docs/en-US/group.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/en-US/group.md b/docs/en-US/group.md index 0863b1df..7f4c0bb4 100644 --- a/docs/en-US/group.md +++ b/docs/en-US/group.md @@ -54,7 +54,7 @@ canvas.addGroup({ ### Class _``_ (Option)   extended class ### scope _``_ (Option) -  scope: When the scope of the node is consistent with the scope of the group, it can be added to the group. You can join as you like without setting it by default +  scope: When the scope of the node is the same as the scope of the group, it can be added to the group. You can join as you like without setting it by default ```js // single scope @@ -64,14 +64,14 @@ group.scope = 'xxx1 xxx2 xxx3'; ``` ### draggable _``_ (Option) -  the node group is draggable. the default value is true +  the group is draggable. the default value is true ### resize _``_ (Option) -  the size of the node group is resizable. the default value is true +  the size of the group is resizable. the default value is true ### group _``_ (Option) -  the id of the parent group: For supporting group nesting, you need to set canvas.theme.group.includeGroups open +  the id of the parent group: For supporting group nesting, you need to set 'canvas.theme.group.includeGroups' open @@ -106,7 +106,7 @@ Class YourGroup extends Group { ### group.getWidth() -*function*: get group width +*description*: get group width *return* @@ -118,7 +118,7 @@ getWidth = () => {} ### group.getHeight () -*function*: get group height +*description*: get group height *return* @@ -130,7 +130,7 @@ getHeight = () => {} ### group.addNode (node) -*function*: add node to the group +*description*: add node to the group *param* @@ -142,7 +142,7 @@ addNode = (node) => {} ### group.addNodes (nodes) -*function*: add multiple nodes to the group +*description*: add multiple nodes to the group *param* @@ -154,7 +154,7 @@ addNodes = (nodes) => {} ### group.removeNode (node) -*function*: delete node from the group +*description*: delete node from the group *param* @@ -166,7 +166,7 @@ removeNode = (node) => {} ### group.removeNodes (nodes) -*function*: delete nodes from the group +*description*: delete nodes from the group *param* @@ -178,7 +178,7 @@ removeNodes = (nodes) => {} ### group.addEndpoint (obj) -*function*: add endpoint to the group +*description*: add endpoint to the group *params* @@ -195,7 +195,7 @@ addEndpoint = (obj) => {} ### group.getEndpoint (id) -*function*: get endpoint by id +*description*: get endpoint by id *param* @@ -211,7 +211,7 @@ getEndpoint = (id) => {} ### group.moveTo (obj) -*function*: move coordinates of the node group +*description*: move coordinates of the group *params* @@ -224,7 +224,7 @@ moveTo = (obj) => {} ### group.emit (event, data) -*function*: emit events,canvas or any elements can receive event from the node group +*description*: emit events,canvas or any elements can receive event from the group *params* @@ -237,12 +237,12 @@ emit = (string, obj) => {} ### group.on (string, callback) -*function*: accept events, the group can accept events from canvas or any elements +*description*: receive events, the group can receive events from canvas or any elements *params* -* `{string} event ` accept event name -* `{function} data `accept event callback +* `{string} event ` receive event name +* `{function} data `receive event callback ```js on = (string, callback) => {} From eabb90304807a11a96fa3a9576d161e1e323dc13 Mon Sep 17 00:00:00 2001 From: letterletter <2602729371@qq.com> Date: Thu, 22 Apr 2021 15:38:07 +0800 Subject: [PATCH 4/5] save --- docs/zh-CN/group.md | 231 +++++++++++++++++++++++++------------- docs/zh-CN/node.md | 264 ++++++++++++++++++++++++++++---------------- 2 files changed, 327 insertions(+), 168 deletions(-) diff --git a/docs/zh-CN/group.md b/docs/zh-CN/group.md index 456073ed..d715c87b 100644 --- a/docs/zh-CN/group.md +++ b/docs/zh-CN/group.md @@ -30,19 +30,12 @@ canvas.addGroup({ ```
-## 属性: - -| key | 说明 | 类型 | 默认值 -| :------ | :------ | :------ | :------ -| id | 节点唯一标识 | string (Require) | - -| top | y轴坐标 | number (Require) | - -| left | x轴坐标 | number (Require) | - -| width | 宽度 | number (Option) | - -| height | 高度 | number (Option) | - -| type | 类型 | string (Option) | normal(随意拖入拖出),inner(只能拖入不能拖出) -| endpoints | 锚点信息 | array (Option) | - -| Class | 拓展类 | Class (Option) | 当传入拓展类的时候,该节点组则会按拓展类的draw方法进行渲染,拓展类的相关方法也会覆盖父类的方法 -| scope | 作用域 | boolean (Option) | 当node的scope和group的scope一致才能加入到节点组。默认不设置即可随意加入 +**`节点的返回的dom必须设置position: absolute;`** + +
+
+ +## 属性 ### id _``_ (必填)   节点唯一标识 @@ -68,98 +61,188 @@ group.scope = 'xxx'; group.scope = 'xxx1 xxx2 xxx3'; ``` -### 自定义节点组: +### draggable _``_ (选填) +  节点组可拖动标识。默认可拖动 +### resize _``_ (选填) +  节点组大小可变标识。默认可变 + + + +### group _``_ (选填) +  父级group的id: 需要开启canvas.theme.group.includeGroups的属性才能支持group嵌套 + + + +
+
+ +## 类重写API: + +```js +import {Group} from 'butterfly-dag'; + +Class YourGroup extends Group { + + /** + * 节点组挂载后的回调 + */ + mount() {} + + /** + * group的渲染方法 + * @param {obj} data - 节点基本信息 + * @return {dom} - 返回渲染dom的根节点 + */ + draw(obj) {} +} +``` + +
+
+ +## 外部调用API: + +### group.getWidth() + +*作用*: 获取节点组宽度 + +*返回* + +* `number`节点组宽度 ```js -/** - * group的渲染方法 - * @param {obj} data - 节点基本信息 - * @return {dom} - 返回渲染dom的根节点 - */ -draw = (obj) => {} - -/** - * 节点组挂载后的回调 - */ -mounted = () => {} -/** - * @return {number} - 节点组宽度 - */ getWidth = () => {} +``` + +### group.getHeight () -/** - * @return {number} - 节点组高度 - */ +*作用*: 获取节点组高度 + +*返回* + +* `number`节点组高度 + +```js getHeight = () => {} ``` -### 新增,删除成员节点: +### group.addNode (node) + +*作用*: 节点组添加单个节点的方法 + +*参数* + +* `{obj} node`节点数据 ```js -/** - * group添加节点 - * @param {obj} node - 节点数据 - */ addNode = (node) => {} +``` + +### group.addNodes (nodes) + +*作用*: 节点组添加多个节点的方法 -/** - * group批量添加节点 - * @param {array} nodes - 节点数组 - */ +*参数* + +* `{array} nodes`节点数组 + +```js addNodes = (nodes) => {} +``` -/** - * group删除节点 - * @param {obj} node - 节点数据 - */ +### group.removeNode (node) + +*作用*: 节点组删除单个节点的方法 + +*参数* + +* `{obj} node`节点数据 + +```js removeNode = (node) => {} +``` + +### group.removeNodes (nodes) + +*作用*: 节点组删除多个节点的方法 + +*参数* + +* `{obj} node`节点数据 -/** - * group删除节点 - * @param {array} nodes - 节点数组 - */ -removeNodes = (nodes) => {} +```js +removeNode = (node) => {} ``` -### 自定义锚点: +### group.addEndpoint (obj) + +*作用*: 节点组添加锚点的方法 + +*参数* + +* `{obj} param`锚点基本信息(此方法必须在节点挂载后执行才有效) +* `{string} param.id`锚点id +* `{string} param.orientation`锚点方向(可控制线段的进行和外出方向) +* `{string} param.scope`作用域 +* `{string} param.type`'source' / 'target' / undefined / 'onlyConnect',可看锚点的type文档 +* `{string} param.dom`可以把分组内的任意一个子dom作为自定义锚点 ```js -/** - * @param {obj} param - 锚点基本信息(此方法必须在节点挂载后执行才有效) - * @param {string} param.id - 锚点id - * @param {string} param.orientation - 锚点方向(可控制线段的进行和外出方向) - * @param {string} param.scope - 作用域 - * @param {string} param.type - 'source' / 'target' / undefined,当undefined的时候锚点既是source又是target - * @param {string} param.dom - 可以把分组内的任意一个子dom作为自定义锚点 - */ addEndpoint = (obj) => {} +``` + +### group.getEndpoint (id) + +*作用*: 节点组获取锚点的方法 + +*参数* -/** - * @param {string} pointId - 锚点的信息 - * @return {Endpoint} - Endpoint的对象 - */ +* `{string} pointId`锚点的信息 + +*返回* + +* `{Endpoint}`Endpoint的对象 + +```js getEndpoint = (id) => {} ``` -### 移动: +### group.moveTo (obj) + +*作用*: 节点组移动坐标的方法 + +*参数* + +* `{number} obj.x `移动位置的x坐标 +* `{number} obj.y `移动位置的y坐标 + ```js -/** - * @param {number} x - 移动位置的x坐标 - * @param {number} y - 移动位置的y坐标 - */ moveTo = (obj) => {} ``` -### 事件: +### group.emit (event, data) + +*作用*: 节点组发送事件的方法,画布及任何一个元素都可接收。 + +*参数* + +* `{string} event `发送事件名称 +* `{number} data `发送事件数据 + ```js -/** - * 发送事件 - */ emit = (string, obj) => {} +``` + +### group.on (string, callback) -/** - * 接受事件 - */ +*作用*: 节点组接收事件的方法,能接收画布及任何一个元素的事件。 + +*参数* + +* `{string} event `接收事件名称 +* `{function} data `接收事件回调 + +```js on = (string, callback) => {} ``` diff --git a/docs/zh-CN/node.md b/docs/zh-CN/node.md index 0d1f1631..dd0bb28a 100644 --- a/docs/zh-CN/node.md +++ b/docs/zh-CN/node.md @@ -32,51 +32,76 @@ canvas.addNode({ }); ``` -## 属性: - -| key | 说明 | 类型 | 默认值 -| :------ | :------ | :------ | :------ -| id | 节点唯一标识 | string (Require) | - -| top | y轴坐标 | number (Require) | - -| left | x轴坐标 | number (Require) | - -| draggable | 可以设置该节点是否能拖动 | boolean (Option) | 可覆盖全局的draggable属性 -| group | group的唯一标识 | string (Option) | - -| endpoints | 锚点信息 | array (Option) | - -| Class | 拓展类 | Class (Option) | 当传入拓展类的时候,该节点组则会按拓展类的draw方法进行渲染,拓展类的相关方法也会覆盖父类的方法 -| scope | 作用域 | boolean (Option) | 当node的scope和group的scope一致才能加入到节点组。默认不设置即可随意加入 +
+
+ +## 属性 + +### id _``_ (必填) +  节点唯一标识 +### top _``_ (必填) +  y轴坐标: 节点所在画布的坐标;若在节点组中,则是相对于节点组内部的坐标 +### left _``_ (必填) +  x轴坐标: 节点所在画布的坐标;若在节点组中,则是相对于节点组内部的坐标 +### draggable _``_ (选填) +  可以设置该节点是否能拖动:为可覆盖全局的draggable属性 +### group _``_ (选填) +  父级group的id: 设置后该节点会添加到节点组中 +### endpoints _``_ (选填) +  锚点信息: 当有此配置会加上系统的锚点 +### Class _``_ (选填) +  拓展类:当传入拓展类的时候,该节点组则会按拓展类的draw方法进行渲染,拓展类的相关方法也会覆盖父类的方法 +### scope _``_ (选填) +  作用域:当scope一致的节点才能拖动进入节点组 + +```js +// 单scope +node.scope = 'xxx'; +// 多scope,任意一个匹配中都能连接 +node.scope = 'xxx1 xxx2 xxx3'; +``` `* 节点的返回的dom必须设置position: absolute;` -## API: +
+
-### 自定义节点组: +## 类重写API: ```js -/** - * 节点的渲染方法 - * @param {obj} data - 节点基本信息 - * @return {dom} - 返回渲染dom的根节点 - */ -draw = (obj) => {} - -/** - * 节点挂载后的回调 - */ -mounted = () => {} - -/** - * 节点更新后的回调 - */ -updated = () => {} - -/** - * 删除节点 - */ -remove = () => {} +import {Node} from 'butterfly-dag'; + +Class YourNode extends Node { + + /** + * 节点挂载后的回调 + */ + mounted() {} + + /** + * node的渲染方法 + * @param {obj} data - 节点基本信息 + * @return {dom} - 返回渲染dom的根节点 + */ + draw(obj) {} + +} +``` + +
+
+ +## 外部调用API: + +### node.getWidth () -/** - * @return {number} - 节点宽度 - */ +*作用*: 获取节点宽度 + +*返回* + +* `number`节点宽度 + +```js getWidth = () => {} ``` @@ -86,90 +111,141 @@ getWidth = () => {} *返回* -/** - * @return {number} - 节点高度 - */ +* `number`节点高度 + +```js getHeight = () => {} +``` -/** - * @param {boolean} draggable - 设置节点是否可移动 - */ -setDraggable = (boolean) => {} +### node.setDraggable (boolean) + +*作用*: 获取节点是否可移动的状态 + +*参数* -/** - * 聚焦回调 - */ -focus = () => {} +* `boolean`设置节点是否可移动 -/** - * 失去聚焦回调 - */ -unFocus = () => {} +```js +setDraggable = (boolean) => {} ``` -### 自定义锚点: +### node.addEndpoint (obj) + +*作用*: 节点中添加锚点。可添加系统锚点;也可添加节点中的某个dom作为锚点。*注意:*此方法必须在节点挂载后执行才有效 + +*参数* + +* `{obj} param` 锚点基本信息(此方法必须在节点挂载后执行才有效) +* `{string} param.id` 锚点id +* `{string} param.orientation` 锚点方向(可控制线段的进入和外出方向) +* `{string} param.scope` 连接作用域 +* `{string} param.type` 'source' / 'target' / undefined / 'onlyConnect',可看锚点的type文档 +* `{string} param.dom`可以把节点内的任意一个子dom作为自定义锚点 ```js -/** - * @param {obj} param - 锚点基本信息(此方法必须在节点挂载后执行才有效) - * @param {string} param.id - 锚点id - * @param {string} param.orientation - 锚点方向(可控制线段的进行和外出方向) - * @param {string} param.scope - 作用域 - * @param {string} param.type - 'source' / 'target' / undefined / 'onlyConnect'。 当undefined的时候锚点既是source又是target,但不能为同是为'source'和'target',先来先到 ; 'onlyConnect',锚点既是source又是target,可同时存在 - * @param {string} param.dom - 可以把节点内的任意一个子dom作为自定义锚点 - */ addEndpoint = (obj) => {} +``` -/** - * @param {string} pointId - 锚点的Id(此方法必须在节点挂载后执行才有效) - * @return {Endpoint} - Endpoint的对象 - */ -removeEndpoint = (obj) => {} - -/** - * @param {string(Require)} pointId - 锚点的信息 - * @param {string(Option)} type - 锚点的类型 - * @return {Endpoint} - Endpoint的对象 - */ +### node.removeEndpoint(string) + +*作用*:节点中删除锚点 + +*参数* + +* `{string} pointId`锚点的Id(此方法必须在节点挂载后执行才有效) + +*返回* + +* ` {Endpoint}`Endpoint的对象 + +```js +removeEndpoint = (string) => {} +``` + +### node.getEndpoint (id, type) + +*作用*:获取节点中的锚点 + +*参数* + +* `{string(必填)} pointId`锚点的信息 +* `{string(选填)} type`锚点的信息。若传入type,则会根据锚点id和type完全匹配才能获取到。 + +*返回* + +* `{Endpoint}`Endpoint的对象 + +``` getEndpoint = (id, type) => {} ``` -### 移动: +### node.moveTo (obj) + +*作用*: 节点移动坐标的方法 + +*参数* + +* `{number} x `移动位置的x坐标 +* `{number} y `移动位置的y坐标 ```js -/** - * @param {number} x - 移动位置的x坐标 - * @param {number} y - 移动位置的y坐标 - */ moveTo = (obj) => {} ``` -### 事件: +### node.remove () + +*作用*: 节点删除的方法。与canvas.removeNode的方法作用一致。 + +```js +remove = () => {} +``` + +### node.emit (event, data) + +*作用*: 节点发送事件的方法,画布及任何一个元素都可接收。 + +*参数* + +* `{string} event `发送事件名称 +* `{number} data `发送事件数据 ```js -/** - * 发送事件 - */ emit = (string, obj) => {} +``` + +### node.on (string, callback) -/** - * 接受事件 - */ +*作用*: 节点接收事件的方法,能接收画布及任何一个元素的事件。 + +*参数* + +* `{string} event `接收事件名称 +* `{function} data `接收事件回调 + +```js on = (string, callback) => {} ``` -### [树状布局] 收缩 & 展开子节点: +### [树状布局]treeNode.collapseNode (string) + +*作用*: 树状节点的节点收缩功能 + +*参数* + +* `{string} nodeId`节点id ```js -/** - * [树状布局] 收缩节点 - * @param {string} nodeId - 节点id - */ collapseNode = (string) => {} +``` + +### [树状布局]treeNode.expandNode (string) -/** - * [树状布局] 展开节点 - * @param {string} nodeId - 节点id - */ +*作用*: 树状节点的节点展开功能 + +*参数* + +* `{string} nodeId`节点id + +```js expandNode = (string) => {} ``` \ No newline at end of file From 4a0d0780baa1fe35678afb0f24d084231c2cf13d Mon Sep 17 00:00:00 2001 From: letterletter <2602729371@qq.com> Date: Fri, 23 Apr 2021 00:08:17 +0800 Subject: [PATCH 5/5] s --- src/utils/link/edgeTypes/_utils.js | 6 +- src/utils/link/edgeTypes/bezier.js | 4 + src/utils/link/index.js | 416 ++++++++++++++++++++++++++++- 3 files changed, 424 insertions(+), 2 deletions(-) diff --git a/src/utils/link/edgeTypes/_utils.js b/src/utils/link/edgeTypes/_utils.js index b79d7c7e..5db17c9e 100644 --- a/src/utils/link/edgeTypes/_utils.js +++ b/src/utils/link/edgeTypes/_utils.js @@ -1,4 +1,5 @@ 'use strict'; +<<<<<<< HEAD import _ from 'lodash'; const MINDIST = 20; @@ -311,4 +312,7 @@ export function _findManhattanPoint (points, pos) { } } return result; -} \ No newline at end of file +} +======= + +>>>>>>> 44fc7b5... chore: optimize link code diff --git a/src/utils/link/edgeTypes/bezier.js b/src/utils/link/edgeTypes/bezier.js index b0da78ee..cba1070a 100644 --- a/src/utils/link/edgeTypes/bezier.js +++ b/src/utils/link/edgeTypes/bezier.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD 'use strict'; import {_findControlPoint, _calcOrientation} from './_utils.js'; @@ -44,3 +45,6 @@ function drawBezier(sourcePoint, targetPoint) { } export default drawBezier; +======= +'use strict'; +>>>>>>> 44fc7b5... chore: optimize link code diff --git a/src/utils/link/index.js b/src/utils/link/index.js index 99ca4b1c..2c465bf6 100644 --- a/src/utils/link/index.js +++ b/src/utils/link/index.js @@ -1,5 +1,6 @@ 'use strict'; +<<<<<<< HEAD import {_findManhattanPoint} from './edgeTypes/_utils.js'; export {default as drawAdvancedBezier} from './edgeTypes/advancedBezier.js' @@ -8,4 +9,417 @@ export {default as drawStraight} from './edgeTypes/straight.js'; export {default as drawFlow} from './edgeTypes/flow.js'; export {default as drawManhattan} from './edgeTypes/manhattan.js'; -export {_findManhattanPoint as findManhattanPoint}; \ No newline at end of file +export {_findManhattanPoint as findManhattanPoint}; +======= +import _ from 'lodash'; +import {_calcOrientation} from './_utils.js'; + +function _drawFlowSegment(segments, offset) { + let current = null; + let next = null; + let cornerRadius = 0; // 拐角角度,按道理可以配置 + let lw = 1; // strokeWidth,线条的粗细 + let _segLength = (s) => { + return Math.sqrt(Math.pow(s[0] - s[2], 2) + Math.pow(s[1] - s[3], 2)); + }; + let result = []; + let _drawStraight = (d) => { + return ['M', d.x1 + offset.x, d.y1 + offset.y, 'L', d.x2 + offset.x, d.y2 + offset.y]; + }; + let _drawArc = (d) => { + + // 有重复,可抽象,计算象限 + let _quadrant = (p1, p2) => { + if (p2[0] > p1[0]) { + return (p2[1] > p1[1]) ? 2 : 1; + } else if (p2[0] === p1[0]) { + return p2[1] > p1[1] ? 2 : 1; + } else { + return (p2[1] > p1[1]) ? 3 : 4; + } + }; + // 计算两点之间的直线的梯度 + let _gradient = (p1, p2) => { + if (p2[0] === p1[0]) { + return p2[1] > p1[0] ? Infinity : -Infinity; + } else if (p2[1] === p1[1]) { + return p2[0] > p1[0] ? 0 : -0; + } else { + return (p2[1] - p1[1]) / (p2[0] - p1[0]); + } + }; + // Calculates the angle between the two points + let _theta = (p1, p2) => { + let m = _gradient(p1, p2); + let t = Math.atan(m); + let s = _quadrant(p1, p2); + if ((s === 4 || s === 3)) { + t += Math.PI; + } + if (t < 0) { + t += (2 * Math.PI); + } + return t; + }; + + let _calcAngle = function (x, y) { + return _theta([d.cx, d.cy], [x, y]); + }; + + let startAngle = _calcAngle(x1, y1); + let endAngle = _calcAngle(x2, y2); + let TWO_PI = 2 * Math.PI; + if (endAngle < 0) { + endAngle += TWO_PI; + } + if (startAngle < 0) { + startAngle += TWO_PI; + } + // we now have startAngle and endAngle as positive numbers, meaning the + // absolute difference (|d|) between them is the sweep (s) of this arc, unless the + // arc is 'anticlockwise' in which case 's' is given by 2PI - |d|. + let ea = endAngle < startAngle ? endAngle + TWO_PI : endAngle; + let sweep = Math.abs(ea - startAngle); + let anticlockwise = d.ac; + + if (anticlockwise) { + sweep = TWO_PI - sweep; + } + + return ['M', d.x1 + offset.x, d.y1 + offset.y, 'A', d.r, d.r, '0', ',', d.x2 + offset.x, d.y2 + offset.y]; + }; + + // let offsetX = sourcePoint.pos[0] < targetPoint.pos[0] ? sourcePoint.pos[0] : targetPoint.pos[0]; + // let offsetY = sourcePoint.pos[1] < targetPoint.pos[1] ? sourcePoint.pos[1] : targetPoint.pos[1]; + + for (let i = 0; i < segments.length - 1; i++) { + current = current || _.cloneDeep(segments[i]); + next = _.cloneDeep(segments[i + 1]); + if (cornerRadius > 0 && current[4] !== next[4]) { + let radiusToUse = Math.min(cornerRadius, _segLength(current), _segLength(next)); + // right angle. adjust current segment's end point, and next segment's start point. + current[2] -= current[5] * radiusToUse; + current[3] -= current[6] * radiusToUse; + next[0] += next[5] * radiusToUse; + next[1] += next[6] * radiusToUse; + let ac = (current[6] === next[5] && next[5] === 1) || + ((current[6] === next[5] && next[5] === 0) && current[5] !== next[6]) || + (current[6] === next[5] && next[5] === -1); + let sgny = next[1] > current[3] ? 1 : -1; + let sgnx = next[0] > current[2] ? 1 : -1; + let sgnEqual = sgny === sgnx; + let cx = (sgnEqual && ac || (!sgnEqual && !ac)) ? next[0] : current[2]; + let cy = (sgnEqual && ac || (!sgnEqual && !ac)) ? current[3] : next[1]; + + let _line1 = _drawStraight({ + x1: current[0], + y1: current[1], + x2: current[2], + y2: current[3] + }); + let _line2 = _drawArc({ + r: radiusToUse, + x1: current[2], + y1: current[3], + x2: next[0], + y2: next[1], + cx: cx, + cy: cy, + ac: ac + }); + result = result.concat(_line1); + result = result.concat(_line2); + } else { + // dx + dy are used to adjust for line width. + let dx = (current[2] === current[0]) ? 0 : (current[2] > current[0]) ? (lw / 2) : -(lw / 2); + let dy = (current[3] === current[1]) ? 0 : (current[3] > current[1]) ? (lw / 2) : -(lw / 2); + let _line = _drawStraight({ + x1: current[0] - dx, + y1: current[1] - dy, + x2: current[2] + dx, + y2: current[3] + dy + }); + result = result.concat(_line); + } + current = next; + } + if (next !== null) { + let _line = _drawStraight({ + x1: next[0], + y1: next[1], + x2: next[2], + y2: next[3] + }); + result = result.concat(_line); + } + return result.join(' '); +} + +function drawFlow(sourcePoint, targetPoint, orientationLimit) { + if (!sourcePoint.orientation) { + sourcePoint.orientation = _calcOrientation(targetPoint.pos[0], targetPoint.pos[1], sourcePoint.pos[0], sourcePoint.pos[1], orientationLimit); + } + + if (!targetPoint.orientation) { + targetPoint.orientation = _calcOrientation(sourcePoint.pos[0], sourcePoint.pos[1], targetPoint.pos[0], targetPoint.pos[1], orientationLimit); + } + + let stub = 30; // 每部分折线的最小长度 + let midpoint = 0.5; // 折线中点 + let w = Math.abs(sourcePoint.pos[0] - targetPoint.pos[0]); + let h = Math.abs(sourcePoint.pos[1] - targetPoint.pos[1]); + let sx = targetPoint.pos[0] < sourcePoint.pos[0] ? w : 0; + let sy = targetPoint.pos[1] < sourcePoint.pos[1] ? h : 0; + let tx = targetPoint.pos[0] < sourcePoint.pos[0] ? 0 : w; + let ty = targetPoint.pos[1] < sourcePoint.pos[1] ? 0 : h; + let offsetX = sourcePoint.pos[0] < targetPoint.pos[0] ? sourcePoint.pos[0] : targetPoint.pos[0]; + let offsetY = sourcePoint.pos[1] < targetPoint.pos[1] ? sourcePoint.pos[1] : targetPoint.pos[1]; + // 小心有可能so[0]和to[0]同时为0;或者是so[1]和to[1]同时为0 + let so = sourcePoint.orientation; + let to = targetPoint.orientation; + // 拿来判断是对面,垂直还是正交 + let oProduct = ((so[0] * to[0]) + (so[1] * to[1])); + + let sourceAxis = so[0] === 0 ? 'y' : 'x'; + + let startStubX = sx + (so[0] * stub); + let startStubY = sy + (so[1] * stub); + let endStubX = tx + (to[0] * stub); + let endStubY = ty + (to[1] * stub); + + let isXGreaterThanStubTimes2 = Math.abs(sx - tx) > (stub + stub); + let isYGreaterThanStubTimes2 = Math.abs(sy - ty) > (stub + stub); + + // 判断方向 + let anchorOrientation = null; + if (oProduct === -1) { + anchorOrientation = 'opposite'; + } else if (oProduct === 0) { + anchorOrientation = 'perpendicular'; + } else if (oProduct === 1) { + anchorOrientation = 'orthogonal'; + } + + // 计算折线的方法 + let _commonStubCalculator = () => { + return [startStubX, startStubY, endStubX, endStubY]; + }; + let stubCalculators = { + perpendicular: _commonStubCalculator, + orthogonal: _commonStubCalculator, + opposite: (axis) => { + let idx = axis === 'x' ? 0 : 1; + let areInProximity = { + x: () => { + return ( (so[idx] === 1 && ( + ( (startStubX > endStubX) && (tx > startStubX) ) || + ( (sx > endStubX) && (tx > sx))))) || + ( (so[idx] === -1 && ( + ( (startStubX < endStubX) && (tx < startStubX) ) || + ( (sx < endStubX) && (tx < sx))))); + }, + y: () => { + return ( (so[idx] === 1 && ( + ( (startStubY > endStubY) && (ty > startStubY) ) || + ( (sy > endStubY) && (ty > sy))))) || + + ( (so[idx] === -1 && ( + ( (startStubY < endStubY) && (ty < startStubY) ) || + ( (sy < endStubY) && (ty < sy))))); + } + }; + + // 判断是否需要折线 + if (areInProximity[axis]()) { // 这判断可以设置总是有折线 + return { + x: [(sx + tx) / 2, startStubY, (sx + tx) / 2, endStubY], + y: [startStubX, (sy + ty) / 2, endStubX, (sy + ty) / 2] + }[axis]; + } else { + return [startStubX, startStubY, endStubX, endStubY]; + } + } + }; + + // 加工线条处理的方法 + let lastx = null; + let lasty = null; + let segments = []; + let _sgn = (n) => { + return n < 0 ? -1 : n === 0 ? 0 : 1; + }; + let _addSegment = (x, y) => { + if (lastx === x && lasty === y) { + return; + } + let lx = lastx == null ? sx : lastx; + let ly = lasty == null ? sy : lasty; + let o = lx === x ? 'v': 'h'; + let sgnx = _sgn(x - lx); + let sgny = _sgn(y - ly); + + lastx = x; + lasty = y; + + segments.push([lx, ly, x, y, o, sgnx, sgny]); + }; + + // 开始实现 + let stubs = stubCalculators[anchorOrientation](sourceAxis); + let idx = sourceAxis === 'x' ? 0 : 1; + let oidx = sourceAxis === 'x' ? 0 : 1; + let ss = stubs[idx]; + let oss = stubs[oidx]; + let es = stubs[idx + 2]; + let oes = stubs[oidx + 2]; + + _addSegment(stubs[0], stubs[1]); + + let midx = startStubX + (endStubX - startStubX) * midpoint; + let midy = startStubY + (endStubY - startStubY) * midpoint; + + let orientations = { x: [ 0, 1 ], y: [ 1, 0 ] }; + let _lineCalculators = { + perpendicular: (axis) => { + let sis = { + x: [ + [[1, 2, 3, 4], null, [2, 1, 4, 3]], + null, + [[4, 3, 2, 1], null, [3, 4, 1, 2]] + ], + y: [ + [[3, 2, 1, 4], null, [2, 3, 4, 1]], + null, + [[4, 1, 2, 3], null, [1, 4, 3, 2]] + ] + }; + let stubs = { + x: [[startStubX, endStubX], null, [endStubX, startStubX]], + y: [[startStubY, endStubY], null, [endStubY, startStubY]] + }; + let midLines = { + x: [[midx, startStubY], [midx, endStubY]], + y: [[startStubX, midy], [endStubX, midy]] + }; + let linesToEnd = { + x: [[endStubX, startStubY]], + y: [[startStubX, endStubY]] + }; + let startToEnd = { + x: [[startStubX, endStubY], [endStubX, endStubY]], + y: [[endStubX, startStubY], [endStubX, endStubY]] + }; + let startToMidToEnd = { + x: [[startStubX, midy], [endStubX, midy], [endStubX, endStubY]], + y: [[midx, startStubY], [midx, endStubY], [endStubX, endStubY]] + }; + let otherStubs = { + x: [startStubY, endStubY], + y: [startStubX, endStubX] + }; + let soIdx = orientations[axis][0]; + let toIdx = orientations[axis][1]; + let _so = so[soIdx] + 1; + let _to = to[toIdx] + 1; + let otherFlipped = (to[toIdx] === -1 && (otherStubs[axis][1] < otherStubs[axis][0])) || (to[toIdx] === 1 && (otherStubs[axis][1] > otherStubs[axis][0])); + let stub1 = stubs[axis][_so][0]; + let stub2 = stubs[axis][_so][1]; + let segmentIndexes = sis[axis][_so][_to]; + + // 计算一下节点象限 + let _quadrant = (p1, p2) => { + if (p2.pos[0] > p1.pos[0]) { + return (p2.pos[1] > p1.pos[1]) ? 2 : 1; + } else if (p2.pos[0] == p1.pos[0]) { + return p2.pos[1] > p1.pos[1] ? 2 : 1; + } else { + return (p2.pos[1] > p1.pos[1]) ? 3 : 4; + } + }; + var segment = _quadrant(sourcePoint, targetPoint); + if (segment === segmentIndexes[3] || (segment === segmentIndexes[2] && otherFlipped)) { + return midLines[axis]; + } else if (segment === segmentIndexes[2] && stub2 < stub1) { + return linesToEnd[axis]; + } else if ((segment === segmentIndexes[2] && stub2 >= stub1) || (segment === segmentIndexes[1] && !otherFlipped)) { + return startToMidToEnd[axis]; + } else if (segment === segmentIndexes[0] || (segment === segmentIndexes[1] && otherFlipped)) { + return startToEnd[axis]; + } + }, + orthogonal: (axis, startStub, otherStartStub, endStub, otherEndStub) => { + let extent = { + x: so[0] === -1 ? Math.min(startStub, endStub) : Math.max(startStub, endStub), + y: so[1] === -1 ? Math.min(startStub, endStub) : Math.max(startStub, endStub) + }[axis]; + + return { + x: [ + [extent, otherStartStub], + [extent, otherEndStub], + [endStub, otherEndStub] + ], + y: [ + [otherStartStub, extent], + [otherEndStub, extent], + [otherEndStub, endStub] + ] + }[axis]; + }, + opposite: (axis, ss, oss, es) => { + let otherAxis = {x: 'y', y: 'x'}[axis]; + let dim = {x: 'height', y: 'width'}[axis]; + let comparator = axis === 'x' ? isXGreaterThanStubTimes2 : isYGreaterThanStubTimes2; + + // 考虑下自连的情况, 现在很不严禁 + if (sourcePoint.pos[0] === targetPoint.pos[0] && sourcePoint.pos[1] === targetPoint.pos[1]) { + // + } else if (!comparator || (so[idx] === 1 && ss > es) || (so[idx] === -1 && ss < es)) { + return { + x: [ + [ss, midy], + [es, midy] + ], + y: [ + [midx, ss], + [midx, es] + ] + }[axis]; + } else if ((so[idx] === 1 && ss < es) || (so[idx] === -1 && ss > es)) { + return { + x: [ + [midx, sy], + [midx, ty] + ], + y: [ + [sx, midy], + [tx, midy] + ] + }[axis]; + } + } + }; + + // 计算剩余线条 + var p = _lineCalculators[anchorOrientation](sourceAxis, ss, oss, es, oes); + if (p) { + for (let i = 0; i < p.length; p++) { + _addSegment(p[i][0], p[i][1]); + } + } + + // line to end stub + _addSegment(stubs[2], stubs[3]); + + // end stub to end (common) + _addSegment(tx, ty); + + // 实际操作svg + return _drawFlowSegment(segments, { + x: offsetX, + y: offsetY + }); +} + +export default drawFlow; +>>>>>>> 44fc7b5... chore: optimize link code