@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
@@ -1,37 +1,63 @@
1
- import { getHtmlTextHeight } from '../../util'
1
+ import { createElement as h } from 'preact/compat'
2
+ import { BaseNodeModel, BaseEdgeModel } from '../../model'
2
3
  import { ElementType, ModelType } from '../../constant'
4
+ import { getHtmlTextHeight } from '../../util'
5
+ import { forEach, toPairs } from 'lodash-es'
6
+
7
+ export type ITextProps = {
8
+ x: number
9
+ y: number
10
+ value: string
11
+ fontSize?: number
12
+ fill?: string
13
+ overflowMode?: 'default' | 'autoWrap' | 'ellipsis'
14
+ textWidth?: number
15
+ lineHeight?: number
16
+ fontFamily?: string | null
17
+ wrapPadding?: string | number | null
18
+ model: BaseNodeModel | BaseEdgeModel
19
+ [key: string]: any
20
+ }
21
+ export type ForeignObjectPropsType =
22
+ 'string | number | SignalLike<string | number | undefined> | undefined'
3
23
 
4
- export function Text(props) {
24
+ export function Text(props: ITextProps): h.JSX.Element | null {
5
25
  const {
6
26
  x = 0,
7
27
  y = 0,
8
28
  value,
9
- fontSize,
29
+ fontSize = 12,
10
30
  fill = 'currentColor',
11
31
  overflowMode = 'default',
12
- textWidth = '',
32
+ // TODO: 确认该 textWidth '' 时跟设置什么值一致
33
+ textWidth = undefined,
13
34
  model,
14
35
  } = props
15
- const attrs = {
16
- textAnchor: 'middle',
17
- 'dominant-baseline': 'middle',
36
+
37
+ const attrs: Record<string, any> = {
18
38
  x,
19
39
  y,
20
40
  fill,
41
+ fontSize,
42
+ textAnchor: 'middle',
43
+ dominantBaseline: 'central',
21
44
  // ...props,
22
45
  }
23
- Object.entries(props).forEach(([k, v]) => {
24
- const valueType = typeof v
25
- if (valueType !== 'object') {
46
+
47
+ forEach(toPairs(props), ([k, v]: [k: string, v: any]) => {
48
+ if (typeof v !== 'object') {
26
49
  attrs[k] = v
27
50
  }
28
51
  })
52
+
29
53
  if (value) {
30
- // String(value),兼容纯数字的文案
54
+ // String(value),兼容纯数字的文案
55
+ // TODO: 将 value 转为纯文本,移除其中 \n \r 等特殊字符,看是否应该丰富该功能
31
56
  const rows = String(value).split(/[\r\n]/g)
32
57
  const rowsLength = rows.length
58
+
33
59
  if (overflowMode !== 'default') {
34
- // 非文本节点设置了自动换行,或边设置了自动换行并且设置了textWidth
60
+ // 非文本节点设置了自动换行,或者边设置了自动换行并且设置了 textWidth
35
61
  const { BaseType, modelType } = model
36
62
  if (
37
63
  (BaseType === ElementType.NODE && modelType !== ModelType.TEXT_NODE) ||
@@ -40,11 +66,12 @@ export function Text(props) {
40
66
  return renderHtmlText(props)
41
67
  }
42
68
  }
69
+
43
70
  if (rowsLength > 1) {
44
- const tSpans = rows.map((row, i) => {
45
- // 保证文字居中,文字Y轴偏移为当前行数对应中心行数的偏移行 * 行高
46
- const tspanLineHeight = fontSize + 2
47
- const offsetY = (i - (rowsLength - 1) / 2) * tspanLineHeight
71
+ const tSpans = rows.map((row, idx) => {
72
+ // 保证文字居中,文字 Y 轴偏移为当前行数对应中心行数的偏移行 * 行高
73
+ const tSpanLineHeight = fontSize + 2
74
+ const offsetY = (idx - (rowsLength - 1) / 2) * tSpanLineHeight
48
75
  return (
49
76
  <tspan className="lf-text-tspan" x={x} y={y + offsetY}>
50
77
  {row}
@@ -55,24 +82,26 @@ export function Text(props) {
55
82
  }
56
83
  return <text {...attrs}>{value}</text>
57
84
  }
58
-
59
85
  return null
60
86
  }
61
87
 
62
- function renderHtmlText(props) {
88
+ export function renderHtmlText(props: ITextProps): h.JSX.Element {
63
89
  const {
90
+ x,
91
+ y,
64
92
  value,
65
- fontSize,
66
93
  model,
67
- fontFamily = '',
94
+ textWidth,
95
+ fontSize = 12,
68
96
  lineHeight,
97
+ fontFamily = '',
69
98
  wrapPadding = '0, 0',
70
99
  overflowMode,
71
- x,
72
- y,
73
100
  } = props
74
- const { width, textHeight } = model
75
- const textRealWidth = props.textWidth || width
101
+
102
+ const { width, height, textHeight } = model
103
+ // TODO: 设置文本宽度为 textWidth 或 节点的宽度
104
+ const textRealWidth: number = textWidth || (width as number)
76
105
  const rows = String(value).split(/[\r\n]/g)
77
106
  const rowsLength = rows.length
78
107
  const textRealHeight = getHtmlTextHeight({
@@ -87,17 +116,20 @@ function renderHtmlText(props) {
87
116
  rowsLength,
88
117
  className: 'lf-get-text-height',
89
118
  })
119
+
90
120
  // 当文字超过边框时,取文字高度的实际值,也就是文字可以超过边框
91
- let foreignObjectHeight =
92
- model.height > textRealHeight ? model.height : textRealHeight
93
- // 如果设置了文字高度,取设置的高度
121
+ let foreignObjectHeight: number =
122
+ (height as number) > textRealHeight ? (height as number) : textRealHeight
123
+ // 如果设置了文本高度,取设置的高度
94
124
  if (textHeight) {
95
- foreignObjectHeight = textHeight
125
+ foreignObjectHeight = textHeight as number
96
126
  }
127
+
97
128
  const isEllipsis = overflowMode === 'ellipsis'
98
129
  if (isEllipsis) {
99
130
  foreignObjectHeight = fontSize + 2
100
131
  }
132
+
101
133
  return (
102
134
  <g>
103
135
  <foreignObject
@@ -105,6 +137,7 @@ function renderHtmlText(props) {
105
137
  height={foreignObjectHeight}
106
138
  x={x - textRealWidth / 2}
107
139
  y={y - foreignObjectHeight / 2}
140
+ style={{ overflow: 'visible', textAlign: 'left' }}
108
141
  >
109
142
  <div
110
143
  className="lf-node-text-auto-wrap"
@@ -121,12 +154,10 @@ function renderHtmlText(props) {
121
154
  : 'lf-node-text-auto-wrap-content'
122
155
  }
123
156
  title={isEllipsis ? rows.join('') : ''}
124
- style={{
125
- ...props,
126
- }}
157
+ style={{ ...(props as h.JSX.CSSProperties) }}
127
158
  >
128
- {rows.map((item) => (
129
- <div className="lf-node-text--auto-wrap-inner">{item}</div>
159
+ {rows.map((row) => (
160
+ <div className="lf-node-text--auto-wrap-inner">{row}</div>
130
161
  ))}
131
162
  </div>
132
163
  </div>
@@ -1,63 +1,102 @@
1
- import { Component, createElement as h } from 'preact/compat'
2
- import { Text } from '../shape'
3
- import { StepDrag } from '../../util'
1
+ import classNames from 'classnames'
2
+ import { createElement as h, Component } from 'preact/compat'
4
3
  import { ElementState } from '../../constant'
5
- import { GraphModel, Model } from '../../model'
4
+ import { GraphModel, BaseNodeModel, BaseEdgeModel } from '../../model'
5
+ import { Text } from '../shape'
6
+ import { IDragParams, StepDrag } from '../../util'
6
7
 
7
- type IProps = {
8
- model: Model.BaseModel
8
+ export type IBaseTextProps = {
9
+ model: BaseNodeModel | BaseEdgeModel
9
10
  graphModel: GraphModel
10
11
  draggable: boolean
11
12
  editable: boolean
12
13
  }
13
- type IState = {
14
+
15
+ export type IBaseTextState = {
14
16
  isHovered: boolean
15
17
  }
16
18
 
17
- export class BaseText extends Component<IProps, IState> {
18
- stepDrag: StepDrag
19
+ export class BaseText<
20
+ P extends IBaseTextProps,
21
+ S extends IBaseTextState,
22
+ > extends Component<P, S> {
23
+ stepperDrag: StepDrag
19
24
 
20
- constructor(config) {
25
+ constructor(props: P) {
21
26
  super()
22
- const { draggable } = config
23
- this.stepDrag = new StepDrag({
27
+ const { draggable } = props
28
+ // TODO: 确认为什么不在 new 的时候传入 model,而在下面使用的时候赋值
29
+ this.stepperDrag = new StepDrag({
24
30
  onDragging: this.onDragging,
25
31
  step: 1,
32
+ // model,
26
33
  isStopPropagation: draggable,
27
34
  })
28
35
  }
29
36
 
30
37
  getShape(): h.JSX.Element | null {
31
38
  const { model, graphModel } = this.props
32
- const { text } = model
33
39
  const { editConfigModel } = graphModel
34
- const { value, x, y, editable, draggable } = text
40
+ const {
41
+ text: { value, x, y, editable, draggable },
42
+ } = model
35
43
  const attr = {
36
44
  x,
37
45
  y,
38
46
  className: '',
39
47
  value,
40
48
  }
41
- if (editable) {
42
- attr.className = 'lf-element-text'
43
- } else if (draggable || editConfigModel.nodeTextDraggable) {
44
- attr.className = 'lf-text-draggable'
45
- } else {
46
- attr.className = 'lf-text-disabled'
47
- }
49
+ // DONE: 代码优化,看是否可以引入 classnames
50
+ // TODO: 确认下面逻辑是否正确,确认正确后删除下面注释
51
+ // if (editable) {
52
+ // attr.className = 'lf-element-text';
53
+ // } else if (draggable || editConfigModel.nodeTextDraggable) {
54
+ // attr.className = 'lf-text-draggable';
55
+ // } else {
56
+ // attr.className = 'lf-text-disabled';
57
+ // }
48
58
  const style = model.getTextStyle()
49
- return <Text {...attr} {...style} model={model} />
59
+ const isDraggable = editConfigModel.nodeTextDraggable || draggable
60
+
61
+ return (
62
+ <Text
63
+ {...attr}
64
+ {...style}
65
+ className={classNames({
66
+ 'lf-element-text': editable,
67
+ 'lf-text-draggable': !editable && isDraggable,
68
+ 'lf-text-disabled': !editable && !isDraggable,
69
+ })}
70
+ model={model}
71
+ />
72
+ )
73
+ }
74
+
75
+ mouseDownHandler = (e: MouseEvent) => {
76
+ const { draggable, model, graphModel } = this.props
77
+ const {
78
+ editConfigModel: { nodeTextDraggable },
79
+ } = graphModel
80
+
81
+ if (draggable || nodeTextDraggable) {
82
+ this.stepperDrag.model = model
83
+ this.stepperDrag.handleMouseDown(e)
84
+ }
50
85
  }
51
86
 
52
- onDragging = ({ deltaX, deltaY }) => {
87
+ onDragging = ({ deltaX, deltaY }: IDragParams) => {
53
88
  const {
54
89
  model,
55
90
  graphModel: { transformModel },
56
91
  } = this.props
57
- const [curDeltaX, curDeltaY] = transformModel.fixDeltaXY(deltaX, deltaY)
58
- model.moveText(curDeltaX, curDeltaY)
92
+
93
+ if (deltaX && deltaY) {
94
+ const [curDeltaX, curDeltaY] = transformModel.fixDeltaXY(deltaX, deltaY)
95
+ model.moveText(curDeltaX, curDeltaY)
96
+ }
59
97
  }
60
- dblClickHandler = () => {
98
+
99
+ dbClickHandler = () => {
61
100
  // 静默模式下,双击不更改状态,不可编辑
62
101
  const { editable } = this.props
63
102
  if (editable) {
@@ -65,27 +104,14 @@ export class BaseText extends Component<IProps, IState> {
65
104
  model.setElementState(ElementState.TEXT_EDIT)
66
105
  }
67
106
  }
68
- mouseDownHandle = (ev: MouseEvent) => {
69
- const {
70
- draggable,
71
- model,
72
- graphModel: {
73
- editConfigModel: { nodeTextDraggable },
74
- },
75
- } = this.props
76
- if (draggable || nodeTextDraggable) {
77
- this.stepDrag.model = model
78
- this.stepDrag.handleMouseDown(ev)
79
- }
80
- }
81
107
 
82
- render() {
108
+ render(): h.JSX.Element | undefined {
83
109
  const {
84
110
  model: { text },
85
111
  } = this.props
86
112
  if (text) {
87
113
  return (
88
- <g onMouseDown={this.mouseDownHandle} onDblClick={this.dblClickHandler}>
114
+ <g onMouseDown={this.mouseDownHandler} onDblClick={this.dbClickHandler}>
89
115
  {this.getShape()}
90
116
  </g>
91
117
  )
@@ -1,40 +1,62 @@
1
- import Text from '../shape/Text'
2
- import Rect from '../shape/Rect'
3
- import BaseText from './BaseText'
4
- import { BaseEdgeModel } from '../../model'
5
- import {
6
- getBytesLength,
7
- getHtmlTextHeight,
8
- getSvgTextWidthHeight,
9
- } from '../../util'
10
-
11
- export class LineText extends BaseText {
12
- constructor(config) {
13
- super(config)
1
+ import { createElement as h } from 'preact/compat'
2
+ import { Text, ITextProps, Rect, IRectProps } from '..'
3
+ import { BaseText } from '.'
4
+ import { BaseEdgeModel, GraphModel } from '../../model'
5
+ import { getHtmlTextHeight, getSvgTextSize } from '../../util'
6
+
7
+ export type ILineTextProps = {
8
+ model: BaseEdgeModel
9
+ graphModel: GraphModel
10
+ draggable: boolean
11
+ editable: boolean
12
+ [key: string]: unknown
13
+ }
14
+
15
+ export type ILineTextState = {
16
+ isHovered: boolean
17
+ }
18
+
19
+ export class LineText extends BaseText<ILineTextProps, ILineTextState> {
20
+ constructor(props: ILineTextProps) {
21
+ super(props)
14
22
  this.state = {
15
23
  isHovered: false,
16
24
  }
17
25
  }
18
26
 
19
- getBackground() {
20
- const model = this.props.model as BaseEdgeModel
27
+ // Hover 状态相关
28
+ setHoverOn = () => {
29
+ this.setState({
30
+ isHovered: true,
31
+ })
32
+ }
33
+ setHoverOff = () => {
34
+ this.setState({
35
+ isHovered: false,
36
+ })
37
+ }
38
+
39
+ getBackground(): h.JSX.Element | null {
40
+ const { isHovered } = this.state
41
+ const { model } = this.props
42
+ const { text } = model
21
43
  const style = model.getTextStyle()
22
- const { text, width: modelWidth } = model
44
+
23
45
  let backgroundStyle = style.background || {}
24
- const { isHovered } = this.state
25
- if (isHovered && style?.hover && style?.hover.background) {
26
- backgroundStyle = { ...backgroundStyle, ...style?.hover.background }
46
+ if (isHovered && style.hover && style.hover.background) {
47
+ backgroundStyle = { ...backgroundStyle, ...style.hover.background }
27
48
  }
28
- // 存在文本并且文本背景不为透明时计算背景框
29
- if (text && text.value && backgroundStyle.fill !== 'transparent') {
30
- const { fontSize, overflowMode, lineHeight, wrapPadding, textWidth } =
31
- style ?? {}
32
- const { value } = text
33
- let { x, y } = text
34
- const rows = String(value).split(/[\r\n]/g)
35
- // 计算行数
49
+
50
+ // 当存在文本并且文本背景不为透明时,计算背景框
51
+ if (text?.value && backgroundStyle?.fill !== 'transparent') {
52
+ const { fontSize, textWidth, lineHeight, overflowMode } = style
53
+ const { wrapPadding } = backgroundStyle
54
+ const rows = text?.value.split(/[\r\n]/g)
36
55
  const rowsLength = rows.length
37
- let rectAttr
56
+
57
+ let { x, y } = text
58
+ let rectAttr: unknown = {}
59
+
38
60
  if (overflowMode === 'autoWrap' && textWidth) {
39
61
  const textHeight = getHtmlTextHeight({
40
62
  rows,
@@ -47,30 +69,18 @@ export class LineText extends BaseText {
47
69
  rowsLength,
48
70
  className: 'lf-get-text-height',
49
71
  })
72
+
50
73
  rectAttr = {
51
74
  ...backgroundStyle,
52
- x: x - 1,
53
- y: y - 1,
75
+ x,
76
+ y,
54
77
  width: textWidth,
55
78
  height: textHeight,
56
79
  }
57
80
  } else {
58
- // 计算文本中最长的一行的字节数
59
- let longestBytes = 0
60
- rows &&
61
- rows.forEach((item) => {
62
- const rowByteLength = getBytesLength(item)
63
- longestBytes =
64
- rowByteLength > longestBytes ? rowByteLength : longestBytes
65
- })
66
- // 背景框宽度,最长一行字节数/2 * fontsize + 2
67
- // 背景框宽度, 行数 * fontsize + 2
68
- let { width, height } = getSvgTextWidthHeight({
69
- rows,
70
- fontSize,
71
- rowsLength,
72
- })
73
-
81
+ // 背景框宽度,最长一行字节数 / 2 * fontSize + 2
82
+ // 背景框宽度,行数 * fontSize + 2
83
+ let { width, height } = getSvgTextSize({ rows, rowsLength, fontSize })
74
84
  if (overflowMode === 'ellipsis') {
75
85
  // https://github.com/didi/LogicFlow/issues/1151
76
86
  // 边上的文字过长(使用"ellipsis"模式)出现省略号,背景也需要进行宽度的重新计算
@@ -78,30 +88,38 @@ export class LineText extends BaseText {
78
88
  // 跟Text.tsx保持同样的计算逻辑(overflowMode === 'ellipsis')
79
89
  // Text.tsx使用textRealWidth=textWidth || width
80
90
  // Text.tsx使用foreignObjectHeight = fontSize + 2;
81
- width = textWidth || (modelWidth as number)
91
+ width = textWidth
82
92
  height = fontSize + 2
83
93
  }
84
94
 
85
- // 根据设置的padding调整width, height, x, y的值
95
+ // 根据设置的 padding 调整 width, height, x, y 的值
96
+ // TODO: 下面方法感觉可以提取成工具方法
86
97
  if (typeof backgroundStyle.wrapPadding === 'string') {
87
- let paddings = backgroundStyle.wrapPadding
98
+ let padding = backgroundStyle.wrapPadding
88
99
  .split(',')
89
100
  .filter((padding) => padding.trim())
90
101
  .map((padding) => parseFloat(padding.trim()))
91
- if (paddings.length > 0 && paddings.length <= 4) {
92
- if (paddings.length === 1) {
93
- paddings = [paddings[0], paddings[0], paddings[0], paddings[0]]
94
- } else if (paddings.length === 2) {
95
- paddings = [paddings[0], paddings[1], paddings[0], paddings[1]]
96
- } else if (paddings.length === 3) {
97
- paddings = [paddings[0], paddings[1], paddings[2], paddings[1]]
102
+
103
+ if (padding.length > 0 && padding.length <= 4) {
104
+ if (padding.length === 1) {
105
+ const [allSides] = padding
106
+ padding = [allSides, allSides, allSides, allSides]
107
+ } else if (padding.length === 2) {
108
+ const [vertical, horizontal] = padding
109
+ padding = [vertical, horizontal, vertical, horizontal]
110
+ } else if (padding.length === 3) {
111
+ const [top, horizontal, bottom] = padding
112
+ padding = [top, horizontal, bottom, horizontal]
98
113
  }
99
- width += paddings[1] + paddings[3]
100
- height += paddings[0] + paddings[2]
101
- x = x + (paddings[1] - paddings[3]) / 2
102
- y = y + (paddings[2] - paddings[0]) / 2
114
+
115
+ const [top, right, bottom, left] = padding
116
+ width += right + left
117
+ height += top + bottom
118
+ x = x + (right - left) / 2
119
+ y = y + (bottom - top) / 2
103
120
  }
104
121
  }
122
+
105
123
  rectAttr = {
106
124
  ...backgroundStyle,
107
125
  x: x - 1,
@@ -110,42 +128,38 @@ export class LineText extends BaseText {
110
128
  height,
111
129
  }
112
130
  }
113
- return <Rect {...rectAttr} />
131
+
132
+ return <Rect {...(rectAttr as IRectProps)} />
114
133
  }
115
- }
116
134
 
117
- setHoverON = () => {
118
- this.setState({
119
- isHovered: true,
120
- })
121
- }
122
- setHoverOFF = () => {
123
- this.setState({
124
- isHovered: false,
125
- })
135
+ return null
126
136
  }
127
137
 
128
- getShape() {
138
+ getShape(): h.JSX.Element | null {
129
139
  const { model } = this.props
130
- const { text } = model
131
- const { value, x, y } = text
140
+ const {
141
+ text: { x, y, value },
142
+ } = model
132
143
  if (!value) return null
144
+
133
145
  const style = model.getTextStyle()
134
- const attr = {
146
+ const attrs: ITextProps = {
135
147
  x,
136
148
  y,
137
- className: 'lf-element-text',
138
149
  value,
139
- ...style, // 透传 edgeText 属性, 如 color fontSize fontWeight fontFamily textAnchor 等
150
+ model,
151
+ className: 'lf-element-text',
152
+ ...style, // 透传 edgeText 属性,如:color, fontSize, fontWeight, fontFamily, textAnchor 等
140
153
  }
154
+
141
155
  return (
142
156
  <g
143
157
  className="lf-line-text"
144
- onMouseEnter={this.setHoverON}
145
- onMouseLeave={this.setHoverOFF}
158
+ onMouseEnter={this.setHoverOn}
159
+ onMouseLeave={this.setHoverOff}
146
160
  >
147
161
  {this.getBackground()}
148
- <Text {...attr} model={model} />
162
+ <Text {...attrs} />
149
163
  </g>
150
164
  )
151
165
  }