@antv/infographic 0.2.13 → 0.2.15

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 (241) hide show
  1. package/README.md +12 -5
  2. package/README.zh-CN.md +12 -5
  3. package/dist/infographic.min.js +180 -171
  4. package/dist/infographic.min.js.map +1 -1
  5. package/esm/designs/structures/index.d.ts +1 -0
  6. package/esm/designs/structures/index.js +1 -0
  7. package/esm/designs/structures/relation-dagre-flow.js +4 -139
  8. package/esm/designs/structures/sequence-interaction.d.ts +54 -0
  9. package/esm/designs/structures/sequence-interaction.js +440 -0
  10. package/esm/designs/utils/geometry.d.ts +44 -0
  11. package/esm/designs/utils/geometry.js +244 -0
  12. package/esm/designs/utils/index.d.ts +1 -0
  13. package/esm/designs/utils/index.js +1 -0
  14. package/esm/editor/commands/UpdateOptions.d.ts +4 -4
  15. package/esm/editor/commands/UpdateOptions.js +6 -3
  16. package/esm/editor/editor.d.ts +5 -1
  17. package/esm/editor/editor.js +16 -5
  18. package/esm/editor/index.d.ts +1 -0
  19. package/esm/editor/index.js +1 -0
  20. package/esm/editor/interactions/brush-select.d.ts +0 -1
  21. package/esm/editor/interactions/brush-select.js +2 -10
  22. package/esm/editor/interactions/drag-canvas.d.ts +35 -0
  23. package/esm/editor/interactions/drag-canvas.js +161 -0
  24. package/esm/editor/interactions/drag-element.js +4 -3
  25. package/esm/editor/interactions/index.d.ts +1 -0
  26. package/esm/editor/interactions/index.js +1 -0
  27. package/esm/editor/interactions/zoom-wheel.d.ts +9 -0
  28. package/esm/editor/interactions/zoom-wheel.js +32 -15
  29. package/esm/editor/managers/index.d.ts +1 -0
  30. package/esm/editor/managers/index.js +1 -0
  31. package/esm/editor/managers/state.d.ts +4 -2
  32. package/esm/editor/managers/state.js +14 -13
  33. package/esm/editor/managers/sync-registry.d.ts +16 -0
  34. package/esm/editor/managers/sync-registry.js +51 -0
  35. package/esm/editor/plugins/{edit-bar/components → components}/button.js +1 -1
  36. package/esm/editor/plugins/{edit-bar/components → components}/color-picker.js +1 -1
  37. package/esm/editor/plugins/{edit-bar/components → components}/icons.d.ts +1 -0
  38. package/esm/editor/plugins/{edit-bar/components → components}/icons.js +1 -0
  39. package/esm/editor/plugins/{edit-bar/components → components}/popover.js +2 -2
  40. package/esm/editor/plugins/{edit-bar/components → components}/select.js +1 -1
  41. package/esm/editor/plugins/core-sync.d.ts +8 -0
  42. package/esm/editor/plugins/core-sync.js +30 -0
  43. package/esm/editor/plugins/edit-bar/edit-items/align-elements.js +1 -1
  44. package/esm/editor/plugins/edit-bar/edit-items/font-align.js +1 -1
  45. package/esm/editor/plugins/edit-bar/edit-items/font-color.js +1 -1
  46. package/esm/editor/plugins/edit-bar/edit-items/font-family.js +1 -1
  47. package/esm/editor/plugins/edit-bar/edit-items/font-size.js +1 -1
  48. package/esm/editor/plugins/edit-bar/edit-items/icon-color.js +1 -1
  49. package/esm/editor/plugins/edit-bar/index.d.ts +2 -2
  50. package/esm/editor/plugins/edit-bar/index.js +1 -1
  51. package/esm/editor/plugins/index.d.ts +2 -0
  52. package/esm/editor/plugins/index.js +2 -0
  53. package/esm/editor/plugins/reset-viewbox.d.ts +33 -0
  54. package/esm/editor/plugins/reset-viewbox.js +186 -0
  55. package/esm/editor/types/editor.d.ts +14 -0
  56. package/esm/editor/types/index.d.ts +1 -0
  57. package/esm/editor/types/interaction.d.ts +9 -0
  58. package/esm/editor/types/state.d.ts +4 -2
  59. package/esm/editor/types/sync.d.ts +27 -0
  60. package/esm/editor/types/sync.js +1 -0
  61. package/esm/editor/utils/data.js +3 -1
  62. package/esm/editor/utils/event.d.ts +1 -0
  63. package/esm/editor/utils/event.js +8 -0
  64. package/esm/editor/utils/index.d.ts +1 -0
  65. package/esm/editor/utils/index.js +1 -0
  66. package/esm/editor/utils/object.d.ts +15 -0
  67. package/esm/editor/utils/object.js +77 -0
  68. package/esm/index.d.ts +4 -3
  69. package/esm/index.js +3 -2
  70. package/esm/options/types.d.ts +7 -0
  71. package/esm/runtime/Infographic.js +20 -7
  72. package/esm/runtime/options.js +7 -2
  73. package/esm/syntax/index.js +40 -20
  74. package/esm/syntax/relations.js +26 -2
  75. package/esm/syntax/schema.js +1 -0
  76. package/esm/templates/built-in.js +27 -2
  77. package/esm/templates/sequence-interaction.d.ts +2 -0
  78. package/esm/templates/sequence-interaction.js +76 -0
  79. package/esm/types/data.d.ts +1 -0
  80. package/esm/utils/index.d.ts +1 -0
  81. package/esm/utils/index.js +1 -0
  82. package/esm/utils/measure-text.js +40 -9
  83. package/esm/utils/padding.d.ts +1 -0
  84. package/esm/utils/padding.js +6 -2
  85. package/esm/utils/types.d.ts +16 -0
  86. package/esm/utils/types.js +12 -0
  87. package/esm/version.d.ts +1 -1
  88. package/esm/version.js +1 -1
  89. package/lib/designs/structures/index.d.ts +1 -0
  90. package/lib/designs/structures/index.js +1 -0
  91. package/lib/designs/structures/relation-dagre-flow.js +5 -140
  92. package/lib/designs/structures/sequence-interaction.d.ts +54 -0
  93. package/lib/designs/structures/sequence-interaction.js +444 -0
  94. package/lib/designs/utils/geometry.d.ts +44 -0
  95. package/lib/designs/utils/geometry.js +256 -0
  96. package/lib/designs/utils/index.d.ts +1 -0
  97. package/lib/designs/utils/index.js +1 -0
  98. package/lib/editor/commands/UpdateOptions.d.ts +4 -4
  99. package/lib/editor/commands/UpdateOptions.js +6 -3
  100. package/lib/editor/editor.d.ts +5 -1
  101. package/lib/editor/editor.js +16 -5
  102. package/lib/editor/index.d.ts +1 -0
  103. package/lib/editor/index.js +1 -0
  104. package/lib/editor/interactions/brush-select.d.ts +0 -1
  105. package/lib/editor/interactions/brush-select.js +1 -9
  106. package/lib/editor/interactions/drag-canvas.d.ts +35 -0
  107. package/lib/editor/interactions/drag-canvas.js +165 -0
  108. package/lib/editor/interactions/drag-element.js +4 -3
  109. package/lib/editor/interactions/index.d.ts +1 -0
  110. package/lib/editor/interactions/index.js +3 -1
  111. package/lib/editor/interactions/zoom-wheel.d.ts +9 -0
  112. package/lib/editor/interactions/zoom-wheel.js +32 -15
  113. package/lib/editor/managers/index.d.ts +1 -0
  114. package/lib/editor/managers/index.js +1 -0
  115. package/lib/editor/managers/state.d.ts +4 -2
  116. package/lib/editor/managers/state.js +12 -11
  117. package/lib/editor/managers/sync-registry.d.ts +16 -0
  118. package/lib/editor/managers/sync-registry.js +55 -0
  119. package/lib/editor/plugins/{edit-bar/components → components}/button.js +1 -1
  120. package/lib/editor/plugins/{edit-bar/components → components}/color-picker.js +1 -1
  121. package/lib/editor/plugins/{edit-bar/components → components}/icons.d.ts +1 -0
  122. package/lib/editor/plugins/{edit-bar/components → components}/icons.js +2 -1
  123. package/lib/editor/plugins/{edit-bar/components → components}/popover.js +2 -2
  124. package/lib/editor/plugins/{edit-bar/components → components}/select.js +1 -1
  125. package/lib/editor/plugins/core-sync.d.ts +8 -0
  126. package/lib/editor/plugins/core-sync.js +34 -0
  127. package/lib/editor/plugins/edit-bar/edit-items/align-elements.js +1 -1
  128. package/lib/editor/plugins/edit-bar/edit-items/font-align.js +1 -1
  129. package/lib/editor/plugins/edit-bar/edit-items/font-color.js +1 -1
  130. package/lib/editor/plugins/edit-bar/edit-items/font-family.js +1 -1
  131. package/lib/editor/plugins/edit-bar/edit-items/font-size.js +1 -1
  132. package/lib/editor/plugins/edit-bar/edit-items/icon-color.js +1 -1
  133. package/lib/editor/plugins/edit-bar/index.d.ts +2 -2
  134. package/lib/editor/plugins/edit-bar/index.js +1 -1
  135. package/lib/editor/plugins/index.d.ts +2 -0
  136. package/lib/editor/plugins/index.js +5 -1
  137. package/lib/editor/plugins/reset-viewbox.d.ts +33 -0
  138. package/lib/editor/plugins/reset-viewbox.js +190 -0
  139. package/lib/editor/types/editor.d.ts +14 -0
  140. package/lib/editor/types/index.d.ts +1 -0
  141. package/lib/editor/types/interaction.d.ts +9 -0
  142. package/lib/editor/types/state.d.ts +4 -2
  143. package/lib/editor/types/sync.d.ts +27 -0
  144. package/lib/editor/types/sync.js +2 -0
  145. package/lib/editor/utils/data.js +3 -1
  146. package/lib/editor/utils/event.d.ts +1 -0
  147. package/lib/editor/utils/event.js +9 -0
  148. package/lib/editor/utils/index.d.ts +1 -0
  149. package/lib/editor/utils/index.js +1 -0
  150. package/lib/editor/utils/object.d.ts +15 -0
  151. package/lib/editor/utils/object.js +80 -0
  152. package/lib/index.d.ts +4 -3
  153. package/lib/index.js +9 -2
  154. package/lib/options/types.d.ts +7 -0
  155. package/lib/runtime/Infographic.js +19 -6
  156. package/lib/runtime/options.js +6 -1
  157. package/lib/syntax/index.js +40 -20
  158. package/lib/syntax/relations.js +26 -2
  159. package/lib/syntax/schema.js +1 -0
  160. package/lib/templates/built-in.js +27 -2
  161. package/lib/templates/sequence-interaction.d.ts +2 -0
  162. package/lib/templates/sequence-interaction.js +79 -0
  163. package/lib/types/data.d.ts +1 -0
  164. package/lib/utils/index.d.ts +1 -0
  165. package/lib/utils/index.js +1 -0
  166. package/lib/utils/measure-text.js +39 -8
  167. package/lib/utils/padding.d.ts +1 -0
  168. package/lib/utils/padding.js +7 -2
  169. package/lib/utils/types.d.ts +16 -0
  170. package/lib/utils/types.js +13 -0
  171. package/lib/version.d.ts +1 -1
  172. package/lib/version.js +1 -1
  173. package/package.json +1 -1
  174. package/src/designs/structures/index.ts +1 -0
  175. package/src/designs/structures/relation-dagre-flow.tsx +14 -178
  176. package/src/designs/structures/sequence-interaction.tsx +885 -0
  177. package/src/designs/utils/geometry.tsx +315 -0
  178. package/src/designs/utils/index.ts +1 -0
  179. package/src/editor/commands/UpdateOptions.ts +11 -6
  180. package/src/editor/editor.ts +26 -5
  181. package/src/editor/index.ts +1 -0
  182. package/src/editor/interactions/brush-select.ts +2 -8
  183. package/src/editor/interactions/drag-canvas.ts +203 -0
  184. package/src/editor/interactions/drag-element.ts +5 -4
  185. package/src/editor/interactions/index.ts +1 -0
  186. package/src/editor/interactions/zoom-wheel.ts +49 -13
  187. package/src/editor/managers/index.ts +1 -0
  188. package/src/editor/managers/state.ts +21 -21
  189. package/src/editor/managers/sync-registry.ts +66 -0
  190. package/src/editor/plugins/{edit-bar/components → components}/button.ts +1 -1
  191. package/src/editor/plugins/{edit-bar/components → components}/color-picker.ts +1 -1
  192. package/src/editor/plugins/{edit-bar/components → components}/icons.ts +4 -0
  193. package/src/editor/plugins/{edit-bar/components → components}/popover.ts +2 -2
  194. package/src/editor/plugins/{edit-bar/components → components}/select.ts +1 -1
  195. package/src/editor/plugins/core-sync.ts +44 -0
  196. package/src/editor/plugins/edit-bar/edit-items/align-elements.ts +2 -2
  197. package/src/editor/plugins/edit-bar/edit-items/font-align.ts +1 -1
  198. package/src/editor/plugins/edit-bar/edit-items/font-color.ts +1 -1
  199. package/src/editor/plugins/edit-bar/edit-items/font-family.ts +1 -1
  200. package/src/editor/plugins/edit-bar/edit-items/font-size.ts +3 -3
  201. package/src/editor/plugins/edit-bar/edit-items/icon-color.ts +1 -1
  202. package/src/editor/plugins/edit-bar/index.ts +2 -2
  203. package/src/editor/plugins/index.ts +2 -0
  204. package/src/editor/plugins/reset-viewbox.ts +258 -0
  205. package/src/editor/types/editor.ts +18 -0
  206. package/src/editor/types/index.ts +1 -0
  207. package/src/editor/types/interaction.ts +31 -0
  208. package/src/editor/types/state.ts +14 -2
  209. package/src/editor/types/sync.ts +33 -0
  210. package/src/editor/utils/data.ts +2 -1
  211. package/src/editor/utils/event.ts +7 -0
  212. package/src/editor/utils/index.ts +1 -0
  213. package/src/editor/utils/object.ts +116 -0
  214. package/src/index.ts +26 -2
  215. package/src/options/types.ts +11 -0
  216. package/src/runtime/Infographic.tsx +27 -17
  217. package/src/runtime/options.ts +8 -1
  218. package/src/syntax/index.ts +51 -18
  219. package/src/syntax/relations.ts +29 -2
  220. package/src/syntax/schema.ts +1 -0
  221. package/src/templates/built-in.ts +30 -0
  222. package/src/templates/sequence-interaction.ts +101 -0
  223. package/src/types/data.ts +1 -0
  224. package/src/utils/index.ts +1 -0
  225. package/src/utils/measure-text.ts +41 -9
  226. package/src/utils/padding.ts +10 -2
  227. package/src/utils/types.ts +61 -0
  228. package/src/version.ts +1 -1
  229. /package/esm/editor/plugins/{edit-bar/components → components}/button.d.ts +0 -0
  230. /package/esm/editor/plugins/{edit-bar/components → components}/color-picker.d.ts +0 -0
  231. /package/esm/editor/plugins/{edit-bar/components → components}/index.d.ts +0 -0
  232. /package/esm/editor/plugins/{edit-bar/components → components}/index.js +0 -0
  233. /package/esm/editor/plugins/{edit-bar/components → components}/popover.d.ts +0 -0
  234. /package/esm/editor/plugins/{edit-bar/components → components}/select.d.ts +0 -0
  235. /package/lib/editor/plugins/{edit-bar/components → components}/button.d.ts +0 -0
  236. /package/lib/editor/plugins/{edit-bar/components → components}/color-picker.d.ts +0 -0
  237. /package/lib/editor/plugins/{edit-bar/components → components}/index.d.ts +0 -0
  238. /package/lib/editor/plugins/{edit-bar/components → components}/index.js +0 -0
  239. /package/lib/editor/plugins/{edit-bar/components → components}/popover.d.ts +0 -0
  240. /package/lib/editor/plugins/{edit-bar/components → components}/select.d.ts +0 -0
  241. /package/src/editor/plugins/{edit-bar/components → components}/index.ts +0 -0
@@ -0,0 +1,440 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "../../jsx-runtime.js";
2
+ import { Defs, getElementBounds, Group, Path, Rect, Text } from '../../jsx/index.js';
3
+ import { BtnAdd, BtnRemove, BtnsGroup, ItemLabel, ItemsGroup, } from '../components/index.js';
4
+ import { FlexLayout } from '../layouts/index.js';
5
+ import { createArrowElements, getColorPrimary, getEdgePathD, getLabelPosition, getNodesAnchors, getPaletteColor, getTangentAngle, getThemeColors, } from '../utils/index.js';
6
+ import { registerStructure } from './registry.js';
7
+ const DEFAULT_LANE_GAP = 350;
8
+ const DEFAULT_NODE_GAP = 80;
9
+ const DEFAULT_LIFELINE_WIDTH = 2;
10
+ const DEFAULT_ARROW_WIDTH = 2;
11
+ const DEFAULT_PADDING = 40;
12
+ const DEFAULT_LANE_HEADER_HEIGHT = 60;
13
+ const DEFAULT_ITEM_WIDTH = 120;
14
+ const DEFAULT_ITEM_HEIGHT = 50;
15
+ const FONT_SIZE = 14;
16
+ const ARROW_SIZE = 14;
17
+ const CORNER_RADIUS_NODE = 6;
18
+ const LANE_PADDING = 60;
19
+ const BTN_HALF_SIZE = 12;
20
+ const BTN_MARGIN = 10;
21
+ const BTN_LANE_ADD_Gap = 20;
22
+ const BOTTOM_AREA_HEIGHT = 60;
23
+ const LANE_HEADER_MARGIN = 10;
24
+ const LABEL_OFFSET_Y = 10;
25
+ const FIRST_GAP = 20;
26
+ const PATH_OFFSET = 40;
27
+ const calculateEdgePath = (fromId, toId, fromLayout, toLayout, edgeMap, fromOutDegree, toInDegree, fromInDegree, toOutDegree) => {
28
+ const fromAnchors = getNodesAnchors(fromLayout);
29
+ const toAnchors = getNodesAnchors(toLayout);
30
+ const reverseKey = `${toId}-${fromId}`;
31
+ const hasReverse = edgeMap.has(reverseKey);
32
+ const isStartLane = fromLayout.laneIndex === 0;
33
+ let points = [];
34
+ if (fromId === toId) {
35
+ // 1. 自连接 (A->A)
36
+ // RT -> Right Arc -> RB
37
+ const start = isStartLane ? fromAnchors.LT : fromAnchors.RT;
38
+ const end = isStartLane ? fromAnchors.LB : fromAnchors.RB;
39
+ const offset = isStartLane ? -PATH_OFFSET : PATH_OFFSET;
40
+ points = [
41
+ [start.x, start.y],
42
+ [start.x + offset, start.y],
43
+ [end.x + offset, end.y],
44
+ [end.x, end.y],
45
+ ];
46
+ }
47
+ else if (fromLayout.laneIndex === toLayout.laneIndex) {
48
+ // 2. 同泳道回环 (Bottom -> Top)
49
+ const start = isStartLane ? fromAnchors.LB : fromAnchors.RB;
50
+ const end = isStartLane ? toAnchors.LT : toAnchors.RT;
51
+ const offset = isStartLane ? -PATH_OFFSET : PATH_OFFSET;
52
+ points = [
53
+ [start.x, start.y],
54
+ [start.x + offset, start.y],
55
+ [end.x + offset, end.y],
56
+ [end.x, end.y],
57
+ ];
58
+ }
59
+ else {
60
+ // 3. 互连 & 单向连接
61
+ const isToRight = toLayout.centerX > fromLayout.centerX;
62
+ const isToLeft = toLayout.centerX < fromLayout.centerX;
63
+ const isSameY = Math.abs(fromLayout.centerY - toLayout.centerY) < 1;
64
+ const isTargetBelow = toLayout.centerY > fromLayout.centerY;
65
+ const isTargetStrictRight = toLayout.x >= fromLayout.x + fromLayout.width;
66
+ let startPoint;
67
+ let endPoint;
68
+ // 优先处理同行情况
69
+ if (isSameY) {
70
+ startPoint = isToRight ? fromAnchors.RC : fromAnchors.LC;
71
+ endPoint = isToRight ? toAnchors.LC : toAnchors.RC;
72
+ }
73
+ // 处理互连情况 (避免重叠,使用对角锚点)
74
+ else if (hasReverse) {
75
+ if (isTargetBelow) {
76
+ startPoint = isToRight ? fromAnchors.RB : fromAnchors.LT;
77
+ endPoint = isToRight ? toAnchors.LT : toAnchors.RB;
78
+ }
79
+ else {
80
+ startPoint = isToRight ? fromAnchors.RT : fromAnchors.LT;
81
+ endPoint = isToRight ? toAnchors.LB : toAnchors.RB;
82
+ }
83
+ }
84
+ // 处理普通单向连接
85
+ else {
86
+ // 1. 确定终点 (End Point)
87
+ if (toInDegree === 1 && toOutDegree === 0) {
88
+ endPoint = isToRight ? toAnchors.LC : toAnchors.RC;
89
+ }
90
+ else if (isTargetBelow) {
91
+ endPoint = isTargetStrictRight ? toAnchors.LT : toAnchors.RT;
92
+ }
93
+ else {
94
+ endPoint = isTargetStrictRight ? toAnchors.LB : toAnchors.RB;
95
+ }
96
+ // 2. 确定起点 (Start Point)
97
+ if (fromOutDegree === 1 && fromInDegree === 0) {
98
+ startPoint = isToRight ? fromAnchors.RC : fromAnchors.LC;
99
+ }
100
+ else if (isToRight) {
101
+ startPoint = fromAnchors.RB;
102
+ }
103
+ else if (isToLeft) {
104
+ startPoint = fromAnchors.LB;
105
+ }
106
+ else {
107
+ startPoint = fromAnchors.RB;
108
+ }
109
+ }
110
+ if (hasReverse && !isSameY) {
111
+ // 1. 跨行(不同 Y 轴)的双向连接
112
+ const startArr = [startPoint.x, startPoint.y];
113
+ const endArr = [endPoint.x, endPoint.y];
114
+ const cx = (startArr[0] + endArr[0]) / 2;
115
+ const cy = startArr[1];
116
+ points = [startArr, [cx, cy], endArr];
117
+ }
118
+ else if (hasReverse && isSameY) {
119
+ // 2. 同行(相同 Y 轴)的双向连接
120
+ const startArr = [startPoint.x, startPoint.y];
121
+ const endArr = [endPoint.x, endPoint.y];
122
+ const midX = (startArr[0] + endArr[0]) / 2;
123
+ const midY = (startArr[1] + endArr[1]) / 2;
124
+ const offsetY = 30;
125
+ const isL2R = startArr[0] < endArr[0];
126
+ const cpY = isL2R ? midY - offsetY : midY + offsetY;
127
+ points = [startArr, [midX, cpY], endArr];
128
+ }
129
+ else {
130
+ // 3. 普通单向连接
131
+ points = [
132
+ [startPoint.x, startPoint.y],
133
+ [endPoint.x, endPoint.y],
134
+ ];
135
+ }
136
+ }
137
+ return { points };
138
+ };
139
+ export const SequenceInteractionFlow = (props) => {
140
+ var _a, _b, _c, _d, _e, _f, _g;
141
+ // 生成实例级唯一ID以避免多图表冲突
142
+ const instanceId = Math.random().toString(36).slice(2, 9);
143
+ const { Title, Item, data, laneGap = DEFAULT_LANE_GAP, nodeGap = DEFAULT_NODE_GAP, lifelineWidth = DEFAULT_LIFELINE_WIDTH, arrowWidth = DEFAULT_ARROW_WIDTH, showLifeline = true, padding = DEFAULT_PADDING, arrowType = 'triangle', showLaneHeader = true, laneHeaderHeight = DEFAULT_LANE_HEADER_HEIGHT, edgeStyle = 'solid', animated = false, edgeColorMode = 'gradient', options, } = props;
144
+ // 获取主题颜色
145
+ const themeColors = getThemeColors(options.themeConfig, options);
146
+ const colorText = (_a = themeColors === null || themeColors === void 0 ? void 0 : themeColors.colorText) !== null && _a !== void 0 ? _a : '#333333';
147
+ const colorBg = (_b = themeColors === null || themeColors === void 0 ? void 0 : themeColors.colorBg) !== null && _b !== void 0 ? _b : '#ffffff';
148
+ const colorBorder = (_c = themeColors === null || themeColors === void 0 ? void 0 : themeColors.colorTextSecondary) !== null && _c !== void 0 ? _c : '#e0e0e0';
149
+ const flowData = data;
150
+ const { title, desc, items = [], relations = [] } = flowData;
151
+ const titleContent = Title ? _jsx(Title, { title: title, desc: desc }) : null;
152
+ // 空状态处理
153
+ if (!items || items.length === 0) {
154
+ const btnBounds = getElementBounds(_jsx(BtnAdd, { indexes: [0] }));
155
+ return (_jsxs(FlexLayout, { id: "infographic-container", flexDirection: "column", justifyContent: "center", alignItems: "center", children: [titleContent, _jsxs(Group, { children: [_jsx(BtnsGroup, { children: _jsx(BtnAdd, { indexes: [0], x: -btnBounds.width / 2, y: -btnBounds.height / 2 }) }), _jsx(Text, { x: 0, y: btnBounds.height / 2 + BTN_MARGIN, width: 200, height: 40, fontSize: 14, alignHorizontal: "center", alignVertical: "middle", fill: (_d = themeColors === null || themeColors === void 0 ? void 0 : themeColors.colorTextSecondary) !== null && _d !== void 0 ? _d : '#999', children: "\u6682\u65E0\u6570\u636E" })] })] }));
156
+ }
157
+ // 泳道列表(每个顶层item是一个泳道)
158
+ const lanes = items;
159
+ // 计算最大行数(所有泳道中 children 的最大 step 或 索引),至少为1
160
+ let maxStep = 0;
161
+ lanes.forEach((lane) => {
162
+ var _a;
163
+ (_a = lane.children) === null || _a === void 0 ? void 0 : _a.forEach((child, index) => {
164
+ var _a;
165
+ const currentStep = (_a = child.step) !== null && _a !== void 0 ? _a : index;
166
+ if (currentStep > maxStep) {
167
+ maxStep = currentStep;
168
+ }
169
+ });
170
+ });
171
+ const maxRows = Math.max(1, maxStep + 1);
172
+ const nodeLayoutById = new Map();
173
+ // 测量Item尺寸
174
+ const designItem = (_e = options.design) === null || _e === void 0 ? void 0 : _e.item;
175
+ const itemConfig = Array.isArray(designItem) ? designItem[0] : designItem;
176
+ // 使用类型安全的访问或默认值
177
+ let itemWidth = (_f = itemConfig === null || itemConfig === void 0 ? void 0 : itemConfig.width) !== null && _f !== void 0 ? _f : DEFAULT_ITEM_WIDTH;
178
+ let itemHeight = (_g = itemConfig === null || itemConfig === void 0 ? void 0 : itemConfig.height) !== null && _g !== void 0 ? _g : DEFAULT_ITEM_HEIGHT;
179
+ // 构建一个扁平化的节点列表用于Item渲染
180
+ const flatNodes = [];
181
+ lanes.forEach((lane, laneIndex) => {
182
+ var _a;
183
+ (_a = lane.children) === null || _a === void 0 ? void 0 : _a.forEach((child, rowIndex) => {
184
+ flatNodes.push({ datum: child, laneIndex, rowIndex });
185
+ });
186
+ });
187
+ // 尝试通过采样修正尺寸 (仅当配置未指定时)
188
+ if ((!(itemConfig === null || itemConfig === void 0 ? void 0 : itemConfig.width) || !(itemConfig === null || itemConfig === void 0 ? void 0 : itemConfig.height)) &&
189
+ Item &&
190
+ flatNodes.length > 0) {
191
+ const sampleNode = flatNodes[0];
192
+ const sampleBounds = getElementBounds(_jsx(Item, { indexes: [0], datum: sampleNode.datum, positionH: "center", positionV: "middle" }));
193
+ // 确保尺寸有效
194
+ if (sampleBounds.width > 0)
195
+ itemWidth = sampleBounds.width;
196
+ if (sampleBounds.height > 0)
197
+ itemHeight = sampleBounds.height;
198
+ }
199
+ // 测量relations标签的最大宽度,自动调整泳道间距
200
+ let maxLabelWidth = 0;
201
+ relations.forEach((relation) => {
202
+ if (relation.label) {
203
+ const labelBounds = getElementBounds(_jsx(Text, { fontSize: FONT_SIZE, fontWeight: "normal", children: relation.label }));
204
+ maxLabelWidth = Math.max(maxLabelWidth, labelBounds.width);
205
+ }
206
+ });
207
+ // 动态计算泳道宽度:需要兼顾节点宽度、标签宽度需求以及用户设置的间距
208
+ const baseWidth = itemWidth + LANE_PADDING;
209
+ const labelWidthRequirement = itemWidth + maxLabelWidth + LANE_PADDING * 2;
210
+ const laneWidth = Math.max(laneGap, baseWidth, labelWidthRequirement);
211
+ // 计算行高度和总高度
212
+ const headerOffset = showLaneHeader ? laneHeaderHeight : 0;
213
+ const contentHeight = FIRST_GAP + maxRows * itemHeight + Math.max(0, maxRows - 1) * nodeGap;
214
+ const totalHeight = headerOffset + contentHeight + padding * 2 + BOTTOM_AREA_HEIGHT;
215
+ const totalWidth = laneWidth * lanes.length + padding * 2;
216
+ // 计算每个泳道的中心X坐标
217
+ const getLaneCenterX = (laneIndex) => {
218
+ return padding + laneWidth / 2 + laneIndex * laneWidth;
219
+ };
220
+ // 计算每行的Y坐标
221
+ const getRowY = (rowIndex) => {
222
+ return (padding +
223
+ headerOffset +
224
+ FIRST_GAP +
225
+ rowIndex * (itemHeight + nodeGap) +
226
+ itemHeight / 2);
227
+ };
228
+ const itemElements = [];
229
+ const decorElements = [];
230
+ const defsElements = [];
231
+ const btnElements = [];
232
+ // 绘制生命线
233
+ if (showLifeline) {
234
+ lanes.forEach((_lane, laneIndex) => {
235
+ const centerX = getLaneCenterX(laneIndex);
236
+ const startY = padding + headerOffset;
237
+ const endY = totalHeight - padding;
238
+ decorElements.push(_jsx(Path, { d: `M ${centerX} ${startY} L ${centerX} ${endY}`, stroke: colorBorder, strokeWidth: lifelineWidth, strokeDasharray: "5,5", fill: "none", "data-element-type": "shape" }));
239
+ // 绘制生命线末端箭头(实心)
240
+ decorElements.push(...createArrowElements(centerX, endY, Math.PI / 2, 'triangle', colorBorder, 1, 10));
241
+ });
242
+ }
243
+ // 绘制泳道标题
244
+ if (showLaneHeader) {
245
+ lanes.forEach((lane, laneIndex) => {
246
+ const centerX = getLaneCenterX(laneIndex);
247
+ const laneColor = getPaletteColor(options, [laneIndex]);
248
+ const laneThemeColors = getThemeColors({ colorPrimary: laneColor }, options);
249
+ // 泳道标题背景
250
+ if (Item) {
251
+ decorElements.push(_jsx(Item, { indexes: [laneIndex], datum: {
252
+ label: lane.label,
253
+ icon: lane.icon,
254
+ desc: lane.desc,
255
+ }, x: centerX - itemWidth / 2, y: padding, width: itemWidth, height: laneHeaderHeight - LANE_HEADER_MARGIN, themeColors: laneThemeColors, positionH: "center" }));
256
+ // 泳道标题删除按钮 (右上角)
257
+ btnElements.push(_jsx(BtnRemove, { indexes: [laneIndex], x: centerX + itemWidth / 2 - BTN_MARGIN, y: padding - BTN_MARGIN }));
258
+ }
259
+ });
260
+ }
261
+ // 绘制节点(按行对齐)
262
+ lanes.forEach((lane, laneIndex) => {
263
+ var _a, _b, _c, _d;
264
+ (_a = lane.children) === null || _a === void 0 ? void 0 : _a.forEach((child, rowIndex) => {
265
+ var _a, _b;
266
+ // 使用 step 属性作为行索引,如果未定义则回退到数组索引
267
+ const effectiveRowIndex = (_a = child.step) !== null && _a !== void 0 ? _a : rowIndex;
268
+ const centerX = getLaneCenterX(laneIndex);
269
+ const centerY = getRowY(effectiveRowIndex);
270
+ const x = centerX - itemWidth / 2;
271
+ const y = centerY - itemHeight / 2;
272
+ // 保存节点布局信息
273
+ nodeLayoutById.set(child.id, {
274
+ x,
275
+ y,
276
+ width: itemWidth,
277
+ height: itemHeight,
278
+ centerX,
279
+ centerY,
280
+ laneIndex,
281
+ rowIndex: effectiveRowIndex,
282
+ });
283
+ const nodeColor = getPaletteColor(options, [laneIndex]);
284
+ const nodeThemeColors = getThemeColors({ colorPrimary: nodeColor }, options);
285
+ // 添加节点背景遮挡层,防止生命线虚线透过半透明节点显示
286
+ // 只在节点中心放置窄条遮挡生命线,避免圆角处露出白色背景
287
+ const maskStripWidth = lifelineWidth + 6;
288
+ decorElements.push(_jsx(Rect, { x: centerX - maskStripWidth / 2, y: y, width: maskStripWidth, height: itemHeight, fill: colorBg }));
289
+ // 构造类似 hierarchy-tree 的 _originalIndex
290
+ const originalIndex = [laneIndex, rowIndex];
291
+ // 附加到数据上,确保 Item 组件能正确识别
292
+ const childWithIndex = Object.assign(Object.assign({}, child), { _originalIndex: originalIndex });
293
+ if (Item) {
294
+ itemElements.push(_jsx(Item, { indexes: originalIndex, datum: childWithIndex, data: data, x: x, y: y, positionH: "center", positionV: "middle", themeColors: nodeThemeColors }));
295
+ // 节点删除按钮 (底部剧中)
296
+ btnElements.push(_jsx(BtnRemove, { indexes: originalIndex, x: x + itemWidth / 2 - BTN_MARGIN, y: y + itemHeight + BTN_MARGIN / 2 }));
297
+ }
298
+ else {
299
+ // 默认节点渲染
300
+ decorElements.push(_jsx(Rect, { x: x, y: y, width: itemWidth, height: itemHeight, fill: (_b = nodeThemeColors === null || nodeThemeColors === void 0 ? void 0 : nodeThemeColors.colorPrimaryBg) !== null && _b !== void 0 ? _b : colorBg, stroke: nodeColor, strokeWidth: 2, rx: CORNER_RADIUS_NODE, "data-element-type": "shape" }));
301
+ if (child.label) {
302
+ decorElements.push(_jsx(Text, { x: x, y: y, width: itemWidth, height: itemHeight, fontSize: 14, fontWeight: "bold", alignHorizontal: "center", alignVertical: "middle", fill: colorText, children: child.label }));
303
+ }
304
+ }
305
+ });
306
+ // 每个泳道底部的添加节点按钮
307
+ const childCount = (_c = (_b = lane.children) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0;
308
+ // 找出当前泳道最大的 step
309
+ let lastEffectRowIndex = -1;
310
+ (_d = lane.children) === null || _d === void 0 ? void 0 : _d.forEach((child, index) => {
311
+ var _a;
312
+ const s = (_a = child.step) !== null && _a !== void 0 ? _a : index;
313
+ if (s > lastEffectRowIndex)
314
+ lastEffectRowIndex = s;
315
+ });
316
+ const lastRowY = lastEffectRowIndex >= 0
317
+ ? getRowY(lastEffectRowIndex)
318
+ : padding + headerOffset;
319
+ const addNodeY = childCount > 0
320
+ ? lastRowY + itemHeight / 2 + BTN_LANE_ADD_Gap
321
+ : lastRowY + FIRST_GAP + BTN_MARGIN;
322
+ const centerX = getLaneCenterX(laneIndex);
323
+ btnElements.push(_jsx(BtnAdd, { indexes: [laneIndex, childCount], x: centerX - BTN_HALF_SIZE, y: addNodeY }));
324
+ });
325
+ // 添加新泳道按钮 (最右侧)
326
+ const lastLaneRightX = getLaneCenterX(lanes.length - 1) + laneWidth / 2;
327
+ const newLaneX = lanes.length > 0 ? lastLaneRightX + BTN_LANE_ADD_Gap : padding;
328
+ const newLaneY = padding + headerOffset / 2 - BTN_HALF_SIZE; // 垂直居中于标题栏
329
+ btnElements.push(_jsx(BtnAdd, { indexes: [lanes.length], x: newLaneX, y: newLaneY }));
330
+ // 预处理边,方便快速查找反向边
331
+ const edgeMap = new Map();
332
+ // 统计入度和出度
333
+ const inDegreeMap = new Map();
334
+ const outDegreeMap = new Map();
335
+ relations.forEach((r) => {
336
+ var _a;
337
+ const key = `${r.from}-${r.to}`;
338
+ if (!edgeMap.has(key))
339
+ edgeMap.set(key, []);
340
+ (_a = edgeMap.get(key)) === null || _a === void 0 ? void 0 : _a.push(r);
341
+ const fromId = String(r.from);
342
+ const toId = String(r.to);
343
+ if (fromId === toId)
344
+ return;
345
+ outDegreeMap.set(fromId, (outDegreeMap.get(fromId) || 0) + 1);
346
+ inDegreeMap.set(toId, (inDegreeMap.get(toId) || 0) + 1);
347
+ });
348
+ // 绘制消息箭头
349
+ relations.forEach((relation, relIndex) => {
350
+ var _a, _b;
351
+ const fromId = String(relation.from);
352
+ const toId = String(relation.to);
353
+ // 使用精确的节点布局信息
354
+ const fromLayout = nodeLayoutById.get(fromId);
355
+ const toLayout = nodeLayoutById.get(toId);
356
+ if (!fromLayout || !toLayout)
357
+ return;
358
+ // 颜色处理
359
+ const fromColor = getPaletteColor(options, [fromLayout.laneIndex]) || '#000000';
360
+ const toColor = getPaletteColor(options, [toLayout.laneIndex]) || '#000000';
361
+ const themePrimary = getColorPrimary(options);
362
+ // 确定线条和箭头颜色
363
+ let edgeStroke = themePrimary || '#999999';
364
+ let targetArrowColor = themePrimary || '#999999';
365
+ let sourceArrowColor = themePrimary || '#999999';
366
+ // 如果是渐变模式,使用渐变色
367
+ const gradientId = `arrow-gradient-${instanceId}-${relIndex}`;
368
+ if (edgeColorMode === 'gradient') {
369
+ edgeStroke = `url(#${gradientId})`;
370
+ targetArrowColor = toColor;
371
+ sourceArrowColor = fromColor;
372
+ }
373
+ const { points } = calculateEdgePath(fromId, toId, fromLayout, toLayout, edgeMap, outDegreeMap.get(fromId) || 0, inDegreeMap.get(toId) || 0, inDegreeMap.get(fromId) || 0, outDegreeMap.get(toId) || 0);
374
+ let maskId;
375
+ let labelRenderNode = null;
376
+ if (relation.label) {
377
+ const labelPoint = getLabelPosition(points);
378
+ if (labelPoint) {
379
+ const labelX = labelPoint[0];
380
+ const labelY = labelPoint[1] - LABEL_OFFSET_Y;
381
+ // 预先计算 Label 的尺寸
382
+ const labelBounds = getElementBounds(_jsx(ItemLabel, { indexes: [relIndex], fontSize: FONT_SIZE, fontWeight: "normal", children: relation.label }));
383
+ const bgX = labelX - labelBounds.width / 2;
384
+ const bgY = labelY - labelBounds.height / 2;
385
+ const bgW = labelBounds.width;
386
+ const bgH = labelBounds.height;
387
+ maskId = `edge-mask-${instanceId}-${relIndex}`;
388
+ // 将 Mask 推入 defsElements
389
+ // 逻辑:白色区域显示(全图),黑色区域隐藏(标签位置)
390
+ defsElements.push(_jsxs("mask", { id: maskId, maskUnits: "userSpaceOnUse", x: 0, y: 0, width: totalWidth, height: totalHeight, children: [_jsx(Rect, { x: 0, y: 0, width: totalWidth, height: totalHeight, fill: "white" }), _jsx(Rect, { x: bgX, y: bgY, width: bgW, height: bgH, fill: "black" })] }));
391
+ labelRenderNode = (_jsx(ItemLabel, { indexes: [relIndex], x: labelX - labelBounds.width / 2, y: labelY - labelBounds.height / 2, width: labelBounds.width, height: labelBounds.height, fontSize: FONT_SIZE, fontWeight: "normal", alignHorizontal: "center", alignVertical: "middle", fill: colorText, children: relation.label }));
392
+ }
393
+ }
394
+ // 生成路径字符串
395
+ const pathD = getEdgePathD(points);
396
+ if (edgeColorMode === 'gradient') {
397
+ const startPoint = points[0];
398
+ const endPoint = points[points.length - 1];
399
+ defsElements.push(_jsxs("linearGradient", { id: gradientId, gradientUnits: "userSpaceOnUse", x1: startPoint[0], y1: startPoint[1], x2: endPoint[0], y2: endPoint[1], children: [_jsx("stop", { offset: "0%", stopColor: fromColor }), _jsx("stop", { offset: "100%", stopColor: toColor })] }));
400
+ }
401
+ decorElements.push(_jsx(Path, { d: pathD, stroke: edgeStroke, strokeWidth: arrowWidth, fill: "none", "data-element-type": "shape",
402
+ // 如果存在 maskId,则应用遮罩
403
+ mask: maskId ? `url(#${maskId})` : undefined, strokeDasharray: relation.lineStyle === 'solid'
404
+ ? undefined
405
+ : ((_a = relation.lineStyle) !== null && _a !== void 0 ? _a : edgeStyle) === 'dashed' || animated
406
+ ? '5,5'
407
+ : undefined, children: animated && (_jsx("animate", { attributeName: "stroke-dashoffset", from: "10", to: "0", dur: "1s", repeatCount: "indefinite" })) }));
408
+ // 绘制箭头头部 (箭头不需要遮罩,保持原样)
409
+ const effectiveArrowSize = ARROW_SIZE;
410
+ const direction = (_b = relation.direction) !== null && _b !== void 0 ? _b : 'forward';
411
+ const arrowConfigs = [
412
+ {
413
+ show: direction === 'forward' || direction === 'both',
414
+ angle: getTangentAngle(points, 1),
415
+ point: points[points.length - 1],
416
+ color: targetArrowColor,
417
+ },
418
+ {
419
+ show: direction === 'both',
420
+ angle: getTangentAngle(points, 0) + Math.PI,
421
+ point: points[0],
422
+ color: sourceArrowColor,
423
+ },
424
+ ];
425
+ arrowConfigs.forEach((cfg) => {
426
+ var _a;
427
+ if (cfg.show) {
428
+ decorElements.push(...createArrowElements(cfg.point[0], cfg.point[1], cfg.angle, (_a = relation.arrowType) !== null && _a !== void 0 ? _a : arrowType, cfg.color, arrowWidth, effectiveArrowSize));
429
+ }
430
+ });
431
+ if (labelRenderNode) {
432
+ decorElements.push(labelRenderNode);
433
+ }
434
+ });
435
+ return (_jsxs(FlexLayout, { id: "infographic-container", flexDirection: "column", justifyContent: "center", alignItems: "center", children: [Title ? _jsx(Title, { title: title, desc: desc }) : null, _jsxs(Group, { children: [_jsx(Rect, { x: 0, y: 0, width: totalWidth, height: totalHeight, fill: "none" }), _jsx(Defs, { children: defsElements }), _jsx(Group, { children: decorElements }), _jsx(ItemsGroup, { children: itemElements }), _jsx(BtnsGroup, { children: btnElements })] })] }));
436
+ };
437
+ registerStructure('sequence-interaction', {
438
+ component: SequenceInteractionFlow,
439
+ composites: ['title', 'item'],
440
+ });
@@ -0,0 +1,44 @@
1
+ import type { JSXElement } from '../../jsx';
2
+ export declare const getMidPoint: (points: [number, number][]) => [number, number] | null;
3
+ export declare const createStraightPath: (points: [number, number][], dx: number, dy: number) => string;
4
+ export declare const createRoundedPath: (points: [number, number][], radius: number, dx: number, dy: number) => string;
5
+ export declare const createArrowElements: (x: number, y: number, angle: number, type: "arrow" | "triangle" | "diamond", fillColor: string, edgeWidth: number, arrowSize: number) => JSXElement[];
6
+ export declare const getNodesAnchors: (node: {
7
+ x: number;
8
+ y: number;
9
+ width: number;
10
+ height: number;
11
+ radio?: number;
12
+ }) => {
13
+ LT: {
14
+ x: number;
15
+ y: number;
16
+ };
17
+ LC: {
18
+ x: number;
19
+ y: number;
20
+ };
21
+ LB: {
22
+ x: number;
23
+ y: number;
24
+ };
25
+ RT: {
26
+ x: number;
27
+ y: number;
28
+ };
29
+ RC: {
30
+ x: number;
31
+ y: number;
32
+ };
33
+ RB: {
34
+ x: number;
35
+ y: number;
36
+ };
37
+ };
38
+ export declare const getTangentAngle: (points: [number, number][], t: 0 | 1) => number;
39
+ /**
40
+ * 计算贝塞尔曲线上任意 t (0-1) 位置的点
41
+ */
42
+ export declare const getPointAtT: (points: [number, number][], t?: number) => [number, number];
43
+ export declare const getLabelPosition: (points: [number, number][], selfLoopOffset?: number) => [number, number];
44
+ export declare const getEdgePathD: (points: [number, number][]) => string;