@zerodep-dev/vue-tsx-pro-ui 0.2.0 → 0.3.0

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 (416) hide show
  1. package/dist/base/Badge.js +3 -3
  2. package/dist/base/Badge.js.map +1 -1
  3. package/dist/base/Can.d.ts +12 -0
  4. package/dist/base/Can.js +20 -0
  5. package/dist/base/Can.js.map +1 -0
  6. package/dist/base/ClientOnly.d.ts +10 -0
  7. package/dist/base/ClientOnly.js +18 -0
  8. package/dist/base/ClientOnly.js.map +1 -0
  9. package/dist/base/CloseButton.js +3 -3
  10. package/dist/base/CloseButton.js.map +1 -1
  11. package/dist/base/CodeBlock.js +5 -5
  12. package/dist/base/CodeBlock.js.map +1 -1
  13. package/dist/base/CopyButton.js +3 -3
  14. package/dist/base/CopyButton.js.map +1 -1
  15. package/dist/base/Icon.js +3 -3
  16. package/dist/base/Icon.js.map +1 -1
  17. package/dist/base/Indicator.js +3 -3
  18. package/dist/base/Indicator.js.map +1 -1
  19. package/dist/base/StatusDot.js +3 -3
  20. package/dist/base/StatusDot.js.map +1 -1
  21. package/dist/base/Tag.js +5 -5
  22. package/dist/base/Tag.js.map +1 -1
  23. package/dist/base/button-core.js +4 -4
  24. package/dist/base/button-core.js.map +1 -1
  25. package/dist/charts/AreaChart.js +3 -3
  26. package/dist/charts/AreaChart.js.map +1 -1
  27. package/dist/charts/BarChart.js +3 -3
  28. package/dist/charts/BarChart.js.map +1 -1
  29. package/dist/charts/ChordChart.js +3 -3
  30. package/dist/charts/ChordChart.js.map +1 -1
  31. package/dist/charts/ComboChart.js +3 -3
  32. package/dist/charts/ComboChart.js.map +1 -1
  33. package/dist/charts/DonutChart.js +3 -3
  34. package/dist/charts/DonutChart.js.map +1 -1
  35. package/dist/charts/FunnelChart.js +5 -5
  36. package/dist/charts/FunnelChart.js.map +1 -1
  37. package/dist/charts/GraphChart.js +3 -3
  38. package/dist/charts/GraphChart.js.map +1 -1
  39. package/dist/charts/LineChart.js +3 -3
  40. package/dist/charts/LineChart.js.map +1 -1
  41. package/dist/charts/MapChart.js +7 -7
  42. package/dist/charts/MapChart.js.map +1 -1
  43. package/dist/charts/RadarChart.js +16 -15
  44. package/dist/charts/RadarChart.js.map +1 -1
  45. package/dist/charts/SankeyChart.js +3 -3
  46. package/dist/charts/SankeyChart.js.map +1 -1
  47. package/dist/charts/ScatterChart.js +3 -3
  48. package/dist/charts/ScatterChart.js.map +1 -1
  49. package/dist/charts/TimelineChart.js +6 -5
  50. package/dist/charts/TimelineChart.js.map +1 -1
  51. package/dist/charts/TreemapChart.js +3 -3
  52. package/dist/charts/TreemapChart.js.map +1 -1
  53. package/dist/charts/WaterfallChart.js +3 -3
  54. package/dist/charts/WaterfallChart.js.map +1 -1
  55. package/dist/charts/XYChart.js +9 -7
  56. package/dist/charts/XYChart.js.map +1 -1
  57. package/dist/charts/frame.js +10 -8
  58. package/dist/charts/frame.js.map +1 -1
  59. package/dist/charts/single.js +4 -3
  60. package/dist/charts/single.js.map +1 -1
  61. package/dist/config/Provider.d.ts +3 -1
  62. package/dist/config/Provider.js +9 -4
  63. package/dist/config/Provider.js.map +1 -1
  64. package/dist/config/context.d.ts +18 -0
  65. package/dist/config/context.js +16 -1
  66. package/dist/config/context.js.map +1 -1
  67. package/dist/config/createUi.d.ts +20 -3
  68. package/dist/config/createUi.js +80 -49
  69. package/dist/config/createUi.js.map +1 -1
  70. package/dist/config/layout/preference.d.ts +43 -0
  71. package/dist/config/layout/preference.js +108 -0
  72. package/dist/config/layout/preference.js.map +1 -0
  73. package/dist/date/Calendar.js +3 -3
  74. package/dist/date/Calendar.js.map +1 -1
  75. package/dist/date/CalendarBoard.js +9 -9
  76. package/dist/date/CalendarBoard.js.map +1 -1
  77. package/dist/date/CalendarView.js +7 -7
  78. package/dist/date/CalendarView.js.map +1 -1
  79. package/dist/date/DateField.js +3 -3
  80. package/dist/date/DateField.js.map +1 -1
  81. package/dist/date/DatePicker.js +5 -5
  82. package/dist/date/DatePicker.js.map +1 -1
  83. package/dist/date/DateRangePicker.js +5 -5
  84. package/dist/date/DateRangePicker.js.map +1 -1
  85. package/dist/date/DateSegmentGroup.js +5 -5
  86. package/dist/date/DateSegmentGroup.js.map +1 -1
  87. package/dist/date/QuarterCalendar.js +6 -6
  88. package/dist/date/QuarterCalendar.js.map +1 -1
  89. package/dist/date/RangeCalendar.js +3 -3
  90. package/dist/date/RangeCalendar.js.map +1 -1
  91. package/dist/date/SegmentedField.js +3 -3
  92. package/dist/date/SegmentedField.js.map +1 -1
  93. package/dist/date/TimeField.js +3 -3
  94. package/dist/date/TimeField.js.map +1 -1
  95. package/dist/date/TimePicker.js +4 -4
  96. package/dist/date/TimePicker.js.map +1 -1
  97. package/dist/date/date-segments.js +1 -1
  98. package/dist/date/date-segments.js.map +1 -1
  99. package/dist/date/picker-popover.js +3 -2
  100. package/dist/date/picker-popover.js.map +1 -1
  101. package/dist/diagram/Diagram.js +12 -12
  102. package/dist/diagram/Diagram.js.map +1 -1
  103. package/dist/diagram/DiagramLanes.js +3 -3
  104. package/dist/diagram/DiagramLanes.js.map +1 -1
  105. package/dist/diagram/DiagramMinimap.js +4 -4
  106. package/dist/diagram/DiagramMinimap.js.map +1 -1
  107. package/dist/display/Accordion.js +6 -6
  108. package/dist/display/Accordion.js.map +1 -1
  109. package/dist/display/AnimatedNumber.js +4 -4
  110. package/dist/display/AnimatedNumber.js.map +1 -1
  111. package/dist/display/Avatar.js +4 -4
  112. package/dist/display/Avatar.js.map +1 -1
  113. package/dist/display/Checklist.js +7 -7
  114. package/dist/display/Checklist.js.map +1 -1
  115. package/dist/display/Collapse.js +8 -5
  116. package/dist/display/Collapse.js.map +1 -1
  117. package/dist/display/Collapsible.js +3 -3
  118. package/dist/display/Collapsible.js.map +1 -1
  119. package/dist/display/Descriptions.js +5 -5
  120. package/dist/display/Descriptions.js.map +1 -1
  121. package/dist/display/Ellipsis.js +3 -3
  122. package/dist/display/Ellipsis.js.map +1 -1
  123. package/dist/display/FieldCompare.js +4 -4
  124. package/dist/display/FieldCompare.js.map +1 -1
  125. package/dist/display/Gauge.js +11 -11
  126. package/dist/display/Gauge.js.map +1 -1
  127. package/dist/display/Image.js +4 -4
  128. package/dist/display/Image.js.map +1 -1
  129. package/dist/display/Marquee.js +3 -3
  130. package/dist/display/Marquee.js.map +1 -1
  131. package/dist/display/ProportionBar.js +4 -4
  132. package/dist/display/ProportionBar.js.map +1 -1
  133. package/dist/display/Sortable.js +4 -4
  134. package/dist/display/Sortable.js.map +1 -1
  135. package/dist/display/Sparkline.js +6 -6
  136. package/dist/display/Sparkline.js.map +1 -1
  137. package/dist/display/Stat.js +3 -3
  138. package/dist/display/Stat.js.map +1 -1
  139. package/dist/display/Timeline.js +7 -7
  140. package/dist/display/Timeline.js.map +1 -1
  141. package/dist/display/Tree.js +10 -10
  142. package/dist/display/Tree.js.map +1 -1
  143. package/dist/display/VirtualList.js +7 -7
  144. package/dist/display/VirtualList.js.map +1 -1
  145. package/dist/display/Watermark.js +3 -3
  146. package/dist/display/Watermark.js.map +1 -1
  147. package/dist/docs-kit/CodeGroup.js +5 -5
  148. package/dist/docs-kit/CodeGroup.js.map +1 -1
  149. package/dist/docs-kit/CodePreview.js +6 -6
  150. package/dist/docs-kit/CodePreview.js.map +1 -1
  151. package/dist/docs-kit/PropsTable.js +4 -4
  152. package/dist/docs-kit/PropsTable.js.map +1 -1
  153. package/dist/feedback/Alert.js +5 -5
  154. package/dist/feedback/Alert.js.map +1 -1
  155. package/dist/feedback/Banner.js +5 -5
  156. package/dist/feedback/Banner.js.map +1 -1
  157. package/dist/feedback/Empty.js +4 -4
  158. package/dist/feedback/Empty.js.map +1 -1
  159. package/dist/feedback/LoadingBar.js +20 -13
  160. package/dist/feedback/LoadingBar.js.map +1 -1
  161. package/dist/feedback/LoadingOverlay.js +3 -3
  162. package/dist/feedback/LoadingOverlay.js.map +1 -1
  163. package/dist/feedback/Progress.js +14 -14
  164. package/dist/feedback/Progress.js.map +1 -1
  165. package/dist/feedback/Result.js +4 -4
  166. package/dist/feedback/Result.js.map +1 -1
  167. package/dist/feedback/SkeletonText.js +3 -3
  168. package/dist/feedback/SkeletonText.js.map +1 -1
  169. package/dist/feedback/Toast.js +6 -6
  170. package/dist/feedback/Toast.js.map +1 -1
  171. package/dist/form/Field.js +7 -7
  172. package/dist/form/Field.js.map +1 -1
  173. package/dist/form/Form.js +3 -3
  174. package/dist/form/Form.js.map +1 -1
  175. package/dist/form/FormErrorSummary.js +3 -3
  176. package/dist/form/FormErrorSummary.js.map +1 -1
  177. package/dist/form/FormSection.js +6 -6
  178. package/dist/form/FormSection.js.map +1 -1
  179. package/dist/index.d.ts +11 -6
  180. package/dist/index.js +10 -5
  181. package/dist/input/Autocomplete.js +3 -3
  182. package/dist/input/Autocomplete.js.map +1 -1
  183. package/dist/input/Cascader.js +7 -7
  184. package/dist/input/Cascader.js.map +1 -1
  185. package/dist/input/CharacterCount.js +3 -3
  186. package/dist/input/CharacterCount.js.map +1 -1
  187. package/dist/input/Checkbox.js +5 -5
  188. package/dist/input/Checkbox.js.map +1 -1
  189. package/dist/input/ColorField.js +4 -4
  190. package/dist/input/ColorField.js.map +1 -1
  191. package/dist/input/Combobox.js +4 -4
  192. package/dist/input/Combobox.js.map +1 -1
  193. package/dist/input/ConditionBuilder.js +15 -14
  194. package/dist/input/ConditionBuilder.js.map +1 -1
  195. package/dist/input/FileDrop.js +3 -3
  196. package/dist/input/FileDrop.js.map +1 -1
  197. package/dist/input/Listbox.js +9 -9
  198. package/dist/input/Listbox.js.map +1 -1
  199. package/dist/input/Mentions.js +3 -3
  200. package/dist/input/Mentions.js.map +1 -1
  201. package/dist/input/NumberField.js +3 -3
  202. package/dist/input/NumberField.js.map +1 -1
  203. package/dist/input/NumberRangeField.js +5 -5
  204. package/dist/input/NumberRangeField.js.map +1 -1
  205. package/dist/input/OtpField.js +5 -5
  206. package/dist/input/OtpField.js.map +1 -1
  207. package/dist/input/PeoplePicker.js +6 -6
  208. package/dist/input/PeoplePicker.js.map +1 -1
  209. package/dist/input/PeoplePickerPanel.js +4 -4
  210. package/dist/input/PeoplePickerPanel.js.map +1 -1
  211. package/dist/input/Radio.js +4 -4
  212. package/dist/input/Radio.js.map +1 -1
  213. package/dist/input/Rating.js +5 -5
  214. package/dist/input/Rating.js.map +1 -1
  215. package/dist/input/Select.js +4 -4
  216. package/dist/input/Select.js.map +1 -1
  217. package/dist/input/SelectedTags.js +4 -4
  218. package/dist/input/SelectedTags.js.map +1 -1
  219. package/dist/input/Slider.js +6 -6
  220. package/dist/input/Slider.js.map +1 -1
  221. package/dist/input/Switch.js +3 -3
  222. package/dist/input/Switch.js.map +1 -1
  223. package/dist/input/TagsInput.js +5 -5
  224. package/dist/input/TagsInput.js.map +1 -1
  225. package/dist/input/TextField.js +5 -5
  226. package/dist/input/TextField.js.map +1 -1
  227. package/dist/input/Textarea.js +4 -4
  228. package/dist/input/Textarea.js.map +1 -1
  229. package/dist/input/ToggleGroup.js +4 -4
  230. package/dist/input/ToggleGroup.js.map +1 -1
  231. package/dist/input/Transfer.js +8 -8
  232. package/dist/input/Transfer.js.map +1 -1
  233. package/dist/input/TreeSelect.js +6 -6
  234. package/dist/input/TreeSelect.js.map +1 -1
  235. package/dist/input/Upload.js +8 -8
  236. package/dist/input/Upload.js.map +1 -1
  237. package/dist/layout/Affix.js +4 -4
  238. package/dist/layout/Affix.js.map +1 -1
  239. package/dist/layout/ResizeHandle.d.ts +6 -2
  240. package/dist/layout/ResizeHandle.js +32 -9
  241. package/dist/layout/ResizeHandle.js.map +1 -1
  242. package/dist/layout/ScrollArea.js +3 -3
  243. package/dist/layout/ScrollArea.js.map +1 -1
  244. package/dist/layout/Separator.js +3 -3
  245. package/dist/layout/Separator.js.map +1 -1
  246. package/dist/layout/Splitter.js +3 -3
  247. package/dist/layout/Splitter.js.map +1 -1
  248. package/dist/layout/ViewportFill.d.ts +2 -2
  249. package/dist/layout/ViewportFill.js +4 -4
  250. package/dist/layout/ViewportFill.js.map +1 -1
  251. package/dist/navigation/Breadcrumbs.js +4 -4
  252. package/dist/navigation/Breadcrumbs.js.map +1 -1
  253. package/dist/navigation/NavBar.js +6 -6
  254. package/dist/navigation/NavBar.js.map +1 -1
  255. package/dist/navigation/NavList.d.ts +1 -0
  256. package/dist/navigation/NavList.js +20 -12
  257. package/dist/navigation/NavList.js.map +1 -1
  258. package/dist/navigation/NavMenu.d.ts +27 -0
  259. package/dist/navigation/NavMenu.js +54 -0
  260. package/dist/navigation/NavMenu.js.map +1 -0
  261. package/dist/navigation/PageJump.js +3 -3
  262. package/dist/navigation/PageJump.js.map +1 -1
  263. package/dist/navigation/PageSizeSelect.js +4 -4
  264. package/dist/navigation/PageSizeSelect.js.map +1 -1
  265. package/dist/navigation/Pagination.js +6 -6
  266. package/dist/navigation/Pagination.js.map +1 -1
  267. package/dist/navigation/PaginationBar.js +5 -5
  268. package/dist/navigation/PaginationBar.js.map +1 -1
  269. package/dist/navigation/Steps.js +4 -4
  270. package/dist/navigation/Steps.js.map +1 -1
  271. package/dist/navigation/TableOfContents.js +5 -5
  272. package/dist/navigation/TableOfContents.js.map +1 -1
  273. package/dist/navigation/Tabs.js +7 -7
  274. package/dist/navigation/Tabs.js.map +1 -1
  275. package/dist/navigation/Toolbar.js +3 -3
  276. package/dist/navigation/Toolbar.js.map +1 -1
  277. package/dist/overlay/AlertDialog.js +4 -4
  278. package/dist/overlay/AlertDialog.js.map +1 -1
  279. package/dist/overlay/CommandPalette.js +4 -4
  280. package/dist/overlay/CommandPalette.js.map +1 -1
  281. package/dist/overlay/ContextMenu.js +3 -3
  282. package/dist/overlay/ContextMenu.js.map +1 -1
  283. package/dist/overlay/Dialog.js +4 -4
  284. package/dist/overlay/Dialog.js.map +1 -1
  285. package/dist/overlay/Drawer.js +5 -5
  286. package/dist/overlay/Drawer.js.map +1 -1
  287. package/dist/overlay/HoverCard.js +5 -3
  288. package/dist/overlay/HoverCard.js.map +1 -1
  289. package/dist/overlay/Lightbox.js +5 -5
  290. package/dist/overlay/Lightbox.js.map +1 -1
  291. package/dist/overlay/Menu.js +7 -7
  292. package/dist/overlay/Menu.js.map +1 -1
  293. package/dist/overlay/ModalCore.js +9 -9
  294. package/dist/overlay/ModalCore.js.map +1 -1
  295. package/dist/overlay/Popconfirm.js +6 -6
  296. package/dist/overlay/Popconfirm.js.map +1 -1
  297. package/dist/overlay/Popover.js +5 -3
  298. package/dist/overlay/Popover.js.map +1 -1
  299. package/dist/overlay/Tooltip.js +5 -3
  300. package/dist/overlay/Tooltip.js.map +1 -1
  301. package/dist/overlay/Tour.js +8 -8
  302. package/dist/overlay/Tour.js.map +1 -1
  303. package/dist/overlay/detached.d.ts +2 -0
  304. package/dist/overlay/detached.js +73 -42
  305. package/dist/overlay/detached.js.map +1 -1
  306. package/dist/patterns/ActionBar.js +3 -3
  307. package/dist/patterns/ActionBar.js.map +1 -1
  308. package/dist/patterns/AppShell.d.ts +28 -1
  309. package/dist/patterns/AppShell.js +158 -52
  310. package/dist/patterns/AppShell.js.map +1 -1
  311. package/dist/patterns/AuthLayout.d.ts +28 -0
  312. package/dist/patterns/AuthLayout.js +77 -0
  313. package/dist/patterns/AuthLayout.js.map +1 -0
  314. package/dist/patterns/CommentThread.js +9 -9
  315. package/dist/patterns/CommentThread.js.map +1 -1
  316. package/dist/patterns/DataImport.js +4 -4
  317. package/dist/patterns/DataImport.js.map +1 -1
  318. package/dist/patterns/DeadlineBadge.js +3 -3
  319. package/dist/patterns/DeadlineBadge.js.map +1 -1
  320. package/dist/patterns/FilterBar.d.ts +11 -1
  321. package/dist/patterns/FilterBar.js +39 -10
  322. package/dist/patterns/FilterBar.js.map +1 -1
  323. package/dist/patterns/FormDialog.d.ts +18 -0
  324. package/dist/patterns/FormDialog.js +46 -0
  325. package/dist/patterns/FormDialog.js.map +1 -0
  326. package/dist/patterns/KanbanBoard.js +8 -8
  327. package/dist/patterns/KanbanBoard.js.map +1 -1
  328. package/dist/patterns/LayoutSwitcher.d.ts +12 -0
  329. package/dist/patterns/LayoutSwitcher.js +79 -0
  330. package/dist/patterns/LayoutSwitcher.js.map +1 -0
  331. package/dist/patterns/NotificationCenter.js +8 -8
  332. package/dist/patterns/NotificationCenter.js.map +1 -1
  333. package/dist/patterns/PageTabs.d.ts +12 -7
  334. package/dist/patterns/PageTabs.js +41 -29
  335. package/dist/patterns/PageTabs.js.map +1 -1
  336. package/dist/patterns/QueryTable.d.ts +7 -1
  337. package/dist/patterns/QueryTable.js +116 -81
  338. package/dist/patterns/QueryTable.js.map +1 -1
  339. package/dist/patterns/SlideCaptcha.d.ts +80 -0
  340. package/dist/patterns/SlideCaptcha.js +354 -0
  341. package/dist/patterns/SlideCaptcha.js.map +1 -0
  342. package/dist/patterns/StepsForm.js +7 -7
  343. package/dist/patterns/StepsForm.js.map +1 -1
  344. package/dist/patterns/ThemeSwitcher.js +3 -3
  345. package/dist/patterns/ThemeSwitcher.js.map +1 -1
  346. package/dist/patterns/index.d.ts +7 -3
  347. package/dist/patterns/index.js +5 -1
  348. package/dist/patterns/messages.d.ts +37 -1
  349. package/dist/patterns/messages.js +38 -2
  350. package/dist/patterns/messages.js.map +1 -1
  351. package/dist/table/ColumnHeaderActions.js +3 -3
  352. package/dist/table/ColumnHeaderActions.js.map +1 -1
  353. package/dist/table/ColumnResizer.js +3 -3
  354. package/dist/table/ColumnResizer.js.map +1 -1
  355. package/dist/table/ColumnSettings.js +5 -5
  356. package/dist/table/ColumnSettings.js.map +1 -1
  357. package/dist/table/ColumnTable.js +8 -8
  358. package/dist/table/ColumnTable.js.map +1 -1
  359. package/dist/table/DataTable.js +8 -8
  360. package/dist/table/DataTable.js.map +1 -1
  361. package/dist/table/DataTableView.js +21 -21
  362. package/dist/table/DataTableView.js.map +1 -1
  363. package/dist/table/PivotTable.js +3 -3
  364. package/dist/table/PivotTable.js.map +1 -1
  365. package/dist/table/SelectionBar.js +4 -4
  366. package/dist/table/SelectionBar.js.map +1 -1
  367. package/dist/table/TreeDataTable.js +5 -5
  368. package/dist/table/TreeDataTable.js.map +1 -1
  369. package/dist/theme-customize/ThemeCustomizer.js +7 -6
  370. package/dist/theme-customize/ThemeCustomizer.js.map +1 -1
  371. package/dist/theme-customize/ThemeThumbnail.js +3 -3
  372. package/dist/theme-customize/ThemeThumbnail.js.map +1 -1
  373. package/dist/three/background/AuroraBackground.js +3 -3
  374. package/dist/three/background/AuroraBackground.js.map +1 -1
  375. package/dist/three/background/MeshGradient.js +3 -3
  376. package/dist/three/background/MeshGradient.js.map +1 -1
  377. package/dist/three/background/ShaderBackground.js +3 -3
  378. package/dist/three/background/ShaderBackground.js.map +1 -1
  379. package/dist/three/core/EffectSurface.js +3 -3
  380. package/dist/three/core/EffectSurface.js.map +1 -1
  381. package/dist/three/core/ThreeCanvas.js +4 -4
  382. package/dist/three/core/ThreeCanvas.js.map +1 -1
  383. package/dist/three/effects/Confetti.js +3 -3
  384. package/dist/three/effects/Confetti.js.map +1 -1
  385. package/dist/three/effects/ParticleField.js +3 -3
  386. package/dist/three/effects/ParticleField.js.map +1 -1
  387. package/dist/three/effects/WaveGrid.js +3 -3
  388. package/dist/three/effects/WaveGrid.js.map +1 -1
  389. package/dist/three/globe/Globe.js +3 -3
  390. package/dist/three/globe/Globe.js.map +1 -1
  391. package/dist/three/model/ModelViewer.js +3 -3
  392. package/dist/three/model/ModelViewer.js.map +1 -1
  393. package/dist/utils/data/number.d.ts +5 -0
  394. package/dist/utils/data/number.js +8 -1
  395. package/dist/utils/data/number.js.map +1 -1
  396. package/dist/utils/dom/element.d.ts +3 -1
  397. package/dist/utils/dom/element.js +8 -4
  398. package/dist/utils/dom/element.js.map +1 -1
  399. package/dist/utils/dom/fullscreen.d.ts +1 -1
  400. package/dist/utils/dom/fullscreen.js +12 -8
  401. package/dist/utils/dom/fullscreen.js.map +1 -1
  402. package/dist/utils/dom/mounted.d.ts +7 -0
  403. package/dist/utils/dom/mounted.js +16 -0
  404. package/dist/utils/dom/mounted.js.map +1 -0
  405. package/dist/utils/dom/overflow.js +2 -1
  406. package/dist/utils/dom/overflow.js.map +1 -1
  407. package/dist/utils/dom/pan-zoom.js +2 -1
  408. package/dist/utils/dom/pan-zoom.js.map +1 -1
  409. package/dist/utils/props.js +3 -13
  410. package/dist/utils/props.js.map +1 -1
  411. package/dist/utils/request/http.d.ts +12 -0
  412. package/dist/utils/request/http.js +6 -2
  413. package/dist/utils/request/http.js.map +1 -1
  414. package/dist/utils/request/use-request.js +4 -2
  415. package/dist/utils/request/use-request.js.map +1 -1
  416. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"FunnelChart.js","names":["_vtp_readonlyProp","_vtp_restProps","_vue_computed","_createVNode","_mergeProps","_createTextVNode"],"sources":["../../src/charts/FunnelChart.tsx"],"sourcesContent":["/**\n * 漏斗图:一串前后相接的环节,看每一步留下多少、在哪一步流失最多(访问 → 注册 → 下单、线索转化)。\n *\n * <FunnelChart aria-label=\"渠道转化\" stages={[{ label: '提交建议', value: 120 }, { label: '立项', value: 46 }]} unit=\"项\" />\n *\n * 每个环节一条居中的横条,长短按数值(最大的环节占满);环节之间写比上一环节的转化率,末尾写总转化。\n * 横条默认同一个颜色(chart1),环节可以单独给 color。Unovis 没有漏斗图:这里用主题 tokens 直接画,\n * 外层结构(单位、加载与空状态、给读屏的数据表)同其他图表(见 ChartFrame)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useLang } from '../config/context';\nimport { useFormat, type NumericFormat } from '../config/lang/format';\nimport { Skeleton } from '../feedback/Skeleton';\nimport { toNumber, type NumericValue } from '../utils/data/numeric';\nimport type { PartProps } from '../utils/props';\nimport { ChartFrame, type ChartFrameParts } from './frame';\nimport { resolveColor, type ChartColor } from './series';\nimport { t } from '../config/theme/tokens';\n\n/** 漏斗的一个环节 */\nexport interface FunnelStage {\n /** 名称 */\n label: string;\n /** 数值:number、bigint 或 Decimal */\n value: NumericValue;\n /** 颜色;不写时用图表的 color */\n color?: ChartColor;\n}\n\n/** 未声明的属性落到外层 div(role=\"figure\")上,aria-label 是图表的名称 */\nexport interface FunnelChartProps extends PartProps<'div', 'role' | 'aria-busy'>, ChartFrameParts {\n /** 各环节:从上到下 */\n stages: readonly FunnelStage[];\n /** 数值的格式(可缩放):横条旁的数值与数据表共用 */\n valueFormat?: NumericFormat;\n /** 单位:显示在左上方,数值后面带上 */\n unit?: string;\n /**\n * 横条的颜色\n * @default 'chart1'\n */\n color?: ChartColor;\n /**\n * 环节之间写转化率,末尾写总转化\n * @default true\n */\n rates?: boolean;\n /**\n * 加载中:显示几条骨架,带 aria-busy\n * @default false\n */\n loading?: boolean;\n /** 没有数据时显示的内容,默认是“暂无数据” */\n empty?: VNodeChild;\n /**\n * 点了一个环节(下钻):参数是这个环节与它的位置;写了它时指针是手形。\n * 点图是鼠标的捷径:同样的去处在页面上还要有链接或按钮\n */\n onItemClick?: (stage: FunnelStage, index: number) => void;\n}\n\n/** FunnelChart 的样式:list、row、label、track、bar、value、rate… */\nexport const funnelChartStyles = css.create({\n // 名称 | 居中的横条 | 数值:三列由整个列表定宽,各行用 subgrid 对齐\n list: {\n display: 'grid',\n gridTemplateColumns: 'max-content minmax(0, 1fr) max-content',\n columnGap: '_md',\n },\n row: {\n display: 'grid',\n gridColumn: '1 / -1',\n gridTemplateColumns: 'subgrid',\n alignItems: 'center',\n paddingBlock: '2px',\n paddingInline: '_xs',\n borderRadius: '_sm',\n },\n rowClickable: { backgroundColor: { default: 'transparent', ':hover': '_fill' } },\n label: { color: '_text', textAlign: 'end', whiteSpace: 'nowrap' },\n track: { display: 'flex', justifyContent: 'center' },\n bar: {\n height: '1.75rem',\n minWidth: '2px',\n borderRadius: '_sm',\n transition: `width ${t.durations.md} ${t.easings.standard}`,\n },\n value: { fontVariantNumeric: 'tabular-nums', fontWeight: '_medium', whiteSpace: 'nowrap' },\n // 环节之间:转化率写在中间那一列,小号的次要文字\n rate: {\n display: 'grid',\n gridColumn: '1 / -1',\n gridTemplateColumns: 'subgrid',\n paddingInline: '_xs',\n color: '_textMuted',\n fontSize: '_xs',\n fontVariantNumeric: 'tabular-nums',\n lineHeight: '_tight',\n },\n rateText: { gridColumn: '2', textAlign: 'center' },\n overall: { gridColumn: '2 / 4', textAlign: 'center', paddingBlockStart: '_xs' },\n skeleton: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '_sm' },\n skeletonBar: { height: '1.75rem', borderRadius: '_sm' },\n});\n\n// 横条的宽度与颜色随数据变:单独一个 create(见 COMPONENTS.md §4)\n/** FunnelChart 的样式:barSize、skeletonWidth */\nexport const funnelChartDynamicStyles = css.create({\n barSize: (width: string, color: string) => ({ width, backgroundColor: color }),\n skeletonWidth: (width: string) => ({ width }),\n});\n\n/** 骨架横条的宽度:从宽到窄 */\nconst SKELETON_WIDTHS = ['90%', '68%', '46%', '28%'];\n\n/** 漏斗图 */\nexport const FunnelChart = _component(\n ({\n stages,\n valueFormat,\n unit,\n color = 'chart1',\n rates = true,\n loading = false,\n empty,\n onItemClick,\n ...rest\n }: FunnelChartProps) => {\n const lang = useLang();\n const format = useFormat();\n const numbers = _derived(stages.map((stage) => Math.max(toNumber(stage.value), 0)));\n const max = _derived(Math.max(0, ...numbers));\n const percent = (value: number) =>\n format.number(value, { style: 'percent', maximumFractionDigits: 1 });\n /** 第 index 个环节比 base 个环节的转化率;base 为 0 时没有 */\n const rate = (index: number, base: number) =>\n numbers[base] ? percent(numbers[index]! / numbers[base]!) : lang.emptyValue;\n const valueText = (stage: FunnelStage) =>\n format.number(stage.value, unit ? { ...valueFormat, suffix: unit } : valueFormat);\n\n return () => (\n <ChartFrame\n {...rest}\n unit={unit}\n height=\"auto\"\n legend={[]}\n hiddenKeys={[]}\n onLegendToggle={() => {}}\n loading={loading}\n skeleton={\n <div aria-hidden=\"true\" {...css.attrs(funnelChartStyles.skeleton)}>\n {SKELETON_WIDTHS.map((width) => (\n <Skeleton\n key={width}\n sx={[funnelChartStyles.skeletonBar, funnelChartDynamicStyles.skeletonWidth(width)]}\n />\n ))}\n </div>\n }\n isEmpty={stages.length === 0}\n empty={empty}\n table={{\n columns: [\n lang.chartStage,\n unit ? `${lang.chartValue}(${unit})` : lang.chartValue,\n lang.chartStepRate,\n lang.chartOverallRate,\n ],\n rows: stages.map((stage, index) => ({\n header: stage.label,\n cells: [\n format.number(stage.value, valueFormat),\n index === 0 ? lang.emptyValue : rate(index, index - 1),\n index === 0 ? lang.emptyValue : rate(index, 0),\n ],\n })),\n }}\n plot={\n <div {...css.attrs(funnelChartStyles.list)}>\n {stages.map((stage, index) => [\n index > 0 && rates && (\n <div key={`rate-${index}`} {...css.attrs(funnelChartStyles.rate)}>\n <span {...css.attrs(funnelChartStyles.rateText)}>↓ {rate(index, index - 1)}</span>\n </div>\n ),\n <div\n key={`stage-${index}`}\n {...css.attrs(funnelChartStyles.row, onItemClick && funnelChartStyles.rowClickable)}\n onClick={onItemClick && (() => onItemClick(stage, index))}\n >\n <span {...css.attrs(funnelChartStyles.label)}>{stage.label}</span>\n <span {...css.attrs(funnelChartStyles.track)}>\n <span\n {...css.attrs(\n funnelChartStyles.bar,\n funnelChartDynamicStyles.barSize(\n max ? `${(numbers[index]! / max) * 100}%` : '0%',\n resolveColor(stage.color ?? color, index),\n ),\n )}\n />\n </span>\n <span {...css.attrs(funnelChartStyles.value)}>{valueText(stage)}</span>\n </div>,\n ])}\n {rates && stages.length > 1 && (\n <div {...css.attrs(funnelChartStyles.rate)}>\n <span {...css.attrs(funnelChartStyles.overall)}>\n {lang.chartOverallRate} {rate(stages.length - 1, 0)}\n </span>\n </div>\n )}\n </div>\n }\n clickable={onItemClick != null}\n />\n );\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"FunnelChart.js","names":["_vtp_readonlyProp","_vtp_restProps","_vue_computed","_createVNode","_mergeProps","_createTextVNode"],"sources":["../../src/charts/FunnelChart.tsx"],"sourcesContent":["/**\n * 漏斗图:一串前后相接的环节,看每一步留下多少、在哪一步流失最多(访问 → 注册 → 下单、线索转化)。\n *\n * <FunnelChart aria-label=\"渠道转化\" stages={[{ label: '提交建议', value: 120 }, { label: '立项', value: 46 }]} unit=\"项\" />\n *\n * 每个环节一条居中的横条,长短按数值(最大的环节占满);环节之间写比上一环节的转化率,末尾写总转化。\n * 横条默认同一个颜色(chart1),环节可以单独给 color。Unovis 没有漏斗图:这里用主题 tokens 直接画,\n * 外层结构(单位、加载与空状态、给读屏的数据表)同其他图表(见 ChartFrame)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useLang } from '../config/context';\nimport { useFormat, type NumericFormat } from '../config/lang/format';\nimport { Skeleton } from '../feedback/Skeleton';\nimport { toNumber, type NumericValue } from '../utils/data/numeric';\nimport type { PartProps } from '../utils/props';\nimport { ChartFrame, type ChartFrameParts } from './frame';\nimport { resolveColor, type ChartColor } from './series';\nimport { t } from '../config/theme/tokens';\n\n/** 漏斗的一个环节 */\nexport interface FunnelStage {\n /** 名称 */\n label: string;\n /** 数值:number、bigint 或 Decimal */\n value: NumericValue;\n /** 颜色;不写时用图表的 color */\n color?: ChartColor;\n}\n\n/** 未声明的属性落到外层 div(role=\"figure\")上,aria-label 是图表的名称 */\nexport interface FunnelChartProps extends PartProps<'div', 'role' | 'aria-busy'>, ChartFrameParts {\n /** 各环节:从上到下 */\n stages: readonly FunnelStage[];\n /** 数值的格式(可缩放):横条旁的数值与数据表共用 */\n valueFormat?: NumericFormat;\n /** 单位:显示在左上方,数值后面带上 */\n unit?: string;\n /**\n * 横条的颜色\n * @default 'chart1'\n */\n color?: ChartColor;\n /**\n * 环节之间写转化率,末尾写总转化\n * @default true\n */\n rates?: boolean;\n /**\n * 加载中:显示几条骨架,带 aria-busy\n * @default false\n */\n loading?: boolean;\n /** 没有数据时显示的内容,默认是“暂无数据” */\n empty?: VNodeChild;\n /**\n * 点了一个环节(下钻):参数是这个环节与它的位置;写了它时指针是手形。\n * 点图是鼠标的捷径:同样的去处在页面上还要有链接或按钮\n */\n onItemClick?: (stage: FunnelStage, index: number) => void;\n}\n\n/** FunnelChart 的样式:list、row、label、track、bar、value、rate… */\nexport const funnelChartStyles = css.create({\n // 名称 | 居中的横条 | 数值:三列由整个列表定宽,各行用 subgrid 对齐\n list: {\n display: 'grid',\n gridTemplateColumns: 'max-content minmax(0, 1fr) max-content',\n columnGap: '_md',\n },\n row: {\n display: 'grid',\n gridColumn: '1 / -1',\n gridTemplateColumns: 'subgrid',\n alignItems: 'center',\n paddingBlock: '2px',\n paddingInline: '_xs',\n borderRadius: '_sm',\n },\n rowClickable: { backgroundColor: { default: 'transparent', ':hover': '_fill' } },\n label: { color: '_text', textAlign: 'end', whiteSpace: 'nowrap' },\n track: { display: 'flex', justifyContent: 'center' },\n bar: {\n height: '1.75rem',\n minWidth: '2px',\n borderRadius: '_sm',\n transition: `width ${t.durations.md} ${t.easings.standard}`,\n },\n value: { fontVariantNumeric: 'tabular-nums', fontWeight: '_medium', whiteSpace: 'nowrap' },\n // 环节之间:转化率写在中间那一列,小号的次要文字\n rate: {\n display: 'grid',\n gridColumn: '1 / -1',\n gridTemplateColumns: 'subgrid',\n paddingInline: '_xs',\n color: '_textMuted',\n fontSize: '_xs',\n fontVariantNumeric: 'tabular-nums',\n lineHeight: '_tight',\n },\n rateText: { gridColumn: '2', textAlign: 'center' },\n overall: { gridColumn: '2 / 4', textAlign: 'center', paddingBlockStart: '_xs' },\n skeleton: { display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '_sm' },\n skeletonBar: { height: '1.75rem', borderRadius: '_sm' },\n});\n\n// 横条的宽度与颜色随数据变:单独一个 create(见 COMPONENTS.md §4)\n/** FunnelChart 的样式:barSize、skeletonWidth */\nexport const funnelChartDynamicStyles = css.create({\n barSize: (width: string, color: string) => ({ width, backgroundColor: color }),\n skeletonWidth: (width: string) => ({ width }),\n});\n\n/** 骨架横条的宽度:从宽到窄 */\nconst SKELETON_WIDTHS = ['90%', '68%', '46%', '28%'];\n\n/** 漏斗图 */\nexport const FunnelChart = _component(\n ({\n stages,\n valueFormat,\n unit,\n color = 'chart1',\n rates = true,\n loading = false,\n empty,\n onItemClick,\n ...rest\n }: FunnelChartProps) => {\n const lang = useLang();\n const format = useFormat();\n const numbers = _derived(stages.map((stage) => Math.max(toNumber(stage.value), 0)));\n const max = _derived(Math.max(0, ...numbers));\n const percent = (value: number) =>\n format.number(value, { style: 'percent', maximumFractionDigits: 1 });\n /** 第 index 个环节比 base 个环节的转化率;base 为 0 时没有 */\n const rate = (index: number, base: number) =>\n numbers[base] ? percent(numbers[index]! / numbers[base]!) : lang.emptyValue;\n const valueText = (stage: FunnelStage) =>\n format.number(stage.value, unit ? { ...valueFormat, suffix: unit } : valueFormat);\n\n return () => (\n <ChartFrame\n {...rest}\n unit={unit}\n height=\"auto\"\n legend={[]}\n hiddenKeys={[]}\n onLegendToggle={() => {}}\n loading={loading}\n skeleton={\n <div aria-hidden=\"true\" {...css.attrs(funnelChartStyles.skeleton)}>\n {SKELETON_WIDTHS.map((width) => (\n <Skeleton\n key={width}\n sx={[funnelChartStyles.skeletonBar, funnelChartDynamicStyles.skeletonWidth(width)]}\n />\n ))}\n </div>\n }\n isEmpty={stages.length === 0}\n empty={empty}\n table={{\n columns: [\n lang.chartStage,\n unit ? `${lang.chartValue}(${unit})` : lang.chartValue,\n lang.chartStepRate,\n lang.chartOverallRate,\n ],\n rows: stages.map((stage, index) => ({\n header: stage.label,\n cells: [\n format.number(stage.value, valueFormat),\n index === 0 ? lang.emptyValue : rate(index, index - 1),\n index === 0 ? lang.emptyValue : rate(index, 0),\n ],\n })),\n }}\n plot={\n <div {...css.attrs(funnelChartStyles.list)}>\n {stages.map((stage, index) => [\n index > 0 && rates && (\n <div key={`rate-${index}`} {...css.attrs(funnelChartStyles.rate)}>\n <span {...css.attrs(funnelChartStyles.rateText)}>↓ {rate(index, index - 1)}</span>\n </div>\n ),\n <div\n key={`stage-${index}`}\n {...css.attrs(funnelChartStyles.row, onItemClick && funnelChartStyles.rowClickable)}\n onClick={onItemClick && (() => onItemClick(stage, index))}\n >\n <span {...css.attrs(funnelChartStyles.label)}>{stage.label}</span>\n <span {...css.attrs(funnelChartStyles.track)}>\n <span\n {...css.attrs(\n funnelChartStyles.bar,\n funnelChartDynamicStyles.barSize(\n max ? `${(numbers[index]! / max) * 100}%` : '0%',\n resolveColor(stage.color ?? color, index),\n ),\n )}\n />\n </span>\n <span {...css.attrs(funnelChartStyles.value)}>{valueText(stage)}</span>\n </div>,\n ])}\n {rates && stages.length > 1 && (\n <div {...css.attrs(funnelChartStyles.rate)}>\n <span {...css.attrs(funnelChartStyles.overall)}>\n {lang.chartOverallRate} {rate(stages.length - 1, 0)}\n </span>\n </div>\n )}\n </div>\n }\n clickable={onItemClick != null}\n />\n );\n },\n);\n"],"mappings":"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"}
@@ -6,8 +6,8 @@ import { Skeleton } from "../feedback/Skeleton.js";
6
6
  import { ChartFrame, chartTooltip, useChartValueText } from "./frame.js";
7
7
  import { resolveColor } from "./series.js";
8
8
  import { useSingleChart } from "./single.js";
9
- import { computed, createVNode, mergeProps, shallowRef } from "vue";
10
- import { _component, bindable, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
9
+ import { computed, createVNode, shallowRef } from "vue";
10
+ import { _component, bindable, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
11
11
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
12
12
  import { Graph, GraphLayoutType, GraphLinkArrowStyle, GraphLinkStyle, GraphNodeSelectionHighlightMode, GraphNodeShape } from "@unovis/ts";
13
13
  //#region src/charts/GraphChart.tsx
@@ -225,7 +225,7 @@ var GraphChart = /*#__PURE__*/ _component((_props, _ctx) => {
225
225
  };
226
226
  }
227
227
  }));
228
- return () => createVNode(ChartFrame, mergeProps(rest, {
228
+ return () => createVNode(ChartFrame, mergeJsxProps(rest, {
229
229
  "sx": [graphChartStyles.root, sx.value],
230
230
  "unit": unit.value,
231
231
  "height": height.value,
@@ -1 +1 @@
1
- {"version":3,"file":"GraphChart.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_computed","_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/charts/GraphChart.tsx"],"sourcesContent":["/**\n * 网络图:节点与连线,看谁和谁有关系、关系有多强(案例与触发事件的匹配、团队与供应商的协作、依赖关系)。\n *\n * <GraphChart aria-label=\"协作关系\" nodes={nodes} links={links} layout=\"dagre\" groups={teams} />\n *\n * 节点是 { id, label?, sublabel?, group?, color?, shape?, size? },连线是 { source, target, value?, label?, dashed? }。\n * 布局交给 Unovis 的 Graph:force(默认,力导向)、dagre(分层,direction 定方向)、circular、concentric、parallel\n * (按 group 分列)、elk(分层且支持分组框,较大,用到时才加载)。布局异步算好再画,第一帧是空的。\n * 写了 groups 时同组的节点框在一起(dagre、elk、parallel 布局;力导向、环形布局里组只决定颜色,框会互相盖住);\n * 节点的颜色默认按组取色板,没有组时都是 chart1。\n * 连线写了 value 时按大小加粗(1–6px),悬停看“起点 → 终点”与数值。点节点选中它(selected 双向绑定),\n * 与它不相连的节点、连线变淡;点空白处取消。能缩放、拖动画布(zoom={false} 关掉),双击回到全图。\n * 给读屏的数据表每条连线一行;单位、加载与空状态同其他图表(见 ChartFrame)。\n */\nimport {\n Graph,\n GraphLayoutType,\n GraphLinkArrowStyle,\n GraphLinkStyle,\n GraphNodeSelectionHighlightMode,\n GraphNodeShape,\n} from '@unovis/ts';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useLang } from '../config/context';\nimport { useFormat, type NumericFormat } from '../config/lang/format';\nimport { colors, fontSizes, opacities } from '../config/theme/tokens';\nimport { Skeleton } from '../feedback/Skeleton';\nimport { toNumber, type NumericValue } from '../utils/data/numeric';\nimport type { PartProps } from '../utils/props';\nimport { ChartFrame, chartTooltip, useChartValueText, type ChartFrameParts } from './frame';\nimport { resolveColor, type ChartColor } from './series';\nimport { useSingleChart, type SingleChart } from './single';\n\n/** 节点的形状 */\nexport interface GraphChartShapes {\n /** 圆(默认) */\n circle: unknown;\n /** 方块 */\n square: unknown;\n /** 六边形 */\n hexagon: unknown;\n /** 三角 */\n triangle: unknown;\n}\n\n/** 布局 */\nexport interface GraphChartLayouts {\n /** 力导向(默认):相连的靠近、不相连的推开,适合看关系疏密 */\n force: unknown;\n /** 分层:沿 direction 一层层排开,适合有先后、上下游的关系 */\n dagre: unknown;\n /** 排成一圈 */\n circular: unknown;\n /** 同心圆:连得多的在中间 */\n concentric: unknown;\n /** 按 group 分列,组内按连接排 */\n parallel: unknown;\n /** 分层,分组框更规整(elkjs,约 1.6 MB,用到时才加载) */\n elk: unknown;\n}\n\n/** 一个节点 */\nexport interface GraphChartNode {\n /** id:连线里用它指节点 */\n id: string;\n /** 名称,写在节点下面;不写时用 id */\n label?: string;\n /** 名称下面的小字 */\n sublabel?: string;\n /** 所在的组(groups 里的 id):同组的框在一起、颜色相同 */\n group?: string;\n /** 颜色;不写时按组取色板,没有组时是 chart1 */\n color?: ChartColor;\n /** 形状,默认 circle */\n shape?: keyof GraphChartShapes;\n /** 大小(px),默认 28 */\n size?: number;\n}\n\n/** 一条连线 */\nexport interface GraphChartLink {\n /** 起点节点的 id */\n source: string;\n /** 终点节点的 id */\n target: string;\n /** 强度:写了时按大小加粗;提示框、数据表里显示 */\n value?: NumericValue;\n /** 线上的短标签(几个字以内) */\n label?: string;\n /** 虚线:弱关系、待定的关系 */\n dashed?: boolean;\n /** 颜色;默认是边框色 */\n color?: ChartColor;\n}\n\n/** 一组节点 */\nexport interface GraphChartGroup {\n /** 组的 id:节点的 group 指它 */\n id: string;\n /** 组名:写在框上 */\n label: string;\n /** 颜色;不写时按组的顺序取色板 */\n color?: ChartColor;\n}\n\n/** 未声明的属性落到外层 div(role=\"figure\")上,aria-label 是图表的名称 */\nexport interface GraphChartProps extends PartProps<'div', 'role' | 'aria-busy'>, ChartFrameParts {\n /** 节点 */\n nodes: readonly GraphChartNode[];\n /** 连线 */\n links: readonly GraphChartLink[];\n /** 分组:同组的节点框在一起(dagre、elk、parallel 布局),颜色相同 */\n groups?: readonly GraphChartGroup[];\n /**\n * 布局\n * @default 'force'\n */\n layout?: keyof GraphChartLayouts;\n /**\n * 分层布局(dagre、elk)的方向:LR 从左到右,TB 从上到下\n * @default 'LR'\n */\n direction?: 'LR' | 'TB';\n /** 连线带箭头;默认分层布局(dagre、elk)带,其余不带 */\n arrows?: boolean;\n /** 连线数值的格式:提示框、数据表共用 */\n valueFormat?: NumericFormat;\n /** 连线数值的单位:显示在左上方,数值后面带上 */\n unit?: string;\n /**\n * 绘图区的高度;数字按 px\n * @default 360\n */\n height?: number | string;\n /**\n * 能缩放、拖动画布\n * @default true\n */\n zoom?: boolean;\n /**\n * 悬停时的提示框\n * @default true\n */\n tooltip?: boolean;\n /** 选中的节点 id:点节点时写回,父级写 _selected={x};点空白处变回 null */\n _selected?: string | null;\n /**\n * 加载中:绘图区显示骨架,带 aria-busy\n * @default false\n */\n loading?: boolean;\n /** 没有数据时显示的内容,默认是“暂无数据” */\n empty?: VNodeChild;\n /**\n * 点了一个节点(下钻):参数是这个节点与它的位置;写了它时节点的指针是手形。\n * 点图是鼠标的捷径:同样的去处在页面上还要有链接或按钮\n */\n onItemClick?: (node: GraphChartNode, index: number) => void;\n}\n\n/** GraphChart 的样式:root(--vis-graph-* 主题变量)、skeleton */\nexport const graphChartStyles = css.create({\n root: {\n '--vis-graph-node-stroke-color': colors.surface,\n '--vis-graph-node-label-text-color': colors.text,\n '--vis-graph-node-label-font-size': fontSizes.xs,\n '--vis-graph-node-label-background': colors.surface,\n '--vis-graph-node-sublabel-text-color': colors.textMuted,\n '--vis-graph-node-sublabel-font-size': fontSizes.xs,\n '--vis-graph-node-selection-color': colors.accent,\n '--vis-graph-node-greyout-color': colors.surfaceMuted,\n '--vis-graph-node-greyout-opacity': opacities.disabled,\n '--vis-graph-link-stroke-color': colors.borderStrong,\n '--vis-graph-link-greyout-opacity': '0.25',\n '--vis-graph-link-label-background': colors.fill,\n '--vis-graph-link-label-text-color-dark': colors.text,\n '--vis-graph-link-label-font-size': fontSizes.xs,\n '--vis-graph-panel-fill-color': colors.surfaceMuted,\n '--vis-graph-panel-border-color': colors.borderMuted,\n '--vis-graph-panel-label-color': colors.textMuted,\n '--vis-graph-panel-label-background': colors.surface,\n '--vis-graph-panel-label-font-size': fontSizes.xs,\n '--vis-graph-panel-label-font-weight': '500',\n },\n skeleton: { display: 'block', width: '100%', height: '100%' },\n});\n\nconst LAYOUTS: Record<keyof GraphChartLayouts, GraphLayoutType> = {\n force: GraphLayoutType.Force,\n dagre: GraphLayoutType.Dagre,\n circular: GraphLayoutType.Circular,\n concentric: GraphLayoutType.Concentric,\n parallel: GraphLayoutType.Parallel,\n elk: GraphLayoutType.Elk,\n};\n\nconst SHAPES: Record<keyof GraphChartShapes, GraphNodeShape> = {\n circle: GraphNodeShape.Circle,\n square: GraphNodeShape.Square,\n hexagon: GraphNodeShape.Hexagon,\n triangle: GraphNodeShape.Triangle,\n};\n\n/** 交给 Unovis 的节点:带上名称与颜色;Unovis 会往上写布局用的字段,每次都复制一份 */\ninterface Node extends GraphChartNode {\n label: string;\n fill: string;\n index: number;\n}\n/** 交给 Unovis 的连线:数值转成 number 算粗细 */\ninterface Link extends GraphChartLink {\n amount: number | undefined;\n}\n/** Unovis 布局后:连线的起点、终点换成了节点对象 */\ntype LaidOutLink = Omit<Link, 'source' | 'target'> & { source: Node; target: Node };\n\n/** 网络图 */\nexport const GraphChart = _component(\n ({\n nodes,\n links,\n groups,\n layout = 'force',\n direction = 'LR',\n arrows,\n valueFormat,\n unit,\n height = 360,\n zoom = true,\n tooltip = true,\n _selected: selected = _bindable<string | null>(null),\n loading = false,\n empty,\n onItemClick,\n sx,\n ...rest\n }: GraphChartProps) => {\n const lang = useLang();\n const format = useFormat();\n const valueText = useChartValueText(() => ({ valueFormat, unit }));\n\n const groupColors = _derived(\n new Map(\n (groups ?? []).map((group, position) => [group.id, resolveColor(group.color, position)]),\n ),\n );\n const resolved = _derived(\n nodes.map((node, index): Node => ({\n ...node,\n label: node.label ?? node.id,\n fill: node.color\n ? resolveColor(node.color, 0)\n : ((node.group && groupColors.get(node.group)) ?? resolveColor('chart1', 0)),\n index,\n })),\n );\n const byId = _derived(new Map(resolved.map((node) => [node.id, node])));\n const labelOf = (id: string) => byId.get(id)?.label ?? id;\n // 只留两端都在的连线;最大值用来把粗细缩放到 1–6px\n const shownLinks = _derived(\n links\n .filter((link) => byId.has(link.source) && byId.has(link.target))\n .map((link): Link => ({\n ...link,\n amount: link.value === undefined ? undefined : toNumber(link.value),\n })),\n );\n const maxAmount = _derived(Math.max(0, ...shownLinks.map((link) => link.amount ?? 0)));\n const degree = _derived.by(() => {\n const counts = new Map<string, number>();\n for (const link of shownLinks) {\n counts.set(link.source, (counts.get(link.source) ?? 0) + 1);\n counts.set(link.target, (counts.get(link.target) ?? 0) + 1);\n }\n return counts;\n });\n\n let plot = _state.raw<HTMLElement | null>(null);\n const chart: SingleChart = useSingleChart<{ nodes: Node[]; links?: Link[] }>(() => ({\n element: plot,\n ready: !loading && nodes.length > 0,\n tooltip,\n build: (instance) => {\n const graph = instance('graph', () => new Graph<Node, Link>({}));\n const layered = layout === 'dagre' || layout === 'elk';\n // 分组框只在按层、按列排的布局里画:其余布局不按组排,框会互相盖住\n const framed = layered || layout === 'parallel';\n graph.setConfig({\n layoutType: LAYOUTS[layout],\n layoutNodeGroup: (node) => node.group ?? '',\n layoutGroupOrder: groups?.map((group) => group.id),\n // 分组框比节点宽出一圈:层与层之间留够,框不相互压住\n dagreLayoutSettings: {\n rankdir: direction,\n nodesep: groups?.length ? 48 : 36,\n ranksep: groups?.length ? 150 : 96,\n },\n layoutElkSettings: {\n 'elk.direction': direction === 'LR' ? 'RIGHT' : 'DOWN',\n 'elk.spacing.nodeNode': '36',\n 'elk.layered.spacing.nodeNodeBetweenLayers': '96',\n },\n layoutElkNodeGroups: groups?.length ? [(node) => node.group ?? ''] : undefined,\n forceLayoutSettings: { linkDistance: 90, charge: -600 },\n nodeSize: (node) => node.size ?? 28,\n nodeShape: (node) => SHAPES[node.shape ?? 'circle'],\n nodeFill: (node) => node.fill,\n nodeStrokeWidth: 2,\n nodeLabel: (node) => node.label,\n nodeSubLabel: (node) => node.sublabel ?? '',\n nodeLabelTrimLength: 16,\n // 不用图标字体:节点只是色块\n nodeIcon: () => '',\n linkWidth: (link) =>\n link.amount === undefined || maxAmount === 0 ? 1.5 : 1 + (5 * link.amount) / maxAmount,\n linkStroke: (link) => (link.color ? resolveColor(link.color, 0) : undefined),\n linkStyle: (link) => (link.dashed ? GraphLinkStyle.Dashed : GraphLinkStyle.Solid),\n linkArrow: (arrows ?? layered) ? GraphLinkArrowStyle.Single : undefined,\n linkLabel: (link) => (link.label ? { text: link.label } : undefined),\n linkCurvature: layered ? 0 : 0.2,\n panels: (framed ? (groups ?? []) : [])\n .filter((group) => resolved.some((node) => node.group === group.id))\n .map((group) => ({\n nodes: resolved.filter((node) => node.group === group.id).map((node) => node.id),\n label: group.label,\n padding: 16,\n borderColor: groupColors.get(group.id),\n })),\n selectedNodeId: selected ?? undefined,\n nodeSelectionHighlightMode: GraphNodeSelectionHighlightMode.GreyoutNonConnected,\n disableZoom: !zoom,\n disableDrag: !zoom,\n disableBrush: true,\n // 上方多留一些:分组框的组名写在框顶外面\n fitViewPadding: { top: 48, right: 32, bottom: 32, left: 32 },\n events: {\n [Graph.selectors.node]: {\n click: (node: Node) => {\n selected = node.id;\n onItemClick?.(nodes[node.index]!, node.index);\n },\n },\n [Graph.selectors.background]: {\n click: () => (selected = null),\n // 双击空白回到全图\n dblclick: () => graph.fitView(),\n },\n },\n });\n return {\n component: graph,\n data: {\n nodes: resolved.map((node) => ({ ...node })),\n links: shownLinks.map((link) => ({ ...link })),\n },\n triggers: {\n [Graph.selectors.node]: (node: Node) =>\n chart.tooltip(\n chartTooltip(node.label, [\n ...(node.sublabel\n ? [{ label: node.sublabel, color: 'transparent', value: '' }]\n : []),\n {\n label: lang.chartDegree(degree.get(node.id) ?? 0),\n color: node.fill,\n value: '',\n },\n ]),\n ),\n [Graph.selectors.link]: (link: LaidOutLink) =>\n chart.tooltip(\n chartTooltip(lang.chartFlowLabel(link.source.label, link.target.label), [\n ...(link.value === undefined\n ? []\n : [\n {\n label: lang.chartValue,\n color: link.source.fill,\n value: valueText(link.value),\n },\n ]),\n ...(link.label ? [{ label: link.label, color: 'transparent', value: '' }] : []),\n ]),\n ),\n },\n };\n },\n }));\n\n return () => (\n <ChartFrame\n {...rest}\n sx={[graphChartStyles.root, sx]}\n unit={unit}\n height={height}\n legend={[]}\n hiddenKeys={[]}\n onLegendToggle={() => {}}\n loading={loading}\n skeleton={<Skeleton sx={graphChartStyles.skeleton} />}\n isEmpty={nodes.length === 0}\n empty={empty}\n clickable={onItemClick != null}\n table={{\n columns: [lang.chartLink, unit ? `${lang.chartValue}(${unit})` : lang.chartValue],\n rows: shownLinks.map((link) => ({\n header: lang.chartFlowLabel(labelOf(link.source), labelOf(link.target)),\n cells: [\n [\n link.value === undefined ? '' : format.number(link.value, valueFormat),\n link.label ?? '',\n ]\n .filter(Boolean)\n .join(' · ') || lang.emptyValue,\n ],\n })),\n }}\n plotRef={(element) => (plot = element)}\n />\n );\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"GraphChart.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_computed","_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/charts/GraphChart.tsx"],"sourcesContent":["/**\n * 网络图:节点与连线,看谁和谁有关系、关系有多强(案例与触发事件的匹配、团队与供应商的协作、依赖关系)。\n *\n * <GraphChart aria-label=\"协作关系\" nodes={nodes} links={links} layout=\"dagre\" groups={teams} />\n *\n * 节点是 { id, label?, sublabel?, group?, color?, shape?, size? },连线是 { source, target, value?, label?, dashed? }。\n * 布局交给 Unovis 的 Graph:force(默认,力导向)、dagre(分层,direction 定方向)、circular、concentric、parallel\n * (按 group 分列)、elk(分层且支持分组框,较大,用到时才加载)。布局异步算好再画,第一帧是空的。\n * 写了 groups 时同组的节点框在一起(dagre、elk、parallel 布局;力导向、环形布局里组只决定颜色,框会互相盖住);\n * 节点的颜色默认按组取色板,没有组时都是 chart1。\n * 连线写了 value 时按大小加粗(1–6px),悬停看“起点 → 终点”与数值。点节点选中它(selected 双向绑定),\n * 与它不相连的节点、连线变淡;点空白处取消。能缩放、拖动画布(zoom={false} 关掉),双击回到全图。\n * 给读屏的数据表每条连线一行;单位、加载与空状态同其他图表(见 ChartFrame)。\n */\nimport {\n Graph,\n GraphLayoutType,\n GraphLinkArrowStyle,\n GraphLinkStyle,\n GraphNodeSelectionHighlightMode,\n GraphNodeShape,\n} from '@unovis/ts';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useLang } from '../config/context';\nimport { useFormat, type NumericFormat } from '../config/lang/format';\nimport { colors, fontSizes, opacities } from '../config/theme/tokens';\nimport { Skeleton } from '../feedback/Skeleton';\nimport { toNumber, type NumericValue } from '../utils/data/numeric';\nimport type { PartProps } from '../utils/props';\nimport { ChartFrame, chartTooltip, useChartValueText, type ChartFrameParts } from './frame';\nimport { resolveColor, type ChartColor } from './series';\nimport { useSingleChart, type SingleChart } from './single';\n\n/** 节点的形状 */\nexport interface GraphChartShapes {\n /** 圆(默认) */\n circle: unknown;\n /** 方块 */\n square: unknown;\n /** 六边形 */\n hexagon: unknown;\n /** 三角 */\n triangle: unknown;\n}\n\n/** 布局 */\nexport interface GraphChartLayouts {\n /** 力导向(默认):相连的靠近、不相连的推开,适合看关系疏密 */\n force: unknown;\n /** 分层:沿 direction 一层层排开,适合有先后、上下游的关系 */\n dagre: unknown;\n /** 排成一圈 */\n circular: unknown;\n /** 同心圆:连得多的在中间 */\n concentric: unknown;\n /** 按 group 分列,组内按连接排 */\n parallel: unknown;\n /** 分层,分组框更规整(elkjs,约 1.6 MB,用到时才加载) */\n elk: unknown;\n}\n\n/** 一个节点 */\nexport interface GraphChartNode {\n /** id:连线里用它指节点 */\n id: string;\n /** 名称,写在节点下面;不写时用 id */\n label?: string;\n /** 名称下面的小字 */\n sublabel?: string;\n /** 所在的组(groups 里的 id):同组的框在一起、颜色相同 */\n group?: string;\n /** 颜色;不写时按组取色板,没有组时是 chart1 */\n color?: ChartColor;\n /** 形状,默认 circle */\n shape?: keyof GraphChartShapes;\n /** 大小(px),默认 28 */\n size?: number;\n}\n\n/** 一条连线 */\nexport interface GraphChartLink {\n /** 起点节点的 id */\n source: string;\n /** 终点节点的 id */\n target: string;\n /** 强度:写了时按大小加粗;提示框、数据表里显示 */\n value?: NumericValue;\n /** 线上的短标签(几个字以内) */\n label?: string;\n /** 虚线:弱关系、待定的关系 */\n dashed?: boolean;\n /** 颜色;默认是边框色 */\n color?: ChartColor;\n}\n\n/** 一组节点 */\nexport interface GraphChartGroup {\n /** 组的 id:节点的 group 指它 */\n id: string;\n /** 组名:写在框上 */\n label: string;\n /** 颜色;不写时按组的顺序取色板 */\n color?: ChartColor;\n}\n\n/** 未声明的属性落到外层 div(role=\"figure\")上,aria-label 是图表的名称 */\nexport interface GraphChartProps extends PartProps<'div', 'role' | 'aria-busy'>, ChartFrameParts {\n /** 节点 */\n nodes: readonly GraphChartNode[];\n /** 连线 */\n links: readonly GraphChartLink[];\n /** 分组:同组的节点框在一起(dagre、elk、parallel 布局),颜色相同 */\n groups?: readonly GraphChartGroup[];\n /**\n * 布局\n * @default 'force'\n */\n layout?: keyof GraphChartLayouts;\n /**\n * 分层布局(dagre、elk)的方向:LR 从左到右,TB 从上到下\n * @default 'LR'\n */\n direction?: 'LR' | 'TB';\n /** 连线带箭头;默认分层布局(dagre、elk)带,其余不带 */\n arrows?: boolean;\n /** 连线数值的格式:提示框、数据表共用 */\n valueFormat?: NumericFormat;\n /** 连线数值的单位:显示在左上方,数值后面带上 */\n unit?: string;\n /**\n * 绘图区的高度;数字按 px\n * @default 360\n */\n height?: number | string;\n /**\n * 能缩放、拖动画布\n * @default true\n */\n zoom?: boolean;\n /**\n * 悬停时的提示框\n * @default true\n */\n tooltip?: boolean;\n /** 选中的节点 id:点节点时写回,父级写 _selected={x};点空白处变回 null */\n _selected?: string | null;\n /**\n * 加载中:绘图区显示骨架,带 aria-busy\n * @default false\n */\n loading?: boolean;\n /** 没有数据时显示的内容,默认是“暂无数据” */\n empty?: VNodeChild;\n /**\n * 点了一个节点(下钻):参数是这个节点与它的位置;写了它时节点的指针是手形。\n * 点图是鼠标的捷径:同样的去处在页面上还要有链接或按钮\n */\n onItemClick?: (node: GraphChartNode, index: number) => void;\n}\n\n/** GraphChart 的样式:root(--vis-graph-* 主题变量)、skeleton */\nexport const graphChartStyles = css.create({\n root: {\n '--vis-graph-node-stroke-color': colors.surface,\n '--vis-graph-node-label-text-color': colors.text,\n '--vis-graph-node-label-font-size': fontSizes.xs,\n '--vis-graph-node-label-background': colors.surface,\n '--vis-graph-node-sublabel-text-color': colors.textMuted,\n '--vis-graph-node-sublabel-font-size': fontSizes.xs,\n '--vis-graph-node-selection-color': colors.accent,\n '--vis-graph-node-greyout-color': colors.surfaceMuted,\n '--vis-graph-node-greyout-opacity': opacities.disabled,\n '--vis-graph-link-stroke-color': colors.borderStrong,\n '--vis-graph-link-greyout-opacity': '0.25',\n '--vis-graph-link-label-background': colors.fill,\n '--vis-graph-link-label-text-color-dark': colors.text,\n '--vis-graph-link-label-font-size': fontSizes.xs,\n '--vis-graph-panel-fill-color': colors.surfaceMuted,\n '--vis-graph-panel-border-color': colors.borderMuted,\n '--vis-graph-panel-label-color': colors.textMuted,\n '--vis-graph-panel-label-background': colors.surface,\n '--vis-graph-panel-label-font-size': fontSizes.xs,\n '--vis-graph-panel-label-font-weight': '500',\n },\n skeleton: { display: 'block', width: '100%', height: '100%' },\n});\n\nconst LAYOUTS: Record<keyof GraphChartLayouts, GraphLayoutType> = {\n force: GraphLayoutType.Force,\n dagre: GraphLayoutType.Dagre,\n circular: GraphLayoutType.Circular,\n concentric: GraphLayoutType.Concentric,\n parallel: GraphLayoutType.Parallel,\n elk: GraphLayoutType.Elk,\n};\n\nconst SHAPES: Record<keyof GraphChartShapes, GraphNodeShape> = {\n circle: GraphNodeShape.Circle,\n square: GraphNodeShape.Square,\n hexagon: GraphNodeShape.Hexagon,\n triangle: GraphNodeShape.Triangle,\n};\n\n/** 交给 Unovis 的节点:带上名称与颜色;Unovis 会往上写布局用的字段,每次都复制一份 */\ninterface Node extends GraphChartNode {\n label: string;\n fill: string;\n index: number;\n}\n/** 交给 Unovis 的连线:数值转成 number 算粗细 */\ninterface Link extends GraphChartLink {\n amount: number | undefined;\n}\n/** Unovis 布局后:连线的起点、终点换成了节点对象 */\ntype LaidOutLink = Omit<Link, 'source' | 'target'> & { source: Node; target: Node };\n\n/** 网络图 */\nexport const GraphChart = _component(\n ({\n nodes,\n links,\n groups,\n layout = 'force',\n direction = 'LR',\n arrows,\n valueFormat,\n unit,\n height = 360,\n zoom = true,\n tooltip = true,\n _selected: selected = _bindable<string | null>(null),\n loading = false,\n empty,\n onItemClick,\n sx,\n ...rest\n }: GraphChartProps) => {\n const lang = useLang();\n const format = useFormat();\n const valueText = useChartValueText(() => ({ valueFormat, unit }));\n\n const groupColors = _derived(\n new Map(\n (groups ?? []).map((group, position) => [group.id, resolveColor(group.color, position)]),\n ),\n );\n const resolved = _derived(\n nodes.map((node, index): Node => ({\n ...node,\n label: node.label ?? node.id,\n fill: node.color\n ? resolveColor(node.color, 0)\n : ((node.group && groupColors.get(node.group)) ?? resolveColor('chart1', 0)),\n index,\n })),\n );\n const byId = _derived(new Map(resolved.map((node) => [node.id, node])));\n const labelOf = (id: string) => byId.get(id)?.label ?? id;\n // 只留两端都在的连线;最大值用来把粗细缩放到 1–6px\n const shownLinks = _derived(\n links\n .filter((link) => byId.has(link.source) && byId.has(link.target))\n .map((link): Link => ({\n ...link,\n amount: link.value === undefined ? undefined : toNumber(link.value),\n })),\n );\n const maxAmount = _derived(Math.max(0, ...shownLinks.map((link) => link.amount ?? 0)));\n const degree = _derived.by(() => {\n const counts = new Map<string, number>();\n for (const link of shownLinks) {\n counts.set(link.source, (counts.get(link.source) ?? 0) + 1);\n counts.set(link.target, (counts.get(link.target) ?? 0) + 1);\n }\n return counts;\n });\n\n let plot = _state.raw<HTMLElement | null>(null);\n const chart: SingleChart = useSingleChart<{ nodes: Node[]; links?: Link[] }>(() => ({\n element: plot,\n ready: !loading && nodes.length > 0,\n tooltip,\n build: (instance) => {\n const graph = instance('graph', () => new Graph<Node, Link>({}));\n const layered = layout === 'dagre' || layout === 'elk';\n // 分组框只在按层、按列排的布局里画:其余布局不按组排,框会互相盖住\n const framed = layered || layout === 'parallel';\n graph.setConfig({\n layoutType: LAYOUTS[layout],\n layoutNodeGroup: (node) => node.group ?? '',\n layoutGroupOrder: groups?.map((group) => group.id),\n // 分组框比节点宽出一圈:层与层之间留够,框不相互压住\n dagreLayoutSettings: {\n rankdir: direction,\n nodesep: groups?.length ? 48 : 36,\n ranksep: groups?.length ? 150 : 96,\n },\n layoutElkSettings: {\n 'elk.direction': direction === 'LR' ? 'RIGHT' : 'DOWN',\n 'elk.spacing.nodeNode': '36',\n 'elk.layered.spacing.nodeNodeBetweenLayers': '96',\n },\n layoutElkNodeGroups: groups?.length ? [(node) => node.group ?? ''] : undefined,\n forceLayoutSettings: { linkDistance: 90, charge: -600 },\n nodeSize: (node) => node.size ?? 28,\n nodeShape: (node) => SHAPES[node.shape ?? 'circle'],\n nodeFill: (node) => node.fill,\n nodeStrokeWidth: 2,\n nodeLabel: (node) => node.label,\n nodeSubLabel: (node) => node.sublabel ?? '',\n nodeLabelTrimLength: 16,\n // 不用图标字体:节点只是色块\n nodeIcon: () => '',\n linkWidth: (link) =>\n link.amount === undefined || maxAmount === 0 ? 1.5 : 1 + (5 * link.amount) / maxAmount,\n linkStroke: (link) => (link.color ? resolveColor(link.color, 0) : undefined),\n linkStyle: (link) => (link.dashed ? GraphLinkStyle.Dashed : GraphLinkStyle.Solid),\n linkArrow: (arrows ?? layered) ? GraphLinkArrowStyle.Single : undefined,\n linkLabel: (link) => (link.label ? { text: link.label } : undefined),\n linkCurvature: layered ? 0 : 0.2,\n panels: (framed ? (groups ?? []) : [])\n .filter((group) => resolved.some((node) => node.group === group.id))\n .map((group) => ({\n nodes: resolved.filter((node) => node.group === group.id).map((node) => node.id),\n label: group.label,\n padding: 16,\n borderColor: groupColors.get(group.id),\n })),\n selectedNodeId: selected ?? undefined,\n nodeSelectionHighlightMode: GraphNodeSelectionHighlightMode.GreyoutNonConnected,\n disableZoom: !zoom,\n disableDrag: !zoom,\n disableBrush: true,\n // 上方多留一些:分组框的组名写在框顶外面\n fitViewPadding: { top: 48, right: 32, bottom: 32, left: 32 },\n events: {\n [Graph.selectors.node]: {\n click: (node: Node) => {\n selected = node.id;\n onItemClick?.(nodes[node.index]!, node.index);\n },\n },\n [Graph.selectors.background]: {\n click: () => (selected = null),\n // 双击空白回到全图\n dblclick: () => graph.fitView(),\n },\n },\n });\n return {\n component: graph,\n data: {\n nodes: resolved.map((node) => ({ ...node })),\n links: shownLinks.map((link) => ({ ...link })),\n },\n triggers: {\n [Graph.selectors.node]: (node: Node) =>\n chart.tooltip(\n chartTooltip(node.label, [\n ...(node.sublabel\n ? [{ label: node.sublabel, color: 'transparent', value: '' }]\n : []),\n {\n label: lang.chartDegree(degree.get(node.id) ?? 0),\n color: node.fill,\n value: '',\n },\n ]),\n ),\n [Graph.selectors.link]: (link: LaidOutLink) =>\n chart.tooltip(\n chartTooltip(lang.chartFlowLabel(link.source.label, link.target.label), [\n ...(link.value === undefined\n ? []\n : [\n {\n label: lang.chartValue,\n color: link.source.fill,\n value: valueText(link.value),\n },\n ]),\n ...(link.label ? [{ label: link.label, color: 'transparent', value: '' }] : []),\n ]),\n ),\n },\n };\n },\n }));\n\n return () => (\n <ChartFrame\n {...rest}\n sx={[graphChartStyles.root, sx]}\n unit={unit}\n height={height}\n legend={[]}\n hiddenKeys={[]}\n onLegendToggle={() => {}}\n loading={loading}\n skeleton={<Skeleton sx={graphChartStyles.skeleton} />}\n isEmpty={nodes.length === 0}\n empty={empty}\n clickable={onItemClick != null}\n table={{\n columns: [lang.chartLink, unit ? `${lang.chartValue}(${unit})` : lang.chartValue],\n rows: shownLinks.map((link) => ({\n header: lang.chartFlowLabel(labelOf(link.source), labelOf(link.target)),\n cells: [\n [\n link.value === undefined ? '' : format.number(link.value, valueFormat),\n link.label ?? '',\n ]\n .filter(Boolean)\n .join(' · ') || lang.emptyValue,\n ],\n })),\n }}\n plotRef={(element) => (plot = element)}\n />\n );\n },\n);\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { colors } from "../config/theme/tokens.js";
2
2
  import { XYChart } from "./XYChart.js";
3
- import { computed, createVNode, mergeProps } from "vue";
4
- import { _component, bindable, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
3
+ import { computed, createVNode } from "vue";
4
+ import { _component, bindable, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
5
5
  import { CurveType, Line, Scatter } from "@unovis/ts";
6
6
  //#region src/charts/LineChart.tsx
7
7
  /**
@@ -73,7 +73,7 @@ var LineChart = /*#__PURE__*/ _component((_props, _ctx) => {
73
73
  })];
74
74
  }
75
75
  }));
76
- return () => createVNode(XYChart, mergeProps(rest, {
76
+ return () => createVNode(XYChart, mergeJsxProps(rest, {
77
77
  "_hiddenSeries": hiddenSeries.value,
78
78
  "onUpdate:_hiddenSeries": _cache[0] || (_cache[0] = ($event) => hiddenSeries.value = $event),
79
79
  "kind": kind.value
@@ -1 +1 @@
1
- {"version":3,"file":"LineChart.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_computed","_createVNode","_mergeProps"],"sources":["../../src/charts/LineChart.tsx"],"sourcesContent":["/**\n * 折线图:每个系列一条线,类目(通常是时间)沿横轴排开;悬停时十字线在各条线上标出当前点,提示框列出各系列的值。\n *\n * <LineChart\n * aria-label=\"月度销售趋势\"\n * data={months}\n * index=\"month\"\n * series={[{ key: 'planned', label: '预期销售' }, { key: 'actual', label: '实际销售' }]}\n * dots=\"hollow\"\n * />\n *\n * 空值(null、undefined)处断开;颜色、坐标轴、提示框、图例、读屏的数据表见 XYChart。\n */\nimport { CurveType, Line, Scatter } from '@unovis/ts';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { colors } from '../config/theme/tokens';\nimport { XYChart, type XYChartKind, type XYChartProps } from './XYChart';\n\n/** 线的形状 */\nexport interface LineCurves {\n /** 折线:相邻的点直线相连(默认) */\n linear: unknown;\n /** 平滑曲线:不会越过数据点(单调插值),趋势更柔和 */\n monotone: unknown;\n /** 阶梯:值保持到下一个点才跳变,适合离散的状态、价格档位 */\n step: unknown;\n}\n\n/** 数据点的样式 */\nexport interface LineDots {\n /** 不画数据点(默认),只在悬停时由十字线标出 */\n none: unknown;\n /** 实心圆点 */\n filled: unknown;\n /** 空心圆点:描边是系列颜色,中间是背景色 */\n hollow: unknown;\n}\n\n/** 未声明的属性落到外层 div(role=\"figure\")上;aria-label 是图表的名称 */\nexport interface LineChartProps<T extends object> extends XYChartProps<T> {\n /** 线的形状,默认 linear */\n curve?: keyof LineCurves;\n /** 数据点,默认 none */\n dots?: keyof LineDots;\n /** 线宽(px),默认 2 */\n lineWidth?: number;\n}\n\n/** 曲线的形状 → Unovis 的 CurveType(折线图、面积图共用) */\nexport const CURVES = {\n linear: CurveType.Linear,\n monotone: CurveType.MonotoneX,\n step: CurveType.StepAfter,\n} satisfies Record<keyof LineCurves, CurveType>;\n\n/** 数据点的直径(px) */\nconst DOT_SIZE = 8;\n\n/** 折线图:直线、平滑或阶梯,可带数据点 */\nexport const LineChart = _component(\n <T extends object>({\n curve = 'linear',\n dots = 'none',\n lineWidth = 2,\n _hiddenSeries: hiddenSeries = _bindable<string[]>([]),\n ...rest\n }: LineChartProps<T>) => {\n const kind = _derived<XYChartKind<T>>({\n crosshairDots: true,\n // 两端的点不贴着绘图区边缘,圆点与十字线的圆点能完整显示\n padding: { left: 12, right: 12, top: 8 },\n components: ({ series, x, y, instance }) => {\n const line = instance('line', () => new Line<T>({ x, y: [] }));\n line.setConfig({\n x,\n y: series.map(y),\n color: (_rows: T[], position: number) => series[position]?.color,\n curveType: CURVES[curve],\n lineWidth,\n });\n if (dots === 'none') return [line];\n const points = series.map((item) => {\n const scatter = instance(`dots:${item.key}`, () => new Scatter<T>({ x, y: () => 0 }));\n scatter.setConfig({\n x,\n y: y(item),\n size: DOT_SIZE,\n color: dots === 'hollow' ? colors.surface : item.color,\n strokeColor: item.color,\n strokeWidth: dots === 'hollow' ? 2 : 0,\n });\n return scatter;\n });\n return [line, ...points];\n },\n });\n return () => <XYChart {...rest} _hiddenSeries={hiddenSeries} kind={kind} />;\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAiDA,IAAa,SAAS;CACpB,QAAQ,UAAU;CAClB,UAAU,UAAU;CACpB,MAAM,UAAU;AAClB;;AAGA,IAAM,WAAW;;AAGjB,IAAa,YAAY,0BACvB,QAAA,SAMyB;CAAA,MAAA,SAAA,CAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,SALf,QAAQ;CAAA,MAAA,OAAAA,aAAA,QAAA,QACT,MAAM;CAAA,MAAA,YAAAA,aAAA,QAAA,aACD,CAAC;CAAA,MAAA,eAAAC,SAAA,QAAA,uBACqC,CAAA,GAAE,KAAA,IAAA;CAAA,MACjD,OAAIC,UAAA,QAAA,MAAA,IAAA;CAEP,MAAM,OAAIC,gBAA4B;EACpC,eAAe;EAEf,SAAS;GAAE,MAAM;GAAI,OAAO;GAAI,KAAK;EAAE;EACvC,aAAa,EAAE,QAAQ,GAAG,GAAG,eAAe;GAC1C,MAAM,OAAO,SAAS,cAAc,IAAI,KAAQ;IAAE;IAAG,GAAG,CAAA;GAAG,CAAC,CAAC;GAC7D,KAAK,UAAU;IACb;IACA,GAAG,OAAO,IAAI,CAAC;IACf,QAAQ,OAAY,aAAqB,OAAO,SAAS,EAAE;IAC3D,WAAW,OAAM,MAAA;IACjB,WAAS,UAAA;GACX,CAAC;GACD,IAAI,KAAA,UAAS,QAAQ,OAAO,CAAC,IAAI;GAajC,OAAO,CAAC,MAAM,GAZC,OAAO,KAAK,SAAS;IAClC,MAAM,UAAU,SAAS,QAAQ,KAAK,aAAa,IAAI,QAAW;KAAE;KAAG,SAAS;IAAE,CAAC,CAAC;IACpF,QAAQ,UAAU;KAChB;KACA,GAAG,EAAE,IAAI;KACT,MAAM;KACN,OAAO,KAAA,UAAS,WAAW,OAAO,UAAU,KAAK;KACjD,aAAa,KAAK;KAClB,aAAa,KAAA,UAAS,WAAW,IAAI;IACvC,CAAC;IACD,OAAO;GACT,CACiB,CAAM;EACzB;CACF,EAAC;CACD,aAAOC,YAAA,SAAAC,WAAmB,MAAI;EAAA,iBAAA,aAAA;EAAA,0BAAA,OAAA,OAAA,OAAA,MAAA,WAAA,aAAA,QAAA;EAAA,QAAA,KAAA;CAAA,CAAA,GAAA,IAAA;AAChC,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
1
+ {"version":3,"file":"LineChart.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_computed","_createVNode","_mergeProps"],"sources":["../../src/charts/LineChart.tsx"],"sourcesContent":["/**\n * 折线图:每个系列一条线,类目(通常是时间)沿横轴排开;悬停时十字线在各条线上标出当前点,提示框列出各系列的值。\n *\n * <LineChart\n * aria-label=\"月度销售趋势\"\n * data={months}\n * index=\"month\"\n * series={[{ key: 'planned', label: '预期销售' }, { key: 'actual', label: '实际销售' }]}\n * dots=\"hollow\"\n * />\n *\n * 空值(null、undefined)处断开;颜色、坐标轴、提示框、图例、读屏的数据表见 XYChart。\n */\nimport { CurveType, Line, Scatter } from '@unovis/ts';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { colors } from '../config/theme/tokens';\nimport { XYChart, type XYChartKind, type XYChartProps } from './XYChart';\n\n/** 线的形状 */\nexport interface LineCurves {\n /** 折线:相邻的点直线相连(默认) */\n linear: unknown;\n /** 平滑曲线:不会越过数据点(单调插值),趋势更柔和 */\n monotone: unknown;\n /** 阶梯:值保持到下一个点才跳变,适合离散的状态、价格档位 */\n step: unknown;\n}\n\n/** 数据点的样式 */\nexport interface LineDots {\n /** 不画数据点(默认),只在悬停时由十字线标出 */\n none: unknown;\n /** 实心圆点 */\n filled: unknown;\n /** 空心圆点:描边是系列颜色,中间是背景色 */\n hollow: unknown;\n}\n\n/** 未声明的属性落到外层 div(role=\"figure\")上;aria-label 是图表的名称 */\nexport interface LineChartProps<T extends object> extends XYChartProps<T> {\n /** 线的形状,默认 linear */\n curve?: keyof LineCurves;\n /** 数据点,默认 none */\n dots?: keyof LineDots;\n /** 线宽(px),默认 2 */\n lineWidth?: number;\n}\n\n/** 曲线的形状 → Unovis 的 CurveType(折线图、面积图共用) */\nexport const CURVES = {\n linear: CurveType.Linear,\n monotone: CurveType.MonotoneX,\n step: CurveType.StepAfter,\n} satisfies Record<keyof LineCurves, CurveType>;\n\n/** 数据点的直径(px) */\nconst DOT_SIZE = 8;\n\n/** 折线图:直线、平滑或阶梯,可带数据点 */\nexport const LineChart = _component(\n <T extends object>({\n curve = 'linear',\n dots = 'none',\n lineWidth = 2,\n _hiddenSeries: hiddenSeries = _bindable<string[]>([]),\n ...rest\n }: LineChartProps<T>) => {\n const kind = _derived<XYChartKind<T>>({\n crosshairDots: true,\n // 两端的点不贴着绘图区边缘,圆点与十字线的圆点能完整显示\n padding: { left: 12, right: 12, top: 8 },\n components: ({ series, x, y, instance }) => {\n const line = instance('line', () => new Line<T>({ x, y: [] }));\n line.setConfig({\n x,\n y: series.map(y),\n color: (_rows: T[], position: number) => series[position]?.color,\n curveType: CURVES[curve],\n lineWidth,\n });\n if (dots === 'none') return [line];\n const points = series.map((item) => {\n const scatter = instance(`dots:${item.key}`, () => new Scatter<T>({ x, y: () => 0 }));\n scatter.setConfig({\n x,\n y: y(item),\n size: DOT_SIZE,\n color: dots === 'hollow' ? colors.surface : item.color,\n strokeColor: item.color,\n strokeWidth: dots === 'hollow' ? 2 : 0,\n });\n return scatter;\n });\n return [line, ...points];\n },\n });\n return () => <XYChart {...rest} _hiddenSeries={hiddenSeries} kind={kind} />;\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAiDA,IAAa,SAAS;CACpB,QAAQ,UAAU;CAClB,UAAU,UAAU;CACpB,MAAM,UAAU;AAClB;;AAGA,IAAM,WAAW;;AAGjB,IAAa,YAAY,0BACvB,QAAA,SAMyB;CAAA,MAAA,SAAA,CAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,SALf,QAAQ;CAAA,MAAA,OAAAA,aAAA,QAAA,QACT,MAAM;CAAA,MAAA,YAAAA,aAAA,QAAA,aACD,CAAC;CAAA,MAAA,eAAAC,SAAA,QAAA,uBACqC,CAAA,GAAE,KAAA,IAAA;CAAA,MACjD,OAAIC,UAAA,QAAA,MAAA,IAAA;CAEP,MAAM,OAAIC,gBAA4B;EACpC,eAAe;EAEf,SAAS;GAAE,MAAM;GAAI,OAAO;GAAI,KAAK;EAAE;EACvC,aAAa,EAAE,QAAQ,GAAG,GAAG,eAAe;GAC1C,MAAM,OAAO,SAAS,cAAc,IAAI,KAAQ;IAAE;IAAG,GAAG,CAAA;GAAG,CAAC,CAAC;GAC7D,KAAK,UAAU;IACb;IACA,GAAG,OAAO,IAAI,CAAC;IACf,QAAQ,OAAY,aAAqB,OAAO,SAAS,EAAE;IAC3D,WAAW,OAAM,MAAA;IACjB,WAAS,UAAA;GACX,CAAC;GACD,IAAI,KAAA,UAAS,QAAQ,OAAO,CAAC,IAAI;GAajC,OAAO,CAAC,MAAM,GAZC,OAAO,KAAK,SAAS;IAClC,MAAM,UAAU,SAAS,QAAQ,KAAK,aAAa,IAAI,QAAW;KAAE;KAAG,SAAS;IAAE,CAAC,CAAC;IACpF,QAAQ,UAAU;KAChB;KACA,GAAG,EAAE,IAAI;KACT,MAAM;KACN,OAAO,KAAA,UAAS,WAAW,OAAO,UAAU,KAAK;KACjD,aAAa,KAAK;KAClB,aAAa,KAAA,UAAS,WAAW,IAAI;IACvC,CAAC;IACD,OAAO;GACT,CACiB,CAAM;EACzB;CACF,EAAC;CACD,aAAOC,YAAA,SAAAC,cAAmB,MAAI;EAAA,iBAAA,aAAA;EAAA,0BAAA,OAAA,OAAA,OAAA,MAAA,WAAA,aAAA,QAAA;EAAA,QAAA,KAAA;CAAA,CAAA,GAAA,IAAA;AAChC,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
@@ -9,8 +9,8 @@ import { ChartFrame, chartTooltip } from "./frame.js";
9
9
  import { resolveColor } from "./series.js";
10
10
  import { useSingleChart } from "./single.js";
11
11
  import { placeLabels, rectsOverlap } from "./label-layout.js";
12
- import { computed, createTextVNode, createVNode, mergeProps, ref, shallowRef } from "vue";
13
- import { _component, effect, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
12
+ import { computed, createTextVNode, createVNode, ref, shallowRef } from "vue";
13
+ import { _component, effect, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
14
14
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
15
15
  import { Maximize, Minus, Plus } from "@lucide/icons";
16
16
  import { MapProjection, TopoJSONMap } from "@unovis/ts";
@@ -499,10 +499,10 @@ var MapChart = /*#__PURE__*/ _component((_props, _ctx) => {
499
499
  const [low, high] = extent.value;
500
500
  if (bins.value) {
501
501
  const step = (high - low) / bins.value;
502
- return createVNode("div", mergeProps(css.attrs(mapChartStyles.legend), { "aria-hidden": "true" }), [Array.from({ length: bins.value }, (_, index) => {
502
+ return createVNode("div", mergeJsxProps(css.attrs(mapChartStyles.legend), { "aria-hidden": "true" }), [Array.from({ length: bins.value }, (_, index) => {
503
503
  const from = low + step * index;
504
504
  const to = index === bins.value - 1 ? high : from + step;
505
- return createVNode("span", mergeProps({ "key": index }, css.attrs(mapChartStyles.bin)), [
505
+ return createVNode("span", mergeJsxProps({ "key": index }, css.attrs(mapChartStyles.bin)), [
506
506
  createVNode("span", css.attrs(mapChartStyles.swatch, mapChartStyles.swatchColor(colorOf((from + to) / 2))), null),
507
507
  numberText(from),
508
508
  createTextVNode(" – "),
@@ -515,7 +515,7 @@ var MapChart = /*#__PURE__*/ _component((_props, _ctx) => {
515
515
  colors.fill,
516
516
  colorOf(high)
517
517
  ] : [colorOf(low), colorOf(high)];
518
- return createVNode("div", mergeProps(css.attrs(mapChartStyles.legend), { "aria-hidden": "true" }), [
518
+ return createVNode("div", mergeJsxProps(css.attrs(mapChartStyles.legend), { "aria-hidden": "true" }), [
519
519
  createVNode("span", null, [numberText(low)]),
520
520
  createVNode("span", css.attrs(mapChartStyles.ramp, mapChartStyles.rampColors(`linear-gradient(to right, ${stops.join(", ")})`)), null),
521
521
  createVNode("span", null, [numberText(high)])
@@ -532,7 +532,7 @@ var MapChart = /*#__PURE__*/ _component((_props, _ctx) => {
532
532
  }, { capture: true });
533
533
  effect(() => () => clearTimeout(hintTimer));
534
534
  /** 缩放按钮:放大、缩小、复位;前面是滚轮的提示 */
535
- const zoomButtons = () => createVNode("span", css.attrs(mapChartStyles.zoom), [wheelHint.value && createVNode("span", mergeProps(css.attrs(mapChartStyles.wheelHint), { "role": "status" }), [lang.chartZoomWheelHint]), [
535
+ const zoomButtons = () => createVNode("span", css.attrs(mapChartStyles.zoom), [wheelHint.value && createVNode("span", mergeJsxProps(css.attrs(mapChartStyles.wheelHint), { "role": "status" }), [lang.chartZoomWheelHint]), [
536
536
  [
537
537
  Plus,
538
538
  lang.chartZoomIn,
@@ -557,7 +557,7 @@ var MapChart = /*#__PURE__*/ _component((_props, _ctx) => {
557
557
  "aria-label": label,
558
558
  "onClick": action
559
559
  }, null))]);
560
- return () => createVNode(ChartFrame, mergeProps(rest, {
560
+ return () => createVNode(ChartFrame, mergeJsxProps(rest, {
561
561
  "sx": [mapChartStyles.root, sx.value],
562
562
  "unit": unit.value,
563
563
  "height": height.value,
@@ -1 +1 @@
1
- {"version":3,"file":"MapChart.js","names":["_vtp_readonlyProp","_vtp_restProps","_vue_computed","_vue_shallowRef","_createVNode","_mergeProps","_createTextVNode","_vue_ref"],"sources":["../../src/charts/MapChart.tsx"],"sourcesContent":["/**\n * 地图:按区域着色(分省的销售额、各国的采购额),标出地点(工厂、供应商)与它们之间的流向。\n * 地理数据是 TopoJSON:Unovis 自带中国省份、世界、美国等(`@unovis/ts/maps`),也可以用自己的。\n *\n * import { ChinaTopoJSON } from '@unovis/ts/maps';\n * <MapChart\n * aria-label=\"各省销售额\"\n * topology={ChinaTopoJSON}\n * feature=\"provinces\"\n * areas={[{ id: 'CN-JS', label: '江苏', value: 623 }, …]} // id 是地图要素的 id\n * points={[{ id: 'sh', label: '上海组装', longitude: 121.47, latitude: 31.23, value: 860 }]}\n * links={[{ from: 'xa', to: 'sh', value: 120 }]}\n * bins={5}\n * areaLabels\n * />\n *\n * 投影:默认按地理数据的范围选——一个国家、一个地区用以它为中心的等积圆锥投影(中国地图常用的 Albers,正着、不歪),\n * 跨了大半个地球时用 Natural Earth;也可以指定 mercator、equalEarth、orthographic(地球仪)或自己的 d3 投影。\n *\n * 着色:sequential(默认)按数值深浅;diverging 以 midpoint 为界两头两种颜色(同比的涨跌);\n * bins 分成几档(分级着色,图例是几个色块),不写时连续着色(图例是色带);区域写了 color 时按它(分类着色)。\n * 没有数据的区域是底色。地点:value 决定大小(面积按比例),color、shape 决定颜色与形状;名字自动避让\n * (换方位、挤时往外退并画引线,数值大的先放,放不下的悬停看;压住名字、地点的区域名藏起来);\n * links 是地点之间的流向,粗细按 value,flow 时有流动的粒子。\n * zoomable 时可以拖动、按住 Ctrl 滚轮缩放,右上角有放大、缩小、复位的按钮。悬停看名称与数值;读屏的数据表列出各区域、地点与流向。\n */\nimport {\n MapProjection,\n TopoJSONMap,\n type MapGraphData,\n type TopoJSONMapConfigInterface,\n} from '@unovis/ts';\nimport { Maximize, Minus, Plus } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { presimplify, simplify } from 'topojson-simplify';\nimport type { VNodeChild } from 'vue';\nimport { IconButton } from '../base/IconButton';\nimport { useLang } from '../config/context';\nimport { useFormat, type NumericFormat } from '../config/lang/format';\nimport { colors } from '../config/theme/tokens';\nimport { Skeleton } from '../feedback/Skeleton';\nimport { toNumber, type NumericValue } from '../utils/data/numeric';\nimport { useEventListener } from '../utils/dom/event-listener';\nimport type { PartProps } from '../utils/props';\nimport { chartTooltip, ChartFrame, type ChartFrameParts } from './frame';\nimport { placeLabels, rectsOverlap, type LabelRect } from './label-layout';\nimport { resolveColor, type ChartColor } from './series';\nimport { useSingleChart, type SingleChart } from './single';\n\n/** 一个区域的数据 */\nexport interface MapArea {\n /** 地图要素的 id(Unovis 的中国省份是 'CN-JS' 这样的写法) */\n id: string;\n /** 显示的名称:提示框、区域名、数据表 */\n label: string;\n /** 数值:决定颜色 */\n value?: NumericValue;\n /** 指定颜色:不按数值着色(分类着色,如所属大区) */\n color?: ChartColor;\n}\n\n/** 一个地点 */\nexport interface MapPoint {\n /** 标识:流向的 from、to 指向它 */\n id: string;\n /** 名称:写在点下方 */\n label: string;\n /** 经度 */\n longitude: number;\n /** 纬度 */\n latitude: number;\n /** 数值:决定点的大小(面积按比例),也显示在提示框 */\n value?: NumericValue;\n /** 颜色,默认 danger */\n color?: ChartColor;\n /** 形状,默认 circle */\n shape?: 'circle' | 'square' | 'triangle';\n}\n\n/** 两个地点之间的流向 */\nexport interface MapLink {\n /** 起点(地点的 id) */\n from: string;\n /** 终点(地点的 id) */\n to: string;\n /** 数值:决定线的粗细,也显示在数据表 */\n value?: NumericValue;\n /** 颜色,默认次要色 */\n color?: ChartColor;\n}\n\n/** 投影的预设 */\nexport interface MapProjections {\n /** 等积圆锥(Albers):以数据为中心,一个国家、一个地区用它(中国地图常用),正着、面积不失真 */\n conic: unknown;\n /** 墨卡托:网页地图常见,高纬度会放大 */\n mercator: unknown;\n /** Natural Earth:世界地图,形状与面积都比较自然 */\n naturalEarth: unknown;\n /** Equal Earth:世界地图,面积准确 */\n equalEarth: unknown;\n /** 正射(地球仪):以数据为中心看半个地球 */\n orthographic: unknown;\n}\n\n/** d3 的投影(TopoJSONMap 的 projection) */\nexport type MapGeoProjection = NonNullable<TopoJSONMapConfigInterface<MapArea>['projection']>;\n\n/** 未声明的属性落到外层 div(role=\"figure\")上;aria-label 是图表的名称 */\nexport interface MapChartProps extends PartProps<'div', 'role' | 'aria-busy'>, ChartFrameParts {\n /** 地理数据(TopoJSON),如 `@unovis/ts/maps` 的 ChinaTopoJSON、WorldMapTopoJSON */\n topology: NonNullable<TopoJSONMapConfigInterface<MapArea>['topojson']>;\n /** 画哪一组要素(TopoJSON 的 objects 里的名字),如中国省份是 'provinces'、世界是 'countries' */\n feature: string;\n /** 投影:预设的名字,或 d3 的投影;不写时按数据的范围选 conic 或 naturalEarth */\n projection?: keyof MapProjections | MapGeoProjection;\n /** 投影的中心 [经度, 纬度]:中央经线(世界地图写 [150, 0] 以太平洋为中心),orthographic 还用纬度;不写时取地理数据范围的中心 */\n center?: readonly [number, number];\n /** 各区域的数值 */\n areas?: readonly MapArea[];\n /** 地点 */\n points?: readonly MapPoint[];\n /** 地点之间的流向 */\n links?: readonly MapLink[];\n /** 着色方式:sequential 按数值深浅(默认),diverging 以 midpoint 为界两头两种颜色 */\n scheme?: 'sequential' | 'diverging';\n /** sequential 的基色,默认 accent */\n color?: ChartColor;\n /** diverging 的两头 [低, 高],默认 ['danger', 'success'] */\n divergingColors?: readonly [ChartColor, ChartColor];\n /** diverging 的分界,默认 0 */\n midpoint?: number;\n /** 分成几档(分级着色);不写时连续着色 */\n bins?: number;\n /** 在区域上写名字(区域够大时) */\n areaLabels?: boolean;\n /** 流向上有流动的粒子 */\n flow?: boolean;\n /** 数值的格式 */\n valueFormat?: NumericFormat;\n /** 单位:显示在左上方,提示框与数据表的数值后面带上 */\n unit?: string;\n /**\n * 绘图区的高度;数字按 px\n * @default 400\n */\n height?: number | string;\n /** 可以拖动、滚轮缩放,右上角有放大、缩小、复位的按钮;默认关(不抢页面的滚动) */\n zoomable?: boolean;\n /** 加载中:绘图区显示骨架 */\n loading?: boolean;\n /** 没有数据时显示的内容 */\n empty?: VNodeChild;\n /** 悬停时的提示框,默认 true */\n tooltip?: boolean;\n /** 点了一个有数据的区域 */\n onAreaClick?: (area: MapArea) => void;\n /** 点了一个地点 */\n onPointClick?: (point: MapPoint) => void;\n}\n\n/** MapChart 的样式 */\nexport const mapChartStyles = css.create({\n // 地图跟随主题:底色、边界是表面色,文字是正文色\n root: {\n '--vis-map-feature-color': colors.fill,\n '--vis-map-boundary-color': colors.surface,\n '--vis-map-point-label-text-color-dark': colors.text,\n '--vis-map-point-label-text-color-light': colors.text,\n '--vis-map-area-label-text-color': colors.text,\n '--vis-map-area-label-font-size': '10px',\n '--vis-map-area-label-font-weight': '400',\n '--vis-map-point-default-stroke-color': colors.surface,\n '--vis-map-point-default-stroke-width': '1.5px',\n },\n skeleton: { display: 'block', width: '100%', height: '100%' },\n // 地点的标签:描一圈表面色的边,压在区域、连线上也看得清;字号、描边宽度随缩放在行内设置\n pointLabels: {\n fontWeight: 600,\n fill: colors.text,\n stroke: colors.surface,\n paintOrder: 'stroke',\n strokeLinejoin: 'round',\n pointerEvents: 'none',\n },\n leader: { stroke: colors.textMuted },\n // 缩放按钮:在标题行的结束边(导出菜单前面)\n zoom: { display: 'inline-flex', alignItems: 'center', gap: '2px', marginInlineStart: 'auto' },\n wheelHint: { marginInlineEnd: '_sm', color: '_textMuted', fontSize: '_xs' },\n // 图例:连续是色带,分档是一排色块\n legend: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n columnGap: '_md',\n rowGap: '_xs',\n fontSize: '_xs',\n color: '_textMuted',\n paddingInline: '_sm',\n },\n ramp: { flexGrow: 1, maxWidth: '16rem', height: '0.5rem', borderRadius: '_full' },\n rampColors: (gradient: string) => ({ backgroundImage: gradient }),\n bin: { display: 'inline-flex', alignItems: 'center', gap: '0.375em', whiteSpace: 'nowrap' },\n swatch: { width: '0.875rem', height: '0.625rem', borderRadius: '2px' },\n swatchColor: (color: string) => ({ backgroundColor: color }),\n});\n\n/** 地点的标签四周留的空(屏幕像素) */\nconst labelPadding = 3;\n\n/** 新建一个 SVG 元素 */\nconst svgElement = <K extends keyof SVGElementTagNameMap>(name: K) =>\n document.createElementNS('http://www.w3.org/2000/svg', name);\n\n/** 混色:基色占 percent,其余透明(落在底色上) */\nconst tint = (color: string, percent: number) =>\n `color-mix(in srgb, ${color} ${Math.round(percent)}%, transparent)`;\n\ntype MapTopology = MapChartProps['topology'];\n\n/** 算好了各点权重的地理数据:同一份 TopoJSON 只算一次 */\nconst presimplified = new WeakMap<MapTopology, MapTopology>();\n/**\n * 简化过的地理数据放进这个类的实例:Unovis 的 setConfig 深拷贝配置,但跳过类的实例,\n * 每次更新就不必把整份 TopoJSON 再拷一遍\n */\nclass SharedTopology {}\n\n/** 简化过的地理数据:TopoJSON → 档位 → 结果 */\nconst simplified = new WeakMap<MapTopology, Map<number, MapTopology>>();\n\n/**\n * 简化地理数据:去掉与前后两点围成的三角形面积不到 minArea(坐标单位的平方,经纬度是平方度)的点\n * (Visvalingam,topojson-simplify)。相邻区域共用的边界一起简化,不会出现缝隙;各段弧的两端总保留。\n * minArea 按 2 的整数次幂分档缓存:绘图区大小变一点不重算。\n */\nexport function simplifyTopology(topology: MapTopology, minArea: number): MapTopology {\n if (!(minArea > 0) || !Number.isFinite(minArea)) return topology;\n const level = 2 ** Math.floor(Math.log2(minArea));\n let byLevel = simplified.get(topology);\n if (!byLevel) simplified.set(topology, (byLevel = new Map()));\n let result = byLevel.get(level);\n if (!result) {\n // topojson-simplify 的类型里要素属性不能是 null(GeoJSON 允许):边界上转一下\n type Input = Parameters<typeof presimplify>[0];\n let weighted = presimplified.get(topology);\n if (!weighted)\n presimplified.set(topology, (weighted = presimplify(topology as Input) as MapTopology));\n result = Object.assign(new SharedTopology(), simplify(weighted as Input, level)) as MapTopology;\n byLevel.set(level, result);\n }\n return result;\n}\n\n/** TopoJSON 的经纬度范围 [西, 南, 东, 北]:有 bbox 用它,否则解出各段弧的坐标(量化的弧是逐点的差值) */\nexport function topologyBounds(\n topology: MapChartProps['topology'],\n): [number, number, number, number] {\n if (topology.bbox) {\n const [west, south, east, north] = topology.bbox;\n return [west, south, east, north];\n }\n const quantized = topology.transform;\n const [scaleX, scaleY] = quantized?.scale ?? [1, 1];\n const [translateX, translateY] = quantized?.translate ?? [0, 0];\n let [west, south, east, north] = [Infinity, Infinity, -Infinity, -Infinity];\n for (const arc of topology.arcs) {\n let x = 0;\n let y = 0;\n for (const position of arc) {\n x = quantized ? x + position[0]! : position[0]!;\n y = quantized ? y + position[1]! : position[1]!;\n const longitude = x * scaleX + translateX;\n const latitude = y * scaleY + translateY;\n west = Math.min(west, longitude);\n east = Math.max(east, longitude);\n south = Math.min(south, latitude);\n north = Math.max(north, latitude);\n }\n }\n return [west, south, east, north];\n}\n\n/** 地图 */\nexport const MapChart = _component(\n ({\n topology,\n feature,\n projection,\n center,\n areas = [],\n points = [],\n links = [],\n scheme = 'sequential',\n color = 'accent',\n divergingColors = ['danger', 'success'],\n midpoint = 0,\n bins,\n areaLabels = false,\n flow = false,\n valueFormat,\n unit,\n height = 400,\n zoomable = false,\n loading = false,\n empty,\n tooltip = true,\n onAreaClick,\n onPointClick,\n sx,\n ...rest\n }: MapChartProps) => {\n const lang = useLang();\n const format = useFormat();\n const bounds = _derived(topologyBounds(topology));\n const numbers = _derived(\n areas.flatMap((area) => (area.value === undefined ? [] : [toNumber(area.value)])),\n );\n const extent = _derived<[number, number] | null>(\n numbers.length ? [Math.min(...numbers), Math.max(...numbers)] : null,\n );\n const largest = (values: readonly { value?: NumericValue }[]) =>\n Math.max(0, ...values.map((item) => (item.value === undefined ? 0 : toNumber(item.value))));\n const valueText = (value: NumericValue | undefined) =>\n value === undefined\n ? lang.emptyValue\n : format.number(value, unit ? { ...valueFormat, suffix: unit } : valueFormat);\n const numberText = (value: number) => format.number(value, valueFormat);\n\n /** 数值 → 颜色:sequential 从 12% 到 100%;diverging 两头各自从分界往外加深;bins 时按档取 */\n function colorOf(value: number): string {\n const [low, high] = extent ?? [0, 0];\n if (scheme === 'diverging') {\n const [lowColor, highColor] = divergingColors.map((item) => resolveColor(item, 0));\n const reach = Math.max(midpoint - low, high - midpoint) || 1;\n let ratio = Math.min(Math.abs(value - midpoint) / reach, 1);\n if (bins) ratio = Math.max(Math.ceil(ratio * bins), 1) / bins;\n return tint(value < midpoint ? lowColor! : highColor!, 12 + ratio * 88);\n }\n let ratio = high === low ? 1 : (value - low) / (high - low);\n if (bins) ratio = Math.min(Math.floor(ratio * bins), bins - 1) / Math.max(bins - 1, 1);\n return tint(resolveColor(color, 0), 12 + ratio * 88);\n }\n const areaColor = (area: MapArea) =>\n area.color\n ? resolveColor(area.color, 0)\n : area.value === undefined\n ? undefined\n : colorOf(toNumber(area.value));\n\n /** 投影:预设按中心旋转;不写时按范围选 */\n function createProjection(): MapGeoProjection {\n if (projection && typeof projection !== 'string') return projection;\n const [west, south, east, north] = bounds;\n const [longitude, latitude] = center ?? [(west + east) / 2, (south + north) / 2];\n const kind = projection ?? (east - west > 180 ? 'naturalEarth' : 'conic');\n if (kind === 'conic')\n // 标准纬线取范围的 1/6 与 5/6 处(中国约是 25°、47°),中央经线是中心\n return MapProjection.ConicEqualArea()\n .rotate([-longitude, 0])\n .parallels([south + (north - south) / 6, north - (north - south) / 6]);\n if (kind === 'orthographic')\n return MapProjection.Orthographic().rotate([-longitude, -latitude]);\n const create =\n kind === 'mercator'\n ? MapProjection.Mercator\n : kind === 'equalEarth'\n ? MapProjection.EqualEarth\n : MapProjection.NaturalEarth1;\n return create().rotate([-longitude, 0]);\n }\n\n // Unovis 只在第一次画时按绘图区适配投影(之后变了大小也会),换上的新投影只沿用旧的比例与平移,地图会画歪、画小;\n // 所以投影的输入(预设、中心、范围、自己的投影)变了就换一个新的 TopoJSONMap,第一次画时由它自己适配\n let mapKey: unknown[] = [];\n let generation = 0;\n let mapProjection: MapGeoProjection | undefined;\n function updateProjection() {\n const key = [projection, center?.[0], center?.[1], ...bounds];\n if (key.some((item, index) => item !== mapKey[index])) {\n if (mapKey.length) {\n map?.destroy();\n generation += 1;\n }\n mapKey = key;\n mapProjection = createProjection();\n }\n }\n\n // Unovis 每次绘制都把整份 TopoJSON 投影成路径:自带的中国省份有 3.5 万个点,画在几百像素里大多看不出来。\n // 按绘图区里一像素对应的经纬度简化(三角形不到一平方像素的点去掉),绘制快一个数量级;\n // 能缩放时留到放大一倍也看不出折角\n function drawnTopology(): MapTopology {\n const width = plot?.clientWidth ?? 0;\n const height = plot?.clientHeight ?? 0;\n if (!width || !height) return topology;\n const [west, south, east, north] = bounds;\n const degreesPerPixel =\n Math.max((east - west) / width, (north - south) / height) / (zoomable ? 2 : 1);\n return simplifyTopology(topology, degreesPerPixel ** 2);\n }\n\n const pointOf = (id: string) => points.find((point) => point.id === id);\n /** Unovis 画连线时给的是 { source, target }(克隆过的地点),不是原来的流向:按两端的 id 找回 */\n const linkOf = (drawn: MapLink) => {\n const { source, target } = drawn as unknown as { source: MapPoint; target: MapPoint };\n return links.find((link) => link.from === source.id && link.to === target.id);\n };\n let map: TopoJSONMap<MapArea, MapPoint, MapLink> | undefined;\n let plot = _state.raw<HTMLElement | null>(null);\n\n const pointMax = _derived(largest(points));\n // 面积按数值比例:半径 3–8 px\n const radiusOf = (point: MapPoint) =>\n point.value === undefined || pointMax === 0\n ? 4\n : 3 + Math.sqrt(toNumber(point.value) / pointMax) * 5;\n\n let labelFrame = 0;\n /** 画完、缩放之后,下一帧重排地点的标签 */\n function scheduleLabels() {\n cancelAnimationFrame(labelFrame);\n labelFrame = requestAnimationFrame(layoutLabels);\n }\n _effect(() => () => cancelAnimationFrame(labelFrame));\n\n /**\n * 地点的标签:Unovis 的标签相撞时只会藏起来,这里用 placeLabels 挪到放得下的方位(挤时画引线),\n * 画在地点那一组里(跟着缩放、拖动);压在标签、地点上的区域名藏起来。\n * 按屏幕像素算:地点那一组的坐标乘缩放级别\n */\n function layoutLabels() {\n const root = map?.g.node();\n const group = root?.querySelector<SVGGElement>(`.${TopoJSONMap.selectors.points}`);\n const svg = group?.ownerSVGElement;\n if (!root || !group || !svg || !mapProjection) return;\n const projectionAt = mapProjection;\n const zoom = Number(svg.style.getPropertyValue('--vis-map-current-zoom-level')) || 1;\n const layer =\n group.querySelector<SVGGElement>(':scope > [data-point-labels]') ?? svgElement('g');\n layer.setAttribute('data-point-labels', '');\n layer.setAttribute('class', css.attrs(mapChartStyles.pointLabels).class ?? '');\n layer.style.fontSize = `${11 / zoom}px`;\n layer.style.strokeWidth = `${3 / zoom}px`;\n // 放在最后:之后加入的地点不会盖住标签\n group.append(layer);\n\n const items = points.flatMap((point) => {\n const position = projectionAt([point.longitude, point.latitude]);\n if (!position || !point.label) return [];\n const text = svgElement('text');\n text.textContent = point.label;\n text.setAttribute('text-anchor', 'middle');\n return [{ point, text, x: position[0] * zoom, y: position[1] * zoom }];\n });\n layer.replaceChildren(...items.map((item) => item.text));\n // 在原点量字形的框:中文字体的行高、基线的位置各浏览器不同,摆放时按量到的上沿对齐\n const glyphs = items.map((item) => item.text.getBBox());\n const anchors = items.map((item, index) => {\n const box = glyphs[index]!;\n return {\n x: item.x,\n y: item.y,\n radius: radiusOf(item.point),\n // 四周留出描边(1.5 px)与一点空隙;Firefox 量到的框比字形的墨迹窄一点\n width: box.width * zoom + labelPadding * 2,\n height: box.height * zoom + labelPadding * 2,\n priority: item.point.value === undefined ? 0 : toNumber(item.point.value),\n };\n });\n\n const areaTexts = [\n ...root.querySelectorAll<SVGTextElement>(`text.${TopoJSONMap.selectors.areaLabel}`),\n ].filter((text) => text.getAttribute('visibility') !== 'hidden');\n const areaBoxes = areaTexts.map((text): LabelRect => {\n text.style.display = '';\n const { e, f } = text.transform.baseVal.consolidate()?.matrix ?? { e: 0, f: 0 };\n const box = text.getBBox();\n return {\n x: (e + box.x) * zoom,\n y: (f + box.y) * zoom,\n width: box.width * zoom,\n height: box.height * zoom,\n };\n });\n // 没放大时整张图在绘图区里:标签也不出界;放大后本来就只看得到一部分\n const bounds =\n zoom === 1 ? { x: 0, y: 0, width: svg.clientWidth, height: svg.clientHeight } : undefined;\n const placements = placeLabels(anchors, { bounds, soft: areaBoxes });\n\n const taken: LabelRect[] = anchors.map((anchor) => ({\n x: anchor.x - anchor.radius,\n y: anchor.y - anchor.radius,\n width: anchor.radius * 2,\n height: anchor.radius * 2,\n }));\n placements.forEach((placement, index) => {\n const { text } = items[index]!;\n if (!placement) {\n text.remove();\n return;\n }\n const { box, leader } = placement;\n taken.push(box);\n text.setAttribute('x', String((box.x + box.width / 2) / zoom));\n text.setAttribute('y', String((box.y + labelPadding) / zoom - glyphs[index]!.y));\n if (leader) layer.insertBefore(leaderLine(anchors[index]!, box, zoom), text);\n });\n areaTexts.forEach((text, index) => {\n if (taken.some((rect) => rectsOverlap(rect, areaBoxes[index]!)))\n text.style.display = 'none';\n });\n }\n\n /** 引线:从标记的边到标签矩形上离标记最近的点 */\n function leaderLine(\n anchor: { x: number; y: number; radius: number },\n box: LabelRect,\n zoom: number,\n ) {\n const toX = Math.min(Math.max(anchor.x, box.x), box.x + box.width);\n const toY = Math.min(Math.max(anchor.y, box.y), box.y + box.height);\n const length = Math.hypot(toX - anchor.x, toY - anchor.y) || 1;\n const line = svgElement('line');\n line.setAttribute('class', css.attrs(mapChartStyles.leader).class ?? '');\n line.setAttribute(\n 'x1',\n String((anchor.x + ((toX - anchor.x) / length) * anchor.radius) / zoom),\n );\n line.setAttribute(\n 'y1',\n String((anchor.y + ((toY - anchor.y) / length) * anchor.radius) / zoom),\n );\n line.setAttribute('x2', String(toX / zoom));\n line.setAttribute('y2', String(toY / zoom));\n line.style.strokeWidth = `${1 / zoom}px`;\n return line;\n }\n const chart: SingleChart = useSingleChart<MapGraphData<MapArea, MapPoint, MapLink>>(() => ({\n element: plot,\n ready: !loading,\n tooltip,\n build: (instance) => {\n const linkMax = largest(links);\n updateProjection();\n map = instance(`map-${generation}`, () => {\n const created = new TopoJSONMap<MapArea, MapPoint, MapLink>();\n // 热力模式的滤镜是写死的 id=\"heatmapFilter\",一页多张地图时 id 重复;不用热力模式,去掉\n created.g.select('filter#heatmapFilter').remove();\n // 缩放时 Unovis 把缩放级别写到 svg 的 style 上:跟着重排标签(拖动只是平移,标签随地点那一组走)\n const observer = new MutationObserver(scheduleLabels);\n queueMicrotask(() => {\n const svg = created.g.node()?.parentElement;\n if (svg) observer.observe(svg, { attributes: true, attributeFilter: ['style'] });\n });\n const destroy = created.destroy.bind(created);\n created.destroy = () => {\n observer.disconnect();\n destroy();\n };\n return created;\n });\n map.setConfig({\n topojson: drawnTopology(),\n mapFeatureName: feature,\n projection: mapProjection,\n disableZoom: !zoomable,\n areaId: (area) => area.id,\n areaColor,\n areaLabel: areaLabels ? (area) => area.label : undefined,\n areaCursor: onAreaClick ? () => 'pointer' : undefined,\n pointId: (point) => point.id,\n longitude: (point) => point.longitude,\n latitude: (point) => point.latitude,\n pointColor: (point) => resolveColor(point.color ?? 'danger', 0),\n pointRadius: radiusOf,\n pointShape: (point) => point.shape ?? 'circle',\n pointCursor: onPointClick ? () => 'pointer' : undefined,\n // 名字由 layoutLabels 自己画(pointLabel 写在点里面,pointBottomLabel 相撞时只会藏起来)\n pointLabel: () => '',\n pointBottomLabel: () => '',\n // 两端给 id:Unovis 克隆了地点,按对象找不到\n linkSource: (link) => link.from,\n linkTarget: (link) => link.to,\n linkColor: (drawn) => resolveColor(linkOf(drawn)?.color ?? 'neutral', 0),\n linkWidth: (drawn) => {\n const value = linkOf(drawn)?.value;\n return value === undefined || linkMax === 0 ? 1.5 : 1 + (toNumber(value) / linkMax) * 4;\n },\n enableFlowAnimation: flow,\n // 流动的粒子按原来的流向画,两端的经纬度直接给;起点已经有地点的标记,不再加一个\n sourceLongitude: (link) => pointOf(link.from)?.longitude,\n sourceLatitude: (link) => pointOf(link.from)?.latitude,\n targetLongitude: (link) => pointOf(link.to)?.longitude,\n targetLatitude: (link) => pointOf(link.to)?.latitude,\n sourcePointRadius: 0,\n flowParticleColor: (link) => resolveColor(link.color ?? 'accent', 0),\n flowParticleRadius: 2,\n // 每经度 0.15 个粒子:默认的 0.6 太密,连成一条线盖住了连线\n flowParticleDensity: 0.15,\n events: {\n [TopoJSONMap.selectors.feature]: {\n click: (shape: { data?: MapArea }) => {\n if (shape.data) onAreaClick?.(shape.data);\n },\n },\n [TopoJSONMap.selectors.point]: {\n click: (point: MapPoint) => onPointClick?.(point),\n },\n },\n });\n return {\n component: map,\n onRender: scheduleLabels,\n data: {\n areas: [...areas],\n points: [...points],\n links: links.filter((link) => pointOf(link.from) && pointOf(link.to)),\n },\n triggers: {\n [TopoJSONMap.selectors.feature]: (shape: { data?: MapArea }) =>\n shape.data\n ? chart.tooltip(\n chartTooltip(shape.data.label, [\n {\n label: lang.chartValue,\n color: areaColor(shape.data) ?? 'transparent',\n value: valueText(shape.data.value),\n },\n ]),\n )\n : undefined,\n [TopoJSONMap.selectors.point]: (point: MapPoint) =>\n chart.tooltip(\n chartTooltip(point.label, [\n {\n label: lang.chartValue,\n color: resolveColor(point.color ?? 'danger', 0),\n value: valueText(point.value),\n },\n ]),\n ),\n },\n };\n },\n }));\n\n /** 图例:分档时每档一个色块与范围,连续时一条色带两端写最小最大 */\n function legend() {\n if (!extent || areas.every((area) => area.color)) return null;\n const [low, high] = extent;\n if (bins) {\n const step = (high - low) / bins;\n return (\n <div {...css.attrs(mapChartStyles.legend)} aria-hidden=\"true\">\n {Array.from({ length: bins }, (_, index) => {\n const from = low + step * index;\n const to = index === bins - 1 ? high : from + step;\n return (\n <span key={index} {...css.attrs(mapChartStyles.bin)}>\n <span\n {...css.attrs(\n mapChartStyles.swatch,\n mapChartStyles.swatchColor(colorOf((from + to) / 2)),\n )}\n />\n {numberText(from)} – {numberText(to)}\n </span>\n );\n })}\n </div>\n );\n }\n const stops =\n scheme === 'diverging'\n ? [colorOf(low), colors.fill, colorOf(high)]\n : [colorOf(low), colorOf(high)];\n return (\n <div {...css.attrs(mapChartStyles.legend)} aria-hidden=\"true\">\n <span>{numberText(low)}</span>\n <span\n {...css.attrs(\n mapChartStyles.ramp,\n mapChartStyles.rampColors(`linear-gradient(to right, ${stops.join(', ')})`),\n )}\n />\n <span>{numberText(high)}</span>\n </div>\n );\n }\n\n // 滚轮默认滚动页面,按住 Ctrl(或 ⌘、触控板捏合)才缩放地图(同 Google 地图的 cooperative 手势):\n // 否则滚动页面经过地图时会把地图缩小。拦下的滚轮在顶栏提示一下\n let wheelHint = _state(false);\n let hintTimer: ReturnType<typeof setTimeout> | undefined;\n useEventListener(\n () => (zoomable ? plot : null),\n 'wheel',\n (event) => {\n if (event.ctrlKey || event.metaKey) return;\n event.stopPropagation();\n wheelHint = true;\n clearTimeout(hintTimer);\n hintTimer = setTimeout(() => (wheelHint = false), 1500);\n },\n { capture: true },\n );\n _effect(() => () => clearTimeout(hintTimer));\n\n /** 缩放按钮:放大、缩小、复位;前面是滚轮的提示 */\n const zoomButtons = () => (\n <span {...css.attrs(mapChartStyles.zoom)}>\n {wheelHint && (\n <span {...css.attrs(mapChartStyles.wheelHint)} role=\"status\">\n {lang.chartZoomWheelHint}\n </span>\n )}\n {(\n [\n [Plus, lang.chartZoomIn, () => map?.zoomIn()],\n [Minus, lang.chartZoomOut, () => map?.zoomOut()],\n [Maximize, lang.chartZoomFit, () => map?.fitView()],\n ] as const\n ).map(([icon, label, action]) => (\n <IconButton\n key={label}\n icon={icon}\n size=\"sm\"\n variant=\"ghost\"\n tone=\"neutral\"\n aria-label={label}\n onClick={action}\n />\n ))}\n </span>\n );\n\n return () => (\n <ChartFrame\n {...rest}\n sx={[mapChartStyles.root, sx]}\n unit={unit}\n height={height}\n legend={[]}\n hiddenKeys={[]}\n onLegendToggle={() => {}}\n loading={loading}\n skeleton={<Skeleton sx={mapChartStyles.skeleton} />}\n isEmpty={false}\n empty={empty}\n actions={zoomable ? zoomButtons() : undefined}\n footer={legend()}\n table={{\n columns: [lang.chartCategory, unit ? `${lang.chartValue}(${unit})` : lang.chartValue],\n rows: [\n ...areas.map((area) => ({ header: area.label, value: area.value })),\n ...points.map((point) => ({ header: point.label, value: point.value })),\n ...links.map((link) => ({\n header: lang.chartFlowLabel(\n pointOf(link.from)?.label ?? link.from,\n pointOf(link.to)?.label ?? link.to,\n ),\n value: link.value,\n })),\n ].map((row) => ({\n header: row.header,\n cells: [\n row.value === undefined ? lang.emptyValue : format.number(row.value, valueFormat),\n ],\n })),\n }}\n plotRef={(element) => (plot = element)}\n />\n );\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"MapChart.js","names":["_vtp_readonlyProp","_vtp_restProps","_vue_computed","_vue_shallowRef","_createVNode","_mergeProps","_createTextVNode","_vue_ref"],"sources":["../../src/charts/MapChart.tsx"],"sourcesContent":["/**\n * 地图:按区域着色(分省的销售额、各国的采购额),标出地点(工厂、供应商)与它们之间的流向。\n * 地理数据是 TopoJSON:Unovis 自带中国省份、世界、美国等(`@unovis/ts/maps`),也可以用自己的。\n *\n * import { ChinaTopoJSON } from '@unovis/ts/maps';\n * <MapChart\n * aria-label=\"各省销售额\"\n * topology={ChinaTopoJSON}\n * feature=\"provinces\"\n * areas={[{ id: 'CN-JS', label: '江苏', value: 623 }, …]} // id 是地图要素的 id\n * points={[{ id: 'sh', label: '上海组装', longitude: 121.47, latitude: 31.23, value: 860 }]}\n * links={[{ from: 'xa', to: 'sh', value: 120 }]}\n * bins={5}\n * areaLabels\n * />\n *\n * 投影:默认按地理数据的范围选——一个国家、一个地区用以它为中心的等积圆锥投影(中国地图常用的 Albers,正着、不歪),\n * 跨了大半个地球时用 Natural Earth;也可以指定 mercator、equalEarth、orthographic(地球仪)或自己的 d3 投影。\n *\n * 着色:sequential(默认)按数值深浅;diverging 以 midpoint 为界两头两种颜色(同比的涨跌);\n * bins 分成几档(分级着色,图例是几个色块),不写时连续着色(图例是色带);区域写了 color 时按它(分类着色)。\n * 没有数据的区域是底色。地点:value 决定大小(面积按比例),color、shape 决定颜色与形状;名字自动避让\n * (换方位、挤时往外退并画引线,数值大的先放,放不下的悬停看;压住名字、地点的区域名藏起来);\n * links 是地点之间的流向,粗细按 value,flow 时有流动的粒子。\n * zoomable 时可以拖动、按住 Ctrl 滚轮缩放,右上角有放大、缩小、复位的按钮。悬停看名称与数值;读屏的数据表列出各区域、地点与流向。\n */\nimport {\n MapProjection,\n TopoJSONMap,\n type MapGraphData,\n type TopoJSONMapConfigInterface,\n} from '@unovis/ts';\nimport { Maximize, Minus, Plus } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { presimplify, simplify } from 'topojson-simplify';\nimport type { VNodeChild } from 'vue';\nimport { IconButton } from '../base/IconButton';\nimport { useLang } from '../config/context';\nimport { useFormat, type NumericFormat } from '../config/lang/format';\nimport { colors } from '../config/theme/tokens';\nimport { Skeleton } from '../feedback/Skeleton';\nimport { toNumber, type NumericValue } from '../utils/data/numeric';\nimport { useEventListener } from '../utils/dom/event-listener';\nimport type { PartProps } from '../utils/props';\nimport { chartTooltip, ChartFrame, type ChartFrameParts } from './frame';\nimport { placeLabels, rectsOverlap, type LabelRect } from './label-layout';\nimport { resolveColor, type ChartColor } from './series';\nimport { useSingleChart, type SingleChart } from './single';\n\n/** 一个区域的数据 */\nexport interface MapArea {\n /** 地图要素的 id(Unovis 的中国省份是 'CN-JS' 这样的写法) */\n id: string;\n /** 显示的名称:提示框、区域名、数据表 */\n label: string;\n /** 数值:决定颜色 */\n value?: NumericValue;\n /** 指定颜色:不按数值着色(分类着色,如所属大区) */\n color?: ChartColor;\n}\n\n/** 一个地点 */\nexport interface MapPoint {\n /** 标识:流向的 from、to 指向它 */\n id: string;\n /** 名称:写在点下方 */\n label: string;\n /** 经度 */\n longitude: number;\n /** 纬度 */\n latitude: number;\n /** 数值:决定点的大小(面积按比例),也显示在提示框 */\n value?: NumericValue;\n /** 颜色,默认 danger */\n color?: ChartColor;\n /** 形状,默认 circle */\n shape?: 'circle' | 'square' | 'triangle';\n}\n\n/** 两个地点之间的流向 */\nexport interface MapLink {\n /** 起点(地点的 id) */\n from: string;\n /** 终点(地点的 id) */\n to: string;\n /** 数值:决定线的粗细,也显示在数据表 */\n value?: NumericValue;\n /** 颜色,默认次要色 */\n color?: ChartColor;\n}\n\n/** 投影的预设 */\nexport interface MapProjections {\n /** 等积圆锥(Albers):以数据为中心,一个国家、一个地区用它(中国地图常用),正着、面积不失真 */\n conic: unknown;\n /** 墨卡托:网页地图常见,高纬度会放大 */\n mercator: unknown;\n /** Natural Earth:世界地图,形状与面积都比较自然 */\n naturalEarth: unknown;\n /** Equal Earth:世界地图,面积准确 */\n equalEarth: unknown;\n /** 正射(地球仪):以数据为中心看半个地球 */\n orthographic: unknown;\n}\n\n/** d3 的投影(TopoJSONMap 的 projection) */\nexport type MapGeoProjection = NonNullable<TopoJSONMapConfigInterface<MapArea>['projection']>;\n\n/** 未声明的属性落到外层 div(role=\"figure\")上;aria-label 是图表的名称 */\nexport interface MapChartProps extends PartProps<'div', 'role' | 'aria-busy'>, ChartFrameParts {\n /** 地理数据(TopoJSON),如 `@unovis/ts/maps` 的 ChinaTopoJSON、WorldMapTopoJSON */\n topology: NonNullable<TopoJSONMapConfigInterface<MapArea>['topojson']>;\n /** 画哪一组要素(TopoJSON 的 objects 里的名字),如中国省份是 'provinces'、世界是 'countries' */\n feature: string;\n /** 投影:预设的名字,或 d3 的投影;不写时按数据的范围选 conic 或 naturalEarth */\n projection?: keyof MapProjections | MapGeoProjection;\n /** 投影的中心 [经度, 纬度]:中央经线(世界地图写 [150, 0] 以太平洋为中心),orthographic 还用纬度;不写时取地理数据范围的中心 */\n center?: readonly [number, number];\n /** 各区域的数值 */\n areas?: readonly MapArea[];\n /** 地点 */\n points?: readonly MapPoint[];\n /** 地点之间的流向 */\n links?: readonly MapLink[];\n /** 着色方式:sequential 按数值深浅(默认),diverging 以 midpoint 为界两头两种颜色 */\n scheme?: 'sequential' | 'diverging';\n /** sequential 的基色,默认 accent */\n color?: ChartColor;\n /** diverging 的两头 [低, 高],默认 ['danger', 'success'] */\n divergingColors?: readonly [ChartColor, ChartColor];\n /** diverging 的分界,默认 0 */\n midpoint?: number;\n /** 分成几档(分级着色);不写时连续着色 */\n bins?: number;\n /** 在区域上写名字(区域够大时) */\n areaLabels?: boolean;\n /** 流向上有流动的粒子 */\n flow?: boolean;\n /** 数值的格式 */\n valueFormat?: NumericFormat;\n /** 单位:显示在左上方,提示框与数据表的数值后面带上 */\n unit?: string;\n /**\n * 绘图区的高度;数字按 px\n * @default 400\n */\n height?: number | string;\n /** 可以拖动、滚轮缩放,右上角有放大、缩小、复位的按钮;默认关(不抢页面的滚动) */\n zoomable?: boolean;\n /** 加载中:绘图区显示骨架 */\n loading?: boolean;\n /** 没有数据时显示的内容 */\n empty?: VNodeChild;\n /** 悬停时的提示框,默认 true */\n tooltip?: boolean;\n /** 点了一个有数据的区域 */\n onAreaClick?: (area: MapArea) => void;\n /** 点了一个地点 */\n onPointClick?: (point: MapPoint) => void;\n}\n\n/** MapChart 的样式 */\nexport const mapChartStyles = css.create({\n // 地图跟随主题:底色、边界是表面色,文字是正文色\n root: {\n '--vis-map-feature-color': colors.fill,\n '--vis-map-boundary-color': colors.surface,\n '--vis-map-point-label-text-color-dark': colors.text,\n '--vis-map-point-label-text-color-light': colors.text,\n '--vis-map-area-label-text-color': colors.text,\n '--vis-map-area-label-font-size': '10px',\n '--vis-map-area-label-font-weight': '400',\n '--vis-map-point-default-stroke-color': colors.surface,\n '--vis-map-point-default-stroke-width': '1.5px',\n },\n skeleton: { display: 'block', width: '100%', height: '100%' },\n // 地点的标签:描一圈表面色的边,压在区域、连线上也看得清;字号、描边宽度随缩放在行内设置\n pointLabels: {\n fontWeight: 600,\n fill: colors.text,\n stroke: colors.surface,\n paintOrder: 'stroke',\n strokeLinejoin: 'round',\n pointerEvents: 'none',\n },\n leader: { stroke: colors.textMuted },\n // 缩放按钮:在标题行的结束边(导出菜单前面)\n zoom: { display: 'inline-flex', alignItems: 'center', gap: '2px', marginInlineStart: 'auto' },\n wheelHint: { marginInlineEnd: '_sm', color: '_textMuted', fontSize: '_xs' },\n // 图例:连续是色带,分档是一排色块\n legend: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n columnGap: '_md',\n rowGap: '_xs',\n fontSize: '_xs',\n color: '_textMuted',\n paddingInline: '_sm',\n },\n ramp: { flexGrow: 1, maxWidth: '16rem', height: '0.5rem', borderRadius: '_full' },\n rampColors: (gradient: string) => ({ backgroundImage: gradient }),\n bin: { display: 'inline-flex', alignItems: 'center', gap: '0.375em', whiteSpace: 'nowrap' },\n swatch: { width: '0.875rem', height: '0.625rem', borderRadius: '2px' },\n swatchColor: (color: string) => ({ backgroundColor: color }),\n});\n\n/** 地点的标签四周留的空(屏幕像素) */\nconst labelPadding = 3;\n\n/** 新建一个 SVG 元素 */\nconst svgElement = <K extends keyof SVGElementTagNameMap>(name: K) =>\n document.createElementNS('http://www.w3.org/2000/svg', name);\n\n/** 混色:基色占 percent,其余透明(落在底色上) */\nconst tint = (color: string, percent: number) =>\n `color-mix(in srgb, ${color} ${Math.round(percent)}%, transparent)`;\n\ntype MapTopology = MapChartProps['topology'];\n\n/** 算好了各点权重的地理数据:同一份 TopoJSON 只算一次 */\nconst presimplified = new WeakMap<MapTopology, MapTopology>();\n/**\n * 简化过的地理数据放进这个类的实例:Unovis 的 setConfig 深拷贝配置,但跳过类的实例,\n * 每次更新就不必把整份 TopoJSON 再拷一遍\n */\nclass SharedTopology {}\n\n/** 简化过的地理数据:TopoJSON → 档位 → 结果 */\nconst simplified = new WeakMap<MapTopology, Map<number, MapTopology>>();\n\n/**\n * 简化地理数据:去掉与前后两点围成的三角形面积不到 minArea(坐标单位的平方,经纬度是平方度)的点\n * (Visvalingam,topojson-simplify)。相邻区域共用的边界一起简化,不会出现缝隙;各段弧的两端总保留。\n * minArea 按 2 的整数次幂分档缓存:绘图区大小变一点不重算。\n */\nexport function simplifyTopology(topology: MapTopology, minArea: number): MapTopology {\n if (!(minArea > 0) || !Number.isFinite(minArea)) return topology;\n const level = 2 ** Math.floor(Math.log2(minArea));\n let byLevel = simplified.get(topology);\n if (!byLevel) simplified.set(topology, (byLevel = new Map()));\n let result = byLevel.get(level);\n if (!result) {\n // topojson-simplify 的类型里要素属性不能是 null(GeoJSON 允许):边界上转一下\n type Input = Parameters<typeof presimplify>[0];\n let weighted = presimplified.get(topology);\n if (!weighted)\n presimplified.set(topology, (weighted = presimplify(topology as Input) as MapTopology));\n result = Object.assign(new SharedTopology(), simplify(weighted as Input, level)) as MapTopology;\n byLevel.set(level, result);\n }\n return result;\n}\n\n/** TopoJSON 的经纬度范围 [西, 南, 东, 北]:有 bbox 用它,否则解出各段弧的坐标(量化的弧是逐点的差值) */\nexport function topologyBounds(\n topology: MapChartProps['topology'],\n): [number, number, number, number] {\n if (topology.bbox) {\n const [west, south, east, north] = topology.bbox;\n return [west, south, east, north];\n }\n const quantized = topology.transform;\n const [scaleX, scaleY] = quantized?.scale ?? [1, 1];\n const [translateX, translateY] = quantized?.translate ?? [0, 0];\n let [west, south, east, north] = [Infinity, Infinity, -Infinity, -Infinity];\n for (const arc of topology.arcs) {\n let x = 0;\n let y = 0;\n for (const position of arc) {\n x = quantized ? x + position[0]! : position[0]!;\n y = quantized ? y + position[1]! : position[1]!;\n const longitude = x * scaleX + translateX;\n const latitude = y * scaleY + translateY;\n west = Math.min(west, longitude);\n east = Math.max(east, longitude);\n south = Math.min(south, latitude);\n north = Math.max(north, latitude);\n }\n }\n return [west, south, east, north];\n}\n\n/** 地图 */\nexport const MapChart = _component(\n ({\n topology,\n feature,\n projection,\n center,\n areas = [],\n points = [],\n links = [],\n scheme = 'sequential',\n color = 'accent',\n divergingColors = ['danger', 'success'],\n midpoint = 0,\n bins,\n areaLabels = false,\n flow = false,\n valueFormat,\n unit,\n height = 400,\n zoomable = false,\n loading = false,\n empty,\n tooltip = true,\n onAreaClick,\n onPointClick,\n sx,\n ...rest\n }: MapChartProps) => {\n const lang = useLang();\n const format = useFormat();\n const bounds = _derived(topologyBounds(topology));\n const numbers = _derived(\n areas.flatMap((area) => (area.value === undefined ? [] : [toNumber(area.value)])),\n );\n const extent = _derived<[number, number] | null>(\n numbers.length ? [Math.min(...numbers), Math.max(...numbers)] : null,\n );\n const largest = (values: readonly { value?: NumericValue }[]) =>\n Math.max(0, ...values.map((item) => (item.value === undefined ? 0 : toNumber(item.value))));\n const valueText = (value: NumericValue | undefined) =>\n value === undefined\n ? lang.emptyValue\n : format.number(value, unit ? { ...valueFormat, suffix: unit } : valueFormat);\n const numberText = (value: number) => format.number(value, valueFormat);\n\n /** 数值 → 颜色:sequential 从 12% 到 100%;diverging 两头各自从分界往外加深;bins 时按档取 */\n function colorOf(value: number): string {\n const [low, high] = extent ?? [0, 0];\n if (scheme === 'diverging') {\n const [lowColor, highColor] = divergingColors.map((item) => resolveColor(item, 0));\n const reach = Math.max(midpoint - low, high - midpoint) || 1;\n let ratio = Math.min(Math.abs(value - midpoint) / reach, 1);\n if (bins) ratio = Math.max(Math.ceil(ratio * bins), 1) / bins;\n return tint(value < midpoint ? lowColor! : highColor!, 12 + ratio * 88);\n }\n let ratio = high === low ? 1 : (value - low) / (high - low);\n if (bins) ratio = Math.min(Math.floor(ratio * bins), bins - 1) / Math.max(bins - 1, 1);\n return tint(resolveColor(color, 0), 12 + ratio * 88);\n }\n const areaColor = (area: MapArea) =>\n area.color\n ? resolveColor(area.color, 0)\n : area.value === undefined\n ? undefined\n : colorOf(toNumber(area.value));\n\n /** 投影:预设按中心旋转;不写时按范围选 */\n function createProjection(): MapGeoProjection {\n if (projection && typeof projection !== 'string') return projection;\n const [west, south, east, north] = bounds;\n const [longitude, latitude] = center ?? [(west + east) / 2, (south + north) / 2];\n const kind = projection ?? (east - west > 180 ? 'naturalEarth' : 'conic');\n if (kind === 'conic')\n // 标准纬线取范围的 1/6 与 5/6 处(中国约是 25°、47°),中央经线是中心\n return MapProjection.ConicEqualArea()\n .rotate([-longitude, 0])\n .parallels([south + (north - south) / 6, north - (north - south) / 6]);\n if (kind === 'orthographic')\n return MapProjection.Orthographic().rotate([-longitude, -latitude]);\n const create =\n kind === 'mercator'\n ? MapProjection.Mercator\n : kind === 'equalEarth'\n ? MapProjection.EqualEarth\n : MapProjection.NaturalEarth1;\n return create().rotate([-longitude, 0]);\n }\n\n // Unovis 只在第一次画时按绘图区适配投影(之后变了大小也会),换上的新投影只沿用旧的比例与平移,地图会画歪、画小;\n // 所以投影的输入(预设、中心、范围、自己的投影)变了就换一个新的 TopoJSONMap,第一次画时由它自己适配\n let mapKey: unknown[] = [];\n let generation = 0;\n let mapProjection: MapGeoProjection | undefined;\n function updateProjection() {\n const key = [projection, center?.[0], center?.[1], ...bounds];\n if (key.some((item, index) => item !== mapKey[index])) {\n if (mapKey.length) {\n map?.destroy();\n generation += 1;\n }\n mapKey = key;\n mapProjection = createProjection();\n }\n }\n\n // Unovis 每次绘制都把整份 TopoJSON 投影成路径:自带的中国省份有 3.5 万个点,画在几百像素里大多看不出来。\n // 按绘图区里一像素对应的经纬度简化(三角形不到一平方像素的点去掉),绘制快一个数量级;\n // 能缩放时留到放大一倍也看不出折角\n function drawnTopology(): MapTopology {\n const width = plot?.clientWidth ?? 0;\n const height = plot?.clientHeight ?? 0;\n if (!width || !height) return topology;\n const [west, south, east, north] = bounds;\n const degreesPerPixel =\n Math.max((east - west) / width, (north - south) / height) / (zoomable ? 2 : 1);\n return simplifyTopology(topology, degreesPerPixel ** 2);\n }\n\n const pointOf = (id: string) => points.find((point) => point.id === id);\n /** Unovis 画连线时给的是 { source, target }(克隆过的地点),不是原来的流向:按两端的 id 找回 */\n const linkOf = (drawn: MapLink) => {\n const { source, target } = drawn as unknown as { source: MapPoint; target: MapPoint };\n return links.find((link) => link.from === source.id && link.to === target.id);\n };\n let map: TopoJSONMap<MapArea, MapPoint, MapLink> | undefined;\n let plot = _state.raw<HTMLElement | null>(null);\n\n const pointMax = _derived(largest(points));\n // 面积按数值比例:半径 3–8 px\n const radiusOf = (point: MapPoint) =>\n point.value === undefined || pointMax === 0\n ? 4\n : 3 + Math.sqrt(toNumber(point.value) / pointMax) * 5;\n\n let labelFrame = 0;\n /** 画完、缩放之后,下一帧重排地点的标签 */\n function scheduleLabels() {\n cancelAnimationFrame(labelFrame);\n labelFrame = requestAnimationFrame(layoutLabels);\n }\n _effect(() => () => cancelAnimationFrame(labelFrame));\n\n /**\n * 地点的标签:Unovis 的标签相撞时只会藏起来,这里用 placeLabels 挪到放得下的方位(挤时画引线),\n * 画在地点那一组里(跟着缩放、拖动);压在标签、地点上的区域名藏起来。\n * 按屏幕像素算:地点那一组的坐标乘缩放级别\n */\n function layoutLabels() {\n const root = map?.g.node();\n const group = root?.querySelector<SVGGElement>(`.${TopoJSONMap.selectors.points}`);\n const svg = group?.ownerSVGElement;\n if (!root || !group || !svg || !mapProjection) return;\n const projectionAt = mapProjection;\n const zoom = Number(svg.style.getPropertyValue('--vis-map-current-zoom-level')) || 1;\n const layer =\n group.querySelector<SVGGElement>(':scope > [data-point-labels]') ?? svgElement('g');\n layer.setAttribute('data-point-labels', '');\n layer.setAttribute('class', css.attrs(mapChartStyles.pointLabels).class ?? '');\n layer.style.fontSize = `${11 / zoom}px`;\n layer.style.strokeWidth = `${3 / zoom}px`;\n // 放在最后:之后加入的地点不会盖住标签\n group.append(layer);\n\n const items = points.flatMap((point) => {\n const position = projectionAt([point.longitude, point.latitude]);\n if (!position || !point.label) return [];\n const text = svgElement('text');\n text.textContent = point.label;\n text.setAttribute('text-anchor', 'middle');\n return [{ point, text, x: position[0] * zoom, y: position[1] * zoom }];\n });\n layer.replaceChildren(...items.map((item) => item.text));\n // 在原点量字形的框:中文字体的行高、基线的位置各浏览器不同,摆放时按量到的上沿对齐\n const glyphs = items.map((item) => item.text.getBBox());\n const anchors = items.map((item, index) => {\n const box = glyphs[index]!;\n return {\n x: item.x,\n y: item.y,\n radius: radiusOf(item.point),\n // 四周留出描边(1.5 px)与一点空隙;Firefox 量到的框比字形的墨迹窄一点\n width: box.width * zoom + labelPadding * 2,\n height: box.height * zoom + labelPadding * 2,\n priority: item.point.value === undefined ? 0 : toNumber(item.point.value),\n };\n });\n\n const areaTexts = [\n ...root.querySelectorAll<SVGTextElement>(`text.${TopoJSONMap.selectors.areaLabel}`),\n ].filter((text) => text.getAttribute('visibility') !== 'hidden');\n const areaBoxes = areaTexts.map((text): LabelRect => {\n text.style.display = '';\n const { e, f } = text.transform.baseVal.consolidate()?.matrix ?? { e: 0, f: 0 };\n const box = text.getBBox();\n return {\n x: (e + box.x) * zoom,\n y: (f + box.y) * zoom,\n width: box.width * zoom,\n height: box.height * zoom,\n };\n });\n // 没放大时整张图在绘图区里:标签也不出界;放大后本来就只看得到一部分\n const bounds =\n zoom === 1 ? { x: 0, y: 0, width: svg.clientWidth, height: svg.clientHeight } : undefined;\n const placements = placeLabels(anchors, { bounds, soft: areaBoxes });\n\n const taken: LabelRect[] = anchors.map((anchor) => ({\n x: anchor.x - anchor.radius,\n y: anchor.y - anchor.radius,\n width: anchor.radius * 2,\n height: anchor.radius * 2,\n }));\n placements.forEach((placement, index) => {\n const { text } = items[index]!;\n if (!placement) {\n text.remove();\n return;\n }\n const { box, leader } = placement;\n taken.push(box);\n text.setAttribute('x', String((box.x + box.width / 2) / zoom));\n text.setAttribute('y', String((box.y + labelPadding) / zoom - glyphs[index]!.y));\n if (leader) layer.insertBefore(leaderLine(anchors[index]!, box, zoom), text);\n });\n areaTexts.forEach((text, index) => {\n if (taken.some((rect) => rectsOverlap(rect, areaBoxes[index]!)))\n text.style.display = 'none';\n });\n }\n\n /** 引线:从标记的边到标签矩形上离标记最近的点 */\n function leaderLine(\n anchor: { x: number; y: number; radius: number },\n box: LabelRect,\n zoom: number,\n ) {\n const toX = Math.min(Math.max(anchor.x, box.x), box.x + box.width);\n const toY = Math.min(Math.max(anchor.y, box.y), box.y + box.height);\n const length = Math.hypot(toX - anchor.x, toY - anchor.y) || 1;\n const line = svgElement('line');\n line.setAttribute('class', css.attrs(mapChartStyles.leader).class ?? '');\n line.setAttribute(\n 'x1',\n String((anchor.x + ((toX - anchor.x) / length) * anchor.radius) / zoom),\n );\n line.setAttribute(\n 'y1',\n String((anchor.y + ((toY - anchor.y) / length) * anchor.radius) / zoom),\n );\n line.setAttribute('x2', String(toX / zoom));\n line.setAttribute('y2', String(toY / zoom));\n line.style.strokeWidth = `${1 / zoom}px`;\n return line;\n }\n const chart: SingleChart = useSingleChart<MapGraphData<MapArea, MapPoint, MapLink>>(() => ({\n element: plot,\n ready: !loading,\n tooltip,\n build: (instance) => {\n const linkMax = largest(links);\n updateProjection();\n map = instance(`map-${generation}`, () => {\n const created = new TopoJSONMap<MapArea, MapPoint, MapLink>();\n // 热力模式的滤镜是写死的 id=\"heatmapFilter\",一页多张地图时 id 重复;不用热力模式,去掉\n created.g.select('filter#heatmapFilter').remove();\n // 缩放时 Unovis 把缩放级别写到 svg 的 style 上:跟着重排标签(拖动只是平移,标签随地点那一组走)\n const observer = new MutationObserver(scheduleLabels);\n queueMicrotask(() => {\n const svg = created.g.node()?.parentElement;\n if (svg) observer.observe(svg, { attributes: true, attributeFilter: ['style'] });\n });\n const destroy = created.destroy.bind(created);\n created.destroy = () => {\n observer.disconnect();\n destroy();\n };\n return created;\n });\n map.setConfig({\n topojson: drawnTopology(),\n mapFeatureName: feature,\n projection: mapProjection,\n disableZoom: !zoomable,\n areaId: (area) => area.id,\n areaColor,\n areaLabel: areaLabels ? (area) => area.label : undefined,\n areaCursor: onAreaClick ? () => 'pointer' : undefined,\n pointId: (point) => point.id,\n longitude: (point) => point.longitude,\n latitude: (point) => point.latitude,\n pointColor: (point) => resolveColor(point.color ?? 'danger', 0),\n pointRadius: radiusOf,\n pointShape: (point) => point.shape ?? 'circle',\n pointCursor: onPointClick ? () => 'pointer' : undefined,\n // 名字由 layoutLabels 自己画(pointLabel 写在点里面,pointBottomLabel 相撞时只会藏起来)\n pointLabel: () => '',\n pointBottomLabel: () => '',\n // 两端给 id:Unovis 克隆了地点,按对象找不到\n linkSource: (link) => link.from,\n linkTarget: (link) => link.to,\n linkColor: (drawn) => resolveColor(linkOf(drawn)?.color ?? 'neutral', 0),\n linkWidth: (drawn) => {\n const value = linkOf(drawn)?.value;\n return value === undefined || linkMax === 0 ? 1.5 : 1 + (toNumber(value) / linkMax) * 4;\n },\n enableFlowAnimation: flow,\n // 流动的粒子按原来的流向画,两端的经纬度直接给;起点已经有地点的标记,不再加一个\n sourceLongitude: (link) => pointOf(link.from)?.longitude,\n sourceLatitude: (link) => pointOf(link.from)?.latitude,\n targetLongitude: (link) => pointOf(link.to)?.longitude,\n targetLatitude: (link) => pointOf(link.to)?.latitude,\n sourcePointRadius: 0,\n flowParticleColor: (link) => resolveColor(link.color ?? 'accent', 0),\n flowParticleRadius: 2,\n // 每经度 0.15 个粒子:默认的 0.6 太密,连成一条线盖住了连线\n flowParticleDensity: 0.15,\n events: {\n [TopoJSONMap.selectors.feature]: {\n click: (shape: { data?: MapArea }) => {\n if (shape.data) onAreaClick?.(shape.data);\n },\n },\n [TopoJSONMap.selectors.point]: {\n click: (point: MapPoint) => onPointClick?.(point),\n },\n },\n });\n return {\n component: map,\n onRender: scheduleLabels,\n data: {\n areas: [...areas],\n points: [...points],\n links: links.filter((link) => pointOf(link.from) && pointOf(link.to)),\n },\n triggers: {\n [TopoJSONMap.selectors.feature]: (shape: { data?: MapArea }) =>\n shape.data\n ? chart.tooltip(\n chartTooltip(shape.data.label, [\n {\n label: lang.chartValue,\n color: areaColor(shape.data) ?? 'transparent',\n value: valueText(shape.data.value),\n },\n ]),\n )\n : undefined,\n [TopoJSONMap.selectors.point]: (point: MapPoint) =>\n chart.tooltip(\n chartTooltip(point.label, [\n {\n label: lang.chartValue,\n color: resolveColor(point.color ?? 'danger', 0),\n value: valueText(point.value),\n },\n ]),\n ),\n },\n };\n },\n }));\n\n /** 图例:分档时每档一个色块与范围,连续时一条色带两端写最小最大 */\n function legend() {\n if (!extent || areas.every((area) => area.color)) return null;\n const [low, high] = extent;\n if (bins) {\n const step = (high - low) / bins;\n return (\n <div {...css.attrs(mapChartStyles.legend)} aria-hidden=\"true\">\n {Array.from({ length: bins }, (_, index) => {\n const from = low + step * index;\n const to = index === bins - 1 ? high : from + step;\n return (\n <span key={index} {...css.attrs(mapChartStyles.bin)}>\n <span\n {...css.attrs(\n mapChartStyles.swatch,\n mapChartStyles.swatchColor(colorOf((from + to) / 2)),\n )}\n />\n {numberText(from)} – {numberText(to)}\n </span>\n );\n })}\n </div>\n );\n }\n const stops =\n scheme === 'diverging'\n ? [colorOf(low), colors.fill, colorOf(high)]\n : [colorOf(low), colorOf(high)];\n return (\n <div {...css.attrs(mapChartStyles.legend)} aria-hidden=\"true\">\n <span>{numberText(low)}</span>\n <span\n {...css.attrs(\n mapChartStyles.ramp,\n mapChartStyles.rampColors(`linear-gradient(to right, ${stops.join(', ')})`),\n )}\n />\n <span>{numberText(high)}</span>\n </div>\n );\n }\n\n // 滚轮默认滚动页面,按住 Ctrl(或 ⌘、触控板捏合)才缩放地图(同 Google 地图的 cooperative 手势):\n // 否则滚动页面经过地图时会把地图缩小。拦下的滚轮在顶栏提示一下\n let wheelHint = _state(false);\n let hintTimer: ReturnType<typeof setTimeout> | undefined;\n useEventListener(\n () => (zoomable ? plot : null),\n 'wheel',\n (event) => {\n if (event.ctrlKey || event.metaKey) return;\n event.stopPropagation();\n wheelHint = true;\n clearTimeout(hintTimer);\n hintTimer = setTimeout(() => (wheelHint = false), 1500);\n },\n { capture: true },\n );\n _effect(() => () => clearTimeout(hintTimer));\n\n /** 缩放按钮:放大、缩小、复位;前面是滚轮的提示 */\n const zoomButtons = () => (\n <span {...css.attrs(mapChartStyles.zoom)}>\n {wheelHint && (\n <span {...css.attrs(mapChartStyles.wheelHint)} role=\"status\">\n {lang.chartZoomWheelHint}\n </span>\n )}\n {(\n [\n [Plus, lang.chartZoomIn, () => map?.zoomIn()],\n [Minus, lang.chartZoomOut, () => map?.zoomOut()],\n [Maximize, lang.chartZoomFit, () => map?.fitView()],\n ] as const\n ).map(([icon, label, action]) => (\n <IconButton\n key={label}\n icon={icon}\n size=\"sm\"\n variant=\"ghost\"\n tone=\"neutral\"\n aria-label={label}\n onClick={action}\n />\n ))}\n </span>\n );\n\n return () => (\n <ChartFrame\n {...rest}\n sx={[mapChartStyles.root, sx]}\n unit={unit}\n height={height}\n legend={[]}\n hiddenKeys={[]}\n onLegendToggle={() => {}}\n loading={loading}\n skeleton={<Skeleton sx={mapChartStyles.skeleton} />}\n isEmpty={false}\n empty={empty}\n actions={zoomable ? zoomButtons() : undefined}\n footer={legend()}\n table={{\n columns: [lang.chartCategory, unit ? `${lang.chartValue}(${unit})` : lang.chartValue],\n rows: [\n ...areas.map((area) => ({ header: area.label, value: area.value })),\n ...points.map((point) => ({ header: point.label, value: point.value })),\n ...links.map((link) => ({\n header: lang.chartFlowLabel(\n pointOf(link.from)?.label ?? link.from,\n pointOf(link.to)?.label ?? link.to,\n ),\n value: link.value,\n })),\n ].map((row) => ({\n header: row.header,\n cells: [\n row.value === undefined ? lang.emptyValue : format.number(row.value, valueFormat),\n ],\n })),\n }}\n plotRef={(element) => (plot = element)}\n />\n );\n },\n);\n"],"mappings":"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"}