@logicflow/core 2.2.0 → 2.2.1

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 (236) hide show
  1. package/dist/index.css +3 -2
  2. package/dist/index.min.js +1 -1
  3. package/dist/index.min.js.map +1 -1
  4. package/es/LogicFlow.d.ts +9 -0
  5. package/es/LogicFlow.js +0 -1
  6. package/es/constant/index.d.ts +1 -1
  7. package/es/constant/index.js +1 -1
  8. package/es/constant/theme.d.ts +136 -0
  9. package/es/constant/theme.js +680 -0
  10. package/es/index.css +3 -2
  11. package/es/model/GraphModel.d.ts +10 -2
  12. package/es/model/GraphModel.js +48 -14
  13. package/es/model/TransformModel.js +9 -9
  14. package/es/model/edge/BaseEdgeModel.js +7 -2
  15. package/es/model/edge/PolylineEdgeModel.d.ts +7 -0
  16. package/es/model/edge/PolylineEdgeModel.js +136 -7
  17. package/es/model/node/BaseNodeModel.d.ts +12 -1
  18. package/es/model/node/BaseNodeModel.js +9 -2
  19. package/es/model/node/HtmlNodeModel.d.ts +12 -0
  20. package/es/model/node/HtmlNodeModel.js +19 -0
  21. package/es/model/node/PolygonNodeModel.js +3 -3
  22. package/es/options.d.ts +4 -2
  23. package/es/style/index.css +3 -2
  24. package/es/style/index.less +3 -2
  25. package/es/style/raw.d.ts +1 -1
  26. package/es/style/raw.js +1 -1
  27. package/es/tool/MultipleSelectTool.js +10 -5
  28. package/es/util/drag.js +0 -1
  29. package/es/util/edge.d.ts +40 -1
  30. package/es/util/edge.js +43 -9
  31. package/es/util/geometry.d.ts +8 -0
  32. package/es/util/geometry.js +79 -0
  33. package/es/util/theme.d.ts +2 -65
  34. package/es/util/theme.js +4 -281
  35. package/es/view/Anchor.d.ts +1 -0
  36. package/es/view/Anchor.js +24 -21
  37. package/es/view/Control.d.ts +5 -0
  38. package/es/view/Control.js +44 -57
  39. package/es/view/edge/BaseEdge.js +9 -0
  40. package/es/view/edge/PolylineEdge.js +13 -2
  41. package/es/view/node/BaseNode.d.ts +1 -0
  42. package/es/view/node/BaseNode.js +23 -11
  43. package/es/view/node/HtmlNode.js +2 -4
  44. package/es/view/overlay/CanvasOverlay.js +5 -2
  45. package/es/view/overlay/Grid.d.ts +12 -1
  46. package/es/view/overlay/Grid.js +85 -23
  47. package/es/view/overlay/OutlineOverlay.d.ts +1 -0
  48. package/es/view/overlay/OutlineOverlay.js +18 -17
  49. package/es/view/overlay/gridConfig.d.ts +46 -0
  50. package/es/view/overlay/gridConfig.js +99 -0
  51. package/es/view/shape/Polygon.d.ts +0 -7
  52. package/es/view/shape/Polygon.js +12 -43
  53. package/lib/LogicFlow.d.ts +9 -0
  54. package/lib/LogicFlow.js +0 -1
  55. package/lib/constant/index.d.ts +1 -1
  56. package/lib/constant/index.js +16 -2
  57. package/lib/constant/theme.d.ts +136 -0
  58. package/lib/constant/theme.js +683 -0
  59. package/lib/index.css +3 -2
  60. package/lib/model/GraphModel.d.ts +10 -2
  61. package/lib/model/GraphModel.js +49 -15
  62. package/lib/model/TransformModel.js +9 -9
  63. package/lib/model/edge/BaseEdgeModel.js +7 -2
  64. package/lib/model/edge/PolylineEdgeModel.d.ts +7 -0
  65. package/lib/model/edge/PolylineEdgeModel.js +136 -7
  66. package/lib/model/node/BaseNodeModel.d.ts +12 -1
  67. package/lib/model/node/BaseNodeModel.js +9 -2
  68. package/lib/model/node/HtmlNodeModel.d.ts +12 -0
  69. package/lib/model/node/HtmlNodeModel.js +19 -0
  70. package/lib/model/node/PolygonNodeModel.js +3 -3
  71. package/lib/options.d.ts +4 -2
  72. package/lib/style/index.css +3 -2
  73. package/lib/style/index.less +3 -2
  74. package/lib/style/raw.d.ts +1 -1
  75. package/lib/style/raw.js +1 -1
  76. package/lib/tool/MultipleSelectTool.js +10 -5
  77. package/lib/util/drag.js +0 -1
  78. package/lib/util/edge.d.ts +40 -1
  79. package/lib/util/edge.js +43 -9
  80. package/lib/util/geometry.d.ts +8 -0
  81. package/lib/util/geometry.js +81 -1
  82. package/lib/util/theme.d.ts +2 -65
  83. package/lib/util/theme.js +15 -292
  84. package/lib/view/Anchor.d.ts +1 -0
  85. package/lib/view/Anchor.js +24 -21
  86. package/lib/view/Control.d.ts +5 -0
  87. package/lib/view/Control.js +44 -57
  88. package/lib/view/edge/BaseEdge.js +9 -0
  89. package/lib/view/edge/PolylineEdge.js +13 -2
  90. package/lib/view/node/BaseNode.d.ts +1 -0
  91. package/lib/view/node/BaseNode.js +22 -10
  92. package/lib/view/node/HtmlNode.js +1 -3
  93. package/lib/view/overlay/CanvasOverlay.js +5 -2
  94. package/lib/view/overlay/Grid.d.ts +12 -1
  95. package/lib/view/overlay/Grid.js +83 -21
  96. package/lib/view/overlay/OutlineOverlay.d.ts +1 -0
  97. package/lib/view/overlay/OutlineOverlay.js +18 -17
  98. package/lib/view/overlay/gridConfig.d.ts +46 -0
  99. package/lib/view/overlay/gridConfig.js +104 -0
  100. package/lib/view/shape/Polygon.d.ts +0 -7
  101. package/lib/view/shape/Polygon.js +13 -45
  102. package/package.json +6 -1
  103. package/.turbo/turbo-build$colon$dev.log +0 -10
  104. package/.turbo/turbo-build.log +0 -33
  105. package/CHANGELOG.md +0 -1849
  106. package/__tests__/algorithm/egde.test.ts +0 -131
  107. package/__tests__/algorithm/index.test.ts +0 -74
  108. package/__tests__/algorithm/outline.test.ts +0 -43
  109. package/__tests__/bugs/1545-spec.test.ts +0 -42
  110. package/__tests__/event/event.test.ts +0 -22
  111. package/__tests__/history/history.test.ts +0 -28
  112. package/__tests__/logicflow.test.ts +0 -575
  113. package/__tests__/model/graphmodel.test.ts +0 -87
  114. package/__tests__/util/compatible.test.ts +0 -48
  115. package/__tests__/util/edge.test.ts +0 -224
  116. package/__tests__/util/geometry.test.ts +0 -14
  117. package/__tests__/util/graph.test.ts +0 -16
  118. package/__tests__/util/matrix.test.ts +0 -41
  119. package/__tests__/util/node.test.ts +0 -68
  120. package/__tests__/util/sampling.test.ts +0 -12
  121. package/__tests__/util/vector.test.ts +0 -50
  122. package/__tests__/util/zIndex.test.ts +0 -10
  123. package/src/LogicFlow.tsx +0 -2008
  124. package/src/algorithm/edge.ts +0 -67
  125. package/src/algorithm/index.ts +0 -70
  126. package/src/algorithm/outline.ts +0 -77
  127. package/src/algorithm/rotate.ts +0 -55
  128. package/src/common/drag.ts +0 -219
  129. package/src/common/history.ts +0 -108
  130. package/src/common/index.ts +0 -6
  131. package/src/common/keyboard.ts +0 -108
  132. package/src/common/matrix.ts +0 -122
  133. package/src/common/vector.ts +0 -93
  134. package/src/constant/index.ts +0 -179
  135. package/src/event/event.md +0 -66
  136. package/src/event/eventArgs.ts +0 -643
  137. package/src/event/eventEmitter.ts +0 -156
  138. package/src/history/index.ts +0 -119
  139. package/src/index.less +0 -1
  140. package/src/index.ts +0 -26
  141. package/src/keyboard/index.ts +0 -112
  142. package/src/keyboard/shortcut.ts +0 -200
  143. package/src/model/BaseModel.ts +0 -250
  144. package/src/model/EditConfigModel.ts +0 -334
  145. package/src/model/GraphModel.ts +0 -1788
  146. package/src/model/NestedTransformModel.ts +0 -121
  147. package/src/model/SnaplineModel.ts +0 -256
  148. package/src/model/TransformModel.ts +0 -258
  149. package/src/model/edge/BaseEdgeModel.ts +0 -777
  150. package/src/model/edge/BezierEdgeModel.ts +0 -197
  151. package/src/model/edge/LineEdgeModel.ts +0 -36
  152. package/src/model/edge/PolylineEdgeModel.ts +0 -672
  153. package/src/model/edge/index.ts +0 -4
  154. package/src/model/index.ts +0 -9
  155. package/src/model/node/BaseNodeModel.ts +0 -949
  156. package/src/model/node/CircleNodeModel.ts +0 -91
  157. package/src/model/node/DiamondNodeModel.ts +0 -132
  158. package/src/model/node/EllipseNodeModel.ts +0 -98
  159. package/src/model/node/HtmlNodeModel.ts +0 -50
  160. package/src/model/node/PolygonNodeModel.ts +0 -150
  161. package/src/model/node/RectNodeModel.ts +0 -69
  162. package/src/model/node/TextNodeModel.ts +0 -54
  163. package/src/model/node/index.ts +0 -8
  164. package/src/options.ts +0 -145
  165. package/src/style/index.less +0 -261
  166. package/src/style/raw.ts +0 -220
  167. package/src/tool/MultipleSelectTool.tsx +0 -132
  168. package/src/tool/TextEditTool.tsx +0 -193
  169. package/src/tool/index.ts +0 -101
  170. package/src/typings.d.ts +0 -5
  171. package/src/util/animation.ts +0 -29
  172. package/src/util/browser.ts +0 -4
  173. package/src/util/compatible.ts +0 -15
  174. package/src/util/drag.ts +0 -220
  175. package/src/util/edge.ts +0 -1060
  176. package/src/util/geometry.ts +0 -55
  177. package/src/util/graph.ts +0 -46
  178. package/src/util/index.ts +0 -17
  179. package/src/util/matrix.ts +0 -129
  180. package/src/util/mobx.ts +0 -23
  181. package/src/util/node.ts +0 -543
  182. package/src/util/raf.ts +0 -28
  183. package/src/util/resize.ts +0 -606
  184. package/src/util/sampling.ts +0 -85
  185. package/src/util/theme.ts +0 -375
  186. package/src/util/uuid.ts +0 -26
  187. package/src/util/vector.ts +0 -93
  188. package/src/util/zIndex.ts +0 -6
  189. package/src/view/Anchor.tsx +0 -445
  190. package/src/view/Control.tsx +0 -512
  191. package/src/view/Graph.tsx +0 -141
  192. package/src/view/Rotate.tsx +0 -113
  193. package/src/view/behavior/dnd.ts +0 -162
  194. package/src/view/behavior/index.ts +0 -2
  195. package/src/view/behavior/snapline.ts +0 -16
  196. package/src/view/edge/AdjustPoint.tsx +0 -425
  197. package/src/view/edge/Arrow.tsx +0 -54
  198. package/src/view/edge/BaseEdge.tsx +0 -650
  199. package/src/view/edge/BezierEdge.tsx +0 -101
  200. package/src/view/edge/LineEdge.tsx +0 -81
  201. package/src/view/edge/PolylineEdge.tsx +0 -299
  202. package/src/view/edge/index.ts +0 -6
  203. package/src/view/index.ts +0 -8
  204. package/src/view/node/BaseNode.tsx +0 -571
  205. package/src/view/node/CircleNode.tsx +0 -21
  206. package/src/view/node/DiamondNode.tsx +0 -24
  207. package/src/view/node/EllipseNode.tsx +0 -22
  208. package/src/view/node/HtmlNode.tsx +0 -95
  209. package/src/view/node/PolygonNode.tsx +0 -28
  210. package/src/view/node/RectNode.tsx +0 -30
  211. package/src/view/node/TextNode.tsx +0 -39
  212. package/src/view/node/index.ts +0 -8
  213. package/src/view/overlay/BackgroundOverlay.tsx +0 -34
  214. package/src/view/overlay/BezierAdjustOverlay.tsx +0 -150
  215. package/src/view/overlay/CanvasOverlay.tsx +0 -288
  216. package/src/view/overlay/Grid.tsx +0 -162
  217. package/src/view/overlay/ModificationOverlay.tsx +0 -31
  218. package/src/view/overlay/OutlineOverlay.tsx +0 -170
  219. package/src/view/overlay/SnaplineOverlay.tsx +0 -44
  220. package/src/view/overlay/ToolOverlay.tsx +0 -65
  221. package/src/view/overlay/getTransformHoc.tsx +0 -50
  222. package/src/view/overlay/index.ts +0 -8
  223. package/src/view/shape/Circle.tsx +0 -41
  224. package/src/view/shape/Ellipse.tsx +0 -42
  225. package/src/view/shape/Line.tsx +0 -39
  226. package/src/view/shape/Path.tsx +0 -22
  227. package/src/view/shape/Polygon.tsx +0 -91
  228. package/src/view/shape/Polyline.tsx +0 -31
  229. package/src/view/shape/Rect.tsx +0 -44
  230. package/src/view/shape/Text.tsx +0 -169
  231. package/src/view/shape/index.ts +0 -8
  232. package/src/view/text/BaseText.tsx +0 -134
  233. package/src/view/text/LineText.tsx +0 -168
  234. package/src/view/text/index.ts +0 -2
  235. package/stats.html +0 -4842
  236. package/tsconfig.json +0 -18
package/src/LogicFlow.tsx DELETED
@@ -1,2008 +0,0 @@
1
- import { ComponentType, createElement as h, render } from 'preact/compat'
2
- import { cloneDeep, forEach, indexOf, isNil } from 'lodash-es'
3
- import { observer } from '.'
4
- import { Options as LFOptions } from './options'
5
- import * as _Model from './model'
6
- import {
7
- BaseEdgeModel,
8
- BaseNodeModel,
9
- IEditConfigType,
10
- GraphModel,
11
- SnaplineModel,
12
- ZoomParamType,
13
- } from './model'
14
-
15
- import Graph from './view/Graph'
16
- import * as _View from './view'
17
- import {
18
- formatData,
19
- addThemeMode,
20
- removeThemeMode,
21
- clearThemeMode,
22
- } from './util'
23
-
24
- import { Dnd, snapline } from './view/behavior'
25
- import Tool from './tool'
26
- import History from './history'
27
- import Keyboard, { initDefaultShortcut } from './keyboard'
28
- import { EventCallback, CallbackArgs, EventArgs } from './event/eventEmitter'
29
- import {
30
- ElementType,
31
- EventType,
32
- OverlapMode,
33
- SegmentDirection,
34
- } from './constant'
35
- import { Grid } from './view/overlay'
36
-
37
- import Extension = LogicFlow.Extension
38
- import ExtensionConfig = LogicFlow.ExtensionConfig
39
- import ExtensionConstructor = LogicFlow.ExtensionConstructor
40
- import GraphConfigData = LogicFlow.GraphConfigData
41
- import NodeConfig = LogicFlow.NodeConfig
42
- import EdgeConfig = LogicFlow.EdgeConfig
43
- import GraphData = LogicFlow.GraphData
44
- import NodeData = LogicFlow.NodeData
45
- import EdgeData = LogicFlow.EdgeData
46
- import RegisterConfig = LogicFlow.RegisterConfig
47
- import RegisterParam = LogicFlow.RegisterParam
48
- import GraphElements = LogicFlow.GraphElements
49
- import Position = LogicFlow.Position
50
- import PointTuple = LogicFlow.PointTuple
51
- import ExtensionRenderFunc = LogicFlow.ExtensionRenderFunc
52
- import RegisterElementFunc = LogicFlow.RegisterElementFunc
53
- import PropertiesType = LogicFlow.PropertiesType
54
- import BaseNodeModelCtor = LogicFlow.BaseNodeModelCtor
55
- import ClientPosition = LogicFlow.ClientPosition
56
- import ExtensionDefinition = LogicFlow.ExtensionDefinition
57
- import ExtensionType = LogicFlow.ExtensionType
58
-
59
- const pluginFlag = Symbol('plugin registered by Logicflow.use')
60
-
61
- export class LogicFlow {
62
- // 只读:logicflow实例挂载的容器。
63
- readonly container: HTMLElement
64
- // 只读:logicflow实例的配置
65
- readonly options: LFOptions.Definition
66
- // 只读:控制整个 LogicFlow 画布的model
67
- readonly graphModel: GraphModel
68
-
69
- viewMap: Map<string, ComponentType> = new Map()
70
- history: History
71
- keyboard: Keyboard
72
- dnd: Dnd
73
- tool: Tool
74
- snaplineModel?: SnaplineModel
75
-
76
- components: ExtensionRenderFunc[] = []
77
- // 个性配置的插件,覆盖全局配置的插件
78
- readonly plugins: ExtensionType[]
79
- // 全局配置的插件,所有的LogicFlow示例都会使用
80
- static extensions: Map<string, ExtensionConfig> = new Map()
81
- // 插件扩展方法
82
- extension: Record<string, Extension | ExtensionDefinition> = {}
83
-
84
- readonly width?: number // 只读:画布宽度
85
- readonly height?: number // 只读:画布高度
86
- /**
87
- * 自定义数据转换方法
88
- * 当接入系统格式和 LogicFlow 数据格式不一致时,可自定义此方法来进行数据格式转换
89
- * 详情请参考 adapter docs
90
- * 包括 adapterIn 和 adapterOut 两个方法
91
- */
92
- // TODO: 如何让用户执行时定义下面方法参数和返回值的类型
93
- adapterIn?: (data: unknown) => GraphData
94
- adapterOut?: (data: GraphData, ...rest: any) => unknown;
95
-
96
- // 支持插件在 LogicFlow 实例上增加自定义方法
97
- [propName: string]: any
98
-
99
- private initContainer(
100
- container: HTMLElement | HTMLDivElement,
101
- width?: number,
102
- height?: number,
103
- ) {
104
- // TODO: 确认是否需要,后续是否只要返回 container 即可(下面方法是为了解决事件绑定问题的)
105
- // fix: destroy keyboard events while destroy LogicFlow.(#1110)
106
- const lfContainer = document.createElement('div')
107
- lfContainer.style.position = 'relative'
108
- lfContainer.style.width = width ? `${width}px` : '100%'
109
- lfContainer.style.height = height ? `${height}px` : '100%'
110
- container.innerHTML = ''
111
- container.appendChild(lfContainer)
112
- return lfContainer
113
- }
114
-
115
- protected get [Symbol.toStringTag]() {
116
- return LogicFlow.toStringTag
117
- }
118
-
119
- constructor(options: LFOptions.Common) {
120
- const initOptions = LFOptions.get(options)
121
- const { container, width, height } = initOptions
122
- this.options = initOptions
123
- this.container = this.initContainer(container, width, height)
124
- this.graphModel = new GraphModel({
125
- ...initOptions,
126
- container: this.container, // TODO:测试该部分是否会有问题
127
- })
128
-
129
- this.plugins = initOptions.plugins ?? []
130
-
131
- const { eventCenter } = this.graphModel
132
- this.tool = new Tool(this)
133
- this.dnd = new Dnd({ lf: this })
134
- this.history = new History(eventCenter)
135
- this.keyboard = new Keyboard({
136
- lf: this,
137
- keyboard: initOptions.keyboard,
138
- })
139
-
140
- if (initOptions.snapline !== false) {
141
- this.snaplineModel = new SnaplineModel(
142
- this.graphModel,
143
- initOptions.snaplineEpsilon,
144
- )
145
- snapline(eventCenter, this.snaplineModel)
146
- }
147
- if (!initOptions.isSilentMode) {
148
- // 先初始化默认内置快捷键,自定义快捷键可以覆盖默认快捷键
149
- initDefaultShortcut(this, this.graphModel)
150
- // 然后再初始化自定义快捷键,自定义快捷键可以覆盖默认快捷键.
151
- // 插件最后初始化。方便插件强制覆盖内置快捷键
152
- this.keyboard.initShortcuts()
153
- }
154
-
155
- this.defaultRegister()
156
- this.installPlugins(initOptions.disabledPlugins)
157
- }
158
-
159
- /*********************************************************
160
- * Register 相关
161
- ********************************************************/
162
- private setView = (type: string, component: ComponentType) =>
163
- this.viewMap.set(type, component)
164
- // 根据 type 获取对应的 view
165
- private getView = (type: string): ComponentType | undefined =>
166
- this.viewMap.get(type)
167
-
168
- // register 方法重载
169
- register(element: RegisterConfig): void
170
- register(
171
- type: string,
172
- fn: RegisterElementFunc,
173
- isObserverView?: boolean,
174
- ): void
175
- /**
176
- * 注册自定义节点和边
177
- * 支持两种方式
178
- * 方式一(推荐)
179
- * 详情见 todo: docs link
180
- * @example
181
- * import { RectNode, RectModel } from '@logicflow/core'
182
- * class CustomView extends RectNode {
183
- * }
184
- * class CustomModel extends RectModel {
185
- * }
186
- * lf.register({
187
- * type: 'custom',
188
- * view: CustomView,
189
- * model: CustomModel
190
- * })
191
- * 方式二
192
- * 不推荐,极个别在自定义的时候需要用到lf的情况下可以用这种方式。
193
- * 大多数情况下,我们可以直接在view中从this.props中获取graphModel
194
- * 或者model中直接this.graphModel获取model的方法。
195
- * @example
196
- * lf.register('custom', ({ RectNode, RectModel }) => {
197
- * class CustomView extends RectNode {}
198
- * class CustomModel extends RectModel {}
199
- * return {
200
- * view: CustomView,
201
- * model: CustomModel
202
- * }
203
- * })
204
- */
205
- register(
206
- element: string | RegisterConfig,
207
- fn?: RegisterElementFunc,
208
- isObserverView = true,
209
- ) {
210
- // 方式1
211
- if (typeof element !== 'string') {
212
- this.registerElement(element)
213
- return
214
- }
215
-
216
- // 方式2 TODO: 优化下面这段代码,没太看懂这一块的背景
217
- const registerParam: RegisterParam = {
218
- BaseEdge: _View.BaseEdge,
219
- BaseEdgeModel: _Model.BaseEdgeModel,
220
- BaseNode: _View.BaseNode,
221
- BaseNodeModel: _Model.BaseNodeModel,
222
- RectNode: _View.RectNode,
223
- RectNodeModel: _Model.RectNodeModel,
224
- CircleNode: _View.CircleNode,
225
- CircleNodeModel: _Model.CircleNodeModel,
226
- PolygonNode: _View.PolygonNode,
227
- PolygonNodeModel: _Model.PolygonNodeModel,
228
- TextNode: _View.TextNode,
229
- TextNodeModel: _Model.TextNodeModel,
230
- LineEdge: _View.LineEdge,
231
- LineEdgeModel: _Model.LineEdgeModel,
232
- DiamondNode: _View.DiamondNode,
233
- DiamondNodeModel: _Model.DiamondNodeModel,
234
- PolylineEdge: _View.PolylineEdge,
235
- PolylineEdgeModel: _Model.PolylineEdgeModel,
236
- BezierEdge: _View.BezierEdge,
237
- BezierEdgeModel: _Model.BezierEdgeModel,
238
- EllipseNode: _View.EllipseNode,
239
- EllipseNodeModel: _Model.EllipseNodeModel,
240
- HtmlNode: _View.HtmlNode,
241
- HtmlNodeModel: _Model.HtmlNodeModel,
242
- // mobx,
243
- h,
244
- type: element,
245
- }
246
- // 为了能让后来注册的可以继承前面注册的
247
- // 例如我注册一个“开始节点”
248
- // 然后我再想注册一个“立即开始节点”
249
- // 注册传递参数改为动态。
250
- // TODO: 确定 extendKey 的作用
251
- this.viewMap.forEach((component) => {
252
- const key = (component as any).extendKey
253
- if (key) {
254
- registerParam[key] = component
255
- }
256
- })
257
- this.graphModel.modelMap.forEach((component) => {
258
- const key = (component as any).extendKey
259
- if (key) {
260
- registerParam[key as string] = component
261
- }
262
- })
263
- if (fn) {
264
- const { view: ViewClass, model: ModelClass } = fn(registerParam)
265
- let vClass = ViewClass as any // TODO: 确认 ViewClass 类型
266
- if (isObserverView && !vClass.isObserved) {
267
- vClass.isObserved = true
268
- vClass = observer(vClass)
269
- }
270
- this.setView(element, vClass)
271
- this.graphModel.setModel(element, ModelClass)
272
- }
273
- }
274
-
275
- /**
276
- * 注册元素(节点 or 边)
277
- * @param config 注册元素的配置项
278
- * @private
279
- */
280
- private registerElement(config: RegisterConfig) {
281
- let ViewComp = config.view
282
-
283
- if (config.isObserverView !== false && !ViewComp.isObserved) {
284
- ViewComp.isObserved = true
285
- ViewComp = observer(ViewComp)
286
- }
287
-
288
- this.setView(config.type, ViewComp)
289
- this.graphModel.setModel(config.type, config.model)
290
- }
291
-
292
- /**
293
- * 批量注册元素
294
- * @param elements 注册的元素
295
- */
296
- batchRegister(elements: RegisterConfig[] = []) {
297
- forEach(elements, (element) => {
298
- this.registerElement(element)
299
- })
300
- }
301
-
302
- private defaultRegister() {
303
- // LogicFlow default Nodes and Edges
304
- const defaultElements: RegisterConfig[] = [
305
- // Node
306
- {
307
- type: 'rect',
308
- view: _View.RectNode,
309
- model: _Model.RectNodeModel,
310
- },
311
- {
312
- type: 'circle',
313
- view: _View.CircleNode,
314
- model: _Model.CircleNodeModel,
315
- },
316
- {
317
- type: 'polygon',
318
- view: _View.PolygonNode,
319
- model: _Model.PolygonNodeModel,
320
- },
321
- {
322
- type: 'text',
323
- view: _View.TextNode,
324
- model: _Model.TextNodeModel,
325
- },
326
- {
327
- type: 'ellipse',
328
- view: _View.EllipseNode,
329
- model: _Model.EllipseNodeModel,
330
- },
331
- {
332
- type: 'diamond',
333
- view: _View.DiamondNode,
334
- model: _Model.DiamondNodeModel,
335
- },
336
- {
337
- type: 'html',
338
- view: _View.HtmlNode,
339
- model: _Model.HtmlNodeModel,
340
- },
341
- // Edge
342
- {
343
- type: 'line',
344
- view: _View.LineEdge,
345
- model: _Model.LineEdgeModel,
346
- },
347
- {
348
- type: 'polyline',
349
- view: _View.PolylineEdge,
350
- model: _Model.PolylineEdgeModel,
351
- },
352
- {
353
- type: 'bezier',
354
- view: _View.BezierEdge,
355
- model: _Model.BezierEdgeModel,
356
- },
357
- ]
358
- this.batchRegister(defaultElements)
359
- }
360
-
361
- /*********************************************************
362
- * Node 相关方法
363
- ********************************************************/
364
- /**
365
- * 添加节点
366
- * @param nodeConfig 节点配置
367
- * @param eventType 新增节点事件类型,默认EventType.NODE_ADD
368
- * @param e MouseEvent 事件
369
- */
370
- addNode(
371
- nodeConfig: NodeConfig,
372
- eventType: EventType = EventType.NODE_ADD,
373
- e?: MouseEvent,
374
- ): BaseNodeModel {
375
- return this.graphModel.addNode(nodeConfig, eventType, e)
376
- }
377
-
378
- /**
379
- * 删除节点
380
- * @param {string} nodeId 节点Id
381
- */
382
- deleteNode(nodeId: string): boolean {
383
- const nodeModel = this.graphModel.getNodeModelById(nodeId)
384
- if (!nodeModel) return false
385
-
386
- const nodeData = nodeModel.getData()
387
- const { guards } = this.options
388
- const isEnableDelete = guards?.beforeDelete
389
- ? guards.beforeDelete(nodeData)
390
- : true
391
- if (isEnableDelete) {
392
- this.graphModel.deleteNode(nodeId)
393
- }
394
- return isEnableDelete
395
- }
396
-
397
- /**
398
- * 克隆节点
399
- * @param nodeId 节点Id
400
- */
401
- cloneNode(nodeId: string): NodeData | undefined {
402
- const nodeModel = this.graphModel.getNodeModelById(nodeId)
403
- const nodeData = nodeModel?.getData()
404
-
405
- if (nodeData) {
406
- const { guards } = this.options
407
- const isEnableClone = guards?.beforeClone
408
- ? guards.beforeClone(nodeData)
409
- : true
410
- if (isEnableClone) {
411
- return this.graphModel.cloneNode(nodeId)
412
- }
413
- }
414
- }
415
-
416
- /**
417
- * 修改节点的id,如果不传新的id,会内部自动创建一个。
418
- * @param { string } nodeId 将要被修改的id
419
- * @param { string } newId 可选,修改后的id
420
- * @returns 修改后的节点id, 如果传入的oldId不存在,返回空字符串
421
- */
422
- changeNodeId(nodeId: string, newId?: string): string {
423
- return this.graphModel.changeNodeId(nodeId, newId)
424
- }
425
-
426
- /**
427
- * 修改指定节点类型
428
- * @param nodeId 节点id
429
- * @param type 节点类型
430
- */
431
- changeNodeType(nodeId: string, type: string): void {
432
- this.graphModel.changeNodeType(nodeId, type)
433
- }
434
-
435
- /**
436
- * 获取节点对象
437
- * @param nodeId 节点Id
438
- */
439
- getNodeModelById(nodeId: string): BaseNodeModel | undefined {
440
- return this.graphModel.getNodeModelById(nodeId)
441
- }
442
-
443
- /**
444
- * 获取节点数据
445
- * @param nodeId 节点
446
- */
447
- getNodeDataById(nodeId: string): NodeData | undefined {
448
- const nodeModel = this.getNodeModelById(nodeId)
449
- return nodeModel?.getData()
450
- }
451
-
452
- /**
453
- * 获取所有以此节点为终点的边
454
- * @param { string } nodeId
455
- */
456
- getNodeIncomingEdge(nodeId: string) {
457
- return this.graphModel.getNodeIncomingEdge(nodeId)
458
- }
459
-
460
- /**
461
- * 获取所有以此节点为起点的边
462
- * @param {string} nodeId
463
- */
464
- getNodeOutgoingEdge(nodeId: string) {
465
- return this.graphModel.getNodeOutgoingEdge(nodeId)
466
- }
467
-
468
- /**
469
- * 获取节点连接到的所有起始节点
470
- * @param {string} nodeId
471
- */
472
- getNodeIncomingNode(nodeId: string) {
473
- return this.graphModel.getNodeIncomingNode(nodeId)
474
- }
475
-
476
- /**
477
- * 获取节点连接到的所有目标节点
478
- * @param {string} nodeId
479
- */
480
- getNodeOutgoingNode(nodeId: string) {
481
- return this.graphModel.getNodeOutgoingNode(nodeId)
482
- }
483
-
484
- /**
485
- * 内部保留方法
486
- * 创建一个fakeNode,用于dnd插件拖动节点进画布的时候使用。
487
- */
488
- createFakeNode(nodeConfig: NodeConfig) {
489
- const Model = this.graphModel.modelMap.get(
490
- nodeConfig.type,
491
- ) as BaseNodeModelCtor
492
- if (!Model) {
493
- console.warn(`不存在为${nodeConfig.type}类型的节点`)
494
- return null
495
- }
496
- // * initNodeData区分是否为虚拟节点
497
- const fakeNodeModel = new Model(
498
- {
499
- ...nodeConfig,
500
- virtual: true,
501
- },
502
- this.graphModel,
503
- )
504
- this.graphModel.setFakeNode(fakeNodeModel)
505
- return fakeNodeModel
506
- }
507
-
508
- /**
509
- * 内部保留方法
510
- * 移除fakeNode
511
- */
512
- removeFakeNode() {
513
- this.graphModel.removeFakeNode()
514
- }
515
-
516
- /**
517
- * 内部保留方法
518
- * 用于fakeNode显示对齐线
519
- */
520
- setNodeSnapLine(data: NodeData) {
521
- this.snaplineModel?.setNodeSnapLine(data)
522
- }
523
-
524
- /**
525
- * 内部保留方法
526
- * 用于fakeNode移除对齐线
527
- */
528
- removeNodeSnapLine() {
529
- this.snaplineModel?.clearSnapline()
530
- }
531
-
532
- /*********************************************************
533
- * Edge 相关方法
534
- ********************************************************/
535
- /**
536
- * 设置默认的边类型。
537
- * 也就是设置在节点直接由用户手动绘制的连线类型。
538
- * @param type LFOptions.EdgeType
539
- */
540
- setDefaultEdgeType(type: LFOptions.EdgeType): void {
541
- this.graphModel.setDefaultEdgeType(type)
542
- }
543
-
544
- /**
545
- * 给两个节点之间添加一条边
546
- * @example
547
- * lf.addEdge({
548
- * type: 'polygon'
549
- * sourceNodeId: 'node_id_1',
550
- * targetNodeId: 'node_id_2',
551
- * })
552
- * @param {EdgeConfig} edgeConfig
553
- */
554
- addEdge(edgeConfig: EdgeConfig): BaseEdgeModel {
555
- return this.graphModel.addEdge(edgeConfig)
556
- }
557
-
558
- /**
559
- * 基于id获取边数据
560
- * @param edgeId 边Id
561
- * @returns EdgeData
562
- */
563
- getEdgeDataById(edgeId: string): EdgeData | undefined {
564
- const edgeModel = this.getEdgeModelById(edgeId)
565
- return edgeModel?.getData()
566
- }
567
-
568
- /**
569
- * 基于边Id获取边的model
570
- * @param edgeId 边的Id
571
- * @return model
572
- */
573
- getEdgeModelById(edgeId: string): BaseEdgeModel | undefined {
574
- return this.graphModel.getEdgeModelById(edgeId)
575
- }
576
-
577
- /**
578
- * 获取满足条件边的model
579
- * @param edgeFilter 过滤条件
580
- * @example
581
- * 获取所有起点为节点 A 的边的 model
582
- * lf.getEdgeModels({
583
- * sourceNodeId: 'nodeA_id'
584
- * })
585
- * 获取所有终点为节点 B 的边的 model
586
- * lf.getEdgeModels({
587
- * targetNodeId: 'nodeB_id'
588
- * })
589
- * 获取起点为节点 A,终点为节点 B 的边
590
- * lf.getEdgeModels({
591
- * sourceNodeId: 'nodeA_id',
592
- * targetNodeId: 'nodeB_id'
593
- * })
594
- * @return model数组
595
- */
596
- getEdgeModels({
597
- sourceNodeId,
598
- targetNodeId,
599
- }: {
600
- sourceNodeId?: string
601
- targetNodeId?: string
602
- }): BaseEdgeModel[] {
603
- const results: BaseEdgeModel[] = []
604
- const { edges } = this.graphModel
605
- if (sourceNodeId && targetNodeId) {
606
- forEach(edges, (edge) => {
607
- if (
608
- edge.sourceNodeId === sourceNodeId &&
609
- edge.targetNodeId === targetNodeId
610
- ) {
611
- results.push(edge)
612
- }
613
- })
614
- } else if (sourceNodeId) {
615
- forEach(edges, (edge) => {
616
- if (edge.sourceNodeId === sourceNodeId) {
617
- results.push(edge)
618
- }
619
- })
620
- } else if (targetNodeId) {
621
- forEach(edges, (edge) => {
622
- if (edge.targetNodeId === targetNodeId) {
623
- results.push(edge)
624
- }
625
- })
626
- }
627
- return results
628
- }
629
-
630
- /**
631
- * 修改边的id, 如果不传新的id,会内部自动创建一个。
632
- * @param { string } edgeId 将要被修改的id
633
- * @param { string } newId 可选,修改后的id
634
- * @returns 修改后的节点id, 如果传入的oldId不存在,返回空字符串
635
- */
636
- changeEdgeId(edgeId: string, newId?: string): string {
637
- return this.graphModel.changeEdgeId(edgeId, newId)
638
- }
639
-
640
- /**
641
- * 切换边的类型
642
- * @param edgeId 边Id
643
- * @param type 边类型
644
- */
645
- changeEdgeType(edgeId: string, type: LFOptions.EdgeType): void {
646
- this.graphModel.changeEdgeType(edgeId, type)
647
- }
648
-
649
- /**
650
- * 删除边
651
- * @param {string} edgeId 边Id
652
- */
653
- deleteEdge(edgeId: string): boolean {
654
- const edgeModel = this.graphModel.getEdgeModelById(edgeId)
655
- if (!edgeModel) return false
656
-
657
- const edgeData = edgeModel.getData()
658
- const { guards } = this.options
659
- const isEnableDelete = guards?.beforeDelete
660
- ? guards.beforeDelete(edgeData)
661
- : true
662
- if (isEnableDelete) {
663
- this.graphModel.deleteEdgeById(edgeId)
664
- }
665
- return isEnableDelete
666
- }
667
-
668
- /**
669
- * 基于给定节点(作为边起点或终点,可以只传其一),删除对应的边
670
- * @param sourceNodeId 边的起点节点ID
671
- * @param targetNodeId 边的终点节点ID
672
- */
673
- deleteEdgeByNodeId({
674
- sourceNodeId,
675
- targetNodeId,
676
- }: {
677
- sourceNodeId?: string
678
- targetNodeId?: string
679
- }): void {
680
- // TODO: 将下面方法从 this.graphModel 解构,并测试代码功能是否正常(需要确认 this 指向是否有异常)
681
- if (sourceNodeId && targetNodeId) {
682
- this.graphModel.deleteEdgeBySourceAndTarget(sourceNodeId, targetNodeId)
683
- } else if (sourceNodeId) {
684
- this.graphModel.deleteEdgeBySource(sourceNodeId)
685
- } else if (targetNodeId) {
686
- this.graphModel.deleteEdgeByTarget(targetNodeId)
687
- }
688
- }
689
-
690
- /**
691
- * 获取节点连接的所有边的model
692
- * @param nodeId 节点ID
693
- * @returns model数组
694
- */
695
- getNodeEdges(nodeId: string): BaseEdgeModel[] {
696
- return this.graphModel.getNodeEdges(nodeId)
697
- }
698
-
699
- /*********************************************************
700
- * Element 相关方法
701
- ********************************************************/
702
- /**
703
- * 添加多个元素, 包括边和节点。
704
- * @param nodes
705
- * @param edges
706
- * @param distance
707
- */
708
- addElements({ nodes, edges }: GraphConfigData, distance = 40): GraphElements {
709
- // TODO: 1. 解决下面方法中 distance 传参缺未使用的问题;该方法在快捷键中有调用
710
- // TODO: 2. review 一下本函数代码逻辑,确认 nodeIdMap 的作用,看是否有优化的空间
711
- console.log('distance', distance)
712
- const nodeIdMap: Record<string, string> = {}
713
- const elements: GraphElements = {
714
- nodes: [],
715
- edges: [],
716
- }
717
- forEach(nodes, (node) => {
718
- const nodeId = node.id
719
- const nodeModel = this.addNode(node)
720
- if (nodeId) nodeIdMap[nodeId] = nodeModel.id
721
- elements.nodes.push(nodeModel)
722
- })
723
- forEach(edges, (edge) => {
724
- let { sourceNodeId, targetNodeId } = edge
725
- if (nodeIdMap[sourceNodeId]) sourceNodeId = nodeIdMap[sourceNodeId]
726
- if (nodeIdMap[targetNodeId]) targetNodeId = nodeIdMap[targetNodeId]
727
- const edgeModel = this.graphModel.addEdge({
728
- ...edge,
729
- sourceNodeId,
730
- targetNodeId,
731
- })
732
- elements.edges.push(edgeModel)
733
- })
734
- return elements
735
- }
736
-
737
- /**
738
- * 将图形选中
739
- * @param id 选择元素ID
740
- * @param multiple 是否允许多选,如果为true,不会将上一个选中的元素重置
741
- * @param toFront 是否将选中的元素置顶,默认为true
742
- */
743
- selectElementById(id: string, multiple = false, toFront = true) {
744
- this.graphModel.selectElementById(id, multiple)
745
- if (!multiple && toFront) {
746
- this.graphModel.toFront(id)
747
- }
748
- }
749
-
750
- /**
751
- * 移除选中的元素
752
- * @param id 元素ID
753
- */
754
- deselectElementById(id: string) {
755
- this.graphModel.deselectElementById(id)
756
- }
757
-
758
- /**
759
- * 获取选中的元素数据
760
- * @param isIgnoreCheck 是否包括sourceNode和targetNode没有被选中的边,默认包括。
761
- * 注意:复制的时候不能包括此类边, 因为复制的时候不允许悬空的边。
762
- */
763
- getSelectElements(isIgnoreCheck = true): GraphData {
764
- return this.graphModel.getSelectElements(isIgnoreCheck)
765
- }
766
-
767
- /**
768
- * 将所有选中的元素设置为非选中
769
- */
770
- clearSelectElements() {
771
- this.graphModel.clearSelectElements()
772
- }
773
-
774
- /**
775
- * 获取节点或边对象
776
- * @param id id
777
- */
778
- getModelById(id: string): LogicFlow.GraphElement | undefined {
779
- return this.graphModel.getElement(id)
780
- }
781
-
782
- /**
783
- * 获取节点或边的数据
784
- * @param id id
785
- */
786
- getDataById(id: string): NodeData | EdgeData | undefined {
787
- return this.graphModel.getElement(id)?.getData()
788
- }
789
-
790
- /**
791
- * 删除元素,在不确定当前id是节点还是边时使用
792
- * @param id 元素id
793
- */
794
- deleteElement(id: string): boolean {
795
- const model = this.getModelById(id)
796
- if (!model) return false
797
-
798
- const callback = {
799
- [ElementType.NODE]: this.deleteNode,
800
- [ElementType.EDGE]: this.deleteEdge,
801
- }
802
- return callback[model.BaseType]?.call(this, id) ?? false
803
- }
804
-
805
- /**
806
- * 设置元素的zIndex.
807
- * 注意:默认堆叠模式下,不建议使用此方法。
808
- * @see todo link 堆叠模式
809
- * @param id 元素id
810
- * @param zIndex zIndex的值,可以传数字,也支持传入 'top' 和 'bottom'
811
- */
812
- setElementZIndex(id: string, zIndex: number | 'top' | 'bottom') {
813
- return this.graphModel.setElementZIndex(id, zIndex)
814
- }
815
-
816
- /**
817
- * 获取指定区域内的所有元素,此区域必须是DOM层。
818
- * 例如鼠标绘制选区后,获取选区内的所有元素。
819
- * @see todo 分层
820
- * @param leftTopPoint 区域左上角坐标, dom层坐标
821
- * @param rightBottomPoint 区域右下角坐标,dom层坐标
822
- * @param wholeEdge
823
- * @param wholeNode
824
- * @param ignoreHideElement
825
- */
826
- getAreaElement(
827
- leftTopPoint: PointTuple,
828
- rightBottomPoint: PointTuple,
829
- wholeEdge = true,
830
- wholeNode = true,
831
- ignoreHideElement = false,
832
- ) {
833
- return this.graphModel
834
- .getAreaElement(
835
- leftTopPoint,
836
- rightBottomPoint,
837
- wholeEdge,
838
- wholeNode,
839
- ignoreHideElement,
840
- )
841
- .map((element) => element.getData())
842
- }
843
-
844
- /**
845
- * 设置元素的自定义属性
846
- * @see http://logicflow.cn/api/detail#setproperties
847
- * @param id 元素的id
848
- * @param properties 自定义属性
849
- */
850
- setProperties(id: string, properties: PropertiesType): void {
851
- this.graphModel.getElement(id)?.setProperties(formatData(properties))
852
- }
853
-
854
- /**
855
- * 获取元素的自定义属性
856
- * @param id 元素的id
857
- * @returns 自定义属性
858
- */
859
- getProperties(id: string): PropertiesType | undefined {
860
- return this.graphModel.getElement(id)?.getProperties()
861
- }
862
-
863
- deleteProperty(id: string, key: string): void {
864
- this.graphModel.getElement(id)?.deleteProperty(key)
865
- }
866
-
867
- /**
868
- * FBI WARNING !!! 慎用 === 不要用
869
- * 修改对应元素 model 中的属性
870
- * 注意:此方法慎用,除非您对logicflow内部有足够的了解。
871
- * 大多数情况下,请使用setProperties、updateText、changeNodeId等方法。
872
- * 例如直接使用此方法修改节点的id,那么就是会导致连接到此节点的边的sourceNodeId出现找不到的情况。
873
- * @param {string} id 元素id
874
- * @param {object} attributes 需要更新的属性
875
- */
876
- updateAttributes(id: string, attributes: object) {
877
- this.graphModel.updateAttributes(id, attributes)
878
- }
879
-
880
- /*********************************************************
881
- * Text 相关方法
882
- ********************************************************/
883
- /**
884
- * 显示节点、连线文本编辑框
885
- * @param id 元素id
886
- */
887
- editText(id: string): void {
888
- this.graphModel.editText(id)
889
- }
890
-
891
- /**
892
- * 更新节点或边的文案
893
- * @param id 节点或者边id
894
- * @param value 文案内容
895
- */
896
- updateText(id: string, value: string) {
897
- this.graphModel.updateText(id, value)
898
- }
899
-
900
- /*********************************************************
901
- * EditConfig 相关方法
902
- ********************************************************/
903
- /**
904
- * 更新流程图编辑相关设置
905
- * @param {object} config 编辑配置
906
- * @see http://logicflow.cn/api/detail#updateeditconfig
907
- */
908
- updateEditConfig(config: Partial<IEditConfigType>) {
909
- const { editConfigModel, transformModel } = this.graphModel
910
- const currentSnapGrid = editConfigModel.snapGrid
911
- editConfigModel.updateEditConfig(config)
912
- if (config?.stopMoveGraph !== undefined) {
913
- transformModel.updateTranslateLimits(config.stopMoveGraph)
914
- }
915
-
916
- // 静默模式切换时,修改快捷键的启用状态
917
- config?.isSilentMode ? this.keyboard.disable() : this.keyboard.enable(true)
918
-
919
- // 切换网格对齐状态时,修改网格尺寸
920
- if (!isNil(config?.snapGrid) && config.snapGrid !== currentSnapGrid) {
921
- const {
922
- grid: { size = 1 },
923
- } = this.graphModel
924
- this.graphModel.updateGridSize(config.snapGrid ? size : 1)
925
- }
926
- this.emit(EventType.EDIT_CONFIG_CHANGED, {
927
- data: editConfigModel.getConfig(),
928
- })
929
- }
930
-
931
- /**
932
- * 获取流程图当前编辑相关设置
933
- * @see http://logicflow.cn/api/detail#geteditconfig
934
- */
935
- getEditConfig() {
936
- return this.graphModel.editConfigModel.getConfig()
937
- }
938
-
939
- /*********************************************************
940
- * Graph 相关方法
941
- ********************************************************/
942
- /**
943
- * 设置主题样式
944
- * @param { object } style 自定义主题样式
945
- * todo docs link
946
- */
947
- setTheme(
948
- style: Partial<LogicFlow.Theme>,
949
- themeMode?: 'radius' | 'dark' | 'colorful' | 'default' | string,
950
- ): void {
951
- this.graphModel.setTheme(style, themeMode)
952
- }
953
- /**
954
- * 获取当前主题样式
955
- * @see todo docs link
956
- */
957
- getTheme(): LogicFlow.Theme {
958
- return this.graphModel.getTheme()
959
- }
960
-
961
- private focusByElement(id: string) {
962
- let coordinate: Position | undefined = undefined
963
- const nodeModel = this.getNodeModelById(id)
964
- if (nodeModel) {
965
- const { x, y } = nodeModel.getData()
966
- coordinate = {
967
- x,
968
- y,
969
- }
970
- }
971
- const edgeModel = this.getEdgeModelById(id)
972
- if (edgeModel) {
973
- const { x, y } = edgeModel.textPosition
974
- coordinate = {
975
- x,
976
- y,
977
- }
978
- }
979
-
980
- if (coordinate) {
981
- this.focusByCoordinate(coordinate)
982
- }
983
- }
984
-
985
- private focusByCoordinate(coordinate: Position) {
986
- const { transformModel, width, height } = this.graphModel
987
- const { x, y } = coordinate
988
- transformModel.focusOn(x, y, width, height)
989
- }
990
-
991
- /**
992
- * 定位到画布视口中心
993
- * 支持用户传入图形当前的坐标或id,可以通过type来区分是节点还是边的id,也可以不传(兜底)
994
- * @param focusOnArgs.id 如果传入的是id, 则画布视口中心移动到此id的元素中心点。
995
- * @param focusOnArgs.coordinate 如果传入的是坐标,则画布视口中心移动到此坐标。
996
- * TODO: 测试下面代码,重构了一下逻辑,重载 api 定义
997
- */
998
- focusOn(id: string): void
999
- focusOn(coordinate: Position): void
1000
- focusOn(focusOnArgs: LogicFlow.FocusOnArgsType): void
1001
- focusOn(focusOnArgs: string | Position | LogicFlow.FocusOnArgsType): void {
1002
- if (typeof focusOnArgs === 'string') {
1003
- // string focusOnArgs -> id
1004
- this.focusByElement(focusOnArgs)
1005
- } else if ('x' in focusOnArgs && 'y' in focusOnArgs) {
1006
- // Position focusOnArgs -> coordinate
1007
- this.focusByCoordinate(focusOnArgs)
1008
- } else {
1009
- // FocusOnArgsType
1010
- const { id, coordinate } = focusOnArgs
1011
- if (id) {
1012
- this.focusByElement(id)
1013
- }
1014
- if (coordinate) {
1015
- this.focusByCoordinate(coordinate)
1016
- }
1017
- }
1018
- }
1019
-
1020
- /**
1021
- * 重新设置画布的宽高
1022
- * 不传会自动计算画布宽高
1023
- */
1024
- resize(width?: number, height?: number): void {
1025
- this.graphModel.resize(width, height)
1026
- this.options.width = this.graphModel.width
1027
- this.options.height = this.graphModel.height
1028
- }
1029
-
1030
- /**
1031
- * 将某个元素放置到顶部。
1032
- * 如果堆叠模式为默认模式,则将原置顶元素重新恢复原有层级。
1033
- * 如果堆叠模式为递增模式,则将需指定元素zIndex设置为当前最大zIndex + 1。
1034
- * @see todo link 堆叠模式
1035
- * @param id 元素Id
1036
- */
1037
- toFront(id: string) {
1038
- this.graphModel.toFront(id)
1039
- }
1040
-
1041
- /**
1042
- * 获取事件位置相对于画布左上角的坐标
1043
- * 画布所在的位置可以是页面任何地方,原生事件返回的坐标是相对于页面左上角的,该方法可以提供以画布左上角为原点的准确位置。
1044
- * @param {number} x
1045
- * @param {number} y
1046
- * @returns {object} Point 事件位置的坐标
1047
- * @returns {object} Point.domOverlayPosition HTML层上的坐标
1048
- * @returns {object} Point.canvasOverlayPosition SVG层上的坐标
1049
- */
1050
- getPointByClient(x: number, y: number): ClientPosition
1051
- getPointByClient(point: Position): ClientPosition
1052
- getPointByClient(
1053
- x: number | Position,
1054
- y?: number,
1055
- ): ClientPosition | undefined {
1056
- if (typeof x === 'object') {
1057
- return this.graphModel.getPointByClient(x)
1058
- } else if (typeof y === 'number') {
1059
- return this.graphModel.getPointByClient({
1060
- x,
1061
- y,
1062
- })
1063
- }
1064
- }
1065
-
1066
- /**
1067
- * 获取流程绘图数据
1068
- * 注意: getGraphData返回的数据受到adapter影响,所以其数据格式不一定是logicflow内部图数据格式。
1069
- * 如果实现通用插件,请使用getGraphRawData
1070
- */
1071
- getGraphData(...params: any): GraphData | unknown {
1072
- const data = this.getGraphRawData()
1073
- if (this.adapterOut) {
1074
- return this.adapterOut(data, ...params)
1075
- }
1076
- return data
1077
- }
1078
-
1079
- /**
1080
- * 获取流程绘图原始数据
1081
- * 在存在adapter时,可以使用getGraphRawData获取图原始数据
1082
- */
1083
- getGraphRawData(): GraphData {
1084
- return this.graphModel.modelToGraphData()
1085
- }
1086
-
1087
- /**
1088
- * 清空画布
1089
- */
1090
- clearData() {
1091
- this.graphModel.clearData()
1092
- // 强制刷新数据, 让 preact 清除对已删除节点的引用
1093
- this.render({})
1094
- }
1095
-
1096
- setOverlapMode(mode: OverlapMode) {
1097
- this.graphModel.setOverlapMode(mode)
1098
- }
1099
- /*********************************************************
1100
- * LogicFlow Render方法
1101
- ********************************************************/
1102
- renderRawData(graphRawData: GraphConfigData) {
1103
- this.graphModel.graphDataToModel(formatData(graphRawData))
1104
- if (this.options.history !== false) {
1105
- this.history.watch(this.graphModel)
1106
- }
1107
- render(
1108
- <Graph
1109
- getView={this.getView}
1110
- tool={this.tool}
1111
- options={this.options}
1112
- dnd={this.dnd}
1113
- snaplineModel={this.snaplineModel}
1114
- graphModel={this.graphModel}
1115
- />,
1116
- this.container,
1117
- )
1118
- this.emit(EventType.GRAPH_RENDERED, {
1119
- data: this.graphModel.modelToGraphData(),
1120
- graphModel: this.graphModel,
1121
- })
1122
- }
1123
-
1124
- /**
1125
- * 渲染图
1126
- * @example
1127
- * lf.render({
1128
- * nodes: [
1129
- * {
1130
- * id: 'node_1',
1131
- * type: 'rect',
1132
- * x: 100,
1133
- * y: 100
1134
- * },
1135
- * {
1136
- * id: 'node_2',
1137
- * type: 'circle',
1138
- * x: 300,
1139
- * y: 200
1140
- * }
1141
- * ],
1142
- * edges: [
1143
- * {
1144
- * sourceNodeId: 'node_1',
1145
- * targetNodeId: 'node_2',
1146
- * type: 'polyline'
1147
- * }
1148
- * ]
1149
- * })
1150
- * @param graphData 图数据
1151
- */
1152
- render(graphData: GraphConfigData) {
1153
- let graphRawData = cloneDeep(graphData)
1154
- if (this.adapterIn) {
1155
- graphRawData = this.adapterIn(graphRawData)
1156
- }
1157
- this.renderRawData(graphRawData)
1158
- }
1159
-
1160
- /*********************************************************
1161
- * History/Resize 相关方法
1162
- ********************************************************/
1163
- /**
1164
- * 历史记录操作
1165
- * 返回上一步
1166
- */
1167
- undo() {
1168
- if (!this.history.undoAble()) return
1169
- // formatData兼容vue数据
1170
- const graphData = formatData(this.history.undo()!)
1171
- this.clearSelectElements()
1172
- this.graphModel.graphDataToModel(graphData)
1173
- }
1174
-
1175
- /**
1176
- * 历史记录操作
1177
- * 恢复下一步
1178
- */
1179
- redo() {
1180
- if (!this.history.redoAble()) return
1181
- // formatData兼容vue数据
1182
- const graphData = formatData(this.history.redo()!)
1183
- this.clearSelectElements()
1184
- this.graphModel.graphDataToModel(graphData)
1185
- }
1186
-
1187
- /**
1188
- * 放大缩小图形
1189
- * @param zoomSize 放大缩小的值,支持传入0-n之间的数字。小于1表示缩小,大于1表示放大。也支持传入true和false按照内置的刻度放大缩小
1190
- * @param point 缩放的原点
1191
- * @returns {string} -放大缩小的比例
1192
- */
1193
- zoom(zoomSize?: ZoomParamType, point?: PointTuple): string {
1194
- const { transformModel } = this.graphModel
1195
- return transformModel.zoom(zoomSize, point)
1196
- }
1197
-
1198
- /**
1199
- * 重置图形的放大缩写比例为默认
1200
- */
1201
- resetZoom(): void {
1202
- const { transformModel } = this.graphModel
1203
- transformModel.resetZoom()
1204
- }
1205
-
1206
- /**
1207
- * 设置图形缩小时,能缩放到的最小倍数。参数为0-1自己。默认0.2
1208
- * @param size 图形缩小的最小值
1209
- */
1210
- setZoomMiniSize(size: number): void {
1211
- const { transformModel } = this.graphModel
1212
- transformModel.setZoomMiniSize(size)
1213
- }
1214
-
1215
- /**
1216
- * 设置图形放大时,能放大到的最大倍数,默认16
1217
- * @param size 图形放大的最大值
1218
- */
1219
- setZoomMaxSize(size: number): void {
1220
- const { transformModel } = this.graphModel
1221
- transformModel.setZoomMaxSize(size)
1222
- }
1223
-
1224
- /**
1225
- * 获取缩放的值和平移的值。
1226
- */
1227
- getTransform() {
1228
- const {
1229
- transformModel: { SCALE_X, SCALE_Y, TRANSLATE_X, TRANSLATE_Y },
1230
- } = this.graphModel
1231
- return {
1232
- SCALE_X,
1233
- SCALE_Y,
1234
- TRANSLATE_X,
1235
- TRANSLATE_Y,
1236
- }
1237
- }
1238
-
1239
- /**
1240
- * 平移图
1241
- * @param x 向x轴移动距离
1242
- * @param y 向y轴移动距离
1243
- */
1244
- translate(x: number, y: number): void {
1245
- const { transformModel } = this.graphModel
1246
- transformModel.translate(x, y)
1247
- }
1248
-
1249
- /**
1250
- * 还原图形为初始位置
1251
- */
1252
- resetTranslate(): void {
1253
- const { transformModel } = this.graphModel
1254
- const { TRANSLATE_X, TRANSLATE_Y } = transformModel
1255
- this.translate(-TRANSLATE_X, -TRANSLATE_Y)
1256
- }
1257
-
1258
- /**
1259
- * 图形画布居中显示
1260
- */
1261
- translateCenter(): void {
1262
- this.graphModel.translateCenter()
1263
- }
1264
-
1265
- /**
1266
- * 图形适应屏幕大小
1267
- * @param verticalOffset number 距离盒子上下的距离, 默认为20
1268
- * @param horizontalOffset number 距离盒子左右的距离, 默认为20
1269
- */
1270
- fitView(verticalOffset?: number, horizontalOffset?: number): void {
1271
- if (horizontalOffset === undefined) {
1272
- horizontalOffset = verticalOffset // 兼容以前的只传一个参数的情况
1273
- }
1274
- this.graphModel.fitView(verticalOffset, horizontalOffset)
1275
- }
1276
-
1277
- /**
1278
- * 开启边的动画
1279
- * @param edgeId string
1280
- */
1281
- openEdgeAnimation(edgeId: string): void {
1282
- this.graphModel.openEdgeAnimation(edgeId)
1283
- }
1284
-
1285
- /**
1286
- * 关闭边的动画
1287
- * @param edgeId string
1288
- */
1289
- closeEdgeAnimation(edgeId: string): void {
1290
- this.graphModel.closeEdgeAnimation(edgeId)
1291
- }
1292
-
1293
- /*********************************************************
1294
- * 事件系统方法
1295
- ********************************************************/
1296
- /**
1297
- * 监听事件
1298
- * 事件详情见 @see todo
1299
- * 支持同时监听多个事件
1300
- * @example
1301
- * lf.on('node:click,node:contextmenu', (data) => {
1302
- * });
1303
- */
1304
- on<T extends keyof EventArgs>(evt: T, callback: EventCallback<T>): void
1305
- on<T extends string>(evt: T, callback: EventCallback<T>): void
1306
- on(evt: string, callback: EventCallback) {
1307
- this.graphModel.eventCenter.on(evt, callback)
1308
- }
1309
-
1310
- /**
1311
- * 撤销监听事件
1312
- */
1313
- off<T extends keyof EventArgs>(evt: T, callback: EventCallback<T>): void
1314
- off<T extends string>(evt: T, callback: EventCallback<T>): void
1315
- off(evt: string, callback: EventCallback) {
1316
- this.graphModel.eventCenter.off(evt, callback)
1317
- }
1318
-
1319
- /**
1320
- * 监听事件,只监听一次
1321
- */
1322
- once<T extends keyof EventArgs>(evt: T, callback: EventCallback<T>): void
1323
- once<T extends string>(evt: T, callback: EventCallback<T>): void
1324
- once(evt: string, callback: EventCallback) {
1325
- this.graphModel.eventCenter.once(evt, callback)
1326
- }
1327
-
1328
- /**
1329
- * 触发监听事件
1330
- */
1331
- emit<T extends keyof EventArgs>(evts: T, eventArgs: CallbackArgs<T>): void
1332
- emit<T extends string>(evts: T, eventArgs: CallbackArgs<T>): void
1333
- emit(evt: string, arg: EventArgs) {
1334
- this.graphModel.eventCenter.emit(evt, arg)
1335
- }
1336
-
1337
- /*********************************************************
1338
- * 插件系统方法
1339
- ********************************************************/
1340
- /**
1341
- * 添加扩展, 待讨论,这里是不是静态方法好一些?
1342
- * 重复添加插件的时候,把上一次添加的插件的销毁。
1343
- * @param extension
1344
- * @param props
1345
- */
1346
- static use(
1347
- extension: ExtensionConstructor | ExtensionDefinition,
1348
- props?: Record<string, unknown>,
1349
- ): void {
1350
- const { pluginName } = extension
1351
- if (!pluginName) {
1352
- throw new Error(`请给插件指定 pluginName!`)
1353
- }
1354
- // TODO: 应该在何时进行插件的销毁???
1355
- // const preExtension = this.extensions.get(pluginName)?.extension
1356
- // preExtension?.destroy?.() // 该代码应该有问题,因为 preExtension 直接用的是 Constructor,没有实例化。无法访问实例方法 destroy
1357
-
1358
- this.extensions.set(pluginName, {
1359
- [pluginFlag]: pluginFlag,
1360
- extension,
1361
- props,
1362
- })
1363
- }
1364
-
1365
- /**
1366
- * 添加主题模式
1367
- * @param themeMode 主题模式
1368
- * @param style 主题样式
1369
- */
1370
- static addThemeMode(themeMode: string, style: Partial<LogicFlow.Theme>) {
1371
- addThemeMode(themeMode, style)
1372
- }
1373
-
1374
- static removeThemeMode(themeMode: string) {
1375
- removeThemeMode(themeMode)
1376
- }
1377
-
1378
- static clearThemeMode() {
1379
- clearThemeMode()
1380
- }
1381
-
1382
- private installPlugins(disabledPlugins: string[] = []) {
1383
- const extensionsAddByUse = Array.from(
1384
- LogicFlow.extensions,
1385
- ([, extension]) => extension,
1386
- )
1387
- // 安装插件,优先使用个性插件
1388
- const extensions = [...this.plugins, ...extensionsAddByUse]
1389
- forEach(extensions, (ext) => {
1390
- let extension: ExtensionConstructor | ExtensionDefinition
1391
- let props: Record<string, any> | undefined
1392
-
1393
- if (pluginFlag in ext) {
1394
- extension = ext.extension
1395
- props = ext.props
1396
- } else {
1397
- extension = ext
1398
- }
1399
-
1400
- const pluginName = extension?.pluginName
1401
-
1402
- if (indexOf(disabledPlugins, pluginName) === -1) {
1403
- this.installPlugin(extension, props)
1404
- }
1405
- })
1406
- }
1407
-
1408
- /**
1409
- * 加载插件-内部方法
1410
- */
1411
- private installPlugin(
1412
- extension: ExtensionConstructor | ExtensionDefinition,
1413
- props?: Record<string, any>,
1414
- ) {
1415
- if ('pluginName' in extension && 'install' in extension) {
1416
- const { pluginName, install, render } = extension
1417
- if (pluginName) {
1418
- install && install.call(extension, this, LogicFlow)
1419
- render && this.components.push(render.bind(extension))
1420
- this.extension[pluginName] = extension
1421
- }
1422
- return
1423
- }
1424
-
1425
- const ExtensionCtor = extension as ExtensionConstructor
1426
- const pluginName = ExtensionCtor.pluginName
1427
- const extensionIns = new ExtensionCtor({
1428
- lf: this,
1429
- LogicFlow,
1430
- props,
1431
- // TODO: 这里的 options 应该传入插件对应的 options,而不是全局的 options
1432
- // 所以应该这么写 this.options.pluginsOptions[ExtensionCtor.pluginName] ?? {}
1433
- options: this.options.pluginsOptions?.[pluginName] ?? {},
1434
- })
1435
- extensionIns.render &&
1436
- this.components.push(extensionIns.render.bind(extensionIns))
1437
- this.extension[pluginName] = extensionIns
1438
- }
1439
-
1440
- /** 销毁当前实例 */
1441
- destroy() {
1442
- this.clearData()
1443
- render(null, this.container)
1444
- this.keyboard.destroy()
1445
- this.graphModel.destroy()
1446
- this.tool.destroy()
1447
- this.history.destroy()
1448
- clearThemeMode()
1449
- for (const extensionName in this.extension) {
1450
- const extensionInstance = this.extension[extensionName]
1451
- if ('destroy' in extensionInstance) {
1452
- extensionInstance.destroy?.()
1453
- }
1454
- }
1455
- }
1456
- }
1457
-
1458
- // Option
1459
- export namespace LogicFlow {
1460
- /**
1461
- * LogicFlow init Options
1462
- */
1463
- export interface Options extends LFOptions.Common {}
1464
-
1465
- export type DomAttributes = {
1466
- className?: string
1467
- [key: string]: string | undefined
1468
- }
1469
-
1470
- export interface PropertiesType {
1471
- width?: number
1472
- height?: number
1473
- rx?: number
1474
- ry?: number
1475
-
1476
- style?: LogicFlow.CommonTheme
1477
- textStyle?: LogicFlow.CommonTheme
1478
-
1479
- [key: string]: any
1480
- }
1481
- export type AttributesType = Record<string, any>
1482
-
1483
- export type VectorData = {
1484
- deltaX: number
1485
- deltaY: number
1486
- }
1487
- export type OffsetData = {
1488
- dx: number
1489
- dy: number
1490
- }
1491
- export type Position = {
1492
- x: number
1493
- y: number
1494
- }
1495
- export type Point = {
1496
- id?: string
1497
- [key: string]: any // TODO: 确认这个属性是干什么的呢?是有可以移除
1498
- } & Position
1499
- export type PointTuple = [number, number]
1500
- export type ClientPosition = {
1501
- domOverlayPosition: Position
1502
- canvasOverlayPosition: Position
1503
- }
1504
-
1505
- export interface LineSegment {
1506
- start: Point
1507
- end: Point
1508
- }
1509
-
1510
- export type Direction = SegmentDirection
1511
- export type RadiusCircleInfo = {
1512
- r: number
1513
- } & Position
1514
- export type Vector = {
1515
- id?: string
1516
- x: number
1517
- y: number
1518
- z: 0
1519
- [key: string]: any
1520
- }
1521
- export type RectSize = {
1522
- width: number
1523
- height: number
1524
- }
1525
- export type TextConfig = {
1526
- value: string
1527
- x: number
1528
- y: number
1529
- editable?: boolean
1530
- draggable?: boolean
1531
- // 直接在这儿设置文本模式
1532
- // overflowMode?: 'default' | 'autoWrap' | 'ellipsis'
1533
- }
1534
-
1535
- // label数据类型声明
1536
- export type LabelConfig = {
1537
- id?: string // label唯一标识
1538
- type?: string
1539
- x: number
1540
- y: number
1541
- content?: string // 富文本内容
1542
- value: string // 纯文本内容
1543
- rotate?: number // 旋转角度
1544
- // 样式属性
1545
- style?: h.JSX.CSSProperties // label自定义样式
1546
-
1547
- // 编辑状态属性
1548
- editable?: boolean
1549
- draggable?: boolean
1550
- labelWidth?: number
1551
- textOverflowMode?: 'ellipsis' | 'wrap' | 'clip' | 'nowrap' | 'default'
1552
-
1553
- // 当前 Label 是否渲染纵向文本
1554
- vertical?: boolean
1555
- }
1556
-
1557
- export type LabelOption = {
1558
- // 节点的所有 Label 是否纵向展示
1559
- isVertical: boolean
1560
- // 是否支持多个 label
1561
- isMultiple: boolean
1562
- // 允许设置多个 label 时最大个数
1563
- maxCount?: number
1564
- }
1565
-
1566
- export interface LabelData extends LabelConfig {
1567
- id: string
1568
- x: number
1569
- y: number
1570
- content: string
1571
- value: string
1572
- }
1573
-
1574
- export type AppendConfig = {
1575
- startIndex: number
1576
- endIndex: number
1577
- direction: Direction
1578
- draggable?: boolean
1579
- } & LineSegment
1580
-
1581
- export type ArrowConfig = {
1582
- markerStart: string
1583
- markerEnd: string
1584
- }
1585
-
1586
- export type ArrowInfo = {
1587
- start: Point
1588
- end: Point
1589
- hover: boolean
1590
- isSelected: boolean
1591
- }
1592
-
1593
- export interface GraphConfigData {
1594
- nodes?: NodeConfig[]
1595
- edges?: EdgeConfig[]
1596
- }
1597
-
1598
- export interface GraphData {
1599
- nodes: NodeData[]
1600
- edges: EdgeData[]
1601
- }
1602
-
1603
- export interface FakeNodeConfig {
1604
- type: string
1605
- text?: TextConfig | string
1606
- properties?: PropertiesType
1607
-
1608
- [key: string]: unknown
1609
- }
1610
-
1611
- // DnD 拖拽插件使用的 NodeConfig
1612
- export type OnDragNodeConfig = {
1613
- type: string
1614
- text?: TextConfig | string
1615
- properties?: Record<string, unknown>
1616
- [key: string]: any
1617
- }
1618
-
1619
- export interface NodeConfig<P extends PropertiesType = PropertiesType> {
1620
- id?: string
1621
- type: string
1622
- x: number
1623
- y: number
1624
- text?: TextConfig | string
1625
- zIndex?: number
1626
- properties?: P
1627
- virtual?: boolean // 是否虚拟节点
1628
- rotate?: number
1629
-
1630
- rotatable?: boolean // 节点是否可旋转
1631
- resizable?: boolean // 节点是否可缩放
1632
-
1633
- [key: string]: any
1634
- }
1635
-
1636
- export interface NodeData extends NodeConfig {
1637
- id: string
1638
- text?: TextConfig
1639
- [key: string]: unknown
1640
- }
1641
-
1642
- export interface EdgeConfig<P extends PropertiesType = PropertiesType> {
1643
- id?: string
1644
- type?: string // TODO: 将所有类型选项列出来;LogicFlow 内部默认为 polyline
1645
-
1646
- sourceNodeId: string
1647
- sourceAnchorId?: string
1648
- targetNodeId: string
1649
- targetAnchorId?: string
1650
- startPoint?: Point
1651
- endPoint?: Point
1652
- text?: TextConfig | string
1653
- pointsList?: Point[]
1654
- zIndex?: number
1655
- properties?: P
1656
- }
1657
-
1658
- export interface EdgeData extends EdgeConfig {
1659
- id: string
1660
- type: string
1661
- text?: TextConfig
1662
- startPoint: Point
1663
- endPoint: Point
1664
-
1665
- [key: string]: unknown
1666
- }
1667
-
1668
- export interface MenuConfig {
1669
- text?: string
1670
- className?: string
1671
- icon?: boolean
1672
- callback: (id: string | number) => void
1673
- }
1674
- }
1675
-
1676
- // Theme
1677
- export namespace LogicFlow {
1678
- export type NumberOrPercent = `${number}%` | number
1679
- /**
1680
- * 颜色 - CSS 属性用颜色
1681
- * 如:#000000, rgba(0, 0, 0, 0), 如果是透明的,可以传 'none'
1682
- */
1683
- export type Color = string | 'none'
1684
- /**
1685
- * svg虚线
1686
- * 格式为逗号分割字符串,如
1687
- * @see https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute/stroke-dasharray
1688
- */
1689
- export type DashArray = string
1690
- export type CommonTheme = {
1691
- fill?: Color // 填充颜色
1692
- stroke?: Color // 边框颜色
1693
- strokeWidth?: number // 边框宽度 TODO: svg 实际可赋值类型:NumberOrPercent
1694
- /**
1695
- * 其他属性 - 我们会把你自定义的所有属性最终传递到 DOM 上
1696
- * 详情请参考 svg 属性规范:
1697
- * https://developer.mozilla.org/zh-CN/docs/Web/SVG/Attribute
1698
- * 注意: 请不要在主题中设置“形状属性”,例如:x、y、width、height、radius、r、rx、ry
1699
- * @see https://docs.logic-flow.cn/docs/#/zh/api/themeApi?id=%e5%bd%a2%e7%8a%b6%e5%b1%9e%e6%80%a7)
1700
- */
1701
- radius?: number
1702
- rx?: number
1703
- ry?: number
1704
- width?: number
1705
- height?: number
1706
- path?: string
1707
- [key: string]: unknown
1708
- }
1709
- export type CommonThemePropTypes = CommonTheme[keyof CommonTheme]
1710
-
1711
- export type AppendAttributes = {
1712
- d: string
1713
- fill: string
1714
- stroke: Color
1715
- strokeWidth: number
1716
- strokeDasharray: DashArray
1717
- }
1718
-
1719
- export type ContainerTheme = {
1720
- width?: string
1721
- height?: string
1722
- }
1723
- // 节点 Shape 类型
1724
- /**
1725
- * rect 节点主题
1726
- * svg基础图形-矩形
1727
- * https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/rect
1728
- */
1729
- export type RectTheme = CommonTheme
1730
- /**
1731
- * circle 节点主题
1732
- * svg基础图形-圆形
1733
- * https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/circle
1734
- */
1735
- export type CircleTheme = CommonTheme
1736
- /**
1737
- * polygon 节点主题
1738
- * svg基础图形-多边形
1739
- * https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/polygon
1740
- */
1741
- export type PolygonTheme = CommonTheme
1742
- /**
1743
- * ellipse 节点主题
1744
- * svg基础图形-椭圆
1745
- * https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/ellipse
1746
- */
1747
- export type EllipseTheme = CommonTheme
1748
- // 锚点样式(svg 基础图形 - 圆)
1749
- export type AnchorTheme = {
1750
- r?: number
1751
- hover?: {
1752
- r?: number
1753
- } & CommonTheme
1754
- } & CommonTheme
1755
-
1756
- // 文本样式
1757
- export type TextTheme = {
1758
- color?: Color
1759
- fontSize: number
1760
- textWidth?: number
1761
- lineHeight?: number
1762
- textAnchor?: 'start' | 'middle' | 'end'
1763
- dominantBaseline?:
1764
- | 'auto'
1765
- | 'text-bottom'
1766
- | 'alphabetic'
1767
- | 'ideographic'
1768
- | 'middle'
1769
- | 'central'
1770
- | 'mathematical'
1771
- | 'hanging'
1772
- | 'text-top'
1773
- } & CommonTheme
1774
-
1775
- // 文本节点样式
1776
- export type TextNodeTheme = {
1777
- background?: RectTheme
1778
- } & TextTheme
1779
-
1780
- // 节点上文本样式
1781
- export type NodeTextTheme = {
1782
- /**
1783
- * 文本超出指定宽度处理方式
1784
- * default: 不特殊处理,允许超出
1785
- * autoWrap: 超出自动换行
1786
- * ellipsis: 超出省略
1787
- */
1788
- overflowMode?: 'default' | 'autoWrap' | 'ellipsis'
1789
- textWidth?: number
1790
- background?: RectTheme
1791
- /**
1792
- * 背景区域 padding
1793
- * wrapPadding: '5px,10px'
1794
- */
1795
- wrapPadding?: string
1796
- } & TextTheme
1797
-
1798
- // 边上文本样式
1799
- export type EdgeTextTheme = {
1800
- textWidth: number
1801
- background?: {
1802
- /**
1803
- * 背景区域 padding
1804
- * wrapPadding: '5px,10px'
1805
- */
1806
- wrapPadding?: string
1807
- } & RectTheme
1808
- // hover状态下文本样式
1809
- hover?: EdgeTextTheme
1810
- } & NodeTextTheme &
1811
- TextTheme
1812
-
1813
- // 边 Edge 主题
1814
- export type EdgeTheme = CommonTheme
1815
- export type EdgeBezierTheme = {
1816
- // 贝塞尔调整线主题
1817
- adjustLine?: EdgeTheme
1818
- // 贝塞尔调整锚点主题
1819
- adjustAnchor?: CircleTheme
1820
- } & EdgeTheme
1821
- export type EdgePolylineTheme = EdgeTheme
1822
- export type EdgeAnimation = {
1823
- stroke?: Color
1824
- strokeDasharray?: string
1825
- strokeDashoffset?: NumberOrPercent
1826
- animationName?: string
1827
- animationDuration?: `${number}s` | `${number}ms`
1828
- animationIterationCount?: 'infinite' | number
1829
- animationTimingFunction?: string
1830
- animationDirection?: string
1831
- }
1832
-
1833
- export type OutlineTheme = {
1834
- hover?: CommonTheme
1835
- } & CommonTheme &
1836
- EdgeAnimation
1837
-
1838
- export type ArrowTheme = {
1839
- /**
1840
- * 箭头长度.
1841
- * 以符号"->"为例, offset表示箭头大于号的宽度。
1842
- */
1843
- offset: number
1844
- /**
1845
- * 箭头垂直于边的距离
1846
- * 以符号"->"为例, verticalLength表示箭头大于号的高度
1847
- */
1848
- refX?: number
1849
- refY?: number
1850
- verticalLength: number
1851
- endArrowType?: 'solid' | 'hollow' | 'diamond' | 'circle' | 'none' // 结束箭头类型
1852
- startArrowType?: 'solid' | 'hollow' | 'diamond' | 'circle' | 'none' // 开始箭头类型
1853
- strokeLinecap?: 'butt' | 'round' | 'square' // 线条的端点样式
1854
- strokeLinejoin?: 'miter' | 'round' | 'bevel' // 线条的连接样式
1855
- } & CommonTheme
1856
- export type ArrowAttributesType = {
1857
- d: string
1858
- } & ArrowTheme
1859
-
1860
- export type AnchorLineTheme = EdgeTheme & EdgeAnimation
1861
-
1862
- export interface Theme {
1863
- baseNode: CommonTheme // 所有节点的通用主题设置
1864
- baseEdge: EdgeTheme // 所有边的通用主题设置
1865
-
1866
- /**
1867
- * 基础图形节点相关主题
1868
- */
1869
- rect: RectTheme // 矩形样式
1870
- circle: CircleTheme // 圆形样式
1871
- diamond: PolygonTheme // 菱形样式
1872
- ellipse: EllipseTheme // 椭圆样式
1873
- polygon: PolygonTheme // 多边形样式
1874
-
1875
- /**
1876
- * 基础图形线相关主题
1877
- */
1878
- line: EdgeTheme // 直线样式
1879
- polyline: EdgePolylineTheme // 折线样式
1880
- bezier: EdgeBezierTheme // 贝塞尔曲线样式
1881
- anchorLine: AnchorLineTheme // 从锚点拉出的边的样式
1882
-
1883
- /**
1884
- * 文本内容相关主题
1885
- */
1886
- text: TextNodeTheme // 文本节点样式
1887
- nodeText: NodeTextTheme // 节点文本样式
1888
- edgeText: EdgeTextTheme // 边文本样式
1889
- inputText?: CommonTheme
1890
-
1891
- /**
1892
- * 其他元素相关主题
1893
- */
1894
- anchor: AnchorTheme // 锚点样式
1895
- arrow: ArrowTheme // 边上箭头的样式
1896
- snapline: EdgeTheme // 对齐线样式
1897
- rotateControl: CommonTheme // 节点旋转控制点样式
1898
- resizeControl: CommonTheme // 节点旋转控制点样式
1899
- resizeOutline: CommonTheme // 节点调整大小时的外框样式
1900
-
1901
- /**
1902
- * REMIND: 当开启了跳转边的起点和终点(adjustEdgeStartAndEnd:true)后
1903
- * 边的两端会出现调整按钮
1904
- * 边连段的调整点样式
1905
- */
1906
- edgeAdjust: CircleTheme
1907
- outline: OutlineTheme // 节点选择状态下外侧的选框样式
1908
- edgeAnimation: EdgeAnimation // 边动画样式
1909
-
1910
- // 画布背景
1911
- background?: boolean | Partial<LFOptions.BackgroundConfig>
1912
- grid?: boolean | Partial<Grid.GridOptions>
1913
- }
1914
- }
1915
-
1916
- // Render or Functions
1917
- export namespace LogicFlow {
1918
- type FocusOnById = {
1919
- id: string
1920
- coordinate?: never
1921
- }
1922
- type FocusOnByCoordinate = {
1923
- id?: string
1924
- coordinate: Position
1925
- }
1926
- export type FocusOnArgsType = FocusOnById | FocusOnByCoordinate
1927
-
1928
- export type BaseNodeModelCtor = typeof BaseNodeModel<PropertiesType>
1929
- export type BaseEdgeModelCtor = typeof BaseEdgeModel<PropertiesType>
1930
-
1931
- export type GraphElementCtor = BaseNodeModelCtor | BaseEdgeModelCtor
1932
- export type GraphElement = BaseNodeModel | BaseEdgeModel
1933
- export type GraphElements = {
1934
- nodes: BaseNodeModel[]
1935
- edges: BaseEdgeModel[]
1936
- }
1937
-
1938
- export type RegisterConfig = {
1939
- type: string
1940
- // TODO: 确认 View 类型中 props 类型该如何动态获取真实组件的 props
1941
- view: ComponentType<any> & {
1942
- isObserved?: boolean
1943
- }
1944
- model: GraphElementCtor // TODO: 确认 model 的类型
1945
- isObserverView?: boolean
1946
- }
1947
- export type RegisterElement = {
1948
- view: any
1949
- model: any
1950
- }
1951
- export type RegisterParam = {
1952
- h: typeof h
1953
- // 当前项目中定义的节点 or 连线的 View 或 Model
1954
- // ...
1955
- [key: string]: unknown
1956
- }
1957
- export type RegisterElementFunc = (params: RegisterParam) => RegisterElement
1958
-
1959
- export interface LogicFlowConstructor {
1960
- new (options: LFOptions.Definition): LogicFlow
1961
- }
1962
-
1963
- /**
1964
- * Extension 插件类型
1965
- */
1966
- export type ExtensionType = ExtensionConstructor | ExtensionDefinition
1967
- export type ExtensionConfig = {
1968
- [pluginFlag]: symbol
1969
- extension: ExtensionType
1970
- props?: Record<string, any> // TODO: 看这类型是否可以更精确
1971
- }
1972
-
1973
- export type IExtensionProps = {
1974
- lf: LogicFlow
1975
- LogicFlow: LogicFlowConstructor
1976
- props?: Record<string, unknown>
1977
- options: Record<string, unknown>
1978
- }
1979
-
1980
- export interface ExtensionConstructor {
1981
- pluginName: string
1982
- new (props: IExtensionProps): Extension
1983
- }
1984
-
1985
- export type ExtensionRenderFunc = (
1986
- lf: LogicFlow,
1987
- container: HTMLElement,
1988
- ) => void
1989
-
1990
- // 对象形式定义的插件
1991
- export type ExtensionDefinition = {
1992
- pluginName: string
1993
- install?: (lf: LogicFlow, LFCtor: LogicFlowConstructor) => void
1994
- render?: ExtensionRenderFunc
1995
- }
1996
-
1997
- export interface Extension {
1998
- render: ExtensionRenderFunc
1999
- destroy?: () => void // TODO: 确认插件销毁函数参数类型
2000
- }
2001
- }
2002
-
2003
- // toStringTag
2004
- export namespace LogicFlow {
2005
- export const toStringTag = `LF.${LogicFlow.name}`
2006
- }
2007
-
2008
- export default LogicFlow