@antv/infographic 0.1.1 → 0.1.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 (556) hide show
  1. package/README.md +26 -2
  2. package/README.zh-CN.md +26 -3
  3. package/dist/infographic.min.js +484 -79
  4. package/dist/infographic.min.js.map +1 -1
  5. package/esm/constants/components.d.ts +1 -0
  6. package/esm/constants/components.js +1 -0
  7. package/esm/constants/element.d.ts +17 -6
  8. package/esm/constants/index.d.ts +2 -0
  9. package/esm/constants/index.js +2 -0
  10. package/esm/constants/shape.d.ts +16 -0
  11. package/esm/designs/components/Btn.js +2 -2
  12. package/esm/designs/components/BtnsGroup.js +1 -1
  13. package/esm/designs/components/Illus.js +2 -2
  14. package/esm/designs/components/ItemDesc.js +1 -2
  15. package/esm/designs/components/ItemIcon.js +1 -1
  16. package/esm/designs/components/ItemLabel.js +1 -2
  17. package/esm/designs/components/ItemValue.js +1 -2
  18. package/esm/designs/components/ItemsGroup.js +1 -1
  19. package/esm/designs/components/Title.js +2 -5
  20. package/esm/designs/items/CandyCardLite.js +1 -1
  21. package/esm/designs/items/CircularProgress.js +2 -1
  22. package/esm/designs/items/HorizontalIconArrow.js +1 -2
  23. package/esm/designs/items/HorizontalIconLine.js +1 -1
  24. package/esm/designs/items/IconBadge.js +1 -1
  25. package/esm/designs/items/LinedText.d.ts +12 -0
  26. package/esm/designs/items/LinedText.js +57 -0
  27. package/esm/designs/items/PlainText.d.ts +1 -0
  28. package/esm/designs/items/PlainText.js +16 -3
  29. package/esm/designs/items/QuarterCircular.js +1 -31
  30. package/esm/designs/items/index.d.ts +1 -0
  31. package/esm/designs/items/index.js +1 -0
  32. package/esm/designs/layouts/Align.js +31 -45
  33. package/esm/designs/layouts/Flex.js +33 -29
  34. package/esm/designs/structures/chart-bar.d.ts +15 -0
  35. package/esm/designs/structures/chart-bar.js +99 -0
  36. package/esm/designs/structures/chart-line.d.ts +12 -0
  37. package/esm/designs/structures/chart-line.js +164 -0
  38. package/esm/designs/structures/chart-pie.d.ts +9 -0
  39. package/esm/designs/structures/chart-pie.js +127 -0
  40. package/esm/designs/structures/compare-binary-horizontal/dividers/pros-cons-arrow.js +1 -1
  41. package/esm/designs/structures/hierarchy-mindmap.d.ts +24 -0
  42. package/esm/designs/structures/hierarchy-mindmap.js +199 -0
  43. package/esm/designs/structures/index.d.ts +4 -0
  44. package/esm/designs/structures/index.js +4 -0
  45. package/esm/designs/structures/list-sector.js +1 -1
  46. package/esm/designs/structures/sequence-circular.js +1 -1
  47. package/esm/designs/structures/sequence-cylinders-3d.js +4 -4
  48. package/esm/designs/structures/sequence-roadmap-vertical.js +1 -1
  49. package/esm/designs/structures/sequence-zigzag-pucks-3d.js +5 -5
  50. package/esm/editor/commands/Batch.d.ts +11 -0
  51. package/esm/editor/commands/Batch.js +21 -0
  52. package/esm/editor/commands/UpdateElement.d.ts +16 -0
  53. package/esm/editor/commands/UpdateElement.js +83 -0
  54. package/esm/editor/commands/UpdateOptions.d.ts +14 -0
  55. package/esm/editor/commands/UpdateOptions.js +25 -0
  56. package/esm/editor/commands/UpdateText.d.ts +16 -0
  57. package/esm/editor/commands/UpdateText.js +40 -0
  58. package/esm/editor/commands/index.d.ts +4 -0
  59. package/esm/editor/commands/index.js +4 -0
  60. package/esm/editor/editor.d.ts +16 -0
  61. package/esm/editor/editor.js +50 -0
  62. package/esm/editor/index.d.ts +4 -0
  63. package/esm/editor/index.js +3 -0
  64. package/esm/editor/interactions/base.d.ts +12 -0
  65. package/esm/editor/interactions/base.js +5 -0
  66. package/esm/editor/interactions/brush-select.d.ts +23 -0
  67. package/esm/editor/interactions/brush-select.js +167 -0
  68. package/esm/editor/interactions/click-select.d.ts +12 -0
  69. package/esm/editor/interactions/click-select.js +67 -0
  70. package/esm/editor/interactions/dblclick-edit-text.d.ts +10 -0
  71. package/esm/editor/interactions/dblclick-edit-text.js +204 -0
  72. package/esm/editor/interactions/drag-element.d.ts +41 -0
  73. package/esm/editor/interactions/drag-element.js +391 -0
  74. package/esm/editor/interactions/hotkey-history.d.ts +10 -0
  75. package/esm/editor/interactions/hotkey-history.js +27 -0
  76. package/esm/editor/interactions/index.d.ts +8 -0
  77. package/esm/editor/interactions/index.js +8 -0
  78. package/esm/editor/interactions/select-highlight.d.ts +16 -0
  79. package/esm/editor/interactions/select-highlight.js +99 -0
  80. package/esm/editor/interactions/zoom-wheel.d.ts +8 -0
  81. package/esm/editor/interactions/zoom-wheel.js +46 -0
  82. package/esm/editor/managers/command.d.ts +19 -0
  83. package/esm/editor/managers/command.js +63 -0
  84. package/esm/editor/managers/index.d.ts +4 -0
  85. package/esm/editor/managers/index.js +4 -0
  86. package/esm/editor/managers/interaction.d.ts +33 -0
  87. package/esm/editor/managers/interaction.js +196 -0
  88. package/esm/editor/managers/plugin.d.ts +14 -0
  89. package/esm/editor/managers/plugin.js +45 -0
  90. package/esm/editor/managers/state.d.ts +22 -0
  91. package/esm/editor/managers/state.js +141 -0
  92. package/esm/editor/plugins/base.d.ts +12 -0
  93. package/esm/editor/plugins/base.js +5 -0
  94. package/esm/editor/plugins/edit-bar/components/button.d.ts +12 -0
  95. package/esm/editor/plugins/edit-bar/components/button.js +53 -0
  96. package/esm/editor/plugins/edit-bar/components/color-picker.d.ts +10 -0
  97. package/esm/editor/plugins/edit-bar/components/color-picker.js +351 -0
  98. package/esm/editor/plugins/edit-bar/components/icons.d.ts +26 -0
  99. package/esm/editor/plugins/edit-bar/components/icons.js +30 -0
  100. package/esm/editor/plugins/edit-bar/components/index.d.ts +5 -0
  101. package/esm/editor/plugins/edit-bar/components/index.js +5 -0
  102. package/esm/editor/plugins/edit-bar/components/popover.d.ts +23 -0
  103. package/esm/editor/plugins/edit-bar/components/popover.js +378 -0
  104. package/esm/editor/plugins/edit-bar/components/select.d.ts +22 -0
  105. package/esm/editor/plugins/edit-bar/components/select.js +201 -0
  106. package/esm/editor/plugins/edit-bar/edit-bar.d.ts +32 -0
  107. package/esm/editor/plugins/edit-bar/edit-bar.js +211 -0
  108. package/esm/editor/plugins/edit-bar/edit-items/align-elements.d.ts +2 -0
  109. package/esm/editor/plugins/edit-bar/edit-items/align-elements.js +312 -0
  110. package/esm/editor/plugins/edit-bar/edit-items/font-align.d.ts +3 -0
  111. package/esm/editor/plugins/edit-bar/edit-items/font-align.js +81 -0
  112. package/esm/editor/plugins/edit-bar/edit-items/font-color.d.ts +3 -0
  113. package/esm/editor/plugins/edit-bar/edit-items/font-color.js +77 -0
  114. package/esm/editor/plugins/edit-bar/edit-items/font-family.d.ts +3 -0
  115. package/esm/editor/plugins/edit-bar/edit-items/font-family.js +115 -0
  116. package/esm/editor/plugins/edit-bar/edit-items/font-size.d.ts +3 -0
  117. package/esm/editor/plugins/edit-bar/edit-items/font-size.js +88 -0
  118. package/esm/editor/plugins/edit-bar/edit-items/icon-color.d.ts +3 -0
  119. package/esm/editor/plugins/edit-bar/edit-items/icon-color.js +77 -0
  120. package/esm/editor/plugins/edit-bar/edit-items/index.d.ts +7 -0
  121. package/esm/editor/plugins/edit-bar/edit-items/index.js +6 -0
  122. package/esm/editor/plugins/edit-bar/edit-items/types.d.ts +3 -0
  123. package/esm/editor/plugins/edit-bar/edit-items/types.js +1 -0
  124. package/esm/editor/plugins/edit-bar/index.d.ts +4 -0
  125. package/esm/editor/plugins/edit-bar/index.js +2 -0
  126. package/esm/editor/plugins/edit-bar/utils.d.ts +4 -0
  127. package/esm/editor/plugins/edit-bar/utils.js +14 -0
  128. package/esm/editor/plugins/index.d.ts +3 -0
  129. package/esm/editor/plugins/index.js +3 -0
  130. package/esm/editor/plugins/resize-element.d.ts +45 -0
  131. package/esm/editor/plugins/resize-element.js +393 -0
  132. package/esm/editor/types/command.d.ts +28 -0
  133. package/esm/editor/types/command.js +1 -0
  134. package/esm/editor/types/editor.d.ts +4 -0
  135. package/esm/editor/types/editor.js +1 -0
  136. package/esm/editor/types/index.d.ts +7 -0
  137. package/esm/editor/types/index.js +1 -0
  138. package/esm/editor/types/interaction.d.ts +44 -0
  139. package/esm/editor/types/interaction.js +1 -0
  140. package/esm/editor/types/plugin.d.ts +30 -0
  141. package/esm/editor/types/plugin.js +1 -0
  142. package/esm/editor/types/selection.d.ts +2 -0
  143. package/esm/editor/types/selection.js +1 -0
  144. package/esm/editor/types/shape.d.ts +16 -0
  145. package/esm/editor/types/shape.js +1 -0
  146. package/esm/editor/types/state.d.ts +57 -0
  147. package/esm/editor/types/state.js +1 -0
  148. package/esm/editor/utils/click-handler.d.ts +28 -0
  149. package/esm/editor/utils/click-handler.js +97 -0
  150. package/esm/editor/utils/coordinate.d.ts +6 -0
  151. package/esm/editor/utils/coordinate.js +31 -0
  152. package/esm/editor/utils/data.d.ts +10 -0
  153. package/esm/editor/utils/data.js +18 -0
  154. package/esm/editor/utils/element.d.ts +2 -0
  155. package/esm/editor/utils/element.js +9 -0
  156. package/esm/editor/utils/event.d.ts +3 -0
  157. package/esm/editor/utils/event.js +63 -0
  158. package/esm/editor/utils/extension.d.ts +13 -0
  159. package/esm/editor/utils/extension.js +39 -0
  160. package/esm/editor/utils/hotkey.d.ts +20 -0
  161. package/esm/editor/utils/hotkey.js +109 -0
  162. package/esm/editor/utils/index.d.ts +7 -0
  163. package/esm/editor/utils/index.js +7 -0
  164. package/esm/exporter/svg.js +7 -5
  165. package/esm/index.d.ts +5 -2
  166. package/esm/index.js +2 -0
  167. package/esm/jsx/components/Polygon.js +2 -1
  168. package/esm/jsx/components/Text.js +66 -68
  169. package/esm/options/types.d.ts +15 -2
  170. package/esm/renderer/composites/background.js +2 -2
  171. package/esm/renderer/composites/button.js +4 -3
  172. package/esm/renderer/composites/icon.d.ts +1 -1
  173. package/esm/renderer/composites/icon.js +2 -0
  174. package/esm/renderer/composites/text.js +2 -1
  175. package/esm/renderer/renderer.js +3 -2
  176. package/esm/renderer/stylize/rough.js +3 -7
  177. package/esm/renderer/types/index.d.ts +0 -1
  178. package/esm/resource/utils/index.d.ts +0 -1
  179. package/esm/resource/utils/index.js +0 -1
  180. package/esm/resource/utils/ref.js +1 -1
  181. package/esm/runtime/Infographic.d.ts +8 -2
  182. package/esm/runtime/Infographic.js +31 -2
  183. package/esm/runtime/options.d.ts +2 -0
  184. package/esm/runtime/options.js +24 -0
  185. package/esm/runtime/utils.d.ts +2 -0
  186. package/esm/runtime/utils.js +18 -0
  187. package/esm/templates/built-in.js +112 -1
  188. package/esm/templates/hierarchy-mindmap.d.ts +2 -0
  189. package/esm/templates/hierarchy-mindmap.js +61 -0
  190. package/esm/types/attrs.d.ts +15 -13
  191. package/esm/types/data.d.ts +2 -0
  192. package/esm/types/element.d.ts +1 -1
  193. package/esm/types/event.d.ts +6 -0
  194. package/esm/types/event.js +1 -0
  195. package/esm/types/index.d.ts +2 -0
  196. package/esm/{renderer/types → types}/text.d.ts +0 -1
  197. package/esm/types/text.js +1 -0
  198. package/esm/utils/attrs.d.ts +1 -0
  199. package/esm/utils/attrs.js +9 -0
  200. package/esm/utils/element.d.ts +4 -0
  201. package/esm/utils/element.js +13 -0
  202. package/esm/utils/icon.d.ts +5 -3
  203. package/esm/utils/icon.js +38 -19
  204. package/esm/utils/index.d.ts +5 -0
  205. package/esm/utils/index.js +5 -0
  206. package/esm/utils/measure-text.d.ts +5 -0
  207. package/esm/utils/measure-text.js +22 -0
  208. package/esm/utils/recognizer.d.ts +15 -0
  209. package/esm/utils/recognizer.js +61 -1
  210. package/esm/utils/style.d.ts +1 -0
  211. package/esm/utils/style.js +8 -0
  212. package/esm/utils/text.d.ts +7 -0
  213. package/esm/utils/text.js +110 -35
  214. package/lib/constants/components.d.ts +1 -0
  215. package/lib/constants/components.js +4 -0
  216. package/lib/constants/element.d.ts +17 -6
  217. package/lib/constants/index.d.ts +2 -0
  218. package/lib/constants/index.js +2 -0
  219. package/lib/constants/shape.d.ts +16 -0
  220. package/lib/designs/components/Btn.js +2 -2
  221. package/lib/designs/components/BtnsGroup.js +1 -1
  222. package/lib/designs/components/Illus.js +2 -2
  223. package/lib/designs/components/ItemDesc.js +1 -2
  224. package/lib/designs/components/ItemIcon.js +1 -1
  225. package/lib/designs/components/ItemLabel.js +1 -2
  226. package/lib/designs/components/ItemValue.js +1 -2
  227. package/lib/designs/components/ItemsGroup.js +1 -1
  228. package/lib/designs/components/Title.js +2 -5
  229. package/lib/designs/items/CandyCardLite.js +1 -1
  230. package/lib/designs/items/CircularProgress.js +2 -1
  231. package/lib/designs/items/HorizontalIconArrow.js +1 -2
  232. package/lib/designs/items/HorizontalIconLine.js +1 -1
  233. package/lib/designs/items/IconBadge.js +1 -1
  234. package/lib/designs/items/LinedText.d.ts +12 -0
  235. package/lib/designs/items/LinedText.js +61 -0
  236. package/lib/designs/items/PlainText.d.ts +1 -0
  237. package/lib/designs/items/PlainText.js +16 -3
  238. package/lib/designs/items/QuarterCircular.js +1 -31
  239. package/lib/designs/items/index.d.ts +1 -0
  240. package/lib/designs/items/index.js +1 -0
  241. package/lib/designs/layouts/Align.js +31 -45
  242. package/lib/designs/layouts/Flex.js +33 -29
  243. package/lib/designs/structures/chart-bar.d.ts +15 -0
  244. package/lib/designs/structures/chart-bar.js +103 -0
  245. package/lib/designs/structures/chart-line.d.ts +12 -0
  246. package/lib/designs/structures/chart-line.js +168 -0
  247. package/lib/designs/structures/chart-pie.d.ts +9 -0
  248. package/lib/designs/structures/chart-pie.js +131 -0
  249. package/lib/designs/structures/compare-binary-horizontal/dividers/pros-cons-arrow.js +1 -1
  250. package/lib/designs/structures/hierarchy-mindmap.d.ts +24 -0
  251. package/lib/designs/structures/hierarchy-mindmap.js +203 -0
  252. package/lib/designs/structures/index.d.ts +4 -0
  253. package/lib/designs/structures/index.js +4 -0
  254. package/lib/designs/structures/list-sector.js +1 -1
  255. package/lib/designs/structures/sequence-circular.js +1 -1
  256. package/lib/designs/structures/sequence-cylinders-3d.js +4 -4
  257. package/lib/designs/structures/sequence-roadmap-vertical.js +1 -1
  258. package/lib/designs/structures/sequence-zigzag-pucks-3d.js +5 -5
  259. package/lib/editor/commands/Batch.d.ts +11 -0
  260. package/lib/editor/commands/Batch.js +25 -0
  261. package/lib/editor/commands/UpdateElement.d.ts +16 -0
  262. package/lib/editor/commands/UpdateElement.js +87 -0
  263. package/lib/editor/commands/UpdateOptions.d.ts +14 -0
  264. package/lib/editor/commands/UpdateOptions.js +29 -0
  265. package/lib/editor/commands/UpdateText.d.ts +16 -0
  266. package/lib/editor/commands/UpdateText.js +44 -0
  267. package/lib/editor/commands/index.d.ts +4 -0
  268. package/lib/editor/commands/index.js +20 -0
  269. package/lib/editor/editor.d.ts +16 -0
  270. package/lib/editor/editor.js +54 -0
  271. package/lib/editor/index.d.ts +4 -0
  272. package/lib/editor/index.js +21 -0
  273. package/lib/editor/interactions/base.d.ts +12 -0
  274. package/lib/editor/interactions/base.js +9 -0
  275. package/lib/editor/interactions/brush-select.d.ts +23 -0
  276. package/lib/editor/interactions/brush-select.js +171 -0
  277. package/lib/editor/interactions/click-select.d.ts +12 -0
  278. package/lib/editor/interactions/click-select.js +71 -0
  279. package/lib/editor/interactions/dblclick-edit-text.d.ts +10 -0
  280. package/lib/editor/interactions/dblclick-edit-text.js +208 -0
  281. package/lib/editor/interactions/drag-element.d.ts +41 -0
  282. package/lib/editor/interactions/drag-element.js +395 -0
  283. package/lib/editor/interactions/hotkey-history.d.ts +10 -0
  284. package/lib/editor/interactions/hotkey-history.js +31 -0
  285. package/lib/editor/interactions/index.d.ts +8 -0
  286. package/lib/editor/interactions/index.js +19 -0
  287. package/lib/editor/interactions/select-highlight.d.ts +16 -0
  288. package/lib/editor/interactions/select-highlight.js +103 -0
  289. package/lib/editor/interactions/zoom-wheel.d.ts +8 -0
  290. package/lib/editor/interactions/zoom-wheel.js +50 -0
  291. package/lib/editor/managers/command.d.ts +19 -0
  292. package/lib/editor/managers/command.js +67 -0
  293. package/lib/editor/managers/index.d.ts +4 -0
  294. package/lib/editor/managers/index.js +20 -0
  295. package/lib/editor/managers/interaction.d.ts +33 -0
  296. package/lib/editor/managers/interaction.js +200 -0
  297. package/lib/editor/managers/plugin.d.ts +14 -0
  298. package/lib/editor/managers/plugin.js +49 -0
  299. package/lib/editor/managers/state.d.ts +22 -0
  300. package/lib/editor/managers/state.js +145 -0
  301. package/lib/editor/plugins/base.d.ts +12 -0
  302. package/lib/editor/plugins/base.js +9 -0
  303. package/lib/editor/plugins/edit-bar/components/button.d.ts +12 -0
  304. package/lib/editor/plugins/edit-bar/components/button.js +57 -0
  305. package/lib/editor/plugins/edit-bar/components/color-picker.d.ts +10 -0
  306. package/lib/editor/plugins/edit-bar/components/color-picker.js +354 -0
  307. package/lib/editor/plugins/edit-bar/components/icons.d.ts +26 -0
  308. package/lib/editor/plugins/edit-bar/components/icons.js +33 -0
  309. package/lib/editor/plugins/edit-bar/components/index.d.ts +5 -0
  310. package/lib/editor/plugins/edit-bar/components/index.js +21 -0
  311. package/lib/editor/plugins/edit-bar/components/popover.d.ts +23 -0
  312. package/lib/editor/plugins/edit-bar/components/popover.js +381 -0
  313. package/lib/editor/plugins/edit-bar/components/select.d.ts +22 -0
  314. package/lib/editor/plugins/edit-bar/components/select.js +204 -0
  315. package/lib/editor/plugins/edit-bar/edit-bar.d.ts +32 -0
  316. package/lib/editor/plugins/edit-bar/edit-bar.js +215 -0
  317. package/lib/editor/plugins/edit-bar/edit-items/align-elements.d.ts +2 -0
  318. package/lib/editor/plugins/edit-bar/edit-items/align-elements.js +316 -0
  319. package/lib/editor/plugins/edit-bar/edit-items/font-align.d.ts +3 -0
  320. package/lib/editor/plugins/edit-bar/edit-items/font-align.js +85 -0
  321. package/lib/editor/plugins/edit-bar/edit-items/font-color.d.ts +3 -0
  322. package/lib/editor/plugins/edit-bar/edit-items/font-color.js +81 -0
  323. package/lib/editor/plugins/edit-bar/edit-items/font-family.d.ts +3 -0
  324. package/lib/editor/plugins/edit-bar/edit-items/font-family.js +119 -0
  325. package/lib/editor/plugins/edit-bar/edit-items/font-size.d.ts +3 -0
  326. package/lib/editor/plugins/edit-bar/edit-items/font-size.js +92 -0
  327. package/lib/editor/plugins/edit-bar/edit-items/icon-color.d.ts +3 -0
  328. package/lib/editor/plugins/edit-bar/edit-items/icon-color.js +81 -0
  329. package/lib/editor/plugins/edit-bar/edit-items/index.d.ts +7 -0
  330. package/lib/editor/plugins/edit-bar/edit-items/index.js +22 -0
  331. package/lib/editor/plugins/edit-bar/edit-items/types.d.ts +3 -0
  332. package/lib/editor/plugins/edit-bar/edit-items/types.js +2 -0
  333. package/lib/editor/plugins/edit-bar/index.d.ts +4 -0
  334. package/lib/editor/plugins/edit-bar/index.js +9 -0
  335. package/lib/editor/plugins/edit-bar/utils.d.ts +4 -0
  336. package/lib/editor/plugins/edit-bar/utils.js +17 -0
  337. package/lib/editor/plugins/index.d.ts +3 -0
  338. package/lib/editor/plugins/index.js +22 -0
  339. package/lib/editor/plugins/resize-element.d.ts +45 -0
  340. package/lib/editor/plugins/resize-element.js +397 -0
  341. package/lib/editor/types/command.d.ts +28 -0
  342. package/lib/editor/types/command.js +2 -0
  343. package/lib/editor/types/editor.d.ts +4 -0
  344. package/lib/editor/types/editor.js +2 -0
  345. package/lib/editor/types/index.d.ts +7 -0
  346. package/lib/editor/types/index.js +2 -0
  347. package/lib/editor/types/interaction.d.ts +44 -0
  348. package/lib/editor/types/interaction.js +2 -0
  349. package/lib/editor/types/plugin.d.ts +30 -0
  350. package/lib/editor/types/plugin.js +2 -0
  351. package/lib/editor/types/selection.d.ts +2 -0
  352. package/lib/editor/types/selection.js +2 -0
  353. package/lib/editor/types/shape.d.ts +16 -0
  354. package/lib/editor/types/shape.js +2 -0
  355. package/lib/editor/types/state.d.ts +57 -0
  356. package/lib/editor/types/state.js +2 -0
  357. package/lib/editor/utils/click-handler.d.ts +28 -0
  358. package/lib/editor/utils/click-handler.js +101 -0
  359. package/lib/editor/utils/coordinate.d.ts +6 -0
  360. package/lib/editor/utils/coordinate.js +38 -0
  361. package/lib/editor/utils/data.d.ts +10 -0
  362. package/lib/editor/utils/data.js +22 -0
  363. package/lib/editor/utils/element.d.ts +2 -0
  364. package/lib/editor/utils/element.js +12 -0
  365. package/lib/editor/utils/event.d.ts +3 -0
  366. package/lib/editor/utils/event.js +67 -0
  367. package/lib/editor/utils/extension.d.ts +13 -0
  368. package/lib/editor/utils/extension.js +43 -0
  369. package/lib/editor/utils/hotkey.d.ts +20 -0
  370. package/lib/editor/utils/hotkey.js +113 -0
  371. package/lib/editor/utils/index.d.ts +7 -0
  372. package/lib/editor/utils/index.js +23 -0
  373. package/lib/exporter/svg.js +6 -4
  374. package/lib/index.d.ts +5 -2
  375. package/lib/index.js +14 -1
  376. package/lib/jsx/components/Polygon.js +2 -1
  377. package/lib/jsx/components/Text.js +66 -68
  378. package/lib/options/types.d.ts +15 -2
  379. package/lib/renderer/composites/background.js +1 -1
  380. package/lib/renderer/composites/button.js +3 -2
  381. package/lib/renderer/composites/icon.d.ts +1 -1
  382. package/lib/renderer/composites/icon.js +2 -0
  383. package/lib/renderer/composites/text.js +2 -1
  384. package/lib/renderer/renderer.js +2 -1
  385. package/lib/renderer/stylize/rough.js +3 -7
  386. package/lib/renderer/types/index.d.ts +0 -1
  387. package/lib/resource/utils/index.d.ts +0 -1
  388. package/lib/resource/utils/index.js +0 -1
  389. package/lib/resource/utils/ref.js +2 -2
  390. package/lib/runtime/Infographic.d.ts +8 -2
  391. package/lib/runtime/Infographic.js +34 -2
  392. package/lib/runtime/options.d.ts +2 -0
  393. package/lib/runtime/options.js +27 -0
  394. package/lib/runtime/utils.d.ts +2 -0
  395. package/lib/runtime/utils.js +21 -0
  396. package/lib/templates/built-in.js +112 -1
  397. package/lib/templates/hierarchy-mindmap.d.ts +2 -0
  398. package/lib/templates/hierarchy-mindmap.js +64 -0
  399. package/lib/types/attrs.d.ts +15 -13
  400. package/lib/types/data.d.ts +2 -0
  401. package/lib/types/element.d.ts +1 -1
  402. package/lib/types/event.d.ts +6 -0
  403. package/lib/types/event.js +2 -0
  404. package/lib/types/index.d.ts +2 -0
  405. package/lib/{renderer/types → types}/text.d.ts +0 -1
  406. package/lib/types/text.js +2 -0
  407. package/lib/utils/attrs.d.ts +1 -0
  408. package/lib/utils/attrs.js +12 -0
  409. package/lib/utils/element.d.ts +4 -0
  410. package/lib/utils/element.js +18 -0
  411. package/lib/utils/icon.d.ts +5 -3
  412. package/lib/utils/icon.js +42 -21
  413. package/lib/utils/index.d.ts +5 -0
  414. package/lib/utils/index.js +5 -0
  415. package/lib/utils/measure-text.d.ts +5 -0
  416. package/lib/utils/measure-text.js +28 -0
  417. package/lib/utils/recognizer.d.ts +15 -0
  418. package/lib/utils/recognizer.js +72 -2
  419. package/lib/utils/style.d.ts +1 -0
  420. package/lib/utils/style.js +11 -0
  421. package/lib/utils/text.d.ts +7 -0
  422. package/lib/utils/text.js +113 -32
  423. package/package.json +7 -3
  424. package/src/constants/components.ts +1 -0
  425. package/src/constants/element.ts +17 -5
  426. package/src/constants/index.ts +2 -0
  427. package/src/constants/shape.ts +16 -0
  428. package/src/designs/components/Btn.tsx +3 -2
  429. package/src/designs/components/BtnsGroup.tsx +8 -1
  430. package/src/designs/components/Illus.tsx +3 -2
  431. package/src/designs/components/ItemDesc.tsx +2 -2
  432. package/src/designs/components/ItemIcon.tsx +3 -2
  433. package/src/designs/components/ItemLabel.tsx +2 -2
  434. package/src/designs/components/ItemValue.tsx +2 -2
  435. package/src/designs/components/ItemsGroup.tsx +2 -1
  436. package/src/designs/components/Title.tsx +8 -5
  437. package/src/designs/items/CandyCardLite.tsx +3 -3
  438. package/src/designs/items/CircularProgress.tsx +19 -8
  439. package/src/designs/items/HorizontalIconArrow.tsx +4 -5
  440. package/src/designs/items/HorizontalIconLine.tsx +7 -10
  441. package/src/designs/items/IconBadge.tsx +3 -3
  442. package/src/designs/items/LinedText.tsx +131 -0
  443. package/src/designs/items/PlainText.tsx +25 -3
  444. package/src/designs/items/QuarterCircular.tsx +2 -31
  445. package/src/designs/items/index.ts +1 -0
  446. package/src/designs/layouts/Align.tsx +31 -48
  447. package/src/designs/layouts/Flex.tsx +33 -31
  448. package/src/designs/structures/chart-bar.tsx +289 -0
  449. package/src/designs/structures/chart-line.tsx +415 -0
  450. package/src/designs/structures/chart-pie.tsx +298 -0
  451. package/src/designs/structures/compare-binary-horizontal/dividers/pros-cons-arrow.tsx +2 -2
  452. package/src/designs/structures/hierarchy-mindmap.tsx +394 -0
  453. package/src/designs/structures/index.ts +4 -0
  454. package/src/designs/structures/list-sector.tsx +2 -1
  455. package/src/designs/structures/sequence-ascending-steps.tsx +0 -1
  456. package/src/designs/structures/sequence-circular.tsx +1 -1
  457. package/src/designs/structures/sequence-cylinders-3d.tsx +5 -5
  458. package/src/designs/structures/sequence-roadmap-vertical.tsx +2 -1
  459. package/src/designs/structures/sequence-zigzag-pucks-3d.tsx +18 -25
  460. package/src/editor/commands/Batch.ts +24 -0
  461. package/src/editor/commands/UpdateElement.ts +115 -0
  462. package/src/editor/commands/UpdateOptions.ts +31 -0
  463. package/src/editor/commands/UpdateText.ts +54 -0
  464. package/src/editor/commands/index.ts +4 -0
  465. package/src/editor/editor.ts +78 -0
  466. package/src/editor/index.ts +4 -0
  467. package/src/editor/interactions/base.ts +25 -0
  468. package/src/editor/interactions/brush-select.ts +204 -0
  469. package/src/editor/interactions/click-select.ts +72 -0
  470. package/src/editor/interactions/dblclick-edit-text.ts +260 -0
  471. package/src/editor/interactions/drag-element.ts +516 -0
  472. package/src/editor/interactions/hotkey-history.ts +34 -0
  473. package/src/editor/interactions/index.ts +8 -0
  474. package/src/editor/interactions/select-highlight.ts +140 -0
  475. package/src/editor/interactions/zoom-wheel.ts +52 -0
  476. package/src/editor/managers/command.ts +83 -0
  477. package/src/editor/managers/index.ts +4 -0
  478. package/src/editor/managers/interaction.ts +244 -0
  479. package/src/editor/managers/plugin.ts +66 -0
  480. package/src/editor/managers/state.ts +186 -0
  481. package/src/editor/plugins/base.ts +25 -0
  482. package/src/editor/plugins/edit-bar/components/button.ts +77 -0
  483. package/src/editor/plugins/edit-bar/components/color-picker.ts +397 -0
  484. package/src/editor/plugins/edit-bar/components/icons.ts +86 -0
  485. package/src/editor/plugins/edit-bar/components/index.ts +5 -0
  486. package/src/editor/plugins/edit-bar/components/popover.ts +446 -0
  487. package/src/editor/plugins/edit-bar/components/select.ts +247 -0
  488. package/src/editor/plugins/edit-bar/edit-bar.ts +292 -0
  489. package/src/editor/plugins/edit-bar/edit-items/align-elements.ts +447 -0
  490. package/src/editor/plugins/edit-bar/edit-items/font-align.ts +129 -0
  491. package/src/editor/plugins/edit-bar/edit-items/font-color.ts +101 -0
  492. package/src/editor/plugins/edit-bar/edit-items/font-family.ts +147 -0
  493. package/src/editor/plugins/edit-bar/edit-items/font-size.ts +116 -0
  494. package/src/editor/plugins/edit-bar/edit-items/icon-color.ts +101 -0
  495. package/src/editor/plugins/edit-bar/edit-items/index.ts +7 -0
  496. package/src/editor/plugins/edit-bar/edit-items/types.ts +9 -0
  497. package/src/editor/plugins/edit-bar/index.ts +18 -0
  498. package/src/editor/plugins/edit-bar/utils.ts +16 -0
  499. package/src/editor/plugins/index.ts +3 -0
  500. package/src/editor/plugins/resize-element.ts +518 -0
  501. package/src/editor/types/command.ts +32 -0
  502. package/src/editor/types/editor.ts +4 -0
  503. package/src/editor/types/index.ts +7 -0
  504. package/src/editor/types/interaction.ts +56 -0
  505. package/src/editor/types/plugin.ts +34 -0
  506. package/src/editor/types/selection.ts +3 -0
  507. package/src/editor/types/shape.ts +28 -0
  508. package/src/editor/types/state.ts +51 -0
  509. package/src/editor/utils/click-handler.ts +114 -0
  510. package/src/editor/utils/coordinate.ts +54 -0
  511. package/src/editor/utils/data.ts +30 -0
  512. package/src/editor/utils/element.ts +13 -0
  513. package/src/editor/utils/event.ts +92 -0
  514. package/src/editor/utils/extension.ts +45 -0
  515. package/src/editor/utils/hotkey.ts +139 -0
  516. package/src/editor/utils/index.ts +7 -0
  517. package/src/exporter/svg.ts +15 -5
  518. package/src/index.ts +14 -3
  519. package/src/jsx/components/Polygon.ts +2 -1
  520. package/src/jsx/components/Text.ts +70 -71
  521. package/src/options/types.ts +17 -2
  522. package/src/renderer/composites/background.ts +2 -2
  523. package/src/renderer/composites/button.ts +4 -3
  524. package/src/renderer/composites/icon.ts +2 -0
  525. package/src/renderer/composites/text.ts +2 -1
  526. package/src/renderer/renderer.ts +4 -2
  527. package/src/renderer/stylize/rough.ts +3 -7
  528. package/src/renderer/types/index.ts +0 -1
  529. package/src/resource/utils/index.ts +0 -1
  530. package/src/resource/utils/ref.ts +1 -1
  531. package/src/runtime/Infographic.tsx +45 -4
  532. package/src/runtime/options.ts +37 -0
  533. package/src/runtime/utils.ts +23 -0
  534. package/src/templates/built-in.ts +112 -1
  535. package/src/templates/hierarchy-mindmap.ts +129 -0
  536. package/src/types/attrs.ts +17 -13
  537. package/src/types/data.ts +2 -0
  538. package/src/types/element.ts +1 -1
  539. package/src/types/event.ts +6 -0
  540. package/src/types/index.ts +2 -0
  541. package/src/{renderer/types → types}/text.ts +0 -1
  542. package/src/utils/attrs.ts +9 -0
  543. package/src/utils/element.ts +26 -0
  544. package/src/utils/icon.ts +45 -25
  545. package/src/utils/index.ts +5 -0
  546. package/src/utils/measure-text.ts +38 -0
  547. package/src/utils/recognizer.ts +75 -1
  548. package/src/utils/style.ts +8 -0
  549. package/src/utils/text.ts +135 -40
  550. /package/esm/{renderer/types/text.js → constants/shape.js} +0 -0
  551. /package/esm/{resource/utils → utils}/hash.d.ts +0 -0
  552. /package/esm/{resource/utils → utils}/hash.js +0 -0
  553. /package/lib/{renderer/types/text.js → constants/shape.js} +0 -0
  554. /package/lib/{resource/utils → utils}/hash.d.ts +0 -0
  555. /package/lib/{resource/utils → utils}/hash.js +0 -0
  556. /package/src/{resource/utils → utils}/hash.ts +0 -0
@@ -0,0 +1,298 @@
1
+ import { arc, pie, type PieArcDatum } from 'd3';
2
+ import { ElementTypeEnum } from '../../constants';
3
+ import type { ComponentType, JSXElement } from '../../jsx';
4
+ import { getElementBounds, Group, Path, Text } from '../../jsx';
5
+ import { ItemDatum } from '../../types';
6
+ import { BtnAdd, BtnRemove, BtnsGroup, ItemsGroup } from '../components';
7
+ import { FlexLayout } from '../layouts';
8
+ import { getColorPrimary, getPaletteColor, getThemeColors } from '../utils';
9
+ import { registerStructure } from './registry';
10
+ import type { BaseStructureProps } from './types';
11
+
12
+ export interface ChartPieProps extends BaseStructureProps {
13
+ radius?: number;
14
+ innerRadius?: number;
15
+ padding?: number;
16
+ showPercentage?: boolean;
17
+ }
18
+
19
+ export const ChartPie: ComponentType<ChartPieProps> = (props) => {
20
+ const {
21
+ Title,
22
+ Item,
23
+ data,
24
+ radius = 140,
25
+ innerRadius = 0,
26
+ padding = 30,
27
+ showPercentage = true,
28
+ options,
29
+ } = props;
30
+
31
+ const { title, desc, items = [] } = data;
32
+ const titleContent = Title ? <Title title={title} desc={desc} /> : null;
33
+
34
+ const btnBounds = getElementBounds(<BtnAdd indexes={[0]} />);
35
+
36
+ // 获取 Item 的预估尺寸
37
+ const sampleDatum: ItemDatum = items[0] ?? { label: '', value: 0 };
38
+ const itemBounds = getElementBounds(
39
+ <Item
40
+ indexes={[0]}
41
+ datum={sampleDatum}
42
+ data={data}
43
+ positionH="center"
44
+ positionV="middle"
45
+ />,
46
+ );
47
+
48
+ const labelWidth = itemBounds.width || 140;
49
+ const labelHeight = itemBounds.height || 32;
50
+
51
+ // 基础半径设置
52
+ const outerRadius = Math.max(radius, 60);
53
+
54
+ // 连线水平拉伸的系数
55
+ const extensionFactor = 1.35;
56
+ const textGap = 8;
57
+
58
+ // 计算画布中心和总尺寸
59
+ // 水平方向:半径 * 系数 + 间距 + 标签宽度 + 边缘padding
60
+ const maxHorizontalDistance =
61
+ outerRadius * extensionFactor + textGap + labelWidth;
62
+ const maxVerticalDistance = outerRadius;
63
+
64
+ const centerX = padding + maxHorizontalDistance;
65
+ const centerY = padding + maxVerticalDistance;
66
+
67
+ const totalWidth = centerX * 2;
68
+ const totalHeight = centerY * 2;
69
+
70
+ // 空数据处理
71
+ if (items.length === 0) {
72
+ return (
73
+ <FlexLayout
74
+ id="infographic-container"
75
+ flexDirection="column"
76
+ justifyContent="center"
77
+ alignItems="center"
78
+ >
79
+ {titleContent}
80
+ <Group width={totalWidth} height={totalHeight}>
81
+ <BtnsGroup>
82
+ <BtnAdd
83
+ indexes={[0]}
84
+ x={centerX - btnBounds.width / 2}
85
+ y={centerY - btnBounds.height / 2}
86
+ />
87
+ </BtnsGroup>
88
+ </Group>
89
+ </FlexLayout>
90
+ );
91
+ }
92
+
93
+ const totalValue = items.reduce(
94
+ (sum, item) => sum + Math.max(item.value ?? 0, 0),
95
+ 0,
96
+ );
97
+ const colorPrimary = getColorPrimary(options);
98
+ const themeColors = getThemeColors(options.themeConfig);
99
+
100
+ // 1. 饼图生成器
101
+ const pieGenerator = pie<ItemDatum>()
102
+ .value((item) => Math.max(item.value ?? 0, 0))
103
+ .sort(null)
104
+ .startAngle(0)
105
+ .endAngle(Math.PI * 2);
106
+
107
+ const arcData = pieGenerator(items);
108
+
109
+ // 2. 弧形生成器
110
+ const arcGenerator = arc<PieArcDatum<ItemDatum>>()
111
+ .innerRadius(innerRadius)
112
+ .outerRadius(outerRadius)
113
+ .cornerRadius(2);
114
+
115
+ // 连线起点
116
+ const innerArc = arc<PieArcDatum<ItemDatum>>()
117
+ .innerRadius(outerRadius)
118
+ .outerRadius(outerRadius);
119
+
120
+ // 连线拐点
121
+ const outerArc = arc<PieArcDatum<ItemDatum>>()
122
+ .innerRadius(outerRadius * 1.15)
123
+ .outerRadius(outerRadius * 1.15);
124
+
125
+ const percentTextRadius = innerRadius + (outerRadius - innerRadius) * 0.5;
126
+ const percentageArc = arc<PieArcDatum<ItemDatum>>()
127
+ .innerRadius(percentTextRadius)
128
+ .outerRadius(percentTextRadius);
129
+
130
+ // 删除按钮位置
131
+ const deleteButtonArc = arc<PieArcDatum<ItemDatum>>()
132
+ .innerRadius(outerRadius * 0.85)
133
+ .outerRadius(outerRadius * 0.85);
134
+
135
+ const sliceElements: JSXElement[] = [];
136
+ const percentElements: JSXElement[] = [];
137
+ const connectorElements: JSXElement[] = [];
138
+ const itemElements: JSXElement[] = [];
139
+ const btnElements: JSXElement[] = [];
140
+
141
+ // 3. 遍历生成图形
142
+ arcData.forEach((arcDatum) => {
143
+ const currentItem = arcDatum.data;
144
+ const originalIndex = arcDatum.index;
145
+
146
+ const color =
147
+ getPaletteColor(options, [originalIndex]) ||
148
+ themeColors.colorPrimary ||
149
+ colorPrimary;
150
+
151
+ // --- 绘制扇形 ---
152
+ const pathD = arcGenerator(arcDatum) || '';
153
+ sliceElements.push(
154
+ <Path
155
+ d={pathD}
156
+ fill={color}
157
+ stroke={themeColors.colorBg}
158
+ strokeWidth={1}
159
+ data-element-type="shape"
160
+ width={outerRadius * 2}
161
+ height={outerRadius * 2}
162
+ />,
163
+ );
164
+
165
+ // --- 计算关键点 ---
166
+ const midAngle =
167
+ arcDatum.startAngle + (arcDatum.endAngle - arcDatum.startAngle) / 2;
168
+ const isRight = midAngle < Math.PI;
169
+
170
+ // 1. 起点
171
+ const p0 = innerArc.centroid(arcDatum);
172
+
173
+ // 2. 拐点
174
+ const p1 = outerArc.centroid(arcDatum);
175
+
176
+ // 3. 终点 (水平拉伸)
177
+ const labelXOffset = outerRadius * extensionFactor * (isRight ? 1 : -1);
178
+ const p2 = [labelXOffset, p1[1]];
179
+
180
+ // --- 绘制连线 ---
181
+ connectorElements.push(
182
+ <Path
183
+ d={`M${centerX + p0[0]} ${centerY + p0[1]} L${centerX + p1[0]} ${centerY + p1[1]} L${centerX + p2[0]} ${centerY + p2[1]}`}
184
+ stroke={colorPrimary}
185
+ strokeOpacity={0.45}
186
+ strokeWidth={2}
187
+ fill="none"
188
+ data-element-type="shape"
189
+ />,
190
+ );
191
+
192
+ // --- 绘制 Item ---
193
+ const itemX = centerX + p2[0] + (isRight ? textGap : -textGap - labelWidth);
194
+ const itemY = centerY + p2[1] - labelHeight / 2;
195
+
196
+ itemElements.push(
197
+ <Item
198
+ indexes={[originalIndex]}
199
+ datum={currentItem}
200
+ data={data}
201
+ x={itemX}
202
+ y={itemY}
203
+ width={labelWidth}
204
+ height={labelHeight}
205
+ positionH={isRight ? 'normal' : 'flipped'}
206
+ positionV="middle"
207
+ themeColors={getThemeColors({ colorPrimary: color }, options)}
208
+ />,
209
+ );
210
+
211
+ // --- 绘制百分比 ---
212
+ if (showPercentage && totalValue > 0) {
213
+ const percentPos = percentageArc.centroid(arcDatum);
214
+ const value = Math.max(arcDatum.value, 0);
215
+ const percentText = ((value * 100) / totalValue).toFixed(1);
216
+
217
+ // 定义文本框尺寸
218
+ const textWidth = 50;
219
+ const textHeight = 20;
220
+
221
+ percentElements.push(
222
+ <Text
223
+ x={centerX + percentPos[0] - textWidth / 2}
224
+ y={centerY + percentPos[1] - textHeight / 2}
225
+ width={textWidth}
226
+ height={textHeight}
227
+ alignHorizontal="center"
228
+ alignVertical="middle"
229
+ fontSize={12}
230
+ fontWeight="bold"
231
+ fill="#ffffff"
232
+ data-value={value}
233
+ data-indexes={[originalIndex]}
234
+ data-element-type={ElementTypeEnum.ItemValue}
235
+ >
236
+ {`${percentText}%`}
237
+ </Text>,
238
+ );
239
+ }
240
+
241
+ // --- 绘制删除按钮 ---
242
+ const deletePos = deleteButtonArc.centroid(arcDatum);
243
+ btnElements.push(
244
+ <BtnRemove
245
+ indexes={[originalIndex]}
246
+ x={centerX + deletePos[0] - btnBounds.width / 2}
247
+ y={centerY + deletePos[1] - btnBounds.height / 2}
248
+ />,
249
+ );
250
+ });
251
+
252
+ // --- 绘制添加按钮 ---
253
+ arcData.forEach((arcDatum, index) => {
254
+ const nextIndex = (index + 1) % arcData.length;
255
+ const currentEnd = arcDatum.endAngle;
256
+ const nextStart =
257
+ arcData[nextIndex].startAngle + (nextIndex === 0 ? Math.PI * 2 : 0);
258
+ const midAngle = (currentEnd + nextStart) / 2;
259
+
260
+ const btnR = outerRadius * 1.0;
261
+ const btnX = Math.sin(midAngle) * btnR;
262
+ const btnY = -Math.cos(midAngle) * btnR;
263
+
264
+ btnElements.push(
265
+ <BtnAdd
266
+ indexes={[index + 1]}
267
+ x={centerX + btnX - btnBounds.width / 2}
268
+ y={centerY + btnY - btnBounds.height / 2}
269
+ />,
270
+ );
271
+ });
272
+
273
+ return (
274
+ <FlexLayout
275
+ id="infographic-container"
276
+ flexDirection="column"
277
+ justifyContent="center"
278
+ alignItems="center"
279
+ gap={30}
280
+ >
281
+ {titleContent}
282
+ <Group width={totalWidth} height={totalHeight}>
283
+ <Group x={centerX} y={centerY}>
284
+ {sliceElements}
285
+ </Group>
286
+ <Group>{connectorElements}</Group>
287
+ <Group>{percentElements}</Group>
288
+ <ItemsGroup>{itemElements}</ItemsGroup>
289
+ <BtnsGroup>{btnElements}</BtnsGroup>
290
+ </Group>
291
+ </FlexLayout>
292
+ );
293
+ };
294
+
295
+ registerStructure('chart-pie', {
296
+ component: ChartPie,
297
+ composites: ['title', 'item'],
298
+ });
@@ -35,10 +35,10 @@ export const ProsConsArrow: ComponentType<DividerProps> = (props) => {
35
35
  fill={colorNegative}
36
36
  />
37
37
  </ShapesGroup>
38
- <Text x={45} y={15} {...textAttrs}>
38
+ <Text x={40} y={15} {...textAttrs}>
39
39
  Pros
40
40
  </Text>
41
- <Text x={65} y={86} {...textAttrs}>
41
+ <Text x={70} y={85} {...textAttrs}>
42
42
  Cons
43
43
  </Text>
44
44
  </Group>
@@ -0,0 +1,394 @@
1
+ import type { HierarchyData, HierarchyNode } from '@antv/hierarchy';
2
+ import { mindmap } from '@antv/hierarchy';
3
+ import type { ComponentType, JSXElement } from '../../jsx';
4
+ import { Defs, Group, Path, getElementBounds } from '../../jsx';
5
+ import type { ItemDatum } from '../../types';
6
+ import { BtnAdd, BtnRemove, BtnsGroup, ItemsGroup } from '../components';
7
+ import { FlexLayout } from '../layouts';
8
+ import type { HierarchyColorMode } from '../utils';
9
+ import {
10
+ getColorPrimary,
11
+ getHierarchyColorIndexes,
12
+ getItemComponent,
13
+ getPaletteColor,
14
+ getThemeColors,
15
+ } from '../utils';
16
+ import { registerStructure } from './registry';
17
+ import type { BaseStructureProps } from './types';
18
+
19
+ type AnnotatedItem = (ItemDatum & HierarchyData) & {
20
+ _indexes: number[];
21
+ _flatIndex?: number;
22
+ children?: AnnotatedItem[];
23
+ };
24
+
25
+ type LayoutNode = HierarchyNode & {
26
+ data: AnnotatedItem;
27
+ children: LayoutNode[];
28
+ parent?: LayoutNode;
29
+ };
30
+
31
+ type LayoutLink = {
32
+ parent: LayoutNode;
33
+ child: LayoutNode;
34
+ };
35
+
36
+ type EdgeAlign = 'top' | 'center' | 'bottom' | number;
37
+ type EdgeType = 'curved' | 'straight';
38
+ type EdgeColorMode = 'solid' | 'gradient';
39
+
40
+ export interface HierarchyMindmapProps extends BaseStructureProps {
41
+ /** 水平层级间距 */
42
+ levelGap?: number;
43
+ /** 垂直节点间距 */
44
+ nodeGap?: number;
45
+ /** 连线在节点上的垂直对齐方式;字符串为固定位置,数字为 0-1 比例 */
46
+ edgeAlign?: EdgeAlign;
47
+ /** 节点/连线着色模式 */
48
+ colorMode?: HierarchyColorMode;
49
+ /** 连线颜色模式 */
50
+ edgeColorMode?: EdgeColorMode;
51
+ /** 连线类型:曲线或直线 */
52
+ edgeType?: EdgeType;
53
+ /** 连线宽度 */
54
+ edgeWidth?: number;
55
+ }
56
+
57
+ const DEFAULT_LEVEL_GAP = 60;
58
+ const DEFAULT_NODE_GAP = 14;
59
+ const LAYOUT_PADDING = 30;
60
+ const DEFAULT_EDGE_ALIGN: EdgeAlign = 'center';
61
+ const DEFAULT_EDGE_TYPE: EdgeType = 'curved';
62
+ const DEFAULT_EDGE_WIDTH = 2;
63
+ const DEFAULT_COLOR_MODE: HierarchyColorMode = 'node';
64
+ const DEFAULT_EDGE_COLOR_MODE: EdgeColorMode = 'solid';
65
+
66
+ const annotateTree = (
67
+ node: ItemDatum & HierarchyData,
68
+ parentIndexes: number[] = [],
69
+ index = 0,
70
+ ): AnnotatedItem => {
71
+ const indexes = [...parentIndexes, index];
72
+ return {
73
+ ...node,
74
+ _indexes: indexes,
75
+ children:
76
+ node.children?.map((child, childIndex) =>
77
+ annotateTree(child, indexes, childIndex),
78
+ ) ?? [],
79
+ };
80
+ };
81
+
82
+ const collectNodes = (
83
+ node: LayoutNode,
84
+ nodes: LayoutNode[],
85
+ links: LayoutLink[],
86
+ parent?: LayoutNode,
87
+ ) => {
88
+ nodes.push(node);
89
+ node.data._flatIndex ??= nodes.length - 1;
90
+ if (parent) links.push({ parent, child: node });
91
+ const children = node.children as unknown as LayoutNode[];
92
+ children?.forEach((child) => collectNodes(child, nodes, links, node));
93
+ };
94
+
95
+ const createCurvePath = (sx: number, sy: number, tx: number, ty: number) => {
96
+ const offsetX = Math.abs(tx - sx) / 2;
97
+ const ctrlX1 = tx > sx ? sx + offsetX : sx - offsetX;
98
+ const ctrlX2 = tx > sx ? tx - offsetX : tx + offsetX;
99
+ return `M ${sx} ${sy} C ${ctrlX1} ${sy} ${ctrlX2} ${ty} ${tx} ${ty}`;
100
+ };
101
+
102
+ const createStraightPath = (sx: number, sy: number, tx: number, ty: number) =>
103
+ `M ${sx} ${sy} L ${tx} ${ty}`;
104
+
105
+ const getEdgeAnchors = (
106
+ parentLayout: { x: number; y: number; width: number; height: number },
107
+ childLayout: { x: number; y: number; width: number; height: number },
108
+ childSide?: 'left' | 'right',
109
+ align: EdgeAlign = DEFAULT_EDGE_ALIGN,
110
+ ) => {
111
+ const clampRatio = (val: number) => Math.max(0, Math.min(1, val));
112
+ const toRatio = (value: EdgeAlign) => {
113
+ if (value === 'top') return 0;
114
+ if (value === 'bottom') return 1;
115
+ if (value === 'center') return 0.5;
116
+ return clampRatio(value);
117
+ };
118
+ const ratio = toRatio(align);
119
+ const parentCy = parentLayout.y + parentLayout.height * ratio;
120
+ const childCy = childLayout.y + childLayout.height * ratio;
121
+ if (childSide === 'left') {
122
+ return {
123
+ sx: parentLayout.x,
124
+ sy: parentCy,
125
+ tx: childLayout.x + childLayout.width,
126
+ ty: childCy,
127
+ };
128
+ }
129
+ return {
130
+ sx: parentLayout.x + parentLayout.width,
131
+ sy: parentCy,
132
+ tx: childLayout.x,
133
+ ty: childCy,
134
+ };
135
+ };
136
+
137
+ export const HierarchyMindmap: ComponentType<HierarchyMindmapProps> = (
138
+ props,
139
+ ) => {
140
+ const {
141
+ Title,
142
+ Items,
143
+ data,
144
+ levelGap = DEFAULT_LEVEL_GAP,
145
+ nodeGap = DEFAULT_NODE_GAP,
146
+ edgeAlign = DEFAULT_EDGE_ALIGN,
147
+ colorMode = DEFAULT_COLOR_MODE,
148
+ edgeColorMode = DEFAULT_EDGE_COLOR_MODE,
149
+ edgeType = DEFAULT_EDGE_TYPE,
150
+ edgeWidth = DEFAULT_EDGE_WIDTH,
151
+ options,
152
+ } = props;
153
+ const { title, desc, items = [] } = data;
154
+ const titleContent = Title ? <Title title={title} desc={desc} /> : null;
155
+ const colorPrimary = getColorPrimary(options);
156
+ const btnBounds = getElementBounds(<BtnAdd indexes={[0]} />);
157
+
158
+ if (!items.length || !Items?.length) {
159
+ return (
160
+ <FlexLayout
161
+ id="infographic-container"
162
+ flexDirection="column"
163
+ justifyContent="center"
164
+ alignItems="center"
165
+ >
166
+ {titleContent}
167
+ <Group>
168
+ <BtnAdd indexes={[0]} x={0} y={0} />
169
+ </Group>
170
+ </FlexLayout>
171
+ );
172
+ }
173
+
174
+ const root = annotateTree(items[0]);
175
+ const nodeSizeCache = new WeakMap<
176
+ AnnotatedItem,
177
+ { width: number; height: number }
178
+ >();
179
+ const colorCache = new WeakMap<AnnotatedItem, string>();
180
+ const themeCache = new WeakMap<AnnotatedItem, any>();
181
+
182
+ const getNodeColorIndexes = (datum: AnnotatedItem, depth: number) =>
183
+ getHierarchyColorIndexes(
184
+ {
185
+ depth,
186
+ originalIndexes: datum._indexes,
187
+ flatIndex: datum._flatIndex,
188
+ },
189
+ colorMode,
190
+ );
191
+
192
+ const getNodeThemeColors = (datum: AnnotatedItem, depth: number) => {
193
+ const cachedTheme = themeCache.get(datum);
194
+ if (cachedTheme) return cachedTheme;
195
+ const colorIndexes = getNodeColorIndexes(datum, depth);
196
+ const primary = getPaletteColor(options, colorIndexes);
197
+ const themeColors = getThemeColors({ colorPrimary: primary }, options);
198
+ themeCache.set(datum, themeColors);
199
+ colorCache.set(datum, primary!);
200
+ return themeColors;
201
+ };
202
+ const measureNode = (
203
+ datum: AnnotatedItem,
204
+ ): { width: number; height: number } => {
205
+ const cached = nodeSizeCache.get(datum);
206
+ if (cached) return cached;
207
+ const depth = Math.max(datum._indexes.length - 1, 0);
208
+ const Component = getItemComponent(Items, depth);
209
+ const bounds = getElementBounds(
210
+ <Component
211
+ indexes={datum._indexes}
212
+ data={data}
213
+ datum={datum}
214
+ positionH="center"
215
+ positionV="middle"
216
+ themeColors={getNodeThemeColors(datum, depth)}
217
+ />,
218
+ );
219
+ nodeSizeCache.set(datum, bounds);
220
+ return bounds;
221
+ };
222
+
223
+ const mindmapRoot = mindmap(root, {
224
+ direction: 'H',
225
+ getSide: (node: HierarchyNode, index: number) => {
226
+ if (!node.parent) return 'right';
227
+ const order = (node.parent.children || []).indexOf(node);
228
+ const rank = order >= 0 ? order : index;
229
+ return rank % 2 === 0 ? 'left' : 'right';
230
+ },
231
+ getWidth: (datum: AnnotatedItem) => measureNode(datum).width,
232
+ getHeight: (datum: AnnotatedItem) => measureNode(datum).height,
233
+ getHGap: () => levelGap,
234
+ getVGap: () => nodeGap,
235
+ }) as LayoutNode;
236
+
237
+ const layoutNodes: LayoutNode[] = [];
238
+ const nodeLinks: LayoutLink[] = [];
239
+ collectNodes(mindmapRoot, layoutNodes, nodeLinks);
240
+
241
+ const minX =
242
+ layoutNodes.length > 0 ? Math.min(...layoutNodes.map((node) => node.x)) : 0;
243
+ const minY =
244
+ layoutNodes.length > 0 ? Math.min(...layoutNodes.map((node) => node.y)) : 0;
245
+ const shiftX = LAYOUT_PADDING - minX;
246
+ const shiftY = LAYOUT_PADDING - minY;
247
+
248
+ const defsElements: JSXElement[] = [];
249
+ const decorElements: JSXElement[] = [];
250
+ const itemElements: JSXElement[] = [];
251
+ const btnElements: JSXElement[] = [];
252
+ const layoutStore = new WeakMap<
253
+ LayoutNode,
254
+ {
255
+ x: number;
256
+ y: number;
257
+ width: number;
258
+ height: number;
259
+ centerX: number;
260
+ centerY: number;
261
+ }
262
+ >();
263
+
264
+ layoutNodes.forEach((node) => {
265
+ const datum = node.data;
266
+ const measured = measureNode(datum);
267
+ const displayX = node.x + shiftX + (node.hgap ?? 0);
268
+ const displayY = node.y + shiftY + (node.vgap ?? 0);
269
+ const Component = getItemComponent(Items, node.depth);
270
+ const positionH =
271
+ node.depth === 0 ? 'center' : node.side === 'left' ? 'flipped' : 'normal';
272
+ const themeColors = getNodeThemeColors(datum, node.depth);
273
+
274
+ itemElements.push(
275
+ <Component
276
+ indexes={datum._indexes}
277
+ data={data}
278
+ datum={datum}
279
+ x={displayX}
280
+ y={displayY}
281
+ positionH={positionH}
282
+ positionV="middle"
283
+ themeColors={themeColors}
284
+ />,
285
+ );
286
+
287
+ layoutStore.set(node, {
288
+ x: displayX,
289
+ y: displayY,
290
+ width: measured.width,
291
+ height: measured.height,
292
+ centerX: displayX + measured.width / 2,
293
+ centerY: displayY + measured.height / 2,
294
+ });
295
+ });
296
+
297
+ nodeLinks.forEach((link) => {
298
+ const { parent, child } = link;
299
+ const childLayout = layoutStore.get(child);
300
+ const parentLayout = layoutStore.get(parent);
301
+ if (!childLayout || !parentLayout) {
302
+ return;
303
+ }
304
+ const childDatum = child.data;
305
+ const { sx, sy, tx, ty } = getEdgeAnchors(
306
+ parentLayout,
307
+ childLayout,
308
+ child.side,
309
+ edgeAlign,
310
+ );
311
+ const childColor =
312
+ colorCache.get(childDatum) ??
313
+ getPaletteColor(options, getNodeColorIndexes(childDatum, child.depth));
314
+ const parentColor =
315
+ colorCache.get(parent.data) ??
316
+ getPaletteColor(options, getNodeColorIndexes(parent.data, parent.depth));
317
+ const pathD =
318
+ edgeType === 'straight'
319
+ ? createStraightPath(sx, sy, tx, ty)
320
+ : createCurvePath(sx, sy, tx, ty);
321
+ const gradientId = `edge-gradient-${childDatum._indexes.join('-')}`;
322
+ decorElements.push(
323
+ <Path
324
+ d={pathD}
325
+ stroke={
326
+ edgeColorMode === 'gradient'
327
+ ? `url(#${gradientId})`
328
+ : (childColor ?? colorPrimary)
329
+ }
330
+ strokeWidth={edgeWidth}
331
+ fill="none"
332
+ />,
333
+ );
334
+ if (edgeColorMode === 'gradient') {
335
+ defsElements.push(
336
+ <linearGradient
337
+ id={gradientId}
338
+ gradientUnits="userSpaceOnUse"
339
+ x1={sx}
340
+ y1={sy}
341
+ x2={tx}
342
+ y2={ty}
343
+ >
344
+ <stop offset="0%" stopColor={parentColor ?? colorPrimary} />
345
+ <stop offset="100%" stopColor={childColor ?? colorPrimary} />
346
+ </linearGradient>,
347
+ );
348
+ }
349
+ const appendIndex = childDatum.children?.length ?? 0;
350
+ const addIndexes = [...childDatum._indexes, appendIndex];
351
+ const btnX = childLayout.x + (childLayout.width - btnBounds.width) / 2;
352
+ const removeY = childLayout.y + childLayout.height + 8;
353
+ const addY = removeY + btnBounds.height + 6;
354
+
355
+ if (child.depth > 0) {
356
+ btnElements.push(
357
+ <BtnRemove indexes={childDatum._indexes} x={btnX} y={removeY} />,
358
+ );
359
+ }
360
+ btnElements.push(<BtnAdd indexes={addIndexes} x={btnX} y={addY} />);
361
+ });
362
+
363
+ const rootLayout = layoutStore.get(mindmapRoot);
364
+ if (rootLayout) {
365
+ const rootDatum = mindmapRoot.data;
366
+ const appendIndex = rootDatum.children?.length ?? 0;
367
+ const addIndexes = [...rootDatum._indexes, appendIndex];
368
+ const btnX = rootLayout.x + (rootLayout.width - btnBounds.width) / 2;
369
+ const addY = rootLayout.y + rootLayout.height + 8 + btnBounds.height + 6;
370
+ btnElements.push(<BtnAdd indexes={addIndexes} x={btnX} y={addY} />);
371
+ }
372
+
373
+ return (
374
+ <FlexLayout
375
+ id="infographic-container"
376
+ flexDirection="column"
377
+ justifyContent="center"
378
+ alignItems="center"
379
+ >
380
+ {titleContent}
381
+ <Group>
382
+ {defsElements.length > 0 ? <Defs>{defsElements}</Defs> : null}
383
+ <Group>{decorElements}</Group>
384
+ <ItemsGroup>{itemElements}</ItemsGroup>
385
+ <BtnsGroup>{btnElements}</BtnsGroup>
386
+ </Group>
387
+ </FlexLayout>
388
+ );
389
+ };
390
+
391
+ registerStructure('hierarchy-mindmap', {
392
+ component: HierarchyMindmap,
393
+ composites: ['title', 'item'],
394
+ });