@logicflow/core 2.0.0-beta.1 → 2.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/.turbo/turbo-build$colon$dev.log +2 -2
  2. package/.turbo/turbo-build.log +8 -8
  3. package/dist/index.min.js +9 -3
  4. package/es/LogicFlow.d.ts +37 -20
  5. package/es/LogicFlow.js +27 -24
  6. package/es/LogicFlow.js.map +1 -1
  7. package/es/common/drag.d.ts +51 -0
  8. package/es/common/drag.js +145 -0
  9. package/es/common/drag.js.map +1 -0
  10. package/es/common/history.d.ts +28 -0
  11. package/es/common/history.js +92 -0
  12. package/es/common/history.js.map +1 -0
  13. package/es/common/index.d.ts +5 -0
  14. package/es/common/index.js +6 -0
  15. package/es/common/index.js.map +1 -0
  16. package/es/common/keyboard.d.ts +34 -0
  17. package/es/common/keyboard.js +80 -0
  18. package/es/common/keyboard.js.map +1 -0
  19. package/es/common/matrix.d.ts +30 -0
  20. package/es/common/matrix.js +155 -0
  21. package/es/common/matrix.js.map +1 -0
  22. package/es/common/vector.d.ts +23 -0
  23. package/es/common/vector.js +97 -0
  24. package/es/common/vector.js.map +1 -0
  25. package/es/event/eventEmitter.js +1 -1
  26. package/es/event/eventEmitter.js.map +1 -1
  27. package/es/index.d.ts +1 -1
  28. package/es/index.js +1 -1
  29. package/es/index.js.map +1 -1
  30. package/es/model/SnaplineModel.d.ts +2 -0
  31. package/es/model/edge/BaseEdgeModel.d.ts +5 -9
  32. package/es/model/edge/BaseEdgeModel.js +26 -23
  33. package/es/model/edge/BaseEdgeModel.js.map +1 -1
  34. package/es/model/edge/BezierEdgeModel.d.ts +2 -0
  35. package/es/model/edge/LineEdgeModel.d.ts +2 -0
  36. package/es/model/edge/PolylineEdgeModel.d.ts +2 -0
  37. package/es/model/node/BaseNodeModel.js +22 -21
  38. package/es/model/node/BaseNodeModel.js.map +1 -1
  39. package/es/model/node/CircleNodeModel.d.ts +2 -0
  40. package/es/model/node/CircleNodeModel.js +2 -2
  41. package/es/model/node/CircleNodeModel.js.map +1 -1
  42. package/es/model/node/DiamondNodeModel.d.ts +2 -0
  43. package/es/model/node/DiamondNodeModel.js +2 -1
  44. package/es/model/node/DiamondNodeModel.js.map +1 -1
  45. package/es/model/node/EllipseNodeModel.d.ts +2 -0
  46. package/es/model/node/EllipseNodeModel.js +2 -1
  47. package/es/model/node/EllipseNodeModel.js.map +1 -1
  48. package/es/model/node/HtmlNodeModel.d.ts +2 -2
  49. package/es/model/node/HtmlNodeModel.js.map +1 -1
  50. package/es/model/node/PolygonNodeModel.d.ts +2 -0
  51. package/es/model/node/PolygonNodeModel.js +2 -2
  52. package/es/model/node/PolygonNodeModel.js.map +1 -1
  53. package/es/model/node/RectNodeModel.d.ts +3 -0
  54. package/es/model/node/RectNodeModel.js +8 -2
  55. package/es/model/node/RectNodeModel.js.map +1 -1
  56. package/es/model/node/TextNodeModel.d.ts +4 -2
  57. package/es/options.d.ts +2 -2
  58. package/es/options.js +2 -11
  59. package/es/options.js.map +1 -1
  60. package/es/tool/tool.js.map +1 -1
  61. package/es/util/edge.d.ts +6 -0
  62. package/es/util/edge.js +15 -1
  63. package/es/util/edge.js.map +1 -1
  64. package/es/util/node.d.ts +6 -2
  65. package/es/util/node.js +22 -7
  66. package/es/util/node.js.map +1 -1
  67. package/es/view/Anchor.d.ts +1 -1
  68. package/es/view/Anchor.js +3 -3
  69. package/es/view/Anchor.js.map +1 -1
  70. package/es/view/Control.js +14 -2
  71. package/es/view/Control.js.map +1 -1
  72. package/es/view/Graph.d.ts +3 -0
  73. package/es/view/Graph.js +38 -3
  74. package/es/view/Graph.js.map +1 -1
  75. package/es/view/edge/AdjustPoint.js +3 -3
  76. package/es/view/edge/AdjustPoint.js.map +1 -1
  77. package/es/view/edge/BaseEdge.d.ts +2 -2
  78. package/es/view/edge/BaseEdge.js +5 -5
  79. package/es/view/node/BaseNode.d.ts +2 -2
  80. package/es/view/node/BaseNode.js +5 -5
  81. package/es/view/node/TextNode.js +1 -1
  82. package/es/view/node/TextNode.js.map +1 -1
  83. package/es/view/shape/Circle.d.ts +9 -1
  84. package/es/view/shape/Circle.js +5 -5
  85. package/es/view/shape/Circle.js.map +1 -1
  86. package/es/view/shape/Ellipse.d.ts +10 -1
  87. package/es/view/shape/Ellipse.js +5 -5
  88. package/es/view/shape/Ellipse.js.map +1 -1
  89. package/es/view/shape/Line.d.ts +14 -1
  90. package/es/view/shape/Line.js +5 -7
  91. package/es/view/shape/Line.js.map +1 -1
  92. package/es/view/shape/Path.d.ts +3 -2
  93. package/es/view/shape/Path.js +3 -3
  94. package/es/view/shape/Path.js.map +1 -1
  95. package/es/view/shape/Polygon.d.ts +5 -3
  96. package/es/view/shape/Polygon.js +6 -6
  97. package/es/view/shape/Polygon.js.map +1 -1
  98. package/es/view/shape/Polyline.d.ts +7 -1
  99. package/es/view/shape/Polyline.js +8 -6
  100. package/es/view/shape/Polyline.js.map +1 -1
  101. package/es/view/shape/Rect.d.ts +11 -13
  102. package/es/view/shape/Rect.js +6 -9
  103. package/es/view/shape/Rect.js.map +1 -1
  104. package/es/view/shape/Text.d.ts +19 -1
  105. package/es/view/shape/Text.js +28 -21
  106. package/es/view/shape/Text.js.map +1 -1
  107. package/es/view/text/BaseText.d.ts +12 -15
  108. package/es/view/text/BaseText.js +37 -27
  109. package/es/view/text/BaseText.js.map +1 -1
  110. package/es/view/text/LineText.d.ts +19 -7
  111. package/es/view/text/LineText.js +62 -54
  112. package/es/view/text/LineText.js.map +1 -1
  113. package/lib/LogicFlow.d.ts +37 -20
  114. package/lib/LogicFlow.js +26 -23
  115. package/lib/LogicFlow.js.map +1 -1
  116. package/lib/common/drag.d.ts +51 -0
  117. package/lib/common/drag.js +148 -0
  118. package/lib/common/drag.js.map +1 -0
  119. package/lib/common/history.d.ts +28 -0
  120. package/lib/common/history.js +95 -0
  121. package/lib/common/history.js.map +1 -0
  122. package/lib/common/index.d.ts +5 -0
  123. package/lib/common/index.js +22 -0
  124. package/lib/common/index.js.map +1 -0
  125. package/lib/common/keyboard.d.ts +34 -0
  126. package/lib/common/keyboard.js +86 -0
  127. package/lib/common/keyboard.js.map +1 -0
  128. package/lib/common/matrix.d.ts +30 -0
  129. package/lib/common/matrix.js +158 -0
  130. package/lib/common/matrix.js.map +1 -0
  131. package/lib/common/vector.d.ts +23 -0
  132. package/lib/common/vector.js +101 -0
  133. package/lib/common/vector.js.map +1 -0
  134. package/lib/event/eventEmitter.js +1 -1
  135. package/lib/event/eventEmitter.js.map +1 -1
  136. package/lib/index.d.ts +1 -1
  137. package/lib/index.js +2 -2
  138. package/lib/index.js.map +1 -1
  139. package/lib/model/SnaplineModel.d.ts +2 -0
  140. package/lib/model/edge/BaseEdgeModel.d.ts +5 -9
  141. package/lib/model/edge/BaseEdgeModel.js +25 -22
  142. package/lib/model/edge/BaseEdgeModel.js.map +1 -1
  143. package/lib/model/edge/BezierEdgeModel.d.ts +2 -0
  144. package/lib/model/edge/LineEdgeModel.d.ts +2 -0
  145. package/lib/model/edge/PolylineEdgeModel.d.ts +2 -0
  146. package/lib/model/node/BaseNodeModel.js +21 -20
  147. package/lib/model/node/BaseNodeModel.js.map +1 -1
  148. package/lib/model/node/CircleNodeModel.d.ts +2 -0
  149. package/lib/model/node/CircleNodeModel.js +2 -2
  150. package/lib/model/node/CircleNodeModel.js.map +1 -1
  151. package/lib/model/node/DiamondNodeModel.d.ts +2 -0
  152. package/lib/model/node/DiamondNodeModel.js +2 -1
  153. package/lib/model/node/DiamondNodeModel.js.map +1 -1
  154. package/lib/model/node/EllipseNodeModel.d.ts +2 -0
  155. package/lib/model/node/EllipseNodeModel.js +2 -1
  156. package/lib/model/node/EllipseNodeModel.js.map +1 -1
  157. package/lib/model/node/HtmlNodeModel.d.ts +2 -2
  158. package/lib/model/node/HtmlNodeModel.js.map +1 -1
  159. package/lib/model/node/PolygonNodeModel.d.ts +2 -0
  160. package/lib/model/node/PolygonNodeModel.js +2 -2
  161. package/lib/model/node/PolygonNodeModel.js.map +1 -1
  162. package/lib/model/node/RectNodeModel.d.ts +3 -0
  163. package/lib/model/node/RectNodeModel.js +8 -2
  164. package/lib/model/node/RectNodeModel.js.map +1 -1
  165. package/lib/model/node/TextNodeModel.d.ts +4 -2
  166. package/lib/options.d.ts +2 -2
  167. package/lib/options.js +2 -11
  168. package/lib/options.js.map +1 -1
  169. package/lib/tool/tool.js.map +1 -1
  170. package/lib/util/edge.d.ts +6 -0
  171. package/lib/util/edge.js +16 -1
  172. package/lib/util/edge.js.map +1 -1
  173. package/lib/util/node.d.ts +6 -2
  174. package/lib/util/node.js +24 -9
  175. package/lib/util/node.js.map +1 -1
  176. package/lib/view/Anchor.d.ts +1 -1
  177. package/lib/view/Anchor.js +2 -2
  178. package/lib/view/Anchor.js.map +1 -1
  179. package/lib/view/Control.js +14 -2
  180. package/lib/view/Control.js.map +1 -1
  181. package/lib/view/Graph.d.ts +3 -0
  182. package/lib/view/Graph.js +37 -2
  183. package/lib/view/Graph.js.map +1 -1
  184. package/lib/view/edge/AdjustPoint.js +2 -2
  185. package/lib/view/edge/AdjustPoint.js.map +1 -1
  186. package/lib/view/edge/BaseEdge.d.ts +2 -2
  187. package/lib/view/edge/BaseEdge.js +5 -5
  188. package/lib/view/node/BaseNode.d.ts +2 -2
  189. package/lib/view/node/BaseNode.js +5 -5
  190. package/lib/view/node/TextNode.js +1 -1
  191. package/lib/view/node/TextNode.js.map +1 -1
  192. package/lib/view/shape/Circle.d.ts +9 -1
  193. package/lib/view/shape/Circle.js +5 -5
  194. package/lib/view/shape/Circle.js.map +1 -1
  195. package/lib/view/shape/Ellipse.d.ts +10 -1
  196. package/lib/view/shape/Ellipse.js +5 -5
  197. package/lib/view/shape/Ellipse.js.map +1 -1
  198. package/lib/view/shape/Line.d.ts +14 -1
  199. package/lib/view/shape/Line.js +5 -7
  200. package/lib/view/shape/Line.js.map +1 -1
  201. package/lib/view/shape/Path.d.ts +3 -2
  202. package/lib/view/shape/Path.js +3 -3
  203. package/lib/view/shape/Path.js.map +1 -1
  204. package/lib/view/shape/Polygon.d.ts +5 -3
  205. package/lib/view/shape/Polygon.js +6 -6
  206. package/lib/view/shape/Polygon.js.map +1 -1
  207. package/lib/view/shape/Polyline.d.ts +7 -1
  208. package/lib/view/shape/Polyline.js +8 -6
  209. package/lib/view/shape/Polyline.js.map +1 -1
  210. package/lib/view/shape/Rect.d.ts +11 -13
  211. package/lib/view/shape/Rect.js +6 -9
  212. package/lib/view/shape/Rect.js.map +1 -1
  213. package/lib/view/shape/Text.d.ts +19 -1
  214. package/lib/view/shape/Text.js +29 -21
  215. package/lib/view/shape/Text.js.map +1 -1
  216. package/lib/view/text/BaseText.d.ts +12 -15
  217. package/lib/view/text/BaseText.js +40 -27
  218. package/lib/view/text/BaseText.js.map +1 -1
  219. package/lib/view/text/LineText.d.ts +19 -7
  220. package/lib/view/text/LineText.js +62 -57
  221. package/lib/view/text/LineText.js.map +1 -1
  222. package/package.json +2 -1
  223. package/src/LogicFlow.tsx +97 -55
  224. package/src/common/drag.ts +205 -0
  225. package/src/common/history.ts +108 -0
  226. package/src/common/index.ts +6 -0
  227. package/src/common/keyboard.ts +108 -0
  228. package/src/common/matrix.ts +122 -0
  229. package/src/common/vector.ts +93 -0
  230. package/src/event/eventEmitter.ts +1 -1
  231. package/src/index.ts +1 -1
  232. package/src/model/edge/BaseEdgeModel.ts +31 -21
  233. package/src/model/node/BaseNodeModel.ts +27 -19
  234. package/src/model/node/CircleNodeModel.ts +2 -2
  235. package/src/model/node/DiamondNodeModel.ts +2 -0
  236. package/src/model/node/EllipseNodeModel.ts +2 -0
  237. package/src/model/node/HtmlNodeModel.ts +2 -2
  238. package/src/model/node/PolygonNodeModel.ts +2 -2
  239. package/src/model/node/RectNodeModel.ts +9 -2
  240. package/src/options.ts +4 -13
  241. package/src/tool/tool.ts +1 -1
  242. package/src/util/edge.ts +26 -1
  243. package/src/util/node.ts +29 -8
  244. package/src/view/Anchor.tsx +4 -4
  245. package/src/view/Control.tsx +5 -2
  246. package/src/view/Graph.tsx +14 -2
  247. package/src/view/edge/AdjustPoint.tsx +3 -3
  248. package/src/view/edge/BaseEdge.tsx +7 -7
  249. package/src/view/node/BaseNode.tsx +7 -7
  250. package/src/view/node/TextNode.tsx +1 -1
  251. package/src/view/shape/Circle.tsx +21 -7
  252. package/src/view/shape/Ellipse.tsx +20 -6
  253. package/src/view/shape/Line.tsx +24 -9
  254. package/src/view/shape/Path.tsx +9 -6
  255. package/src/view/shape/Polygon.tsx +13 -10
  256. package/src/view/shape/Polyline.tsx +20 -8
  257. package/src/view/shape/Rect.tsx +19 -19
  258. package/src/view/shape/Text.tsx +64 -33
  259. package/src/view/text/BaseText.tsx +67 -41
  260. package/src/view/text/LineText.tsx +94 -80
@@ -0,0 +1,6 @@
1
+ export * from './drag'
2
+ export * from './history'
3
+ export * from './keyboard'
4
+
5
+ export * from './matrix'
6
+ export * from './vector'
@@ -0,0 +1,108 @@
1
+ import Mousetrap, { MousetrapInstance } from 'mousetrap'
2
+ import { forEach, isArray } from 'lodash-es'
3
+ import LogicFlow from '..'
4
+
5
+ export class Keyboard {
6
+ private target: HTMLElement
7
+ readonly mousetrap: MousetrapInstance
8
+ options: Required<Keyboard.Options>
9
+
10
+ constructor(options: Keyboard.Options) {
11
+ const { lf } = options
12
+ if (!options.keyboard) {
13
+ options.keyboard = { enabled: false }
14
+ }
15
+ this.options = options as Required<Keyboard.Options>
16
+ this.target = lf.container
17
+ this.mousetrap = new Mousetrap(this.target)
18
+
19
+ if (options.keyboard?.enabled) {
20
+ this.enable(true)
21
+ }
22
+ }
23
+
24
+ protected formatKey(key: string) {
25
+ return key
26
+ .toLowerCase()
27
+ .replace(/\s/g, '')
28
+ .replace('delete', 'del')
29
+ .replace('cmd', 'command')
30
+ }
31
+
32
+ private getKeys(keys: string | string[]) {
33
+ return (isArray(keys) ? keys : [keys]).map((key) => this.formatKey(key))
34
+ }
35
+
36
+ get disabled() {
37
+ return this.options.keyboard?.enabled !== true
38
+ }
39
+
40
+ on(
41
+ keys: string | string[],
42
+ callback: Keyboard.HandlerFunc,
43
+ action?: Keyboard.ActionType,
44
+ ) {
45
+ this.mousetrap.bind(this.getKeys(keys), callback, action)
46
+ }
47
+
48
+ off(keys: string | string[], action?: Keyboard.ActionType) {
49
+ this.mousetrap.unbind(this.getKeys(keys), action)
50
+ }
51
+
52
+ enable(force: boolean) {
53
+ if (this.disabled || force) {
54
+ this.options.keyboard.enabled = true
55
+ if (this.target instanceof HTMLElement) {
56
+ this.target.setAttribute('tabindex', '-1')
57
+ // 去掉节点被选中时 container 出现的边框
58
+ this.target.style.outline = 'none'
59
+ }
60
+ }
61
+ }
62
+
63
+ disable() {
64
+ if (!this.disabled) {
65
+ this.options.keyboard.enabled = false
66
+ if (this.target instanceof HTMLElement) {
67
+ this.target.removeAttribute('tabindex')
68
+ }
69
+ }
70
+ }
71
+
72
+ initShortcuts() {
73
+ const { shortcuts } = this.options.keyboard
74
+ if (shortcuts) {
75
+ if (isArray(shortcuts)) {
76
+ forEach(shortcuts, ({ keys, callback, action }) => {
77
+ this.on(keys, callback, action)
78
+ })
79
+ } else {
80
+ const { keys, callback, action } = shortcuts
81
+ this.on(keys, callback, action)
82
+ }
83
+ }
84
+ }
85
+ }
86
+
87
+ export namespace Keyboard {
88
+ export type ActionType = 'keypress' | 'keydown' | 'keyup'
89
+ export type HandlerFunc = (e: KeyboardEvent) => void
90
+
91
+ export interface Shortcut {
92
+ keys: string | string[]
93
+ callback: HandlerFunc
94
+ action?: ActionType
95
+ }
96
+
97
+ export interface KeyboardDef {
98
+ enabled: boolean
99
+ shortcuts?: Shortcut | Shortcut[]
100
+ }
101
+
102
+ export interface Options {
103
+ lf: LogicFlow
104
+ keyboard?: KeyboardDef
105
+ }
106
+ }
107
+
108
+ export default Keyboard
@@ -0,0 +1,122 @@
1
+ import { Vector } from './vector'
2
+
3
+ export class Matrix extends Array {
4
+ rows: number
5
+ columns: number
6
+
7
+ constructor(...vectors: any[]) {
8
+ super(vectors.length)
9
+ this.fill(new Array(3))
10
+ vectors.forEach((v: any, index: number) => {
11
+ this[index] = v
12
+ })
13
+ this.columns = vectors[0].length
14
+ this.rows = vectors.length
15
+ Object.setPrototypeOf(this, Matrix.prototype)
16
+ }
17
+
18
+ getRow(index: number) {
19
+ return this[index]
20
+ }
21
+
22
+ getColumn(index: number) {
23
+ return [...this.map((row: number[]) => row[index])]
24
+ }
25
+
26
+ // 转置
27
+ transpose() {
28
+ const rows: any[] = []
29
+ for (let i = 0; i < this.columns; i++) {
30
+ rows.push(this.getColumn(i))
31
+ }
32
+ return new Matrix(...rows)
33
+ }
34
+
35
+ // 叉乘
36
+ cross(m1: Matrix) {
37
+ const arr = new Array(this.rows).fill('').map((): any => [])
38
+ if (this.columns === m1.rows) {
39
+ for (let i = 0; i < this.rows; i++) {
40
+ const row = this.getRow(i)
41
+ for (let j = 0; j < m1.columns; j++) {
42
+ const column = m1.getColumn(j)
43
+ arr[i][j] = row.reduce(
44
+ (prev: number, r: number, index: number) =>
45
+ prev + r * column[index],
46
+ 0,
47
+ )
48
+ }
49
+ }
50
+ }
51
+ return new Matrix(...arr)
52
+ }
53
+
54
+ // 返回二维坐标(降维)
55
+ to2D() {
56
+ return this.map((item: any) => [item[0], item[1]])
57
+ }
58
+
59
+ toString(): string {
60
+ const [[a, b], [c, d], [e, f]] = this
61
+ return `matrix(${a} ${b} ${c} ${d} ${e} ${f})`
62
+ }
63
+
64
+ translate(tx: number, ty: number): Matrix {
65
+ return this.cross(new TranslateMatrix(tx, ty))
66
+ }
67
+
68
+ rotate(angle: number): Matrix {
69
+ return this.cross(new RotateMatrix(angle))
70
+ }
71
+
72
+ scale(sx: number, sy: number): Matrix {
73
+ return this.cross(new ScaleMatrix(sx, sy))
74
+ }
75
+ }
76
+
77
+ export class RotateMatrix extends Matrix {
78
+ constructor(theta: number) {
79
+ super(
80
+ new Vector(+Math.cos(theta).toFixed(2), +Math.sin(theta).toFixed(2), 0),
81
+ new Vector(-Math.sin(theta).toFixed(2), +Math.cos(theta).toFixed(2), 0),
82
+ new Vector(0, 0, 1),
83
+ )
84
+ Object.setPrototypeOf(this, RotateMatrix.prototype)
85
+ }
86
+
87
+ inverse() {
88
+ return this.transpose()
89
+ }
90
+ }
91
+
92
+ export class ScaleMatrix extends Matrix {
93
+ private readonly sx: number
94
+ private readonly sy: number
95
+
96
+ constructor(sx: number, sy: number) {
97
+ super(new Vector(sx, 0, 0), new Vector(0, sy, 0), new Vector(0, 0, 1))
98
+ this.sx = sx
99
+ this.sy = sy
100
+ Object.setPrototypeOf(this, ScaleMatrix.prototype)
101
+ }
102
+
103
+ inverse() {
104
+ return new ScaleMatrix(1 / this.sx, 1 / this.sy)
105
+ }
106
+ }
107
+
108
+ export class TranslateMatrix extends Matrix {
109
+ private readonly tx: number
110
+ private readonly ty: number
111
+
112
+ constructor(tx: number, ty: number) {
113
+ super(new Vector(1, 0, 0), new Vector(0, 1, 0), new Vector(tx, ty, 1))
114
+ this.tx = tx
115
+ this.ty = ty
116
+ Object.setPrototypeOf(this, TranslateMatrix.prototype)
117
+ }
118
+
119
+ inverse() {
120
+ return new TranslateMatrix(-this.tx, -this.ty)
121
+ }
122
+ }
@@ -0,0 +1,93 @@
1
+ function isVector(a1: any, a2: any): boolean {
2
+ return a1 instanceof Vector && a2 instanceof Vector
3
+ }
4
+
5
+ class Base extends Array {
6
+ x: number
7
+ y: number
8
+ z: number
9
+
10
+ constructor(x: number, y: number, z: number) {
11
+ super(3)
12
+ this[0] = x
13
+ this[1] = y
14
+ this[2] = z
15
+ this.x = x
16
+ this.y = y
17
+ this.z = z
18
+ Object.setPrototypeOf(this, Base.prototype)
19
+ }
20
+
21
+ add(v1: Vector | Point): Vector | Point {
22
+ if (isVector(this, v1)) {
23
+ return new Vector(this.x + v1.x, this.y + v1.y)
24
+ }
25
+ const z = this.z + v1.z
26
+ return new Point((this.x + v1.x) / z, (this.y + v1.y) / z)
27
+ }
28
+
29
+ subtract(v1: Vector | Point): Vector | Point {
30
+ if (isVector(this, v1)) {
31
+ return new Vector(this.x - v1.x, this.y - v1.y)
32
+ }
33
+ const z = this.z - v1.z
34
+ return z === 0
35
+ ? new Vector(this.x - v1.x, this.y - v1.y)
36
+ : new Point((this.x - v1.x) / z, (this.y - v1.y) / z)
37
+ }
38
+ }
39
+
40
+ class Vector extends Base {
41
+ constructor(x: number, y: number, z?: number) {
42
+ super(x, y, z ?? 0)
43
+ Object.setPrototypeOf(this, Vector.prototype)
44
+ }
45
+
46
+ toString(): string {
47
+ return 'Vector'
48
+ }
49
+
50
+ dot(v1: Vector) {
51
+ return v1.reduce((prev, cur, index) => prev + cur * this[index])
52
+ }
53
+
54
+ cross(v1: Vector) {
55
+ return new Vector(
56
+ this.y * v1.z - this.z * v1.y,
57
+ this.z * v1.x - this.x * v1.z,
58
+ this.x * v1.y - this.y * v1.x,
59
+ )
60
+ }
61
+
62
+ getLength() {
63
+ return Math.hypot(this.x, this.y)
64
+ }
65
+
66
+ normalize() {
67
+ const len = this.getLength()
68
+ return new Vector(this.x / len, this.y / len)
69
+ }
70
+
71
+ crossZ(v1: Vector) {
72
+ return this.x * v1.y - this.y * v1.x
73
+ }
74
+
75
+ angle(v1: Vector) {
76
+ const negative = this.crossZ(v1)
77
+ const r = Math.acos(this.normalize().dot(v1.normalize()))
78
+ return negative >= 0 ? r : -r
79
+ }
80
+ }
81
+
82
+ class Point extends Base {
83
+ constructor(x: number, y: number) {
84
+ super(x, y, 1)
85
+ Object.setPrototypeOf(this, Point.prototype)
86
+ }
87
+
88
+ toString(): string {
89
+ return 'Point'
90
+ }
91
+ }
92
+
93
+ export { Vector, Point }
@@ -77,7 +77,7 @@ export default class EventEmitter {
77
77
  emit(evts: string, eventArgs: EventCallback) {
78
78
  evts?.split(',').forEach((evt) => {
79
79
  const events = this._events[evt] || []
80
- // TODO: 这是什么???
80
+ // TODO: 这是什么??? +1
81
81
  const wildcardEvents = this._events[WILDCARD] || []
82
82
  // 实际的处理 emit 方法
83
83
  const doEmit = (es: EventType[]) => {
package/src/index.ts CHANGED
@@ -16,6 +16,6 @@ export * from './options'
16
16
  export * from './keyboard'
17
17
  export { ElementState, ModelType, ElementType, EventType } from './constant'
18
18
 
19
- export { formateAnchorConnectValidateData } from './util/node'
19
+ export { formatAnchorConnectValidateData } from './util/node'
20
20
 
21
21
  export default LogicFlow
@@ -1,4 +1,4 @@
1
- import { assign, cloneDeep, find } from 'lodash-es'
1
+ import { assign, cloneDeep, find, isUndefined } from 'lodash-es'
2
2
  import { action, computed, observable, toJS } from 'mobx'
3
3
  import { BaseNodeModel, GraphModel, Model } from '..'
4
4
  import LogicFlow from '../../LogicFlow'
@@ -20,6 +20,7 @@ import {
20
20
  import Point = LogicFlow.Point
21
21
  import EdgeData = LogicFlow.EdgeData
22
22
  import EdgeConfig = LogicFlow.EdgeConfig
23
+ import TextConfig = LogicFlow.TextConfig
23
24
 
24
25
  export interface IBaseEdgeModel extends Model.BaseModel {
25
26
  /**
@@ -56,7 +57,7 @@ export class BaseEdgeModel implements IBaseEdgeModel {
56
57
  @observable startPoint!: Point
57
58
  @observable endPoint!: Point
58
59
 
59
- @observable text = {
60
+ @observable text: Required<TextConfig> = {
60
61
  value: '',
61
62
  x: 0,
62
63
  y: 0,
@@ -431,8 +432,7 @@ export class BaseEdgeModel implements IBaseEdgeModel {
431
432
 
432
433
  /**
433
434
  * 设置边的属性,会触发重新渲染
434
- * @param key 属性名
435
- * @param val 属性值
435
+ * @param properties 要更新的 properties,会做合并
436
436
  */
437
437
  @action
438
438
  setProperties(properties: Record<string, any>): void {
@@ -497,28 +497,38 @@ export class BaseEdgeModel implements IBaseEdgeModel {
497
497
  * 内部方法,处理初始化文本格式
498
498
  */
499
499
  @action formatText(data: EdgeConfig) {
500
- // 暂时处理,只传入text的情况
501
500
  const { x, y } = this.textPosition
502
- if (!data.text || typeof data.text === 'string') {
503
- this.text = {
504
- value: data.text || '',
505
- x,
506
- y,
507
- draggable: this.text.draggable,
508
- editable: this.text.editable,
509
- }
510
- return
501
+ const { text } = data
502
+ let textConfig: Required<TextConfig> = {
503
+ value: '',
504
+ x,
505
+ y,
506
+ draggable: false,
507
+ editable: true,
511
508
  }
512
509
 
513
- if (Object.prototype.toString.call(data.text) === '[object Object]') {
514
- this.text = {
515
- x: data.text.x || x,
516
- y: data.text.y || y,
517
- value: data.text.value || '',
518
- draggable: this.text.draggable,
519
- editable: this.text.editable,
510
+ if (text) {
511
+ if (typeof text === 'string') {
512
+ textConfig = {
513
+ ...textConfig,
514
+ value: text,
515
+ }
516
+ } else {
517
+ textConfig = {
518
+ ...textConfig,
519
+ x: text.x ?? x,
520
+ y: text.y ?? y,
521
+ value: text.value ?? '',
522
+ }
523
+ if (!isUndefined(text.draggable)) {
524
+ textConfig.draggable = text.draggable
525
+ }
526
+ if (!isUndefined(text.editable)) {
527
+ textConfig.editable = text.editable
528
+ }
520
529
  }
521
530
  }
531
+ this.text = textConfig
522
532
  }
523
533
 
524
534
  /**
@@ -1,5 +1,5 @@
1
1
  import { action, computed, isObservable, observable, toJS } from 'mobx'
2
- import { assign, cloneDeep, has, isNil, mapKeys } from 'lodash-es'
2
+ import { assign, cloneDeep, has, isNil, isUndefined, mapKeys } from 'lodash-es'
3
3
  import { GraphModel, Model } from '..'
4
4
  import LogicFlow from '../../LogicFlow'
5
5
  import {
@@ -186,6 +186,7 @@ export class BaseNodeModel implements IBaseNodeModel {
186
186
  }
187
187
 
188
188
  this.formatText(data)
189
+ // 在下面又将 NodeConfig 中的数据赋值给了 this,应该会触发 setAttributes,确认是否符合预期
189
190
  assign(this, pickNodeConfig(data)) // TODO: 确认 constructor 中赋值 properties 是否必要
190
191
  const { overlapMode } = this.graphModel
191
192
  if (overlapMode === OverlapMode.INCREASE) {
@@ -219,27 +220,34 @@ export class BaseNodeModel implements IBaseNodeModel {
219
220
  * 始化文本属性
220
221
  */
221
222
  private formatText(data: NodeConfig): void {
222
- if (!data.text) {
223
- data.text = {
224
- value: '',
225
- x: data.x,
226
- y: data.y,
227
- draggable: false,
228
- editable: true,
229
- }
230
- } else {
231
- if (typeof data.text === 'string') {
232
- data.text = {
233
- value: data.text,
234
- x: data.x,
235
- y: data.y,
236
- draggable: false,
237
- editable: true,
238
- }
223
+ const { x, y, text } = data
224
+ let textConfig: TextConfig = {
225
+ value: '',
226
+ x,
227
+ y,
228
+ draggable: false,
229
+ editable: true,
230
+ }
231
+ if (text) {
232
+ if (typeof text === 'string') {
233
+ textConfig.value = text
239
234
  } else {
240
- data.text.editable = data.text.editable ?? true
235
+ textConfig = {
236
+ ...textConfig,
237
+ x: text.x ?? x,
238
+ y: text.y ?? y,
239
+ value: text.value ?? '',
240
+ }
241
+ if (!isUndefined(text.draggable)) {
242
+ textConfig.draggable = text.draggable
243
+ }
244
+ if (!isUndefined(text.editable)) {
245
+ textConfig.draggable = text.draggable
246
+ }
241
247
  }
242
248
  }
249
+
250
+ data.text = textConfig
243
251
  }
244
252
 
245
253
  /**
@@ -54,11 +54,11 @@ export class CircleNodeModel extends BaseNodeModel {
54
54
  theme: { circle },
55
55
  },
56
56
  } = this
57
- const { style: customStyle } = this.properties
57
+ const { style: customStyle = {} } = this.properties
58
58
  return {
59
59
  ...style,
60
- ...(customStyle ?? {}),
61
60
  ...cloneDeep(circle),
61
+ ...cloneDeep(customStyle),
62
62
  }
63
63
  }
64
64
 
@@ -53,9 +53,11 @@ export class DiamondNodeModel extends BaseNodeModel {
53
53
  theme: { diamond },
54
54
  },
55
55
  } = this
56
+ const { style: customStyle = {} } = this.properties
56
57
  return {
57
58
  ...style,
58
59
  ...cloneDeep(diamond),
60
+ ...cloneDeep(customStyle),
59
61
  }
60
62
  }
61
63
 
@@ -51,9 +51,11 @@ export class EllipseNodeModel extends BaseNodeModel {
51
51
  theme: { ellipse },
52
52
  },
53
53
  } = this
54
+ const { style: customStyle = {} } = this.properties
54
55
  return {
55
56
  ...style,
56
57
  ...cloneDeep(ellipse),
58
+ ...cloneDeep(customStyle),
57
59
  }
58
60
  }
59
61
 
@@ -7,7 +7,7 @@ import { observable } from 'mobx'
7
7
  import LogicFlow from '../../LogicFlow'
8
8
  import GraphModel from '../GraphModel'
9
9
 
10
- export type IHtmlNodeModel = {
10
+ export type IHtmlNodeProperties = {
11
11
  width?: number
12
12
  height?: number
13
13
  style?: LogicFlow.CommonTheme
@@ -18,7 +18,7 @@ export type IHtmlNodeModel = {
18
18
 
19
19
  export class HtmlNodeModel extends BaseNodeModel {
20
20
  modelType = ModelType.HTML_NODE
21
- @observable properties: IHtmlNodeModel = {}
21
+ @observable properties: IHtmlNodeProperties = {}
22
22
 
23
23
  constructor(data: LogicFlow.NodeConfig, graphModel: GraphModel) {
24
24
  super(data, graphModel)
@@ -66,11 +66,11 @@ export class PolygonNodeModel extends BaseNodeModel {
66
66
  theme: { polygon },
67
67
  },
68
68
  } = this
69
- const { style: customStyle } = this.properties
69
+ const { style: customStyle = {} } = this.properties
70
70
  return {
71
71
  ...style,
72
72
  ...cloneDeep(polygon),
73
- ...(cloneDeep(customStyle) || {}),
73
+ ...cloneDeep(customStyle),
74
74
  }
75
75
  }
76
76
 
@@ -8,6 +8,7 @@ import { ModelType } from '../../constant'
8
8
  export type IRectNodeModel = {
9
9
  width?: number
10
10
  height?: number
11
+ radius?: number
11
12
  style?: LogicFlow.CommonTheme
12
13
  textStyle?: LogicFlow.CommonTheme
13
14
 
@@ -21,17 +22,21 @@ export class RectNodeModel extends BaseNodeModel {
21
22
 
22
23
  constructor(data: LogicFlow.NodeConfig, graphModel: GraphModel) {
23
24
  super(data, graphModel)
24
- this.properties = data.properties || {}
25
25
 
26
+ // TODO:类字段初始化会覆盖 super、setAttributes 中设置的属性
27
+ this.properties = data.properties || {}
28
+ // TODO: bug here, 上面更新 properties 会触发 setAttributes,下面再主动调用,会导致触发两次
26
29
  this.setAttributes()
27
30
  }
28
31
 
29
32
  setAttributes() {
30
33
  super.setAttributes()
31
34
 
32
- const { width, height } = this.properties
35
+ const { width, height, radius } = this.properties
33
36
  if (width) this.width = width
34
37
  if (height) this.height = height
38
+ // 矩形特有
39
+ if (radius) this.radius = radius
35
40
  }
36
41
 
37
42
  getDefaultAnchor() {
@@ -47,9 +52,11 @@ export class RectNodeModel extends BaseNodeModel {
47
52
  getNodeStyle() {
48
53
  const style = super.getNodeStyle()
49
54
  const { rect } = this.graphModel.theme
55
+ const { style: customStyle = {} } = this.properties
50
56
  return {
51
57
  ...style,
52
58
  ...cloneDeep(rect),
59
+ ...cloneDeep(customStyle),
53
60
  }
54
61
  }
55
62
  }
package/src/options.ts CHANGED
@@ -10,8 +10,8 @@ import GridOptions = Grid.GridOptions
10
10
  export namespace Options {
11
11
  import NodeData = LogicFlow.NodeData
12
12
  import EdgeData = LogicFlow.EdgeData
13
- import ExtensionConstructor = LogicFlow.ExtensionConstructor
14
13
  import GraphData = LogicFlow.GraphData
14
+ import ExtensionType = LogicFlow.ExtensionType
15
15
  export type EdgeType = 'line' | 'polyline' | 'bezier' | string
16
16
  export type BackgroundConfig = {
17
17
  // 背景图片地址
@@ -88,7 +88,7 @@ export namespace Options {
88
88
  guards?: GuardsConfig
89
89
  overlapMode?: OverlapMode
90
90
 
91
- plugins?: ExtensionConstructor[]
91
+ plugins?: ExtensionType[]
92
92
  pluginsOptions?: Record<string, any>
93
93
  disabledPlugins?: string[]
94
94
  disabledTools?: string[]
@@ -111,22 +111,13 @@ export namespace Options {
111
111
  export function get(options: Partial<Manual>) {
112
112
  const { ...others } = options
113
113
  const container = options.container
114
- if (container != null) {
115
- if (options.width == null) {
116
- others.width = container.clientWidth
117
- }
118
- if (options.height == null) {
119
- others.height = container.clientHeight
120
- }
121
- } else {
114
+ if (!container) {
122
115
  throw new Error(
123
116
  'Ensure the container of LogicFlow is specified and valid.',
124
117
  )
125
118
  }
126
119
 
127
- const result = assign({}, defaults, others) as Options.Definition
128
-
129
- return result
120
+ return assign({}, defaults, others) as Options.Definition
130
121
  }
131
122
  }
132
123
 
package/src/tool/tool.ts CHANGED
@@ -3,8 +3,8 @@ import { VNode } from 'preact'
3
3
  import TextEdit from './TextEditTool'
4
4
  import MultipleSelect from './MultipleSelectTool'
5
5
  import LogicFlow from '../LogicFlow'
6
- import { GraphModel, BaseEdgeModel, BaseNodeModel } from '../model'
7
6
  import { ElementState, EventType } from '../constant'
7
+ import { GraphModel, BaseEdgeModel, BaseNodeModel } from '../model'
8
8
 
9
9
  export type IToolProps = {
10
10
  textEditElement?: BaseNodeModel | BaseEdgeModel