@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":"WaterfallChart.js","names":["_vtp_readonlyProp","_vtp_restProps","_vue_computed","_createVNode","_mergeProps"],"sources":["../../src/charts/WaterfallChart.tsx"],"sourcesContent":["/**\n * 瀑布图:从起点出发,一步步加减到终点,看总数是怎么变过来的(测算两版之间各参数的影响、预算到实际的差异拆解)。\n *\n * <WaterfallChart\n * aria-label=\"V1 到 V2 的变化\"\n * steps={[\n * { label: 'V1 测算', value: 120, total: true },\n * { label: '材料单价', value: -18 },\n * { label: '工时', value: 6.5 },\n * { label: 'V2 测算', total: true },\n * ]}\n * unit=\"万元\"\n * />\n *\n * 每一步是 { label, value }:value 是这一步的变动(正数往上、负数往下),可以是 Decimal、bigint;\n * total: true 的是合计柱,从 0 画到当时的累计(写了 value 时以它为准,作为新的起点,如“V1 测算”)。\n * 往上的步用 success 色、往下的用 danger 色、合计用 chart1(increaseColor、decreaseColor、totalColor 可改:\n * 成本类的图里减少是好事时对调)。提示框与读屏的数据表列出变动与累计。\n * 坐标轴、目标线、下钻、加载与空状态同 BarChart(见 XYChart)。\n */\nimport { StackedBar } from '@unovis/ts';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { useLang } from '../config/context';\nimport { useFormat } from '../config/lang/format';\nimport { toNumber, type NumericValue } from '../utils/data/numeric';\nimport { useChartValueText } from './frame';\nimport { resolveColor, type ChartColor } from './series';\nimport { XYChart, type XYChartKind, type XYChartProps } from './XYChart';\n\n/** 瀑布图的一步 */\nexport interface WaterfallStep {\n /** 名称:类目轴的刻度 */\n label: string;\n /** 这一步的变动;合计柱写了时是新的累计(作为之后的起点) */\n value?: NumericValue;\n /** 合计柱:从 0 画到当时的累计 */\n total?: boolean;\n}\n\n/** 画图用的一行(waterfallRows 算出):柱子从 low 画到 high;跨过 0 的分成正负两段(Unovis 的堆叠正负分开叠) */\nexport interface WaterfallRow {\n /** 名称 */\n label: string;\n /** 这一步的种类:决定颜色 */\n kind: 'increase' | 'decrease' | 'total';\n /** 这一步的变动(原值,提示框与数据表按它格式化) */\n change: NumericValue | undefined;\n /** 这一步之后的累计 */\n cumulative: number;\n /** 透明的垫底:柱子悬在上一步的累计处 */\n base: number;\n /** 看得见的一段 */\n bar: number;\n /** 跨过 0 时负的那一段 */\n below: number;\n /** 柱子的下沿 */\n low: number;\n /** 柱子的上沿 */\n high: number;\n}\n\n/** 未声明的属性落到外层 div(role=\"figure\")上;aria-label 是图表的名称 */\nexport interface WaterfallChartProps extends Omit<\n XYChartProps<WaterfallRow>,\n 'data' | 'index' | 'series' | 'indexFormat' | 'legend' | 'hiddenSeries' | 'onItemClick'\n> {\n /** 各步:按顺序从左到右 */\n steps: readonly WaterfallStep[];\n /** 往上走的颜色,默认 success */\n increaseColor?: ChartColor;\n /** 往下走的颜色,默认 danger */\n decreaseColor?: ChartColor;\n /** 合计柱的颜色,默认 chart1 */\n totalColor?: ChartColor;\n /**\n * 柱子末端的圆角(px)\n * @default 2\n */\n radius?: number;\n /**\n * 数值轴从 0 起;false 时从接近最低的累计处起:合计很大、各步变动很小时变动也看得清\n * (合计柱被截短,读数看轴上的刻度)。写了 valueDomain 时以它为准\n * @default true\n */\n fromZero?: boolean;\n /** 点了一步(下钻):参数是这一步与它的位置;写了它时指针是手形 */\n onItemClick?: (step: WaterfallStep, index: number) => void;\n}\n\n/** 各步算成画图用的行:累计、每根柱子的上下沿 */\nexport function waterfallRows(steps: readonly WaterfallStep[]): WaterfallRow[] {\n let running = 0;\n return steps.map((step) => {\n const before = step.total ? 0 : running;\n if (step.total) running = step.value === undefined ? running : toNumber(step.value);\n else running += step.value === undefined ? 0 : toNumber(step.value);\n const [low, high] = before <= running ? [before, running] : [running, before];\n // 不跨 0:透明的一段垫到较近 0 的一端,看得见的一段补到另一端;跨 0:正负各一段,不垫底\n const crosses = low < 0 && high > 0;\n const base = crosses ? 0 : high <= 0 ? high : low;\n const bar = crosses ? high : high <= 0 ? low - high : high - low;\n return {\n label: step.label,\n kind: step.total ? 'total' : running >= before ? 'increase' : 'decrease',\n change: step.value,\n cumulative: running,\n base,\n bar,\n below: crosses ? low : 0,\n low,\n high,\n };\n });\n}\n\n/** 瀑布图 */\nexport const WaterfallChart = _component(\n ({\n steps,\n increaseColor,\n decreaseColor,\n totalColor,\n radius = 2,\n fromZero = true,\n onItemClick,\n ...rest\n }: WaterfallChartProps) => {\n const lang = useLang();\n const format = useFormat();\n const valueText = useChartValueText(() => ({ valueFormat: rest.valueFormat, unit: rest.unit }));\n const rows = _derived(waterfallRows(steps));\n const colorOf = (row: WaterfallRow) =>\n resolveColor(\n row.kind === 'total'\n ? (totalColor ?? 'chart1')\n : row.kind === 'increase'\n ? (increaseColor ?? 'success')\n : (decreaseColor ?? 'danger'),\n 0,\n );\n /** 变动:带正负号;suffix 时数值后面带单位(提示框) */\n const changeText = (row: WaterfallRow, suffix = false) =>\n row.change === undefined\n ? lang.emptyValue\n : format.number(row.change, {\n ...rest.valueFormat,\n signDisplay: 'exceptZero',\n ...(suffix && rest.unit ? { suffix: rest.unit } : {}),\n });\n const cumulativeText = (row: WaterfallRow) => format.number(row.cumulative, rest.valueFormat);\n\n const kind = _derived<XYChartKind<WaterfallRow>>({\n skeleton: 'bars',\n stacked: true,\n domainValues: (list) => list.flatMap((row) => [row.low, row.high]),\n itemSelector: StackedBar.selectors.bar,\n components: ({ x, instance, events }) => {\n const bars = instance('waterfall', () => new StackedBar<WaterfallRow>({ x, y: [] }));\n bars.setConfig({\n x,\n y: [(row) => row.base, (row) => row.bar, (row) => row.below],\n // 垫底的一段透明:看起来柱子悬在上一步的累计处\n color: (row: WaterfallRow, position: number) =>\n position === 0 ? 'transparent' : colorOf(row),\n roundedCorners: radius,\n barPadding: 0.3,\n barMaxWidth: 56,\n events,\n });\n return [bars];\n },\n tooltipItems: (row) => [\n {\n label: row.kind === 'total' ? lang.chartTotal : lang.chartChange,\n color: colorOf(row),\n value: row.kind === 'total' ? valueText(row.cumulative) : changeText(row, true),\n },\n ...(row.kind === 'total'\n ? []\n : [\n {\n label: lang.chartCumulative,\n color: 'transparent',\n value: valueText(row.cumulative),\n },\n ]),\n ],\n table: (list) => ({\n columns: [\n lang.chartCategory,\n rest.unit ? `${lang.chartChange}(${rest.unit})` : lang.chartChange,\n rest.unit ? `${lang.chartCumulative}(${rest.unit})` : lang.chartCumulative,\n ],\n rows: list.map((row) => ({\n header: row.label,\n cells: [row.kind === 'total' ? lang.emptyValue : changeText(row), cumulativeText(row)],\n })),\n }),\n });\n\n /**\n * 不从 0 起时轴的下沿:最低的累计再往下留出变动幅度的一半(没有变动时留出它的一成);\n * 有负的累计时仍按数据自动取,不截\n */\n const zoomedDomain = (): [number | undefined, undefined] => {\n const values = rows.flatMap((row) =>\n row.kind === 'total' ? [row.high] : [row.low, row.high],\n );\n const low = Math.min(...values);\n if (low <= 0) return [undefined, undefined];\n const span = Math.max(...values) - low || low * 0.1;\n return [Math.max(0, low - span * 0.5), undefined];\n };\n\n return () => (\n <XYChart<WaterfallRow>\n {...rest}\n valueDomain={\n rest.valueDomain ?? (fromZero || rows.length === 0 ? undefined : zoomedDomain())\n }\n data={rows}\n index=\"label\"\n // 系列只用来给十字线定位与算范围;画法、提示框、数据表由 kind 决定\n series={[{ key: 'bar', label: lang.chartChange }]}\n legend={false}\n kind={kind}\n onItemClick={onItemClick && ((_row, position) => onItemClick(steps[position]!, position))}\n />\n );\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"WaterfallChart.js","names":["_vtp_readonlyProp","_vtp_restProps","_vue_computed","_createVNode","_mergeProps"],"sources":["../../src/charts/WaterfallChart.tsx"],"sourcesContent":["/**\n * 瀑布图:从起点出发,一步步加减到终点,看总数是怎么变过来的(测算两版之间各参数的影响、预算到实际的差异拆解)。\n *\n * <WaterfallChart\n * aria-label=\"V1 到 V2 的变化\"\n * steps={[\n * { label: 'V1 测算', value: 120, total: true },\n * { label: '材料单价', value: -18 },\n * { label: '工时', value: 6.5 },\n * { label: 'V2 测算', total: true },\n * ]}\n * unit=\"万元\"\n * />\n *\n * 每一步是 { label, value }:value 是这一步的变动(正数往上、负数往下),可以是 Decimal、bigint;\n * total: true 的是合计柱,从 0 画到当时的累计(写了 value 时以它为准,作为新的起点,如“V1 测算”)。\n * 往上的步用 success 色、往下的用 danger 色、合计用 chart1(increaseColor、decreaseColor、totalColor 可改:\n * 成本类的图里减少是好事时对调)。提示框与读屏的数据表列出变动与累计。\n * 坐标轴、目标线、下钻、加载与空状态同 BarChart(见 XYChart)。\n */\nimport { StackedBar } from '@unovis/ts';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { useLang } from '../config/context';\nimport { useFormat } from '../config/lang/format';\nimport { toNumber, type NumericValue } from '../utils/data/numeric';\nimport { useChartValueText } from './frame';\nimport { resolveColor, type ChartColor } from './series';\nimport { XYChart, type XYChartKind, type XYChartProps } from './XYChart';\n\n/** 瀑布图的一步 */\nexport interface WaterfallStep {\n /** 名称:类目轴的刻度 */\n label: string;\n /** 这一步的变动;合计柱写了时是新的累计(作为之后的起点) */\n value?: NumericValue;\n /** 合计柱:从 0 画到当时的累计 */\n total?: boolean;\n}\n\n/** 画图用的一行(waterfallRows 算出):柱子从 low 画到 high;跨过 0 的分成正负两段(Unovis 的堆叠正负分开叠) */\nexport interface WaterfallRow {\n /** 名称 */\n label: string;\n /** 这一步的种类:决定颜色 */\n kind: 'increase' | 'decrease' | 'total';\n /** 这一步的变动(原值,提示框与数据表按它格式化) */\n change: NumericValue | undefined;\n /** 这一步之后的累计 */\n cumulative: number;\n /** 透明的垫底:柱子悬在上一步的累计处 */\n base: number;\n /** 看得见的一段 */\n bar: number;\n /** 跨过 0 时负的那一段 */\n below: number;\n /** 柱子的下沿 */\n low: number;\n /** 柱子的上沿 */\n high: number;\n}\n\n/** 未声明的属性落到外层 div(role=\"figure\")上;aria-label 是图表的名称 */\nexport interface WaterfallChartProps extends Omit<\n XYChartProps<WaterfallRow>,\n 'data' | 'index' | 'series' | 'indexFormat' | 'legend' | 'hiddenSeries' | 'onItemClick'\n> {\n /** 各步:按顺序从左到右 */\n steps: readonly WaterfallStep[];\n /** 往上走的颜色,默认 success */\n increaseColor?: ChartColor;\n /** 往下走的颜色,默认 danger */\n decreaseColor?: ChartColor;\n /** 合计柱的颜色,默认 chart1 */\n totalColor?: ChartColor;\n /**\n * 柱子末端的圆角(px)\n * @default 2\n */\n radius?: number;\n /**\n * 数值轴从 0 起;false 时从接近最低的累计处起:合计很大、各步变动很小时变动也看得清\n * (合计柱被截短,读数看轴上的刻度)。写了 valueDomain 时以它为准\n * @default true\n */\n fromZero?: boolean;\n /** 点了一步(下钻):参数是这一步与它的位置;写了它时指针是手形 */\n onItemClick?: (step: WaterfallStep, index: number) => void;\n}\n\n/** 各步算成画图用的行:累计、每根柱子的上下沿 */\nexport function waterfallRows(steps: readonly WaterfallStep[]): WaterfallRow[] {\n let running = 0;\n return steps.map((step) => {\n const before = step.total ? 0 : running;\n if (step.total) running = step.value === undefined ? running : toNumber(step.value);\n else running += step.value === undefined ? 0 : toNumber(step.value);\n const [low, high] = before <= running ? [before, running] : [running, before];\n // 不跨 0:透明的一段垫到较近 0 的一端,看得见的一段补到另一端;跨 0:正负各一段,不垫底\n const crosses = low < 0 && high > 0;\n const base = crosses ? 0 : high <= 0 ? high : low;\n const bar = crosses ? high : high <= 0 ? low - high : high - low;\n return {\n label: step.label,\n kind: step.total ? 'total' : running >= before ? 'increase' : 'decrease',\n change: step.value,\n cumulative: running,\n base,\n bar,\n below: crosses ? low : 0,\n low,\n high,\n };\n });\n}\n\n/** 瀑布图 */\nexport const WaterfallChart = _component(\n ({\n steps,\n increaseColor,\n decreaseColor,\n totalColor,\n radius = 2,\n fromZero = true,\n onItemClick,\n ...rest\n }: WaterfallChartProps) => {\n const lang = useLang();\n const format = useFormat();\n const valueText = useChartValueText(() => ({ valueFormat: rest.valueFormat, unit: rest.unit }));\n const rows = _derived(waterfallRows(steps));\n const colorOf = (row: WaterfallRow) =>\n resolveColor(\n row.kind === 'total'\n ? (totalColor ?? 'chart1')\n : row.kind === 'increase'\n ? (increaseColor ?? 'success')\n : (decreaseColor ?? 'danger'),\n 0,\n );\n /** 变动:带正负号;suffix 时数值后面带单位(提示框) */\n const changeText = (row: WaterfallRow, suffix = false) =>\n row.change === undefined\n ? lang.emptyValue\n : format.number(row.change, {\n ...rest.valueFormat,\n signDisplay: 'exceptZero',\n ...(suffix && rest.unit ? { suffix: rest.unit } : {}),\n });\n const cumulativeText = (row: WaterfallRow) => format.number(row.cumulative, rest.valueFormat);\n\n const kind = _derived<XYChartKind<WaterfallRow>>({\n skeleton: 'bars',\n stacked: true,\n domainValues: (list) => list.flatMap((row) => [row.low, row.high]),\n itemSelector: StackedBar.selectors.bar,\n components: ({ x, instance, events }) => {\n const bars = instance('waterfall', () => new StackedBar<WaterfallRow>({ x, y: [] }));\n bars.setConfig({\n x,\n y: [(row) => row.base, (row) => row.bar, (row) => row.below],\n // 垫底的一段透明:看起来柱子悬在上一步的累计处\n color: (row: WaterfallRow, position: number) =>\n position === 0 ? 'transparent' : colorOf(row),\n roundedCorners: radius,\n barPadding: 0.3,\n barMaxWidth: 56,\n events,\n });\n return [bars];\n },\n tooltipItems: (row) => [\n {\n label: row.kind === 'total' ? lang.chartTotal : lang.chartChange,\n color: colorOf(row),\n value: row.kind === 'total' ? valueText(row.cumulative) : changeText(row, true),\n },\n ...(row.kind === 'total'\n ? []\n : [\n {\n label: lang.chartCumulative,\n color: 'transparent',\n value: valueText(row.cumulative),\n },\n ]),\n ],\n table: (list) => ({\n columns: [\n lang.chartCategory,\n rest.unit ? `${lang.chartChange}(${rest.unit})` : lang.chartChange,\n rest.unit ? `${lang.chartCumulative}(${rest.unit})` : lang.chartCumulative,\n ],\n rows: list.map((row) => ({\n header: row.label,\n cells: [row.kind === 'total' ? lang.emptyValue : changeText(row), cumulativeText(row)],\n })),\n }),\n });\n\n /**\n * 不从 0 起时轴的下沿:最低的累计再往下留出变动幅度的一半(没有变动时留出它的一成);\n * 有负的累计时仍按数据自动取,不截\n */\n const zoomedDomain = (): [number | undefined, undefined] => {\n const values = rows.flatMap((row) =>\n row.kind === 'total' ? [row.high] : [row.low, row.high],\n );\n const low = Math.min(...values);\n if (low <= 0) return [undefined, undefined];\n const span = Math.max(...values) - low || low * 0.1;\n return [Math.max(0, low - span * 0.5), undefined];\n };\n\n return () => (\n <XYChart<WaterfallRow>\n {...rest}\n valueDomain={\n rest.valueDomain ?? (fromZero || rows.length === 0 ? undefined : zoomedDomain())\n }\n data={rows}\n index=\"label\"\n // 系列只用来给十字线定位与算范围;画法、提示框、数据表由 kind 决定\n series={[{ key: 'bar', label: lang.chartChange }]}\n legend={false}\n kind={kind}\n onItemClick={onItemClick && ((_row, position) => onItemClick(steps[position]!, position))}\n />\n );\n },\n);\n"],"mappings":"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"}
@@ -4,12 +4,13 @@ import { useLang } from "../config/context.js";
4
4
  import { Button } from "../base/Button.js";
5
5
  import { useFormat } from "../config/lang/format.js";
6
6
  import { Skeleton } from "../feedback/Skeleton.js";
7
+ import { useDetachedRender } from "../overlay/detached.js";
7
8
  import { Slider } from "../input/Slider.js";
8
9
  import { alignedTicks } from "./axis-ticks.js";
9
10
  import { ChartFrame, chartDuration, chartTooltip, createChartInstances, uniqueHighlightFilter, useChartValueText, usePlotSeen } from "./frame.js";
10
11
  import { resolveColor, resolveSeries, seriesNumber, seriesValue } from "./series.js";
11
- import { computed, createVNode, mergeProps, render, shallowRef, useId } from "vue";
12
- import { _component, bindable, effect, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
12
+ import { computed, createVNode, shallowRef, useId } from "vue";
13
+ import { _component, bindable, effect, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
13
14
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
14
15
  import { Axis, AxisType, Crosshair, Plotband, PlotbandLabelPosition, Plotline, PlotlineLabelPosition, PlotlineLineStylePresets, Position, Scatter, Tooltip, XYContainer } from "@unovis/ts";
15
16
  //#region src/charts/XYChart.tsx
@@ -88,7 +89,7 @@ var xyChartStyles = css.create({
88
89
  /** 加载中绘图区的骨架:柱状图是一排高低不一的柱(横向时是条),其余是一整块 */
89
90
  function chartSkeleton({ skeleton = "block", horizontal = false }) {
90
91
  if (skeleton === "block") return createVNode(Skeleton, { "sx": xyChartStyles.skeleton }, null);
91
- return createVNode("div", mergeProps({ "aria-hidden": "true" }, css.attrs(xyChartStyles.skeletonBars, horizontal && xyChartStyles.skeletonBarsHorizontal)), [SKELETON_BARS.map((percent, position) => createVNode(Skeleton, {
92
+ return createVNode("div", mergeJsxProps({ "aria-hidden": "true" }, css.attrs(xyChartStyles.skeletonBars, horizontal && xyChartStyles.skeletonBarsHorizontal)), [SKELETON_BARS.map((percent, position) => createVNode(Skeleton, {
92
93
  "key": position,
93
94
  "sx": [xyChartStyles.skeletonBar, horizontal ? xyChartStyles.skeletonBarSizeHorizontal(`${percent}%`) : xyChartStyles.skeletonBarSize(`${percent}%`)]
94
95
  }, null))]);
@@ -165,7 +166,8 @@ var XYChart = /*#__PURE__*/ _component((_props, _ctx) => {
165
166
  }, null), zoomRange.value && createVNode(Button, {
166
167
  "variant": "link",
167
168
  "size": "sm",
168
- "onClick": _cache[2] || (_cache[2] = () => zoomRange.value = null)
169
+ "onClick": _cache[2] || (_cache[2] = () => zoomRange.value = null),
170
+ "key": "__site0"
169
171
  }, {
170
172
  default: () => [lang.chartZoomReset],
171
173
  $stable: true
@@ -173,6 +175,7 @@ var XYChart = /*#__PURE__*/ _component((_props, _ctx) => {
173
175
  };
174
176
  const instances = createChartInstances();
175
177
  let tooltipElement;
178
+ const renderDetached = useDetachedRender();
176
179
  let hovered = null;
177
180
  const hover = (row) => {
178
181
  hovered = row === void 0 ? null : {
@@ -184,7 +187,7 @@ var XYChart = /*#__PURE__*/ _component((_props, _ctx) => {
184
187
  function renderTooltip(row) {
185
188
  tooltipElement ??= document.createElement("div");
186
189
  if (kind.value.pointTooltip) hover(row);
187
- render(chartTooltip(categoryText(row), kind.value.tooltipItems?.(row) ?? [...kind.value.continuousX ? [{
190
+ renderDetached(chartTooltip(categoryText(row), kind.value.tooltipItems?.(row) ?? [...kind.value.continuousX ? [{
188
191
  label: kind.value.continuousX.label,
189
192
  color: "transparent",
190
193
  value: xText(row)
@@ -205,7 +208,6 @@ var XYChart = /*#__PURE__*/ _component((_props, _ctx) => {
205
208
  let containerElement;
206
209
  effect(() => () => {
207
210
  container?.destroy();
208
- if (tooltipElement) render(null, tooltipElement);
209
211
  });
210
212
  effect(() => {
211
213
  const range = zoom.value && !kind.value.continuousX ? zoomRange.value : null;
@@ -437,7 +439,7 @@ var XYChart = /*#__PURE__*/ _component((_props, _ctx) => {
437
439
  uniqueHighlightFilter(element, `${id}-highlight`);
438
440
  }
439
441
  });
440
- return () => createVNode(ChartFrame, mergeProps(rest, {
442
+ return () => createVNode(ChartFrame, mergeJsxProps(rest, {
441
443
  "sx": [css.select(() => !kind.value.crosshairDots && xyChartStyles.hideCrosshairLine, true), sx.value],
442
444
  "unit": kind.value.percent ? void 0 : unit.value,
443
445
  "unitEnd": kind.value.secondary?.unit,
@@ -1 +1 @@
1
- {"version":3,"file":"XYChart.js","names":["_createVNode","_mergeProps","_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_computed","_vue_shallowRef"],"sources":["../../src/charts/XYChart.tsx"],"sourcesContent":["/**\n * 直角坐标图表(柱状图、折线图、面积图)的公共部分:坐标轴、十字线与提示框、数值范围;外层结构(图例、单位、\n * 空与加载状态、给读屏的数据表)交给 ChartFrame。\n * 绘图交给 Unovis 的 XYContainer:组件实例只建一次,数据与配置变化时 update,卸载时 destroy;\n * 绘图区换了元素(加载、空状态之后重新出现)时容器连同全部实例一起重建。\n * 各种图只决定画什么(kind.components),坐标轴、十字线、提示框、配色都在这里统一。\n * 目标线(targets)用 Unovis 的 Plotline。点了下钻(onItemClick):有图形可点的图(柱子)按图形的点击事件\n * (kind.itemSelector),折线、面积图按十字线所在的那一行,散点图按悬停的点。\n *\n * 标注(annotations):类目上的事件画成竖线(Plotline),圈出某个系列的值画成空心圈带文字(Scatter);\n * 区间(bands)画成浅色的带(Plotband)。百分比堆叠(kind.percent)按每个类目里各系列的占比画。\n * 第二数值轴(kind.secondary,组合图):刻度与主轴对齐(alignedTicks),第二轴的系列换算到主轴的坐标里画,\n * 右侧的刻度文字是不裁剪的 Plotline 标签。\n */\nimport {\n Axis,\n AxisType,\n Crosshair,\n Plotband,\n PlotbandLabelPosition,\n Plotline,\n PlotlineLabelPosition,\n PlotlineLineStylePresets,\n Position,\n Scatter,\n Tooltip,\n XYContainer,\n type XYComponentCore,\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 { render, useId, type VNodeChild } from 'vue';\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 { Button } from '../base/Button';\nimport { Slider } from '../input/Slider';\nimport { alignedTicks, type AlignedAxes } from './axis-ticks';\nimport { toNumber, type NumericValue } from '../utils/data/numeric';\nimport type { PartProps } from '../utils/props';\nimport {\n ChartFrame,\n chartDuration,\n chartTooltip,\n createChartInstances,\n uniqueHighlightFilter,\n useChartValueText,\n usePlotSeen,\n type ChartFrameParts,\n type ChartTable,\n type ChartTooltipItem,\n} from './frame';\nimport {\n resolveColor,\n resolveSeries,\n seriesNumber,\n seriesValue,\n type ChartColor,\n type ChartSeries,\n type ResolvedSeries,\n} from './series';\n\n/** 目标线(参考线):数值轴上的一条虚线 */\nexport interface ChartTarget {\n /** 位置:数值轴上的值 */\n value: NumericValue;\n /** 标签:写在线的一端,后面带上格式化的数值(“年度指标 1,200”) */\n label?: string;\n /** 颜色;默认是 danger(要够到的线) */\n color?: ChartColor;\n}\n\n/** 标注:类目上发生的事(竖线),或圈出某个系列在这个类目上的值 */\nexport interface ChartAnnotation {\n /** 标在哪个类目上:index 字段的值(散点图是横轴上的数值) */\n at: unknown;\n /** 文字 */\n label: string;\n /** 圈出这个系列在这里的值(系列的 key);不写时是一条竖线(换供应商、调价生效这类事件) */\n series?: string;\n /** 颜色;竖线默认是次要色,圈默认是系列色 */\n color?: ChartColor;\n}\n\n/** 区间:类目轴上的一段(试运行期、促销期),或数值轴上的一段(目标区间) */\nexport interface ChartBand {\n /** 在哪条轴上,默认 index(类目轴) */\n axis?: 'index' | 'value';\n /** 起点:类目轴是 index 字段的值(含这一项),数值轴是数值 */\n from: unknown;\n /** 终点:同 from(含这一项) */\n to: unknown;\n /** 文字:类目轴上的写在带的左下角,数值轴上的写在左上角 */\n label?: string;\n /** 颜色,默认 neutral;画成很浅的底色 */\n color?: ChartColor;\n}\n\n/** 第二数值轴(右侧):哪些系列画在它上面,它的格式与单位 */\nexport interface ChartSecondaryAxis {\n /** 画在第二数值轴上的系列 */\n keys: readonly string[];\n /** 数值的格式 */\n format?: NumericFormat;\n /** 单位:显示在右上方,提示框与数据表的数值后面带上 */\n unit?: string;\n}\n\n/** 加载中的骨架 */\nexport interface ChartSkeletons {\n /** 一排高低不一的柱(柱状图) */\n bars: unknown;\n /** 一整块(默认) */\n block: unknown;\n}\n\n/** 直角坐标图表共有的属性;未声明的属性落到外层 div(role=\"figure\")上,aria-label 是图表的名称 */\nexport interface XYChartProps<T extends object>\n extends PartProps<'div', 'role' | 'aria-busy'>, ChartFrameParts {\n /** 数据:每一行是类目轴上的一项(一个月、一个项目) */\n data: readonly T[];\n /** 类目字段:类目轴的刻度、提示框的标题、数据表的第一列 */\n index: keyof T & string;\n /** 系列:每个系列画成一组柱子、一条线或一片面积 */\n series: readonly ChartSeries<T>[];\n /** 类目的显示文字;不写时把字段的值转成字符串 */\n indexFormat?: (value: T[keyof T & string], row: T) => string;\n /**\n * 数值的格式:数值轴、提示框、数据表共用,按当前语言格式化。以万元为单位画金额时写\n * `{ scale: 10_000, maximumFractionDigits: 1 }` 并配 `unit=\"万元\"`\n */\n valueFormat?: NumericFormat;\n /** 单位:显示在数值轴上方,提示框与数据表的数值后面带上 */\n unit?: string;\n /**\n * 绘图区的高度;数字按 px\n * @default 240\n */\n height?: number | string;\n /** 图例:默认多于一个系列时显示;点图例可以隐藏、恢复系列 */\n legend?: boolean;\n /**\n * 数值轴的网格线\n * @default true\n */\n grid?: boolean;\n /** 数值轴的范围 [最小, 最大];不写的一端按数据自动取,最小值默认从 0 起(数据有负数时取负数) */\n valueDomain?: readonly [number | undefined, number | undefined];\n /**\n * 悬停时的提示框\n * @default true\n */\n tooltip?: boolean;\n /**\n * 加载中:绘图区显示扫光的骨架(柱状图是一排高低不一的柱),带 aria-busy\n * @default false\n */\n loading?: boolean;\n /** 隐藏的系列(存系列的 key):点图例时写回,父级可以写 _hiddenSeries={keys} */\n _hiddenSeries?: string[];\n /** 没有数据时显示的内容,默认是“暂无数据” */\n empty?: VNodeChild;\n /** 目标线、参考线:数值轴上的虚线(横向图是竖线),如年度销售指标;数值轴的范围会包含它 */\n targets?: readonly ChartTarget[];\n /** 标注:类目上的事件(竖线),或圈出某个系列的值(横向图只画竖线) */\n annotations?: readonly ChartAnnotation[];\n /** 区间:类目轴或数值轴上的一段,画成浅色的带(数值轴的范围会包含它) */\n bands?: readonly ChartBand[];\n /**\n * 点了一个类目(下钻,如跳到筛好条件的台账):参数是这一行与它的位置;写了它时绘图区的指针是手形。\n * 点图是鼠标的捷径:同样的去处在页面上还要有链接或按钮,键盘与读屏才到得了(WCAG 2.1.1)\n */\n onItemClick?: (row: T, index: number) => void;\n /** 缩放:绘图区下面一条区间滑块,选一段类目放大看(几年的月度数据);读屏的数据表仍是全部 */\n zoom?: boolean;\n /** 缩放的区间 [起, 止]:类目的位置,含两端;父级可以写 _zoomRange={range},null 是全部 */\n _zoomRange?: [number, number] | null;\n}\n\n/** 交给各种图的绘制上下文 */\nexport interface XYChartContext<T extends object> {\n /** 显示中的系列(去掉了图例里隐藏的),颜色已定 */\n series: ResolvedSeries<T>[];\n /** 类目的位置:第几行 */\n x: (row: T, index: number) => number;\n /** 系列的取值函数,空值返回 undefined(Unovis 跳过) */\n y: (series: ResolvedSeries<T>) => (row: T) => number | undefined;\n /** 取一个跨渲染保留的组件实例:第一次调用时创建;Unovis 组件保留实例,更新时才有过渡动画 */\n instance: <C>(key: string, create: () => C) => C;\n /** 点图形下钻的事件(写了 itemSelector 时):并进组件的 events;没有 onItemClick 时是空的。参数同 Unovis:图形的数据、事件、位置 */\n events: Record<string, Record<string, (row: T, event: Event, index: number) => void>>;\n}\n\n/** 一种图:画哪些组件,以及与坐标轴、十字线有关的差别 */\nexport interface XYChartKind<T extends object> {\n /** 配置并返回要画的 Unovis 组件(每次数据或属性变化都会调用) */\n components: (context: XYChartContext<T>) => XYComponentCore<T>[];\n /** 横向:类目在纵轴、数值在横轴 */\n horizontal?: boolean;\n /** 十字线上给每个系列画圆点(折线图、面积图);柱状图不画 */\n crosshairDots?: boolean;\n /** 加载中的骨架,默认 block */\n skeleton?: keyof ChartSkeletons;\n /** 绘图区四周的留白(px):折线两端不贴着边缘 */\n padding?: { left?: number; right?: number; top?: number; bottom?: number };\n /** 数值范围按堆叠后的总和算(堆叠的柱子、面积) */\n stacked?: boolean;\n /** 百分比堆叠:各系列按它在这个类目里的占比画(加起来 100%),数值轴是百分比,提示框带上占比 */\n percent?: boolean;\n /** 第二数值轴(组合图):这些系列画在右侧的轴上,刻度与主轴对齐 */\n secondary?: ChartSecondaryAxis;\n /** 十字线只在这些系列上画圆点(组合图里只给线画);不写时按 crosshairDots */\n crosshairSeries?: (series: ResolvedSeries<T>) => boolean;\n /** 横轴是连续的数值(散点图):取值、刻度与提示框里的写法、数据表的列名、轴下方的标题;不写时横轴是类目(第几行) */\n continuousX?: {\n value: (row: T) => number | undefined;\n format: (value: number) => string;\n label: string;\n title?: string;\n };\n /** 数值轴默认从 0 起(数据有负数时取负数);false 时按数据自动取(散点图) */\n zeroBaseline?: boolean;\n /** 提示框跟着数据点(散点图),没有十字线:按选择器触发,悬停的数据是这一行 */\n pointTooltip?: string;\n /** 提示框里列的项;不写时每个显示中的系列一行(瀑布图列变动与累计) */\n tooltipItems?: (row: T) => ChartTooltipItem[];\n /** 数值轴(主轴)的范围要包含的值;shown 是显示中的系列(第二数值轴的已去掉)。不写时按系列的值(stacked 时按正负各自的总和) */\n domainValues?: (rows: readonly T[], shown: readonly ResolvedSeries<T>[]) => number[];\n /** 给读屏的数据表;不写时类目一列加每个系列一列 */\n table?: (rows: readonly T[]) => ChartTable;\n /** 点哪种图形算点了这一行(柱子的选择器,图形绑定的数据是这一行);不写时按十字线所在的那一行 */\n itemSelector?: string;\n}\n\n/** 第二数值轴的刻度文字占的宽度(px) */\nconst SECONDARY_AXIS_WIDTH = 48;\n\n/** 骨架柱的高度(百分比):高低错落,看起来像一组数据 */\nconst SKELETON_BARS = [55, 80, 40, 70, 90, 50, 65];\n\n/** XYChart 的样式:hideCrosshairLine 与加载中的骨架(外层结构的样式见 chartStyles) */\nexport const xyChartStyles = css.create({\n // 柱状图的十字线只用来定位提示框,不画竖线\n hideCrosshairLine: { '--vis-crosshair-line-stroke-opacity': '0' },\n skeleton: { display: 'block', width: '100%', height: '100%' },\n // 缩放:滑块占满,“显示全部”在结束边\n zoom: { display: 'flex', alignItems: 'center', gap: '_md', paddingInline: '_sm' },\n zoomSlider: { flexGrow: 1, minWidth: 0 },\n skeletonBars: {\n display: 'flex',\n alignItems: 'flex-end',\n justifyContent: 'space-around',\n gap: '_md',\n height: '100%',\n },\n skeletonBarsHorizontal: { flexDirection: 'column', alignItems: 'flex-start' },\n skeletonBar: { display: 'block', flexGrow: 1, flexBasis: 0, borderRadius: '_sm' },\n skeletonBarSize: (percent: string) => ({ height: percent }),\n skeletonBarSizeHorizontal: (percent: string) => ({ width: percent }),\n});\n\n/** 加载中绘图区的骨架:柱状图是一排高低不一的柱(横向时是条),其余是一整块 */\nfunction chartSkeleton({\n skeleton = 'block',\n horizontal = false,\n}: Pick<XYChartKind<object>, 'skeleton' | 'horizontal'>) {\n if (skeleton === 'block') return <Skeleton sx={xyChartStyles.skeleton} />;\n return (\n <div\n aria-hidden=\"true\"\n {...css.attrs(xyChartStyles.skeletonBars, horizontal && xyChartStyles.skeletonBarsHorizontal)}\n >\n {SKELETON_BARS.map((percent, position) => (\n <Skeleton\n key={position}\n sx={[\n xyChartStyles.skeletonBar,\n horizontal\n ? xyChartStyles.skeletonBarSizeHorizontal(`${percent}%`)\n : xyChartStyles.skeletonBarSize(`${percent}%`),\n ]}\n />\n ))}\n </div>\n );\n}\n\n/** 直角坐标图表的公共实现(组件库内部用,见 BarChart、LineChart、AreaChart) */\nexport const XYChart = _component(\n <T extends object>({\n data,\n index,\n series,\n indexFormat,\n valueFormat,\n unit,\n height = 240,\n legend,\n grid = true,\n valueDomain,\n tooltip = true,\n loading = false,\n _hiddenSeries: hiddenSeries = _bindable<string[]>([]),\n empty,\n targets,\n annotations,\n bands,\n onItemClick,\n zoom = false,\n _zoomRange: zoomRange = _bindable<[number, number] | null>(null),\n kind,\n sx,\n ...rest\n }: XYChartProps<T> & { kind: XYChartKind<T> }) => {\n const lang = useLang();\n const format = useFormat();\n const id = useId();\n const resolved = _derived(resolveSeries(series));\n const visible = _derived(resolved.filter((item) => !hiddenSeries.includes(item.key)));\n\n const categoryText = (row: T | undefined) =>\n row === undefined\n ? ''\n : indexFormat\n ? indexFormat(row[index], row)\n : String(row[index] ?? '');\n const valueText = useChartValueText(() => ({ valueFormat, unit }));\n const secondaryText = useChartValueText(() => ({\n valueFormat: kind.secondary?.format,\n unit: kind.secondary?.unit,\n }));\n const onSecondary = (key: string) => kind.secondary?.keys.includes(key) ?? false;\n /** 一个系列的值的文字:第二数值轴上的按它的格式与单位 */\n const seriesText = (key: string, value: NumericValue | undefined) =>\n onSecondary(key) ? secondaryText(value) : valueText(value);\n /** 一行里显示中的系列的总和(百分比堆叠的分母;负数不计) */\n const rowTotal = (row: T) =>\n visible.reduce((sum, item) => sum + Math.max(seriesNumber(row, item.key) ?? 0, 0), 0);\n const percentText = (value: number) =>\n format.number(value, { style: 'percent', maximumFractionDigits: 1 });\n\n const xText = (row: T) => {\n const x = kind.continuousX?.value(row);\n return x === undefined ? lang.emptyValue : kind.continuousX!.format(x);\n };\n\n function toggle(key: string) {\n hiddenSeries = hiddenSeries.includes(key)\n ? hiddenSeries.filter((item) => item !== key)\n : [...hiddenSeries, key];\n }\n\n /** 缩放的滑块:两端是类目;缩小过时旁边有“显示全部” */\n const zoomBar = () => {\n const last = data.length - 1;\n return (\n <div {...css.attrs(xyChartStyles.zoom)}>\n <Slider\n _value={zoomRange ?? [0, last]}\n onUpdate:_value={(next: [number, number]) =>\n (zoomRange = next[0] === 0 && next[1] === last ? null : next)\n }\n min={0}\n max={last}\n step={1}\n size=\"sm\"\n valueText={(position) => categoryText(data[position])}\n aria-label={lang.chartZoom}\n propsRoot={{ sx: xyChartStyles.zoomSlider }}\n />\n {zoomRange && (\n <Button variant=\"link\" size=\"sm\" onClick={() => (zoomRange = null)}>\n {lang.chartZoomReset}\n </Button>\n )}\n </div>\n );\n };\n\n const instances = createChartInstances();\n let tooltipElement: HTMLElement | undefined;\n\n // 指针所在的那一行:十字线移动时记下,点绘图区时下钻到它;离开绘图区时清掉\n let hovered: { row: T; index: number } | null = null;\n const hover = (row: T | undefined) => {\n hovered = row === undefined ? null : { row, index: data.indexOf(row) };\n };\n\n /** 十字线的提示框:内容用 Vue 渲染进同一个元素,交给 Unovis 定位 */\n function renderTooltip(row: T) {\n tooltipElement ??= document.createElement('div');\n // 跟着数据点的提示框(散点图)没有十字线:悬停哪个点就是哪一行\n if (kind.pointTooltip) hover(row);\n render(\n chartTooltip(\n categoryText(row),\n kind.tooltipItems?.(row) ?? [\n ...(kind.continuousX\n ? [{ label: kind.continuousX.label, color: 'transparent', value: xText(row) }]\n : []),\n // 跟着数据点的提示框只列这一行有值的系列(散点图里一行通常只落在一个系列上)\n ...visible\n .filter((item) => !kind.pointTooltip || seriesValue(row, item.key) !== undefined)\n .map((item) => {\n const value = seriesValue(row, item.key);\n const total = kind.percent ? rowTotal(row) : 0;\n return {\n label: item.label,\n color: item.color,\n value:\n kind.percent && value !== undefined && total > 0\n ? `${seriesText(item.key, value)}(${percentText(toNumber(value) / total)})`\n : seriesText(item.key, value),\n };\n }),\n ],\n ),\n tooltipElement,\n );\n return tooltipElement;\n }\n\n let plot = _state.raw<HTMLElement | null>(null);\n const seen = usePlotSeen(() => plot);\n let container: XYContainer<T> | undefined;\n let containerElement: HTMLElement | undefined;\n _effect(() => () => {\n container?.destroy();\n if (tooltipElement) render(null, tooltipElement);\n });\n _effect(() => {\n // 缩放:只画选中的一段(散点图的横轴是连续的数值,不按类目缩放)\n const range = zoom && !kind.continuousX ? zoomRange : null;\n const rows = range ? data.slice(range[0], range[1] + 1) : [...data];\n const shown = visible;\n const element = plot;\n if (!element || loading || rows.length === 0 || !seen()) return;\n // 绘图区换了元素:旧容器连同它的组件、坐标轴一起销毁,实例表清空后重新创建\n if (container && containerElement !== element) {\n container.destroy();\n container = undefined;\n instances.reset();\n }\n\n const primarySeries = shown.filter((item) => !onSecondary(item.key));\n const secondarySeries = shown.filter((item) => onSecondary(item.key));\n const totals = rows.map((row) =>\n primarySeries.map((item) => seriesNumber(row, item.key) ?? 0),\n );\n const seriesValues = kind.domainValues\n ? kind.domainValues(rows, primarySeries)\n : kind.stacked\n ? totals.flatMap((row) => [\n row.reduce((sum, value) => sum + Math.max(value, 0), 0),\n row.reduce((sum, value) => sum + Math.min(value, 0), 0),\n ])\n : totals.flat();\n // 目标线、数值轴上的区间要落在数值轴的范围里\n const values = [\n ...seriesValues,\n ...(targets ?? []).map((target) => toNumber(target.value)),\n ...(bands ?? [])\n .filter((band) => band.axis === 'value')\n .flatMap((band) => [Number(band.from), Number(band.to)]),\n ];\n // 第二数值轴:两条轴的刻度对齐,第二轴的值换算到主轴的坐标\n const aligned: AlignedAxes | undefined =\n secondarySeries.length > 0\n ? alignedTicks(\n [\n ...values,\n ...[valueDomain?.[0], valueDomain?.[1]].filter(\n (end): end is number => end !== undefined,\n ),\n ],\n rows.flatMap((row) =>\n secondarySeries.map((item) => seriesNumber(row, item.key) ?? 0),\n ),\n )\n : undefined;\n const domain: [number | undefined, number | undefined] = kind.percent\n ? [0, 1]\n : aligned\n ? aligned.primary.domain\n : [\n valueDomain?.[0] ??\n (kind.zeroBaseline === false ? undefined : Math.min(0, ...values)),\n valueDomain?.[1],\n ];\n const x = kind.continuousX\n ? (row: T) => kind.continuousX!.value(row) ?? Number.NaN\n : (_row: T, position: number) => position;\n const y = (item: (typeof shown)[number]) => {\n if (kind.percent)\n return (row: T) => {\n const value = seriesNumber(row, item.key);\n const total = rowTotal(row);\n return value === undefined || total === 0 ? undefined : value / total;\n };\n if (aligned && onSecondary(item.key))\n return (row: T) => {\n const value = seriesNumber(row, item.key);\n return value === undefined ? undefined : aligned.toPrimary(value);\n };\n return (row: T) => seriesNumber(row, item.key);\n };\n /** 类目在类目轴上的位置:散点图是横轴的数值,其余是第几行;找不到时 undefined */\n const positionOf = (at: unknown) => {\n if (kind.continuousX) return Number(at);\n const found = rows.findIndex((row) => row[index] === at);\n return found < 0 ? undefined : found;\n };\n const categoryAxisName = kind.horizontal ? AxisType.Y : AxisType.X;\n const valueAxisName = kind.horizontal ? AxisType.X : AxisType.Y;\n const lines = (targets ?? []).map((target, position) => {\n const line = instances.get(`target-${position}`, () => new Plotline<T>({}));\n const value = toNumber(target.value);\n const label = valueText(target.value);\n line.setConfig({\n axis: kind.horizontal ? 'x' : 'y',\n value,\n color: resolveColor(target.color ?? 'danger', 0),\n lineWidth: 1.5,\n lineStyle: PlotlineLineStylePresets.Dash,\n labelText: target.label ? `${target.label} ${label}` : label,\n labelPosition: kind.horizontal\n ? PlotlineLabelPosition.TopRight\n : PlotlineLabelPosition.TopLeft,\n labelOffsetX: 4,\n labelOffsetY: 10,\n });\n return line;\n });\n\n // 区间:浅色的带,文字在左上角\n const bandComponents = (bands ?? []).flatMap((band, position) => {\n const onIndex = band.axis !== 'value';\n const from = onIndex ? positionOf(band.from) : Number(band.from);\n const to = onIndex ? positionOf(band.to) : Number(band.to);\n if (from === undefined || to === undefined) return [];\n // 类目轴上的区间盖住两端的类目:往外各扩半格\n const half = onIndex && !kind.continuousX ? 0.5 : 0;\n const plotband = instances.get(`band-${position}`, () => new Plotband<T>({}));\n plotband.setConfig({\n axis: onIndex ? categoryAxisName : valueAxisName,\n from: Math.min(from, to) - half,\n to: Math.max(from, to) + half,\n color: `color-mix(in srgb, ${resolveColor(band.color ?? 'neutral', 0)} 12%, transparent)`,\n labelText: band.label,\n // 类目轴上的区间文字在左下角:顶上留给事件竖线的文字\n labelPosition: onIndex\n ? PlotbandLabelPosition.BottomLeftInside\n : PlotbandLabelPosition.TopLeftInside,\n labelColor: colors.textMuted,\n labelOffsetX: 6,\n labelOffsetY: 6,\n });\n return [plotband];\n });\n\n // 标注:事件是类目上的竖线;圈出的值是一个空心圈,文字在上方\n const events = (annotations ?? []).filter((item) => item.series === undefined);\n const eventLines = events.flatMap((item, position) => {\n const at = positionOf(item.at);\n if (at === undefined) return [];\n const line = instances.get(`event-${position}`, () => new Plotline<T>({}));\n line.setConfig({\n axis: categoryAxisName,\n value: at,\n color: resolveColor(item.color ?? 'neutral', 0),\n lineWidth: 1,\n lineStyle: PlotlineLineStylePresets.ShortDash,\n labelText: item.label,\n labelPosition: kind.horizontal\n ? PlotlineLabelPosition.BottomRight\n : PlotlineLabelPosition.TopRight,\n labelOffsetX: 4,\n labelOffsetY: 4,\n });\n return [line];\n });\n const marked = (annotations ?? []).filter(\n (item) => item.series !== undefined && !kind.horizontal,\n );\n const markOf = (row: T) => {\n const at = kind.continuousX ? kind.continuousX.value(row) : rows.indexOf(row);\n return marked.find(\n (item) =>\n positionOf(item.at) === at && shown.some((series) => series.key === item.series),\n );\n };\n /** 圈的位置:系列的值;堆叠时是它在这一摞里的顶端 */\n const markY = (row: T) => {\n const mark = markOf(row);\n if (!mark) return undefined;\n const series = shown.find((item) => item.key === mark.series)!;\n if (!kind.stacked || kind.percent) return y(series)(row);\n const upTo = shown.slice(0, shown.indexOf(series) + 1);\n return upTo.reduce((sum, item) => sum + Math.max(y(item)(row) ?? 0, 0), 0);\n };\n const markColor = (row: T) => {\n const mark = markOf(row);\n const series = shown.find((item) => item.key === mark?.series);\n return mark?.color ? resolveColor(mark.color, 0) : (series?.color ?? colors.textMuted);\n };\n const marks = instances.get('marks', () => new Scatter<T>({ x, y: () => undefined }));\n marks.setConfig({\n x,\n y: markY,\n size: 16,\n color: 'transparent',\n strokeColor: markColor,\n strokeWidth: 2,\n label: (row: T) => markOf(row)?.label ?? '',\n labelPosition: Position.Top,\n labelColor: colors.text,\n });\n\n // 第二数值轴的刻度:与主轴的刻度同高,文字在绘图区右侧(不裁剪的 Plotline 标签,线本身透明)\n const secondaryLabels = aligned\n ? aligned.secondary.ticks.map((tick, position) => {\n const label = instances.get(`secondary-${position}`, () => {\n const line = new Plotline<T>({});\n line.clippable = false;\n return line;\n });\n label.setConfig({\n axis: 'y',\n value: aligned.primary.ticks[position]!,\n color: 'transparent',\n lineWidth: 0,\n labelText: format.number(tick, kind.secondary?.format),\n labelPosition: PlotlineLabelPosition.Right,\n labelOffsetX: -(SECONDARY_AXIS_WIDTH - 4),\n labelColor: colors.textMuted,\n });\n return label;\n })\n : [];\n const components = [\n ...bandComponents,\n ...kind.components({\n series: shown,\n x,\n y,\n instance: instances.get,\n events:\n kind.itemSelector && onItemClick\n ? {\n [kind.itemSelector]: {\n // 分组柱给的是原来的行;堆叠柱给的是拼出来的副本,第三个参数才是行的位置\n click: (row: T, _event: Event, index: number) => {\n const position = data.indexOf(row);\n const at = position >= 0 ? position : index;\n onItemClick(data[at] ?? row, at);\n },\n },\n }\n : {},\n }),\n ...lines,\n ...eventLines,\n ...(marked.length > 0 ? [marks] : []),\n ...secondaryLabels,\n ];\n const xAxis = instances.get('xAxis', () => new Axis<T>({ type: 'x' }));\n const yAxis = instances.get('yAxis', () => new Axis<T>({ type: 'y' }));\n const crosshair = instances.get('crosshair', () => new Crosshair<T>());\n const tooltipBox = instances.get('tooltip', () => new Tooltip());\n const [categoryAxis, valueAxis] = kind.horizontal ? [yAxis, xAxis] : [xAxis, yAxis];\n const continuous = kind.continuousX;\n categoryAxis.setConfig({\n type: kind.horizontal ? 'y' : 'x',\n // 连续的横轴:Unovis 自己取刻度,网格线与数值轴一样;类目轴:每行一个刻度\n tickValues: continuous ? undefined : rows.map((_row, position) => position),\n numTicks: continuous ? 6 : undefined,\n tickFormat: continuous\n ? (tick) => continuous.format(Number(tick))\n : (tick) => categoryText(rows[Number(tick)]),\n gridLine: continuous ? grid : false,\n tickLine: false,\n domainLine: false,\n tickTextHideOverlapping: true,\n tickPadding: 8,\n label: continuous?.title,\n labelMargin: 8,\n });\n valueAxis.setConfig({\n type: kind.horizontal ? 'x' : 'y',\n numTicks: 5,\n // 有第二数值轴时用对齐的刻度,两边的刻度落在同一组网格线上\n tickValues: aligned?.primary.ticks,\n tickFormat: (tick) =>\n kind.percent\n ? format.number(Number(tick), { style: 'percent', maximumFractionDigits: 0 })\n : format.number(Number(tick), valueFormat),\n gridLine: grid,\n tickLine: false,\n domainLine: false,\n tickPadding: 8,\n });\n const dotted = kind.crosshairSeries ? shown.filter(kind.crosshairSeries) : shown;\n crosshair.setConfig({\n // 访问器直接给:容器还没按尺寸渲染过时不会把组件的访问器转交十字线,Unovis 会报 “Y accessors have not been configured”\n x,\n ...(kind.stacked ? { yStacked: dotted.map(y) } : { y: dotted.map(y) }),\n template: (row: T) => renderTooltip(row),\n color: (_row: T, position: number) => dotted[position]?.color ?? 'transparent',\n getCircles: kind.crosshairDots ? undefined : () => [],\n hideWhenFarFromPointer: false,\n onCrosshairMove: (_x, row) => hover(row),\n });\n\n tooltipBox.setConfig({\n triggers: kind.pointTooltip ? { [kind.pointTooltip]: (row: T) => renderTooltip(row) } : {},\n });\n const config = {\n components,\n xAxis,\n yAxis,\n // 能下钻时没有提示框也要十字线:靠它知道指针在哪一行\n crosshair:\n (tooltip || (onItemClick && !kind.itemSelector)) && !kind.pointTooltip\n ? crosshair\n : undefined,\n tooltip: tooltip ? tooltipBox : undefined,\n [kind.horizontal ? 'xDomain' : 'yDomain']: domain,\n // 第二数值轴的刻度文字画在右侧留出的空白里\n padding: aligned\n ? { ...kind.padding, right: Math.max(kind.padding?.right ?? 0, SECONDARY_AXIS_WIDTH) }\n : (kind.padding ?? {}),\n ariaLabel: null,\n duration: chartDuration(element),\n onRenderComplete: haloPlotlineLabels,\n };\n if (container) container.update(config, undefined, rows);\n else {\n container = new XYContainer<T>(element, config, rows);\n containerElement = element;\n uniqueHighlightFilter(element, `${id}-highlight`);\n }\n });\n\n return () => (\n <ChartFrame\n {...rest}\n sx={[!kind.crosshairDots && xyChartStyles.hideCrosshairLine, sx]}\n // 百分比堆叠时数值轴是占比:轴上方不写单位(提示框、数据表里仍带)\n unit={kind.percent ? undefined : unit}\n unitEnd={kind.secondary?.unit}\n height={height}\n legend={(legend ?? resolved.length > 1) ? resolved : []}\n hiddenKeys={hiddenSeries}\n onLegendToggle={toggle}\n loading={loading}\n skeleton={chartSkeleton(kind)}\n isEmpty={data.length === 0}\n empty={empty}\n clickable={onItemClick != null}\n onPlotClick={\n onItemClick && !kind.itemSelector\n ? () => {\n if (hovered) onItemClick(hovered.row, hovered.index);\n }\n : undefined\n }\n table={\n kind.table?.(data) ?? {\n columns: [\n lang.chartCategory,\n ...(kind.continuousX ? [kind.continuousX.label] : []),\n ...resolved.map((item) => {\n const itemUnit = onSecondary(item.key) ? kind.secondary?.unit : unit;\n return itemUnit ? `${item.label}(${itemUnit})` : item.label;\n }),\n ],\n rows: data.map((row) => ({\n header: categoryText(row),\n cells: [\n ...(kind.continuousX ? [xText(row)] : []),\n ...resolved.map((item) => {\n const value = seriesValue(row, item.key);\n return value === undefined\n ? lang.emptyValue\n : format.number(\n value,\n onSecondary(item.key) ? kind.secondary?.format : valueFormat,\n );\n }),\n ],\n })),\n }\n }\n plotRef={(element) => (plot = element)}\n footer={zoom && !kind.continuousX && data.length > 2 ? zoomBar() : undefined}\n />\n );\n },\n);\n\n/**\n * 目标线、事件竖线的文字描一圈表面色的边(同地图上地点的名字):压在柱子、折线上也看得清。\n * Unovis 的 Plotline 文字没有描边的配置项,渲染完成后补在元素上;导出图片时按计算样式一并带走\n */\nfunction haloPlotlineLabels(svg: SVGSVGElement) {\n for (const label of svg.querySelectorAll<SVGTextElement>('text[class*=\"plotline-label\"]')) {\n label.style.setProperty('paint-order', 'stroke');\n label.style.setProperty('stroke', colors.surface);\n label.style.setProperty('stroke-width', '3px');\n label.style.setProperty('stroke-linejoin', 'round');\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4OA,IAAM,uBAAuB;;AAG7B,IAAM,gBAAgB;CAAC;CAAI;CAAI;CAAI;CAAI;CAAI;CAAI;AAAE;;AAGjD,IAAa,gBAAgB,IAAI,OAAO;CAEtC,mBAAmB,EAAE,uCAAuC,IAAI;CAChE,UAAU;EAAE,SAAS;EAAS,OAAO;EAAQ,QAAQ;CAAO;CAE5D,MAAM;EAAE,SAAS;EAAQ,YAAY;EAAU,KAAK;EAAO,eAAe;CAAM;CAChF,YAAY;EAAE,UAAU;EAAG,UAAU;CAAE;CACvC,cAAc;EACZ,SAAS;EACT,YAAY;EACZ,gBAAgB;EAChB,KAAK;EACL,QAAQ;CACV;CACA,wBAAwB;EAAE,eAAe;EAAU,YAAY;CAAa;CAC5E,aAAa;EAAE,SAAS;EAAS,UAAU;EAAG,WAAW;EAAG,cAAc;CAAM;CAChF,kBAAkB,aAAqB,EAAE,QAAQ,QAAQ;CACzD,4BAA4B,aAAqB,EAAE,OAAO,QAAQ;AACpE,CAAC;;AAGD,SAAS,cAAc,EACrB,WAAW,SACX,aAAa,SAC0C;CACvD,IAAI,aAAa,SAAS,OAAAA,YAAA,UAAA,EAAA,MAAqB,cAAc,SAAQ,GAAA,IAAA;CACrE,OAAAA,YAAA,OAAAC,WAAA,EAAA,eAAA,OAAA,GAGQ,IAAI,MAAM,cAAc,cAAc,cAAc,cAAc,sBAAsB,CAAC,GAAA,CAE5F,cAAc,KAAK,SAAS,aAAQD,YAAA,UAAA;EAAA,OAE5B;EAAQ,MACT,CACF,cAAc,aACd,aACI,cAAc,0BAA0B,GAAG,QAAO,EAAG,IACrD,cAAc,gBAAgB,GAAG,QAAO,EAAG,CAAC;CACjD,GAAA,IAAA,CAEJ,CAAC,CAAA;AAGR;;AAGA,IAAa,UAAU,0BACrB,QAAA,SAwBkD;CAAA,MAAA,SAAA,CAAA;CAAA,MAAA,OAAAE,aAAA,QAAA,MAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,cAAAA,aAAA,QAAA,aAAA;CAAA,MAAA,cAAAA,aAAA,QAAA,aAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,MAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,UAjBvC,GAAG;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,QAEL,IAAI;CAAA,MAAA,cAAAA,aAAA,QAAA,aAAA;CAAA,MAAA,UAAAA,aAAA,QAAA,WAED,IAAI;CAAA,MAAA,UAAAA,aAAA,QAAA,WACJ,KAAK;CAAA,MAAA,eAAAC,SAAA,QAAA,uBACmC,CAAA,GAAE,KAAA,IAAA;CAAA,MAAA,QAAAD,aAAA,QAAA,OAAA;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,cAAAA,aAAA,QAAA,aAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,cAAAA,aAAA,QAAA,aAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,QAM7C,KAAK;CAAA,MAAA,YAAAC,SAAA,QAAA,oBAC+C,MAAI,KAAA,IAAA;CAAA,MAAA,OAAAD,aAAA,QAAA,MAAA;CAAA,MAAA,KAAAA,aAAA,QAAA,IAAA;CAAA,MAG5D,OAAIE,UAAA,QAAA,MAAA,IAAA;CAEP,MAAM,OAAO,QAAQ;CACrB,MAAM,SAAS,UAAU;CACzB,MAAM,KAAK,MAAM;CACjB,MAAM,WAAQC,eAAY,cAAa,OAAA,KAAO,CAAC;CAC/C,MAAM,UAAOA,eAAY,SAAA,MAAS,QAAQ,SAAS,CAAC,aAAA,MAAa,SAAS,KAAK,GAAG,CAAC,CAAC;CAEpF,MAAM,gBAAgB,QACpB,QAAQ,KAAA,IACJ,KACA,YAAA,QACE,YAAA,MAAY,IAAG,MAAA,QAAS,GAAG,IAC3B,OAAO,IAAG,MAAA,UAAW,EAAE;CAC/B,MAAM,YAAY,yBAAyB;EAAE,aAAW,YAAA;EAAE,MAAI,KAAA;CAAC,EAAE;CACjE,MAAM,gBAAgB,yBAAyB;EAC7C,aAAa,KAAA,MAAK,WAAW;EAC7B,MAAM,KAAA,MAAK,WAAW;CACxB,EAAE;CACF,MAAM,eAAe,QAAgB,KAAA,MAAK,WAAW,KAAK,SAAS,GAAG,KAAK;;CAE3E,MAAM,cAAc,KAAa,UAC/B,YAAY,GAAG,IAAI,cAAc,KAAK,IAAI,UAAU,KAAK;;CAE3D,MAAM,YAAY,QAChB,QAAA,MAAQ,QAAQ,KAAK,SAAS,MAAM,KAAK,IAAI,aAAa,KAAK,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC;CACtF,MAAM,eAAe,UACnB,OAAO,OAAO,OAAO;EAAE,OAAO;EAAW,uBAAuB;CAAE,CAAC;CAErE,MAAM,SAAS,QAAW;EACxB,MAAM,IAAI,KAAA,MAAK,aAAa,MAAM,GAAG;EACrC,OAAO,MAAM,KAAA,IAAY,KAAK,aAAa,KAAA,MAAK,YAAa,OAAO,CAAC;CACvE;CAEA,SAAS,OAAO,KAAa;EAC3B,aAAA,QAAe,aAAA,MAAa,SAAS,GAAG,IACpC,aAAA,MAAa,QAAQ,SAAS,SAAS,GAAG,IAC1C,CAAC,GAAA,aAAA,OAAiB,GAAG;CAC3B;;CAGA,MAAM,gBAAgB;EACpB,MAAM,OAAO,KAAA,MAAK,SAAS;EAC3B,OAAAL,YAAA,OACW,IAAI,MAAM,cAAc,IAAI,GAAC,CAAAA,YAAA,QAAA;GAAA,UAE1B,UAAA,SAAa,CAAC,GAAG,IAAI;GAAC,oBACZ,SACf,UAAA,QAAY,KAAK,OAAO,KAAK,KAAK,OAAO,OAAO,OAAO;GAAK,OAE1D;GAAC,OACD;GAAI,QACH;GAAC,QAAA;GAAA,aAAA,OAAA,OAAA,OAAA,MAEK,aAAa,aAAa,KAAA,MAAK,SAAS;GAAC,cACzC,KAAK;GAAS,aAAA,OAAA,OAAA,OAAA,KACf,EAAE,IAAI,cAAc,WAAW;EAAC,GAAA,IAAA,GAE5C,UAAA,SAAAA,YAAA,QAAA;GAAA,WAAA;GAAA,QAAA;GAAA,WAAA,OAAA,OAAA,OAAA,WACkD,UAAA,QAAY;EAAK,GAAA;GAAA,eAAA,CAC/D,KAAK,cAAc;GAAA,SAAA;EAAA,CAAA,CAEvB,CAAA;CAGP;CAEA,MAAM,YAAY,qBAAqB;CACvC,IAAI;CAGJ,IAAI,UAA4C;CAChD,MAAM,SAAS,QAAuB;EACpC,UAAU,QAAQ,KAAA,IAAY,OAAO;GAAE;GAAK,OAAO,KAAA,MAAK,QAAQ,GAAG;EAAE;CACvE;;CAGA,SAAS,cAAc,KAAQ;EAC7B,mBAAmB,SAAS,cAAc,KAAK;EAE/C,IAAI,KAAA,MAAK,cAAc,MAAM,GAAG;EAChC,OACE,aACE,aAAa,GAAG,GAChB,KAAA,MAAK,eAAe,GAAG,KAAK,CAC1B,GAAI,KAAA,MAAK,cACL,CAAC;GAAE,OAAO,KAAA,MAAK,YAAY;GAAO,OAAO;GAAe,OAAO,MAAM,GAAG;EAAE,CAAC,IAC3E,CAAA,GAEJ,GAAG,QAAA,MACA,QAAQ,SAAS,CAAC,KAAA,MAAK,gBAAgB,YAAY,KAAK,KAAK,GAAG,MAAM,KAAA,CAAS,CAAC,CAChF,KAAK,SAAS;GACb,MAAM,QAAQ,YAAY,KAAK,KAAK,GAAG;GACvC,MAAM,QAAQ,KAAA,MAAK,UAAU,SAAS,GAAG,IAAI;GAC7C,OAAO;IACL,OAAO,KAAK;IACZ,OAAO,KAAK;IACZ,OACE,KAAA,MAAK,WAAW,UAAU,KAAA,KAAa,QAAQ,IAC3C,GAAG,WAAW,KAAK,KAAK,KAAK,EAAC,GAAI,YAAY,SAAS,KAAK,IAAI,KAAK,EAAC,KACtE,WAAW,KAAK,KAAK,KAAK;GAClC;EACF,CAAC,CAAC,CAER,GACA,cACF;EACA,OAAO;CACT;CAEA,IAAI,OAAIM,WAAkC,IAAI;CAC9C,MAAM,OAAO,kBAAY,KAAA,KAAU;CACnC,IAAI;CACJ,IAAI;CACJ,mBAAoB;EAClB,WAAW,QAAQ;EACnB,IAAI,gBAAgB,OAAO,MAAM,cAAc;CACjD,CAAC;CACD,aAAc;EAEZ,MAAM,QAAQ,KAAA,SAAQ,CAAC,KAAA,MAAK,cAAW,UAAA,QAAe;EACtD,MAAM,OAAO,QAAQ,KAAA,MAAK,MAAM,MAAM,IAAI,MAAM,KAAK,CAAC,IAAI,CAAC,GAAA,KAAA,KAAO;EAClE,MAAM,QAAK,QAAA;EACX,MAAM,UAAO,KAAA;EACb,IAAI,CAAC,WAAO,QAAA,SAAe,KAAK,WAAW,KAAK,CAAC,KAAK,GAAG;EAEzD,IAAI,aAAa,qBAAqB,SAAS;GAC7C,UAAU,QAAQ;GAClB,YAAY,KAAA;GACZ,UAAU,MAAM;EAClB;EAEA,MAAM,gBAAgB,MAAM,QAAQ,SAAS,CAAC,YAAY,KAAK,GAAG,CAAC;EACnE,MAAM,kBAAkB,MAAM,QAAQ,SAAS,YAAY,KAAK,GAAG,CAAC;EACpE,MAAM,SAAS,KAAK,KAAK,QACvB,cAAc,KAAK,SAAS,aAAa,KAAK,KAAK,GAAG,KAAK,CAAC,CAC9D;EAUA,MAAM,SAAS;GACb,GAVmB,KAAA,MAAK,eACtB,KAAA,MAAK,aAAa,MAAM,aAAa,IACrC,KAAA,MAAK,UACH,OAAO,SAAS,QAAQ,CACtB,IAAI,QAAQ,KAAK,UAAU,MAAM,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,GACtD,IAAI,QAAQ,KAAK,UAAU,MAAM,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CACxD,IACD,OAAO,KAAK;GAIhB,IAAI,QAAA,SAAW,CAAA,EAAA,CAAI,KAAK,WAAW,SAAS,OAAO,KAAK,CAAC;GACzD,IAAI,MAAA,SAAS,CAAA,EAAA,CACV,QAAQ,SAAS,KAAK,SAAS,OAAO,CAAC,CACvC,SAAS,SAAS,CAAC,OAAO,KAAK,IAAI,GAAG,OAAO,KAAK,EAAE,CAAC,CAAC;EAAC;EAG5D,MAAM,UACJ,gBAAgB,SAAS,IACrB,aACE,CACE,GAAG,QACH,GAAG,CAAC,YAAA,QAAc,IAAI,YAAA,QAAc,EAAE,CAAC,CAAC,QACrC,QAAuB,QAAQ,KAAA,CAClC,CAAC,GAEH,KAAK,SAAS,QACZ,gBAAgB,KAAK,SAAS,aAAa,KAAK,KAAK,GAAG,KAAK,CAAC,CAChE,CACF,IACA,KAAA;EACN,MAAM,SAAmD,KAAA,MAAK,UAC1D,CAAC,GAAG,CAAC,IACL,UACE,QAAQ,QAAQ,SAChB,CACE,YAAA,QAAc,OACX,KAAA,MAAK,iBAAiB,QAAQ,KAAA,IAAY,KAAK,IAAI,GAAG,GAAG,MAAM,IAClE,YAAA,QAAc,EAAE;EAExB,MAAM,IAAI,KAAA,MAAK,eACV,QAAW,KAAA,MAAK,YAAa,MAAM,GAAG,KAAK,OAC3C,MAAS,aAAqB;EACnC,MAAM,KAAK,SAAiC;GAC1C,IAAI,KAAA,MAAK,SACP,QAAQ,QAAW;IACjB,MAAM,QAAQ,aAAa,KAAK,KAAK,GAAG;IACxC,MAAM,QAAQ,SAAS,GAAG;IAC1B,OAAO,UAAU,KAAA,KAAa,UAAU,IAAI,KAAA,IAAY,QAAQ;GAClE;GACF,IAAI,WAAW,YAAY,KAAK,GAAG,GACjC,QAAQ,QAAW;IACjB,MAAM,QAAQ,aAAa,KAAK,KAAK,GAAG;IACxC,OAAO,UAAU,KAAA,IAAY,KAAA,IAAY,QAAQ,UAAU,KAAK;GAClE;GACF,QAAQ,QAAW,aAAa,KAAK,KAAK,GAAG;EAC/C;;EAEA,MAAM,cAAc,OAAgB;GAClC,IAAI,KAAA,MAAK,aAAa,OAAO,OAAO,EAAE;GACtC,MAAM,QAAQ,KAAK,WAAW,QAAQ,IAAG,MAAA,WAAY,EAAE;GACvD,OAAO,QAAQ,IAAI,KAAA,IAAY;EACjC;EACA,MAAM,mBAAmB,KAAA,MAAK,aAAa,SAAS,IAAI,SAAS;EACjE,MAAM,gBAAgB,KAAA,MAAK,aAAa,SAAS,IAAI,SAAS;EAC9D,MAAM,SAAS,QAAA,SAAW,CAAA,EAAA,CAAI,KAAK,QAAQ,aAAa;GACtD,MAAM,OAAO,UAAU,IAAI,UAAU,kBAAkB,IAAI,SAAY,CAAC,CAAC,CAAC;GAC1E,MAAM,QAAQ,SAAS,OAAO,KAAK;GACnC,MAAM,QAAQ,UAAU,OAAO,KAAK;GACpC,KAAK,UAAU;IACb,MAAM,KAAA,MAAK,aAAa,MAAM;IAC9B;IACA,OAAO,aAAa,OAAO,SAAS,UAAU,CAAC;IAC/C,WAAW;IACX,WAAW,yBAAyB;IACpC,WAAW,OAAO,QAAQ,GAAG,OAAO,MAAK,GAAI,UAAU;IACvD,eAAe,KAAA,MAAK,aAChB,sBAAsB,WACtB,sBAAsB;IAC1B,cAAc;IACd,cAAc;GAChB,CAAC;GACD,OAAO;EACT,CAAC;EAGD,MAAM,kBAAkB,MAAA,SAAS,CAAA,EAAA,CAAI,SAAS,MAAM,aAAa;GAC/D,MAAM,UAAU,KAAK,SAAS;GAC9B,MAAM,OAAO,UAAU,WAAW,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI;GAC/D,MAAM,KAAK,UAAU,WAAW,KAAK,EAAE,IAAI,OAAO,KAAK,EAAE;GACzD,IAAI,SAAS,KAAA,KAAa,OAAO,KAAA,GAAW,OAAO,CAAA;GAEnD,MAAM,OAAO,WAAW,CAAC,KAAA,MAAK,cAAc,KAAM;GAClD,MAAM,WAAW,UAAU,IAAI,QAAQ,kBAAkB,IAAI,SAAY,CAAC,CAAC,CAAC;GAC5E,SAAS,UAAU;IACjB,MAAM,UAAU,mBAAmB;IACnC,MAAM,KAAK,IAAI,MAAM,EAAE,IAAI;IAC3B,IAAI,KAAK,IAAI,MAAM,EAAE,IAAI;IACzB,OAAO,sBAAsB,aAAa,KAAK,SAAS,WAAW,CAAC,EAAC;IACrE,WAAW,KAAK;IAEhB,eAAe,UACX,sBAAsB,mBACtB,sBAAsB;IAC1B,YAAY,OAAO;IACnB,cAAc;IACd,cAAc;GAChB,CAAC;GACD,OAAO,CAAC,QAAQ;EAClB,CAAC;EAID,MAAM,cADU,YAAA,SAAe,CAAA,EAAA,CAAI,QAAQ,SAAS,KAAK,WAAW,KAAA,CACjD,CAAM,CAAC,SAAS,MAAM,aAAa;GACpD,MAAM,KAAK,WAAW,KAAK,EAAE;GAC7B,IAAI,OAAO,KAAA,GAAW,OAAO,CAAA;GAC7B,MAAM,OAAO,UAAU,IAAI,SAAS,kBAAkB,IAAI,SAAY,CAAC,CAAC,CAAC;GACzE,KAAK,UAAU;IACb,MAAM;IACN,OAAO;IACP,OAAO,aAAa,KAAK,SAAS,WAAW,CAAC;IAC9C,WAAW;IACX,WAAW,yBAAyB;IACpC,WAAW,KAAK;IAChB,eAAe,KAAA,MAAK,aAChB,sBAAsB,cACtB,sBAAsB;IAC1B,cAAc;IACd,cAAc;GAChB,CAAC;GACD,OAAO,CAAC,IAAI;EACd,CAAC;EACD,MAAM,UAAU,YAAA,SAAe,CAAA,EAAA,CAAI,QAChC,SAAS,KAAK,WAAW,KAAA,KAAa,CAAC,KAAA,MAAK,UAC/C;EACA,MAAM,UAAU,QAAW;GACzB,MAAM,KAAK,KAAA,MAAK,cAAc,KAAA,MAAK,YAAY,MAAM,GAAG,IAAI,KAAK,QAAQ,GAAG;GAC5E,OAAO,OAAO,MACX,SACC,WAAW,KAAK,EAAE,MAAM,MAAM,MAAM,MAAM,WAAW,OAAO,QAAQ,KAAK,MAAM,CACnF;EACF;;EAEA,MAAM,SAAS,QAAW;GACxB,MAAM,OAAO,OAAO,GAAG;GACvB,IAAI,CAAC,MAAM,OAAO,KAAA;GAClB,MAAM,SAAS,MAAM,MAAM,SAAS,KAAK,QAAQ,KAAK,MAAM;GAC5D,IAAI,CAAC,KAAA,MAAK,WAAW,KAAA,MAAK,SAAS,OAAO,EAAE,MAAM,CAAC,CAAC,GAAG;GAEvD,OADa,MAAM,MAAM,GAAG,MAAM,QAAQ,MAAM,IAAI,CAC7C,CAAI,CAAC,QAAQ,KAAK,SAAS,MAAM,KAAK,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC;EAC3E;EACA,MAAM,aAAa,QAAW;GAC5B,MAAM,OAAO,OAAO,GAAG;GACvB,MAAM,SAAS,MAAM,MAAM,SAAS,KAAK,QAAQ,MAAM,MAAM;GAC7D,OAAO,MAAM,QAAQ,aAAa,KAAK,OAAO,CAAC,IAAK,QAAQ,SAAS,OAAO;EAC9E;EACA,MAAM,QAAQ,UAAU,IAAI,eAAe,IAAI,QAAW;GAAE;GAAG,SAAS,KAAA;EAAU,CAAC,CAAC;EACpF,MAAM,UAAU;GACd;GACA,GAAG;GACH,MAAM;GACN,OAAO;GACP,aAAa;GACb,aAAa;GACb,QAAQ,QAAW,OAAO,GAAG,CAAC,EAAE,SAAS;GACzC,eAAe,SAAS;GACxB,YAAY,OAAO;EACrB,CAAC;EAGD,MAAM,kBAAkB,UACpB,QAAQ,UAAU,MAAM,KAAK,MAAM,aAAa;GAC9C,MAAM,QAAQ,UAAU,IAAI,aAAa,kBAAkB;IACzD,MAAM,OAAO,IAAI,SAAY,CAAC,CAAC;IAC/B,KAAK,YAAY;IACjB,OAAO;GACT,CAAC;GACD,MAAM,UAAU;IACd,MAAM;IACN,OAAO,QAAQ,QAAQ,MAAM;IAC7B,OAAO;IACP,WAAW;IACX,WAAW,OAAO,OAAO,MAAM,KAAA,MAAK,WAAW,MAAM;IACrD,eAAe,sBAAsB;IACrC,cAAc;IACd,YAAY,OAAO;GACrB,CAAC;GACD,OAAO;EACT,CAAC,IACD,CAAA;EACJ,MAAM,aAAa;GACjB,GAAG;GACH,GAAG,KAAA,MAAK,WAAW;IACjB,QAAQ;IACR;IACA;IACA,UAAU,UAAU;IACpB,QACE,KAAA,MAAK,gBAAY,YAAA,QACb,GACG,KAAA,MAAK,eAAe,EAEnB,QAAQ,KAAQ,QAAe,UAAkB;KAC/C,MAAM,WAAW,KAAA,MAAK,QAAQ,GAAG;KACjC,MAAM,KAAK,YAAY,IAAI,WAAW;KACtC,YAAA,MAAY,KAAA,MAAK,OAAO,KAAK,EAAE;IACjC,EACF,EACF,IACA,CAAC;GACT,CAAC;GACD,GAAG;GACH,GAAG;GACH,GAAI,OAAO,SAAS,IAAI,CAAC,KAAK,IAAI,CAAA;GAClC,GAAG;EAAe;EAEpB,MAAM,QAAQ,UAAU,IAAI,eAAe,IAAI,KAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;EACrE,MAAM,QAAQ,UAAU,IAAI,eAAe,IAAI,KAAQ,EAAE,MAAM,IAAI,CAAC,CAAC;EACrE,MAAM,YAAY,UAAU,IAAI,mBAAmB,IAAI,UAAa,CAAC;EACrE,MAAM,aAAa,UAAU,IAAI,iBAAiB,IAAI,QAAQ,CAAC;EAC/D,MAAM,CAAC,cAAc,aAAa,KAAA,MAAK,aAAa,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,KAAK;EAClF,MAAM,aAAa,KAAA,MAAK;EACxB,aAAa,UAAU;GACrB,MAAM,KAAA,MAAK,aAAa,MAAM;GAE9B,YAAY,aAAa,KAAA,IAAY,KAAK,KAAK,MAAM,aAAa,QAAQ;GAC1E,UAAU,aAAa,IAAI,KAAA;GAC3B,YAAY,cACP,SAAS,WAAW,OAAO,OAAO,IAAI,CAAC,KACvC,SAAS,aAAa,KAAK,OAAO,IAAI,EAAE;GAC7C,UAAU,aAAU,KAAA,QAAU;GAC9B,UAAU;GACV,YAAY;GACZ,yBAAyB;GACzB,aAAa;GACb,OAAO,YAAY;GACnB,aAAa;EACf,CAAC;EACD,UAAU,UAAU;GAClB,MAAM,KAAA,MAAK,aAAa,MAAM;GAC9B,UAAU;GAEV,YAAY,SAAS,QAAQ;GAC7B,aAAa,SACX,KAAA,MAAK,UACD,OAAO,OAAO,OAAO,IAAI,GAAG;IAAE,OAAO;IAAW,uBAAuB;GAAE,CAAC,IAC1E,OAAO,OAAO,OAAO,IAAI,GAAC,YAAA,KAAa;GAC7C,UAAQ,KAAA;GACR,UAAU;GACV,YAAY;GACZ,aAAa;EACf,CAAC;EACD,MAAM,SAAS,KAAA,MAAK,kBAAkB,MAAM,OAAO,KAAA,MAAK,eAAe,IAAI;EAC3E,UAAU,UAAU;GAElB;GACA,GAAI,KAAA,MAAK,UAAU,EAAE,UAAU,OAAO,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,OAAO,IAAI,CAAC,EAAE;GACpE,WAAW,QAAW,cAAc,GAAG;GACvC,QAAQ,MAAS,aAAqB,OAAO,SAAS,EAAE,SAAS;GACjE,YAAY,KAAA,MAAK,gBAAgB,KAAA,UAAkB,CAAA;GACnD,wBAAwB;GACxB,kBAAkB,IAAI,QAAQ,MAAM,GAAG;EACzC,CAAC;EAED,WAAW,UAAU,EACnB,UAAU,KAAA,MAAK,eAAe,GAAG,KAAA,MAAK,gBAAgB,QAAW,cAAc,GAAG,EAAE,IAAI,CAAC,EAC3F,CAAC;EACD,MAAM,SAAS;GACb;GACA;GACA;GAEA,YACG,QAAA,SAAY,YAAA,SAAe,CAAC,KAAA,MAAK,iBAAkB,CAAC,KAAA,MAAK,eACtD,YACA,KAAA;GACN,SAAS,QAAA,QAAU,aAAa,KAAA;IAC/B,KAAA,MAAK,aAAa,YAAY,YAAY;GAE3C,SAAS,UACL;IAAE,GAAG,KAAA,MAAK;IAAS,OAAO,KAAK,IAAI,KAAA,MAAK,SAAS,SAAS,GAAG,oBAAoB;GAAE,IAClF,KAAA,MAAK,WAAW,CAAC;GACtB,WAAW;GACX,UAAU,cAAc,OAAO;GAC/B,kBAAkB;EACpB;EACA,IAAI,WAAW,UAAU,OAAO,QAAQ,KAAA,GAAW,IAAI;OAClD;GACH,YAAY,IAAI,YAAe,SAAS,QAAQ,IAAI;GACpD,mBAAmB;GACnB,sBAAsB,SAAS,GAAG,GAAE,WAAY;EAClD;CACF,CAAC;CAED,aAAON,YAAA,YAAAC,WAEC,MAAI;EAAA,MACJ,CAAA,IAAA,aAAC,CAAC,KAAA,MAAK,iBAAiB,cAAc,mBAAiB,IAAA,GAAA,GAAA,KAAA;EAAK,QAE1D,KAAA,MAAK,UAAU,KAAA,IAAS,KAAA;EAAO,WAC5B,KAAA,MAAK,WAAW;EAAI,UAAA,OAAA;EAAA,UAEpB,OAAA,SAAU,SAAA,MAAS,SAAS,IAAC,SAAA,QAAe,CAAA;EAAE,cAAA,aAAA;EAAA,kBAEvC;EAAM,WAAA,QAAA;EAAA,YAEZ,cAAa,KAAA,KAAK;EAAC,WACpB,KAAA,MAAK,WAAW;EAAC,SAAA,MAAA;EAAA,aAEf,YAAA,SAAe;EAAI,eAE5B,YAAA,SAAe,CAAC,KAAA,MAAK,qBACX;GACJ,IAAI,SAAS,YAAA,MAAY,QAAQ,KAAK,QAAQ,KAAK;EACrD,IACA,KAAA;EAAS,SAGb,KAAA,MAAK,QAAK,KAAA,KAAO,KAAK;GACpB,SAAS;IACP,KAAK;IACL,GAAI,KAAA,MAAK,cAAc,CAAC,KAAA,MAAK,YAAY,KAAK,IAAI,CAAA;IAClD,GAAG,SAAA,MAAS,KAAK,SAAS;KACxB,MAAM,WAAW,YAAY,KAAK,GAAG,IAAI,KAAA,MAAK,WAAW,OAAI,KAAA;KAC7D,OAAO,WAAW,GAAG,KAAK,MAAK,GAAI,SAAQ,KAAM,KAAK;IACxD,CAAC;GAAC;GAEJ,MAAM,KAAA,MAAK,KAAK,SAAS;IACvB,QAAQ,aAAa,GAAG;IACxB,OAAO,CACL,GAAI,KAAA,MAAK,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,CAAA,GACtC,GAAG,SAAA,MAAS,KAAK,SAAS;KACxB,MAAM,QAAQ,YAAY,KAAK,KAAK,GAAG;KACvC,OAAO,UAAU,KAAA,IACb,KAAK,aACL,OAAO,OACL,OACA,YAAY,KAAK,GAAG,IAAI,KAAA,MAAK,WAAW,SAAM,YAAA,KAChD;IACN,CAAC,CAAC;GAEN,EAAE;EACJ;EAAC,WAAA,OAAA,OAAA,OAAA,MAEO,YAAa,KAAA,QAAO;EAAQ,UAC9B,KAAA,SAAQ,CAAC,KAAA,MAAK,eAAe,KAAA,MAAK,SAAS,IAAI,QAAQ,IAAI,KAAA;CAAS,CAAA,GAAA,IAAA;AAGlF,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH;;;;;AAMA,SAAS,mBAAmB,KAAoB;CAC9C,KAAK,MAAM,SAAS,IAAI,iBAAiC,iCAA+B,GAAG;EACzF,MAAM,MAAM,YAAY,eAAe,QAAQ;EAC/C,MAAM,MAAM,YAAY,UAAU,OAAO,OAAO;EAChD,MAAM,MAAM,YAAY,gBAAgB,KAAK;EAC7C,MAAM,MAAM,YAAY,mBAAmB,OAAO;CACpD;AACF"}
1
+ {"version":3,"file":"XYChart.js","names":["_createVNode","_mergeProps","_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_computed","_vue_shallowRef"],"sources":["../../src/charts/XYChart.tsx"],"sourcesContent":["/**\n * 直角坐标图表(柱状图、折线图、面积图)的公共部分:坐标轴、十字线与提示框、数值范围;外层结构(图例、单位、\n * 空与加载状态、给读屏的数据表)交给 ChartFrame。\n * 绘图交给 Unovis 的 XYContainer:组件实例只建一次,数据与配置变化时 update,卸载时 destroy;\n * 绘图区换了元素(加载、空状态之后重新出现)时容器连同全部实例一起重建。\n * 各种图只决定画什么(kind.components),坐标轴、十字线、提示框、配色都在这里统一。\n * 目标线(targets)用 Unovis 的 Plotline。点了下钻(onItemClick):有图形可点的图(柱子)按图形的点击事件\n * (kind.itemSelector),折线、面积图按十字线所在的那一行,散点图按悬停的点。\n *\n * 标注(annotations):类目上的事件画成竖线(Plotline),圈出某个系列的值画成空心圈带文字(Scatter);\n * 区间(bands)画成浅色的带(Plotband)。百分比堆叠(kind.percent)按每个类目里各系列的占比画。\n * 第二数值轴(kind.secondary,组合图):刻度与主轴对齐(alignedTicks),第二轴的系列换算到主轴的坐标里画,\n * 右侧的刻度文字是不裁剪的 Plotline 标签。\n */\nimport {\n Axis,\n AxisType,\n Crosshair,\n Plotband,\n PlotbandLabelPosition,\n Plotline,\n PlotlineLabelPosition,\n PlotlineLineStylePresets,\n Position,\n Scatter,\n Tooltip,\n XYContainer,\n type XYComponentCore,\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 { useId, type VNodeChild } from 'vue';\nimport { useDetachedRender } from '../overlay/detached';\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 { Button } from '../base/Button';\nimport { Slider } from '../input/Slider';\nimport { alignedTicks, type AlignedAxes } from './axis-ticks';\nimport { toNumber, type NumericValue } from '../utils/data/numeric';\nimport type { PartProps } from '../utils/props';\nimport {\n ChartFrame,\n chartDuration,\n chartTooltip,\n createChartInstances,\n uniqueHighlightFilter,\n useChartValueText,\n usePlotSeen,\n type ChartFrameParts,\n type ChartTable,\n type ChartTooltipItem,\n} from './frame';\nimport {\n resolveColor,\n resolveSeries,\n seriesNumber,\n seriesValue,\n type ChartColor,\n type ChartSeries,\n type ResolvedSeries,\n} from './series';\n\n/** 目标线(参考线):数值轴上的一条虚线 */\nexport interface ChartTarget {\n /** 位置:数值轴上的值 */\n value: NumericValue;\n /** 标签:写在线的一端,后面带上格式化的数值(“年度指标 1,200”) */\n label?: string;\n /** 颜色;默认是 danger(要够到的线) */\n color?: ChartColor;\n}\n\n/** 标注:类目上发生的事(竖线),或圈出某个系列在这个类目上的值 */\nexport interface ChartAnnotation {\n /** 标在哪个类目上:index 字段的值(散点图是横轴上的数值) */\n at: unknown;\n /** 文字 */\n label: string;\n /** 圈出这个系列在这里的值(系列的 key);不写时是一条竖线(换供应商、调价生效这类事件) */\n series?: string;\n /** 颜色;竖线默认是次要色,圈默认是系列色 */\n color?: ChartColor;\n}\n\n/** 区间:类目轴上的一段(试运行期、促销期),或数值轴上的一段(目标区间) */\nexport interface ChartBand {\n /** 在哪条轴上,默认 index(类目轴) */\n axis?: 'index' | 'value';\n /** 起点:类目轴是 index 字段的值(含这一项),数值轴是数值 */\n from: unknown;\n /** 终点:同 from(含这一项) */\n to: unknown;\n /** 文字:类目轴上的写在带的左下角,数值轴上的写在左上角 */\n label?: string;\n /** 颜色,默认 neutral;画成很浅的底色 */\n color?: ChartColor;\n}\n\n/** 第二数值轴(右侧):哪些系列画在它上面,它的格式与单位 */\nexport interface ChartSecondaryAxis {\n /** 画在第二数值轴上的系列 */\n keys: readonly string[];\n /** 数值的格式 */\n format?: NumericFormat;\n /** 单位:显示在右上方,提示框与数据表的数值后面带上 */\n unit?: string;\n}\n\n/** 加载中的骨架 */\nexport interface ChartSkeletons {\n /** 一排高低不一的柱(柱状图) */\n bars: unknown;\n /** 一整块(默认) */\n block: unknown;\n}\n\n/** 直角坐标图表共有的属性;未声明的属性落到外层 div(role=\"figure\")上,aria-label 是图表的名称 */\nexport interface XYChartProps<T extends object>\n extends PartProps<'div', 'role' | 'aria-busy'>, ChartFrameParts {\n /** 数据:每一行是类目轴上的一项(一个月、一个项目) */\n data: readonly T[];\n /** 类目字段:类目轴的刻度、提示框的标题、数据表的第一列 */\n index: keyof T & string;\n /** 系列:每个系列画成一组柱子、一条线或一片面积 */\n series: readonly ChartSeries<T>[];\n /** 类目的显示文字;不写时把字段的值转成字符串 */\n indexFormat?: (value: T[keyof T & string], row: T) => string;\n /**\n * 数值的格式:数值轴、提示框、数据表共用,按当前语言格式化。以万元为单位画金额时写\n * `{ scale: 10_000, maximumFractionDigits: 1 }` 并配 `unit=\"万元\"`\n */\n valueFormat?: NumericFormat;\n /** 单位:显示在数值轴上方,提示框与数据表的数值后面带上 */\n unit?: string;\n /**\n * 绘图区的高度;数字按 px\n * @default 240\n */\n height?: number | string;\n /** 图例:默认多于一个系列时显示;点图例可以隐藏、恢复系列 */\n legend?: boolean;\n /**\n * 数值轴的网格线\n * @default true\n */\n grid?: boolean;\n /** 数值轴的范围 [最小, 最大];不写的一端按数据自动取,最小值默认从 0 起(数据有负数时取负数) */\n valueDomain?: readonly [number | undefined, number | undefined];\n /**\n * 悬停时的提示框\n * @default true\n */\n tooltip?: boolean;\n /**\n * 加载中:绘图区显示扫光的骨架(柱状图是一排高低不一的柱),带 aria-busy\n * @default false\n */\n loading?: boolean;\n /** 隐藏的系列(存系列的 key):点图例时写回,父级可以写 _hiddenSeries={keys} */\n _hiddenSeries?: string[];\n /** 没有数据时显示的内容,默认是“暂无数据” */\n empty?: VNodeChild;\n /** 目标线、参考线:数值轴上的虚线(横向图是竖线),如年度销售指标;数值轴的范围会包含它 */\n targets?: readonly ChartTarget[];\n /** 标注:类目上的事件(竖线),或圈出某个系列的值(横向图只画竖线) */\n annotations?: readonly ChartAnnotation[];\n /** 区间:类目轴或数值轴上的一段,画成浅色的带(数值轴的范围会包含它) */\n bands?: readonly ChartBand[];\n /**\n * 点了一个类目(下钻,如跳到筛好条件的台账):参数是这一行与它的位置;写了它时绘图区的指针是手形。\n * 点图是鼠标的捷径:同样的去处在页面上还要有链接或按钮,键盘与读屏才到得了(WCAG 2.1.1)\n */\n onItemClick?: (row: T, index: number) => void;\n /** 缩放:绘图区下面一条区间滑块,选一段类目放大看(几年的月度数据);读屏的数据表仍是全部 */\n zoom?: boolean;\n /** 缩放的区间 [起, 止]:类目的位置,含两端;父级可以写 _zoomRange={range},null 是全部 */\n _zoomRange?: [number, number] | null;\n}\n\n/** 交给各种图的绘制上下文 */\nexport interface XYChartContext<T extends object> {\n /** 显示中的系列(去掉了图例里隐藏的),颜色已定 */\n series: ResolvedSeries<T>[];\n /** 类目的位置:第几行 */\n x: (row: T, index: number) => number;\n /** 系列的取值函数,空值返回 undefined(Unovis 跳过) */\n y: (series: ResolvedSeries<T>) => (row: T) => number | undefined;\n /** 取一个跨渲染保留的组件实例:第一次调用时创建;Unovis 组件保留实例,更新时才有过渡动画 */\n instance: <C>(key: string, create: () => C) => C;\n /** 点图形下钻的事件(写了 itemSelector 时):并进组件的 events;没有 onItemClick 时是空的。参数同 Unovis:图形的数据、事件、位置 */\n events: Record<string, Record<string, (row: T, event: Event, index: number) => void>>;\n}\n\n/** 一种图:画哪些组件,以及与坐标轴、十字线有关的差别 */\nexport interface XYChartKind<T extends object> {\n /** 配置并返回要画的 Unovis 组件(每次数据或属性变化都会调用) */\n components: (context: XYChartContext<T>) => XYComponentCore<T>[];\n /** 横向:类目在纵轴、数值在横轴 */\n horizontal?: boolean;\n /** 十字线上给每个系列画圆点(折线图、面积图);柱状图不画 */\n crosshairDots?: boolean;\n /** 加载中的骨架,默认 block */\n skeleton?: keyof ChartSkeletons;\n /** 绘图区四周的留白(px):折线两端不贴着边缘 */\n padding?: { left?: number; right?: number; top?: number; bottom?: number };\n /** 数值范围按堆叠后的总和算(堆叠的柱子、面积) */\n stacked?: boolean;\n /** 百分比堆叠:各系列按它在这个类目里的占比画(加起来 100%),数值轴是百分比,提示框带上占比 */\n percent?: boolean;\n /** 第二数值轴(组合图):这些系列画在右侧的轴上,刻度与主轴对齐 */\n secondary?: ChartSecondaryAxis;\n /** 十字线只在这些系列上画圆点(组合图里只给线画);不写时按 crosshairDots */\n crosshairSeries?: (series: ResolvedSeries<T>) => boolean;\n /** 横轴是连续的数值(散点图):取值、刻度与提示框里的写法、数据表的列名、轴下方的标题;不写时横轴是类目(第几行) */\n continuousX?: {\n value: (row: T) => number | undefined;\n format: (value: number) => string;\n label: string;\n title?: string;\n };\n /** 数值轴默认从 0 起(数据有负数时取负数);false 时按数据自动取(散点图) */\n zeroBaseline?: boolean;\n /** 提示框跟着数据点(散点图),没有十字线:按选择器触发,悬停的数据是这一行 */\n pointTooltip?: string;\n /** 提示框里列的项;不写时每个显示中的系列一行(瀑布图列变动与累计) */\n tooltipItems?: (row: T) => ChartTooltipItem[];\n /** 数值轴(主轴)的范围要包含的值;shown 是显示中的系列(第二数值轴的已去掉)。不写时按系列的值(stacked 时按正负各自的总和) */\n domainValues?: (rows: readonly T[], shown: readonly ResolvedSeries<T>[]) => number[];\n /** 给读屏的数据表;不写时类目一列加每个系列一列 */\n table?: (rows: readonly T[]) => ChartTable;\n /** 点哪种图形算点了这一行(柱子的选择器,图形绑定的数据是这一行);不写时按十字线所在的那一行 */\n itemSelector?: string;\n}\n\n/** 第二数值轴的刻度文字占的宽度(px) */\nconst SECONDARY_AXIS_WIDTH = 48;\n\n/** 骨架柱的高度(百分比):高低错落,看起来像一组数据 */\nconst SKELETON_BARS = [55, 80, 40, 70, 90, 50, 65];\n\n/** XYChart 的样式:hideCrosshairLine 与加载中的骨架(外层结构的样式见 chartStyles) */\nexport const xyChartStyles = css.create({\n // 柱状图的十字线只用来定位提示框,不画竖线\n hideCrosshairLine: { '--vis-crosshair-line-stroke-opacity': '0' },\n skeleton: { display: 'block', width: '100%', height: '100%' },\n // 缩放:滑块占满,“显示全部”在结束边\n zoom: { display: 'flex', alignItems: 'center', gap: '_md', paddingInline: '_sm' },\n zoomSlider: { flexGrow: 1, minWidth: 0 },\n skeletonBars: {\n display: 'flex',\n alignItems: 'flex-end',\n justifyContent: 'space-around',\n gap: '_md',\n height: '100%',\n },\n skeletonBarsHorizontal: { flexDirection: 'column', alignItems: 'flex-start' },\n skeletonBar: { display: 'block', flexGrow: 1, flexBasis: 0, borderRadius: '_sm' },\n skeletonBarSize: (percent: string) => ({ height: percent }),\n skeletonBarSizeHorizontal: (percent: string) => ({ width: percent }),\n});\n\n/** 加载中绘图区的骨架:柱状图是一排高低不一的柱(横向时是条),其余是一整块 */\nfunction chartSkeleton({\n skeleton = 'block',\n horizontal = false,\n}: Pick<XYChartKind<object>, 'skeleton' | 'horizontal'>) {\n if (skeleton === 'block') return <Skeleton sx={xyChartStyles.skeleton} />;\n return (\n <div\n aria-hidden=\"true\"\n {...css.attrs(xyChartStyles.skeletonBars, horizontal && xyChartStyles.skeletonBarsHorizontal)}\n >\n {SKELETON_BARS.map((percent, position) => (\n <Skeleton\n key={position}\n sx={[\n xyChartStyles.skeletonBar,\n horizontal\n ? xyChartStyles.skeletonBarSizeHorizontal(`${percent}%`)\n : xyChartStyles.skeletonBarSize(`${percent}%`),\n ]}\n />\n ))}\n </div>\n );\n}\n\n/** 直角坐标图表的公共实现(组件库内部用,见 BarChart、LineChart、AreaChart) */\nexport const XYChart = _component(\n <T extends object>({\n data,\n index,\n series,\n indexFormat,\n valueFormat,\n unit,\n height = 240,\n legend,\n grid = true,\n valueDomain,\n tooltip = true,\n loading = false,\n _hiddenSeries: hiddenSeries = _bindable<string[]>([]),\n empty,\n targets,\n annotations,\n bands,\n onItemClick,\n zoom = false,\n _zoomRange: zoomRange = _bindable<[number, number] | null>(null),\n kind,\n sx,\n ...rest\n }: XYChartProps<T> & { kind: XYChartKind<T> }) => {\n const lang = useLang();\n const format = useFormat();\n const id = useId();\n const resolved = _derived(resolveSeries(series));\n const visible = _derived(resolved.filter((item) => !hiddenSeries.includes(item.key)));\n\n const categoryText = (row: T | undefined) =>\n row === undefined\n ? ''\n : indexFormat\n ? indexFormat(row[index], row)\n : String(row[index] ?? '');\n const valueText = useChartValueText(() => ({ valueFormat, unit }));\n const secondaryText = useChartValueText(() => ({\n valueFormat: kind.secondary?.format,\n unit: kind.secondary?.unit,\n }));\n const onSecondary = (key: string) => kind.secondary?.keys.includes(key) ?? false;\n /** 一个系列的值的文字:第二数值轴上的按它的格式与单位 */\n const seriesText = (key: string, value: NumericValue | undefined) =>\n onSecondary(key) ? secondaryText(value) : valueText(value);\n /** 一行里显示中的系列的总和(百分比堆叠的分母;负数不计) */\n const rowTotal = (row: T) =>\n visible.reduce((sum, item) => sum + Math.max(seriesNumber(row, item.key) ?? 0, 0), 0);\n const percentText = (value: number) =>\n format.number(value, { style: 'percent', maximumFractionDigits: 1 });\n\n const xText = (row: T) => {\n const x = kind.continuousX?.value(row);\n return x === undefined ? lang.emptyValue : kind.continuousX!.format(x);\n };\n\n function toggle(key: string) {\n hiddenSeries = hiddenSeries.includes(key)\n ? hiddenSeries.filter((item) => item !== key)\n : [...hiddenSeries, key];\n }\n\n /** 缩放的滑块:两端是类目;缩小过时旁边有“显示全部” */\n const zoomBar = () => {\n const last = data.length - 1;\n return (\n <div {...css.attrs(xyChartStyles.zoom)}>\n <Slider\n _value={zoomRange ?? [0, last]}\n onUpdate:_value={(next: [number, number]) =>\n (zoomRange = next[0] === 0 && next[1] === last ? null : next)\n }\n min={0}\n max={last}\n step={1}\n size=\"sm\"\n valueText={(position) => categoryText(data[position])}\n aria-label={lang.chartZoom}\n propsRoot={{ sx: xyChartStyles.zoomSlider }}\n />\n {zoomRange && (\n <Button variant=\"link\" size=\"sm\" onClick={() => (zoomRange = null)}>\n {lang.chartZoomReset}\n </Button>\n )}\n </div>\n );\n };\n\n const instances = createChartInstances();\n let tooltipElement: HTMLElement | undefined;\n // 提示框的内容渲染进 Unovis 管的元素:带上调用处的主题与语言,组件卸载时一起卸载\n const renderDetached = useDetachedRender();\n\n // 指针所在的那一行:十字线移动时记下,点绘图区时下钻到它;离开绘图区时清掉\n let hovered: { row: T; index: number } | null = null;\n const hover = (row: T | undefined) => {\n hovered = row === undefined ? null : { row, index: data.indexOf(row) };\n };\n\n /** 十字线的提示框:内容用 Vue 渲染进同一个元素,交给 Unovis 定位 */\n function renderTooltip(row: T) {\n tooltipElement ??= document.createElement('div');\n // 跟着数据点的提示框(散点图)没有十字线:悬停哪个点就是哪一行\n if (kind.pointTooltip) hover(row);\n renderDetached(\n chartTooltip(\n categoryText(row),\n kind.tooltipItems?.(row) ?? [\n ...(kind.continuousX\n ? [{ label: kind.continuousX.label, color: 'transparent', value: xText(row) }]\n : []),\n // 跟着数据点的提示框只列这一行有值的系列(散点图里一行通常只落在一个系列上)\n ...visible\n .filter((item) => !kind.pointTooltip || seriesValue(row, item.key) !== undefined)\n .map((item) => {\n const value = seriesValue(row, item.key);\n const total = kind.percent ? rowTotal(row) : 0;\n return {\n label: item.label,\n color: item.color,\n value:\n kind.percent && value !== undefined && total > 0\n ? `${seriesText(item.key, value)}(${percentText(toNumber(value) / total)})`\n : seriesText(item.key, value),\n };\n }),\n ],\n ),\n tooltipElement,\n );\n return tooltipElement;\n }\n\n let plot = _state.raw<HTMLElement | null>(null);\n const seen = usePlotSeen(() => plot);\n let container: XYContainer<T> | undefined;\n let containerElement: HTMLElement | undefined;\n _effect(() => () => {\n container?.destroy();\n });\n _effect(() => {\n // 缩放:只画选中的一段(散点图的横轴是连续的数值,不按类目缩放)\n const range = zoom && !kind.continuousX ? zoomRange : null;\n const rows = range ? data.slice(range[0], range[1] + 1) : [...data];\n const shown = visible;\n const element = plot;\n if (!element || loading || rows.length === 0 || !seen()) return;\n // 绘图区换了元素:旧容器连同它的组件、坐标轴一起销毁,实例表清空后重新创建\n if (container && containerElement !== element) {\n container.destroy();\n container = undefined;\n instances.reset();\n }\n\n const primarySeries = shown.filter((item) => !onSecondary(item.key));\n const secondarySeries = shown.filter((item) => onSecondary(item.key));\n const totals = rows.map((row) =>\n primarySeries.map((item) => seriesNumber(row, item.key) ?? 0),\n );\n const seriesValues = kind.domainValues\n ? kind.domainValues(rows, primarySeries)\n : kind.stacked\n ? totals.flatMap((row) => [\n row.reduce((sum, value) => sum + Math.max(value, 0), 0),\n row.reduce((sum, value) => sum + Math.min(value, 0), 0),\n ])\n : totals.flat();\n // 目标线、数值轴上的区间要落在数值轴的范围里\n const values = [\n ...seriesValues,\n ...(targets ?? []).map((target) => toNumber(target.value)),\n ...(bands ?? [])\n .filter((band) => band.axis === 'value')\n .flatMap((band) => [Number(band.from), Number(band.to)]),\n ];\n // 第二数值轴:两条轴的刻度对齐,第二轴的值换算到主轴的坐标\n const aligned: AlignedAxes | undefined =\n secondarySeries.length > 0\n ? alignedTicks(\n [\n ...values,\n ...[valueDomain?.[0], valueDomain?.[1]].filter(\n (end): end is number => end !== undefined,\n ),\n ],\n rows.flatMap((row) =>\n secondarySeries.map((item) => seriesNumber(row, item.key) ?? 0),\n ),\n )\n : undefined;\n const domain: [number | undefined, number | undefined] = kind.percent\n ? [0, 1]\n : aligned\n ? aligned.primary.domain\n : [\n valueDomain?.[0] ??\n (kind.zeroBaseline === false ? undefined : Math.min(0, ...values)),\n valueDomain?.[1],\n ];\n const x = kind.continuousX\n ? (row: T) => kind.continuousX!.value(row) ?? Number.NaN\n : (_row: T, position: number) => position;\n const y = (item: (typeof shown)[number]) => {\n if (kind.percent)\n return (row: T) => {\n const value = seriesNumber(row, item.key);\n const total = rowTotal(row);\n return value === undefined || total === 0 ? undefined : value / total;\n };\n if (aligned && onSecondary(item.key))\n return (row: T) => {\n const value = seriesNumber(row, item.key);\n return value === undefined ? undefined : aligned.toPrimary(value);\n };\n return (row: T) => seriesNumber(row, item.key);\n };\n /** 类目在类目轴上的位置:散点图是横轴的数值,其余是第几行;找不到时 undefined */\n const positionOf = (at: unknown) => {\n if (kind.continuousX) return Number(at);\n const found = rows.findIndex((row) => row[index] === at);\n return found < 0 ? undefined : found;\n };\n const categoryAxisName = kind.horizontal ? AxisType.Y : AxisType.X;\n const valueAxisName = kind.horizontal ? AxisType.X : AxisType.Y;\n const lines = (targets ?? []).map((target, position) => {\n const line = instances.get(`target-${position}`, () => new Plotline<T>({}));\n const value = toNumber(target.value);\n const label = valueText(target.value);\n line.setConfig({\n axis: kind.horizontal ? 'x' : 'y',\n value,\n color: resolveColor(target.color ?? 'danger', 0),\n lineWidth: 1.5,\n lineStyle: PlotlineLineStylePresets.Dash,\n labelText: target.label ? `${target.label} ${label}` : label,\n labelPosition: kind.horizontal\n ? PlotlineLabelPosition.TopRight\n : PlotlineLabelPosition.TopLeft,\n labelOffsetX: 4,\n labelOffsetY: 10,\n });\n return line;\n });\n\n // 区间:浅色的带,文字在左上角\n const bandComponents = (bands ?? []).flatMap((band, position) => {\n const onIndex = band.axis !== 'value';\n const from = onIndex ? positionOf(band.from) : Number(band.from);\n const to = onIndex ? positionOf(band.to) : Number(band.to);\n if (from === undefined || to === undefined) return [];\n // 类目轴上的区间盖住两端的类目:往外各扩半格\n const half = onIndex && !kind.continuousX ? 0.5 : 0;\n const plotband = instances.get(`band-${position}`, () => new Plotband<T>({}));\n plotband.setConfig({\n axis: onIndex ? categoryAxisName : valueAxisName,\n from: Math.min(from, to) - half,\n to: Math.max(from, to) + half,\n color: `color-mix(in srgb, ${resolveColor(band.color ?? 'neutral', 0)} 12%, transparent)`,\n labelText: band.label,\n // 类目轴上的区间文字在左下角:顶上留给事件竖线的文字\n labelPosition: onIndex\n ? PlotbandLabelPosition.BottomLeftInside\n : PlotbandLabelPosition.TopLeftInside,\n labelColor: colors.textMuted,\n labelOffsetX: 6,\n labelOffsetY: 6,\n });\n return [plotband];\n });\n\n // 标注:事件是类目上的竖线;圈出的值是一个空心圈,文字在上方\n const events = (annotations ?? []).filter((item) => item.series === undefined);\n const eventLines = events.flatMap((item, position) => {\n const at = positionOf(item.at);\n if (at === undefined) return [];\n const line = instances.get(`event-${position}`, () => new Plotline<T>({}));\n line.setConfig({\n axis: categoryAxisName,\n value: at,\n color: resolveColor(item.color ?? 'neutral', 0),\n lineWidth: 1,\n lineStyle: PlotlineLineStylePresets.ShortDash,\n labelText: item.label,\n labelPosition: kind.horizontal\n ? PlotlineLabelPosition.BottomRight\n : PlotlineLabelPosition.TopRight,\n labelOffsetX: 4,\n labelOffsetY: 4,\n });\n return [line];\n });\n const marked = (annotations ?? []).filter(\n (item) => item.series !== undefined && !kind.horizontal,\n );\n const markOf = (row: T) => {\n const at = kind.continuousX ? kind.continuousX.value(row) : rows.indexOf(row);\n return marked.find(\n (item) =>\n positionOf(item.at) === at && shown.some((series) => series.key === item.series),\n );\n };\n /** 圈的位置:系列的值;堆叠时是它在这一摞里的顶端 */\n const markY = (row: T) => {\n const mark = markOf(row);\n if (!mark) return undefined;\n const series = shown.find((item) => item.key === mark.series)!;\n if (!kind.stacked || kind.percent) return y(series)(row);\n const upTo = shown.slice(0, shown.indexOf(series) + 1);\n return upTo.reduce((sum, item) => sum + Math.max(y(item)(row) ?? 0, 0), 0);\n };\n const markColor = (row: T) => {\n const mark = markOf(row);\n const series = shown.find((item) => item.key === mark?.series);\n return mark?.color ? resolveColor(mark.color, 0) : (series?.color ?? colors.textMuted);\n };\n const marks = instances.get('marks', () => new Scatter<T>({ x, y: () => undefined }));\n marks.setConfig({\n x,\n y: markY,\n size: 16,\n color: 'transparent',\n strokeColor: markColor,\n strokeWidth: 2,\n label: (row: T) => markOf(row)?.label ?? '',\n labelPosition: Position.Top,\n labelColor: colors.text,\n });\n\n // 第二数值轴的刻度:与主轴的刻度同高,文字在绘图区右侧(不裁剪的 Plotline 标签,线本身透明)\n const secondaryLabels = aligned\n ? aligned.secondary.ticks.map((tick, position) => {\n const label = instances.get(`secondary-${position}`, () => {\n const line = new Plotline<T>({});\n line.clippable = false;\n return line;\n });\n label.setConfig({\n axis: 'y',\n value: aligned.primary.ticks[position]!,\n color: 'transparent',\n lineWidth: 0,\n labelText: format.number(tick, kind.secondary?.format),\n labelPosition: PlotlineLabelPosition.Right,\n labelOffsetX: -(SECONDARY_AXIS_WIDTH - 4),\n labelColor: colors.textMuted,\n });\n return label;\n })\n : [];\n const components = [\n ...bandComponents,\n ...kind.components({\n series: shown,\n x,\n y,\n instance: instances.get,\n events:\n kind.itemSelector && onItemClick\n ? {\n [kind.itemSelector]: {\n // 分组柱给的是原来的行;堆叠柱给的是拼出来的副本,第三个参数才是行的位置\n click: (row: T, _event: Event, index: number) => {\n const position = data.indexOf(row);\n const at = position >= 0 ? position : index;\n onItemClick(data[at] ?? row, at);\n },\n },\n }\n : {},\n }),\n ...lines,\n ...eventLines,\n ...(marked.length > 0 ? [marks] : []),\n ...secondaryLabels,\n ];\n const xAxis = instances.get('xAxis', () => new Axis<T>({ type: 'x' }));\n const yAxis = instances.get('yAxis', () => new Axis<T>({ type: 'y' }));\n const crosshair = instances.get('crosshair', () => new Crosshair<T>());\n const tooltipBox = instances.get('tooltip', () => new Tooltip());\n const [categoryAxis, valueAxis] = kind.horizontal ? [yAxis, xAxis] : [xAxis, yAxis];\n const continuous = kind.continuousX;\n categoryAxis.setConfig({\n type: kind.horizontal ? 'y' : 'x',\n // 连续的横轴:Unovis 自己取刻度,网格线与数值轴一样;类目轴:每行一个刻度\n tickValues: continuous ? undefined : rows.map((_row, position) => position),\n numTicks: continuous ? 6 : undefined,\n tickFormat: continuous\n ? (tick) => continuous.format(Number(tick))\n : (tick) => categoryText(rows[Number(tick)]),\n gridLine: continuous ? grid : false,\n tickLine: false,\n domainLine: false,\n tickTextHideOverlapping: true,\n tickPadding: 8,\n label: continuous?.title,\n labelMargin: 8,\n });\n valueAxis.setConfig({\n type: kind.horizontal ? 'x' : 'y',\n numTicks: 5,\n // 有第二数值轴时用对齐的刻度,两边的刻度落在同一组网格线上\n tickValues: aligned?.primary.ticks,\n tickFormat: (tick) =>\n kind.percent\n ? format.number(Number(tick), { style: 'percent', maximumFractionDigits: 0 })\n : format.number(Number(tick), valueFormat),\n gridLine: grid,\n tickLine: false,\n domainLine: false,\n tickPadding: 8,\n });\n const dotted = kind.crosshairSeries ? shown.filter(kind.crosshairSeries) : shown;\n crosshair.setConfig({\n // 访问器直接给:容器还没按尺寸渲染过时不会把组件的访问器转交十字线,Unovis 会报 “Y accessors have not been configured”\n x,\n ...(kind.stacked ? { yStacked: dotted.map(y) } : { y: dotted.map(y) }),\n template: (row: T) => renderTooltip(row),\n color: (_row: T, position: number) => dotted[position]?.color ?? 'transparent',\n getCircles: kind.crosshairDots ? undefined : () => [],\n hideWhenFarFromPointer: false,\n onCrosshairMove: (_x, row) => hover(row),\n });\n\n tooltipBox.setConfig({\n triggers: kind.pointTooltip ? { [kind.pointTooltip]: (row: T) => renderTooltip(row) } : {},\n });\n const config = {\n components,\n xAxis,\n yAxis,\n // 能下钻时没有提示框也要十字线:靠它知道指针在哪一行\n crosshair:\n (tooltip || (onItemClick && !kind.itemSelector)) && !kind.pointTooltip\n ? crosshair\n : undefined,\n tooltip: tooltip ? tooltipBox : undefined,\n [kind.horizontal ? 'xDomain' : 'yDomain']: domain,\n // 第二数值轴的刻度文字画在右侧留出的空白里\n padding: aligned\n ? { ...kind.padding, right: Math.max(kind.padding?.right ?? 0, SECONDARY_AXIS_WIDTH) }\n : (kind.padding ?? {}),\n ariaLabel: null,\n duration: chartDuration(element),\n onRenderComplete: haloPlotlineLabels,\n };\n if (container) container.update(config, undefined, rows);\n else {\n container = new XYContainer<T>(element, config, rows);\n containerElement = element;\n uniqueHighlightFilter(element, `${id}-highlight`);\n }\n });\n\n return () => (\n <ChartFrame\n {...rest}\n sx={[!kind.crosshairDots && xyChartStyles.hideCrosshairLine, sx]}\n // 百分比堆叠时数值轴是占比:轴上方不写单位(提示框、数据表里仍带)\n unit={kind.percent ? undefined : unit}\n unitEnd={kind.secondary?.unit}\n height={height}\n legend={(legend ?? resolved.length > 1) ? resolved : []}\n hiddenKeys={hiddenSeries}\n onLegendToggle={toggle}\n loading={loading}\n skeleton={chartSkeleton(kind)}\n isEmpty={data.length === 0}\n empty={empty}\n clickable={onItemClick != null}\n onPlotClick={\n onItemClick && !kind.itemSelector\n ? () => {\n if (hovered) onItemClick(hovered.row, hovered.index);\n }\n : undefined\n }\n table={\n kind.table?.(data) ?? {\n columns: [\n lang.chartCategory,\n ...(kind.continuousX ? [kind.continuousX.label] : []),\n ...resolved.map((item) => {\n const itemUnit = onSecondary(item.key) ? kind.secondary?.unit : unit;\n return itemUnit ? `${item.label}(${itemUnit})` : item.label;\n }),\n ],\n rows: data.map((row) => ({\n header: categoryText(row),\n cells: [\n ...(kind.continuousX ? [xText(row)] : []),\n ...resolved.map((item) => {\n const value = seriesValue(row, item.key);\n return value === undefined\n ? lang.emptyValue\n : format.number(\n value,\n onSecondary(item.key) ? kind.secondary?.format : valueFormat,\n );\n }),\n ],\n })),\n }\n }\n plotRef={(element) => (plot = element)}\n footer={zoom && !kind.continuousX && data.length > 2 ? zoomBar() : undefined}\n />\n );\n },\n);\n\n/**\n * 目标线、事件竖线的文字描一圈表面色的边(同地图上地点的名字):压在柱子、折线上也看得清。\n * Unovis 的 Plotline 文字没有描边的配置项,渲染完成后补在元素上;导出图片时按计算样式一并带走\n */\nfunction haloPlotlineLabels(svg: SVGSVGElement) {\n for (const label of svg.querySelectorAll<SVGTextElement>('text[class*=\"plotline-label\"]')) {\n label.style.setProperty('paint-order', 'stroke');\n label.style.setProperty('stroke', colors.surface);\n label.style.setProperty('stroke-width', '3px');\n label.style.setProperty('stroke-linejoin', 'round');\n }\n}\n"],"mappings":"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"}
@@ -11,8 +11,8 @@ import { useFormat } from "../config/lang/format.js";
11
11
  import { Empty } from "../feedback/Empty.js";
12
12
  import { Menu as Menu$1, MenuItem } from "../overlay/Menu.js";
13
13
  import { exportChartData, exportChartImage } from "./export.js";
14
- import { createVNode, mergeProps, shallowRef, watch } from "vue";
15
- import { _component, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
14
+ import { createVNode, shallowRef, watch } from "vue";
15
+ import { _component, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
16
16
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
17
17
  import { Download, FileSpreadsheet, ImageDown } from "@lucide/icons";
18
18
  //#region src/charts/frame.tsx
@@ -136,7 +136,7 @@ var chartStyles = css.create({
136
136
  /** 提示框的一行 */
137
137
  /** 提示框的内容:标题(类目、扇区名)+ 每个系列一行;Unovis 定位,Vue 渲染 */
138
138
  function chartTooltip(title, items) {
139
- return createVNode("div", css.attrs(chartStyles.tooltip), [title && createVNode("div", css.attrs(chartStyles.tooltipTitle), [title]), items.map((item) => createVNode("div", mergeProps({ "key": item.label }, css.attrs(chartStyles.tooltipRow)), [
139
+ return createVNode("div", css.attrs(chartStyles.tooltip), [title && createVNode("div", css.attrs(chartStyles.tooltipTitle), [title]), items.map((item) => createVNode("div", mergeJsxProps({ "key": item.label }, css.attrs(chartStyles.tooltipRow)), [
140
140
  createVNode("span", css.attrs(chartStyles.swatch, chartStyles.swatchColor(item.color)), null),
141
141
  createVNode("span", css.attrs(chartStyles.tooltipLabel), [item.label]),
142
142
  createVNode("span", css.attrs(chartStyles.tooltipValue), [item.value])
@@ -255,7 +255,7 @@ var ChartFrame = /*#__PURE__*/ _component((_props, _ctx) => {
255
255
  let plotElement = null;
256
256
  const fileName = () => exportName.value ?? rest["aria-label"] ?? lang.chartExportName;
257
257
  /** 导出菜单:图片要绘图区里有 SVG(漏斗图这类直接用 HTML 画的没有) */
258
- const exportMenu = () => createVNode(Menu$1, { "trigger": _cache[0] || (_cache[0] = (props) => createVNode(IconButton, mergeProps(props, {
258
+ const exportMenu = () => createVNode(Menu$1, { "trigger": _cache[0] || (_cache[0] = (props) => createVNode(IconButton, mergeJsxProps(props, {
259
259
  "icon": Download,
260
260
  "variant": "ghost",
261
261
  "tone": "neutral",
@@ -266,13 +266,15 @@ var ChartFrame = /*#__PURE__*/ _component((_props, _ctx) => {
266
266
  "onAction": _cache[1] || (_cache[1] = () => {
267
267
  const svg = plotElement?.querySelector("svg");
268
268
  if (svg) exportChartImage(svg, fileName());
269
- })
269
+ }),
270
+ "key": "__site0"
270
271
  }, {
271
272
  default: () => [lang.chartExportImage],
272
273
  $stable: true
273
274
  }), createVNode(MenuItem, {
274
275
  "icon": FileSpreadsheet,
275
- "onAction": _cache[2] || (_cache[2] = () => exportChartData(table.value, format, fileName()))
276
+ "onAction": _cache[2] || (_cache[2] = () => exportChartData(table.value, format, fileName())),
277
+ "key": "__site1"
276
278
  }, {
277
279
  default: () => [lang.chartExportData],
278
280
  $stable: true
@@ -291,7 +293,7 @@ var ChartFrame = /*#__PURE__*/ _component((_props, _ctx) => {
291
293
  unit.value && createVNode("span", mergeAttrs({ sx: chartStyles.unit }, propsUnit.value), [unit.value]),
292
294
  legend.value.length > 0 && createVNode("div", mergeAttrs({ sx: chartStyles.legend }, propsLegend.value, { role: "group" }), [legend.value.map((item) => {
293
295
  const off = hiddenKeys.value.includes(item.key);
294
- return createVNode(ButtonBase, mergeProps({ "key": item.key }, mergePartProps({
296
+ return createVNode(ButtonBase, mergeJsxProps({ "key": item.key }, mergePartProps({
295
297
  sx: [chartStyles.legendItem, off && chartStyles.legendItemHidden],
296
298
  ripple: false
297
299
  }, propsLegendItem.value, {
@@ -303,7 +305,7 @@ var ChartFrame = /*#__PURE__*/ _component((_props, _ctx) => {
303
305
  !isEmpty.value && !loading.value && actions.value,
304
306
  exportable.value && !isEmpty.value && !loading.value && exportMenu()
305
307
  ]),
306
- body ? createVNode("div", mergeProps({ "key": "state" }, css.attrs(chartStyles.plot, css.bind(chartStyles.plotHeight, () => [plotHeight]))), [body]) : createVNode("div", mergeProps({ "key": "plot" }, mergeAttrs({ sx: [
308
+ body ? createVNode("div", mergeJsxProps({ "key": "state" }, css.attrs(chartStyles.plot, css.bind(chartStyles.plotHeight, () => [plotHeight]))), [body]) : createVNode("div", mergeJsxProps({ "key": "plot" }, mergeAttrs({ sx: [
307
309
  chartStyles.plot,
308
310
  css.bind(chartStyles.plotHeight, () => [plotHeight]),
309
311
  (clickable.value || onPlotClick.value) && chartStyles.plotClickable
@@ -1 +1 @@
1
- {"version":3,"file":"frame.js","names":["_createVNode","_mergeProps","_vtp_readonlyProp","_vtp_restProps","Menu"],"sources":["../../src/charts/frame.tsx"],"sourcesContent":["/**\n * 各种图表共用的外层结构(XYChart、DonutChart、SankeyChart、ChordChart、FunnelChart、GraphChart):外层 figure、单位与图例、绘图区(加载中的骨架、空状态、Unovis 画布)、\n * 给读屏的数据表;还有提示框的内容、Unovis 实例表与主题变量。\n *\n * <ChartFrame unit=\"万元\" legend={items} hiddenKeys={hidden} onLegendToggle={toggle} loading={loading}\n * isEmpty={rows.length === 0} skeleton={…} table={{ columns, rows }} plotRef={(el) => (plot = el)} />\n *\n * 外观全走主题:Unovis 的样式由 --vis-* 变量控制,这里把它们指到 tokens 上;系列颜色是 CSS 变量,\n * 切换主题、改品牌色都不用重画。绘图区对读屏隐藏,数据由同样内容的表格读出。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { shallowRef, watch, type VNodeChild } from 'vue';\nimport { Download, FileSpreadsheet, ImageDown } from '@lucide/icons';\nimport { ButtonBase, type ButtonBaseProps } from '../base/ButtonBase';\nimport { IconButton } from '../base/IconButton';\nimport { Menu, MenuItem } from '../overlay/Menu';\nimport { exportChartData, exportChartImage } from './export';\nimport { visuallyHiddenStyles } from '../base/VisuallyHidden';\nimport { useLang } from '../config/context';\nimport { useFormat, type NumericFormat } from '../config/lang/format';\nimport {\n borderWidths,\n colors,\n durations,\n fonts,\n fontSizes,\n fontWeights,\n radii,\n shadows,\n space,\n t,\n} from '../config/theme/tokens';\nimport { Empty } from '../feedback/Empty';\nimport type { NumericValue } from '../utils/data/numeric';\nimport { themeTransition } from '../utils/motion/animation';\nimport { useEventListener } from '../utils/dom/event-listener';\nimport { useIntersectionObserver } from '../utils/dom/intersection';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\n\n/** 图例里的一项 */\nexport interface ChartLegendItem {\n /** 系列(或扇区)的 key */\n key: string;\n /** 显示的名字 */\n label: string;\n /** CSS 颜色 */\n color: string;\n}\n\n/** 给读屏的数据表:列名与每一行(行标题加各列的文字) */\nexport interface ChartTable {\n /** 列名:第一列是行标题的列 */\n columns: readonly string[];\n /** 每一行:行标题加其余各列的文字 */\n rows: readonly { header: string; cells: readonly string[] }[];\n}\n\n/** 各种图表共有的选项与部件属性 */\nexport interface ChartFrameParts {\n /** 右上角的导出菜单:绘图区存成 PNG 图片、数据表存成 CSV */\n exportable?: boolean;\n /** 导出的文件名(不含扩展名);不写时用图表的名称(aria-label) */\n exportName?: string;\n /** 图表上方一行(单位与图例)的部件属性 */\n propsHeader?: PartProps<'div'>;\n /** 单位的部件属性 */\n propsUnit?: PartProps<'span'>;\n /** 图例的部件属性 */\n propsLegend?: PartProps<'div', 'role'>;\n /** 图例每一项(按钮)的部件属性 */\n propsLegendItem?: Omit<Partial<ButtonBaseProps>, 'aria-pressed' | 'onClick'>;\n /** 绘图区(Unovis 画在这里)的部件属性 */\n propsPlot?: PartProps<'div', 'aria-hidden'>;\n /** 给读屏的数据表的部件属性 */\n propsTable?: PartProps<'table'>;\n}\n\n/** 图表共用的样式:root(--vis-* 主题变量)、header、unit、legend、swatch、plot、tooltip… */\nexport const chartStyles = css.create({\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: '_sm',\n // 在居中、弹性布局的容器里也占满一行:绘图区按容器宽度自适应\n width: '100%',\n minWidth: 0,\n fontSize: '_sm',\n // Unovis 的外观变量:坐标轴、网格、十字线、提示框、标签都指到主题 tokens\n '--vis-font-family': fonts.sans,\n '--vis-axis-tick-label-font-size': fontSizes.xs,\n '--vis-axis-tick-label-color': colors.textMuted,\n '--vis-axis-label-color': colors.textMuted,\n '--vis-axis-label-font-size': fontSizes.xs,\n '--vis-axis-label-weight': fontWeights.normal,\n '--vis-axis-grid-color': colors.borderMuted,\n '--vis-axis-domain-color': colors.border,\n '--vis-axis-tick-color': colors.border,\n '--vis-crosshair-line-stroke-color': colors.borderStrong,\n '--vis-crosshair-circle-stroke-color': colors.surface,\n '--vis-tooltip-background-color': colors.surfaceRaised,\n '--vis-tooltip-border-color': colors.borderMuted,\n '--vis-tooltip-text-color': colors.text,\n '--vis-tooltip-border-radius': radii.md,\n '--vis-tooltip-box-shadow': shadows.md,\n '--vis-tooltip-padding': `${space.sm} ${space.md}`,\n '--vis-tooltip-backdrop-filter': 'none',\n '--vis-tooltip-transition-duration': durations.sm,\n '--vis-grouped-bar-hover-stroke-width': '0',\n // 环形图:底色、扇区之间的缝、中间的标签\n '--vis-donut-background-color': colors.fill,\n '--vis-donut-segment-stroke-width': borderWidths.md,\n '--vis-donut-central-label-text-color': colors.text,\n '--vis-donut-central-label-font-size': fontSizes.xl,\n '--vis-donut-central-sub-label-text-color': colors.textMuted,\n '--vis-donut-central-sub-label-font-size': fontSizes.xs,\n // 目标线:虚线,标签是小号的次要文字(颜色由各条线自己给)\n '--vis-plotline-label-font-size': fontSizes.xs,\n '--vis-plotline-label-color': colors.textMuted,\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '_md',\n minHeight: '1.5em',\n },\n unit: { color: '_textMuted', fontSize: '_xs' },\n legend: {\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n gap: `${t.space.xs} ${t.space.md}`,\n marginInlineStart: 'auto',\n },\n // 图例项:ButtonBase 给出焦点环与按下的反馈,这里只定文字\n legendItem: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '_xs',\n color: { default: '_textMuted', ':hover': '_text' },\n fontSize: '_xs',\n borderRadius: '_sm',\n },\n // 隐藏的系列:划线、色块变空心;不降低不透明度,文字仍要满足对比度\n legendItemHidden: { textDecorationLine: 'line-through' },\n swatch: {\n width: '0.625em',\n height: '0.625em',\n borderRadius: '_sm',\n flexShrink: 0,\n },\n swatchColor: (color: string) => ({ backgroundColor: color }),\n swatchHidden: (color: string) => ({\n backgroundColor: 'transparent',\n boxShadow: `inset 0 0 0 ${borderWidths.md} ${color}`,\n }),\n // contain: inline-size:画好的 SVG 写死了宽度,不能让它反过来撑住按内容定宽的外层(表格式的滚动区、\n // 起始对齐的弹性布局);不然容器变窄时图表还是原来那么宽,Unovis 量不到变化也就不重画\n plot: { position: 'relative', minWidth: 0, contain: 'inline-size' },\n // 点了能下钻:手形指针\n plotClickable: { cursor: 'pointer' },\n plotHeight: (height: string) => ({ height }),\n center: { display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' },\n tooltip: { display: 'flex', flexDirection: 'column', gap: '_xs', fontSize: '_xs' },\n tooltipTitle: { fontWeight: '_semibold' },\n tooltipRow: { display: 'flex', alignItems: 'center', gap: '_sm' },\n tooltipLabel: { color: '_textMuted', flexGrow: 1 },\n tooltipValue: {\n fontVariantNumeric: 'tabular-nums',\n fontWeight: '_medium',\n marginInlineStart: '_lg',\n },\n});\n\n/** 提示框的一行 */\nexport interface ChartTooltipItem {\n /** 系列或数值的名字 */\n label: string;\n /** 色块的 CSS 颜色;transparent 时不画色块 */\n color: string;\n /** 格式化好的数值 */\n value: string;\n}\n\n/** 提示框的内容:标题(类目、扇区名)+ 每个系列一行;Unovis 定位,Vue 渲染 */\nexport function chartTooltip(title: string, items: readonly ChartTooltipItem[]) {\n return (\n <div {...css.attrs(chartStyles.tooltip)}>\n {title && <div {...css.attrs(chartStyles.tooltipTitle)}>{title}</div>}\n {items.map((item) => (\n <div key={item.label} {...css.attrs(chartStyles.tooltipRow)}>\n <span {...css.attrs(chartStyles.swatch, chartStyles.swatchColor(item.color))} />\n <span {...css.attrs(chartStyles.tooltipLabel)}>{item.label}</span>\n <span {...css.attrs(chartStyles.tooltipValue)}>{item.value}</span>\n </div>\n ))}\n </div>\n );\n}\n\n/**\n * 图表里数值的文字(提示框、读屏数据表、扇区标签):按 valueFormat 格式化、带上单位;\n * 没有值时是语言包的 emptyValue。setup 里调用,返回的函数在渲染里用\n */\nexport function useChartValueText(read: () => { valueFormat?: NumericFormat; unit?: string }) {\n const lang = useLang();\n const format = useFormat();\n return (value: NumericValue | undefined) => {\n if (value === undefined) return lang.emptyValue;\n const { valueFormat, unit } = read();\n return format.number(value, unit ? { ...valueFormat, suffix: unit } : valueFormat);\n };\n}\n\n/** 绘图区离视口多近就算看见了(px):滚到之前先画好,进来时已经是画好的 */\nconst SEEN_MARGIN = 200;\n\n/**\n * 绘图区进入过视口:之前不画,进来之后一直算看见(滚出去不拆掉)。一页很多图表时先画看得见的,\n * 其余的滚到附近再画(地图、网络图绘制很重)。在 setup 里调用,绘制的 effect 里读返回的函数。\n * 挂上时就在视口附近的立即算看见(不等观察器的第一次回调;没有布局的测试环境里框都在原点,也算看见);\n * 打印前全部画上;没有 IntersectionObserver 的环境当作看见了。\n */\nexport function usePlotSeen(plot: () => HTMLElement | null | undefined): () => boolean {\n const seen = shallowRef(typeof IntersectionObserver === 'undefined');\n const near = (element: Element) => {\n const box = element.getBoundingClientRect();\n return (\n box.top < window.innerHeight + SEEN_MARGIN &&\n box.bottom > -SEEN_MARGIN &&\n box.left < window.innerWidth + SEEN_MARGIN &&\n box.right > -SEEN_MARGIN\n );\n };\n watch(\n plot,\n (element) => {\n if (element && !seen.value && near(element)) seen.value = true;\n },\n { immediate: true, flush: 'post' },\n );\n useIntersectionObserver(\n () => (seen.value ? null : plot()),\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) seen.value = true;\n },\n () => ({ rootMargin: `${SEEN_MARGIN}px` }),\n );\n useEventListener(\n () => window,\n 'beforeprint',\n () => (seen.value = true),\n );\n return () => seen.value;\n}\n\n/** 主题的 lg 时长(毫秒),减少动态效果时为 0;读不到(元素不在主题范围内)时不要动画 */\nexport function chartDuration(element: Element): number {\n try {\n return themeTransition(element, { duration: 'lg' }).duration ?? 0;\n } catch {\n return 0;\n }\n}\n\n/**\n * Unovis 每个容器都插一个 id 固定为 saturate 的滤镜(悬停高亮用),一页多张图时 id 重复;\n * 改成每张图自己的 id,并让引用它的 CSS 变量指过去\n */\nexport function uniqueHighlightFilter(element: HTMLElement, id: string): void {\n const filter = element.querySelector<SVGFilterElement>('filter#saturate');\n if (!filter) return;\n filter.id = id;\n element.querySelector('svg')?.style.setProperty('--highlight-filter-id', `url(#${id})`);\n}\n\n/**\n * Unovis 实例表:组件、坐标轴、十字线只建一次,之后 setConfig + update(保留实例才有过渡动画)。\n * 容器 destroy 时会连带销毁这些实例:重建容器前 reset,下次取用时重新创建\n */\nexport function createChartInstances() {\n let instances = new Map<string, unknown>();\n return {\n /** 取一个实例:第一次调用时创建 */\n get: <C,>(key: string, create: () => C): C => {\n if (!instances.has(key)) instances.set(key, create());\n return instances.get(key) as C;\n },\n /** 容器销毁了:清空,之后重新创建 */\n reset() {\n instances = new Map();\n },\n };\n}\n\n/** ChartFrame 的属性:未声明的属性落到外层 div(role=\"figure\")上 */\nexport interface ChartFrameProps extends PartProps<'div', 'role' | 'aria-busy'>, ChartFrameParts {\n /** 单位:显示在左上方 */\n unit?: string;\n /** 第二数值轴的单位:显示在右上方(组合图) */\n unitEnd?: string;\n /** 绘图区的高度 */\n height: number | string;\n /** 图例的各项;空数组时不显示图例 */\n legend: readonly ChartLegendItem[];\n /** 图例里隐藏着的项 */\n hiddenKeys: readonly string[];\n /** 点了图例的一项 */\n onLegendToggle: (key: string) => void;\n /** 加载中:绘图区显示 skeleton,外层带 aria-busy */\n loading: boolean;\n /** 加载中显示的骨架 */\n skeleton: VNodeChild;\n /** 没有数据:绘图区显示空状态,没有数据表 */\n isEmpty: boolean;\n /** 空状态的内容,默认是“暂无数据” */\n empty?: VNodeChild;\n /** 给读屏的数据表 */\n table: ChartTable;\n /** 取得绘图区元素(Unovis 画在这里);加载、空状态之后重新出现时是新的元素 */\n plotRef?: (element: HTMLElement | null) => void;\n /** 绘图区里直接渲染的内容(不用 Unovis 的图,如漏斗图);同样对读屏隐藏 */\n plot?: VNodeChild;\n /** 绘图区下面的内容(缩放的滑块、地图的色带) */\n footer?: VNodeChild;\n /** 上方一行右端的操作(地图的缩放按钮),在导出菜单前面 */\n actions?: VNodeChild;\n /** 点了绘图区(下钻):写了它时指针是手形 */\n onPlotClick?: () => void;\n /** 图里的项能点(手形指针),点击由图自己处理(环形图的扇区、网络图的节点) */\n clickable?: boolean;\n}\n\n/** 图表的外层结构 */\nexport const ChartFrame = _component(\n ({\n unit,\n unitEnd,\n height,\n legend,\n hiddenKeys,\n onLegendToggle,\n loading,\n skeleton,\n isEmpty,\n empty,\n table,\n plotRef,\n footer,\n actions,\n plot,\n onPlotClick,\n clickable = false,\n propsHeader,\n propsUnit,\n propsLegend,\n propsLegendItem,\n propsPlot,\n propsTable,\n exportable = false,\n exportName,\n ...rest\n }: ChartFrameProps) => {\n const lang = useLang();\n const format = useFormat();\n let plotElement: HTMLElement | null = null;\n const fileName = () => exportName ?? rest['aria-label'] ?? lang.chartExportName;\n /** 导出菜单:图片要绘图区里有 SVG(漏斗图这类直接用 HTML 画的没有) */\n const exportMenu = () => (\n <Menu\n trigger={(props) => (\n <IconButton\n {...props}\n icon={Download}\n variant=\"ghost\"\n tone=\"neutral\"\n size=\"sm\"\n aria-label={lang.chartExport}\n />\n )}\n >\n <MenuItem\n icon={ImageDown}\n onAction={() => {\n const svg = plotElement?.querySelector('svg');\n if (svg) void exportChartImage(svg, fileName());\n }}\n >\n {lang.chartExportImage}\n </MenuItem>\n <MenuItem\n icon={FileSpreadsheet}\n onAction={() => exportChartData(table, format, fileName())}\n >\n {lang.chartExportData}\n </MenuItem>\n </Menu>\n );\n return () => {\n const plotHeight = typeof height === 'number' ? `${height}px` : height;\n const body = loading ? (\n skeleton\n ) : isEmpty ? (\n <div {...css.attrs(chartStyles.center)}>\n {empty ?? <Empty size=\"sm\" title={lang.chartEmpty} />}\n </div>\n ) : null;\n return (\n <div\n {...mergeAttrs<'div'>({ sx: chartStyles.root }, rest, {\n role: 'figure',\n 'aria-busy': loading || undefined,\n })}\n >\n {(unit || unitEnd || legend.length > 0 || exportable || actions) && (\n <div {...mergeAttrs<'div'>({ sx: chartStyles.header }, propsHeader)}>\n {unit && (\n <span {...mergeAttrs<'span'>({ sx: chartStyles.unit }, propsUnit)}>{unit}</span>\n )}\n {legend.length > 0 && (\n <div\n {...mergeAttrs<'div'>({ sx: chartStyles.legend }, propsLegend, { role: 'group' })}\n >\n {legend.map((item) => {\n const off = hiddenKeys.includes(item.key);\n return (\n <ButtonBase\n key={item.key}\n {...mergePartProps<ButtonBaseProps>(\n {\n sx: [chartStyles.legendItem, off && chartStyles.legendItemHidden],\n ripple: false,\n },\n propsLegendItem,\n { 'aria-pressed': !off, onClick: () => onLegendToggle(item.key) },\n )}\n >\n <span\n {...css.attrs(\n chartStyles.swatch,\n off\n ? chartStyles.swatchHidden(item.color)\n : chartStyles.swatchColor(item.color),\n )}\n />\n {item.label}\n </ButtonBase>\n );\n })}\n </div>\n )}\n {unitEnd && (\n <span {...mergeAttrs<'span'>({ sx: chartStyles.unit }, propsUnit)}>{unitEnd}</span>\n )}\n {!isEmpty && !loading && actions}\n {exportable && !isEmpty && !loading && exportMenu()}\n </div>\n )}\n {/* key 不同:两种状态不复用同一个 div,否则 Unovis 画进去的 svg 会留在骨架、空状态里 */}\n {body ? (\n <div key=\"state\" {...css.attrs(chartStyles.plot, chartStyles.plotHeight(plotHeight))}>\n {body}\n </div>\n ) : (\n <div\n key=\"plot\"\n {...mergeAttrs<'div'>(\n {\n sx: [\n chartStyles.plot,\n chartStyles.plotHeight(plotHeight),\n (clickable || onPlotClick) && chartStyles.plotClickable,\n ],\n },\n propsPlot,\n {\n 'aria-hidden': true,\n ref: (element: unknown) => {\n plotElement = element instanceof HTMLElement ? element : null;\n plotRef?.(plotElement);\n },\n onClick: onPlotClick,\n },\n )}\n >\n {plot}\n </div>\n )}\n {!body && footer}\n {!isEmpty && (\n <table {...mergeAttrs<'table'>({ sx: visuallyHiddenStyles.hidden }, propsTable)}>\n <thead>\n <tr>\n {table.columns.map((column) => (\n <th key={column} scope=\"col\">\n {column}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {table.rows.map((row, position) => (\n <tr key={position}>\n <th scope=\"row\">{row.header}</th>\n {row.cells.map((cell, column) => (\n <td key={column}>{cell}</td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n )}\n </div>\n );\n };\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"frame.js","names":["_createVNode","_mergeProps","_vtp_readonlyProp","_vtp_restProps","Menu"],"sources":["../../src/charts/frame.tsx"],"sourcesContent":["/**\n * 各种图表共用的外层结构(XYChart、DonutChart、SankeyChart、ChordChart、FunnelChart、GraphChart):外层 figure、单位与图例、绘图区(加载中的骨架、空状态、Unovis 画布)、\n * 给读屏的数据表;还有提示框的内容、Unovis 实例表与主题变量。\n *\n * <ChartFrame unit=\"万元\" legend={items} hiddenKeys={hidden} onLegendToggle={toggle} loading={loading}\n * isEmpty={rows.length === 0} skeleton={…} table={{ columns, rows }} plotRef={(el) => (plot = el)} />\n *\n * 外观全走主题:Unovis 的样式由 --vis-* 变量控制,这里把它们指到 tokens 上;系列颜色是 CSS 变量,\n * 切换主题、改品牌色都不用重画。绘图区对读屏隐藏,数据由同样内容的表格读出。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { shallowRef, watch, type VNodeChild } from 'vue';\nimport { Download, FileSpreadsheet, ImageDown } from '@lucide/icons';\nimport { ButtonBase, type ButtonBaseProps } from '../base/ButtonBase';\nimport { IconButton } from '../base/IconButton';\nimport { Menu, MenuItem } from '../overlay/Menu';\nimport { exportChartData, exportChartImage } from './export';\nimport { visuallyHiddenStyles } from '../base/VisuallyHidden';\nimport { useLang } from '../config/context';\nimport { useFormat, type NumericFormat } from '../config/lang/format';\nimport {\n borderWidths,\n colors,\n durations,\n fonts,\n fontSizes,\n fontWeights,\n radii,\n shadows,\n space,\n t,\n} from '../config/theme/tokens';\nimport { Empty } from '../feedback/Empty';\nimport type { NumericValue } from '../utils/data/numeric';\nimport { themeTransition } from '../utils/motion/animation';\nimport { useEventListener } from '../utils/dom/event-listener';\nimport { useIntersectionObserver } from '../utils/dom/intersection';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\n\n/** 图例里的一项 */\nexport interface ChartLegendItem {\n /** 系列(或扇区)的 key */\n key: string;\n /** 显示的名字 */\n label: string;\n /** CSS 颜色 */\n color: string;\n}\n\n/** 给读屏的数据表:列名与每一行(行标题加各列的文字) */\nexport interface ChartTable {\n /** 列名:第一列是行标题的列 */\n columns: readonly string[];\n /** 每一行:行标题加其余各列的文字 */\n rows: readonly { header: string; cells: readonly string[] }[];\n}\n\n/** 各种图表共有的选项与部件属性 */\nexport interface ChartFrameParts {\n /** 右上角的导出菜单:绘图区存成 PNG 图片、数据表存成 CSV */\n exportable?: boolean;\n /** 导出的文件名(不含扩展名);不写时用图表的名称(aria-label) */\n exportName?: string;\n /** 图表上方一行(单位与图例)的部件属性 */\n propsHeader?: PartProps<'div'>;\n /** 单位的部件属性 */\n propsUnit?: PartProps<'span'>;\n /** 图例的部件属性 */\n propsLegend?: PartProps<'div', 'role'>;\n /** 图例每一项(按钮)的部件属性 */\n propsLegendItem?: Omit<Partial<ButtonBaseProps>, 'aria-pressed' | 'onClick'>;\n /** 绘图区(Unovis 画在这里)的部件属性 */\n propsPlot?: PartProps<'div', 'aria-hidden'>;\n /** 给读屏的数据表的部件属性 */\n propsTable?: PartProps<'table'>;\n}\n\n/** 图表共用的样式:root(--vis-* 主题变量)、header、unit、legend、swatch、plot、tooltip… */\nexport const chartStyles = css.create({\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: '_sm',\n // 在居中、弹性布局的容器里也占满一行:绘图区按容器宽度自适应\n width: '100%',\n minWidth: 0,\n fontSize: '_sm',\n // Unovis 的外观变量:坐标轴、网格、十字线、提示框、标签都指到主题 tokens\n '--vis-font-family': fonts.sans,\n '--vis-axis-tick-label-font-size': fontSizes.xs,\n '--vis-axis-tick-label-color': colors.textMuted,\n '--vis-axis-label-color': colors.textMuted,\n '--vis-axis-label-font-size': fontSizes.xs,\n '--vis-axis-label-weight': fontWeights.normal,\n '--vis-axis-grid-color': colors.borderMuted,\n '--vis-axis-domain-color': colors.border,\n '--vis-axis-tick-color': colors.border,\n '--vis-crosshair-line-stroke-color': colors.borderStrong,\n '--vis-crosshair-circle-stroke-color': colors.surface,\n '--vis-tooltip-background-color': colors.surfaceRaised,\n '--vis-tooltip-border-color': colors.borderMuted,\n '--vis-tooltip-text-color': colors.text,\n '--vis-tooltip-border-radius': radii.md,\n '--vis-tooltip-box-shadow': shadows.md,\n '--vis-tooltip-padding': `${space.sm} ${space.md}`,\n '--vis-tooltip-backdrop-filter': 'none',\n '--vis-tooltip-transition-duration': durations.sm,\n '--vis-grouped-bar-hover-stroke-width': '0',\n // 环形图:底色、扇区之间的缝、中间的标签\n '--vis-donut-background-color': colors.fill,\n '--vis-donut-segment-stroke-width': borderWidths.md,\n '--vis-donut-central-label-text-color': colors.text,\n '--vis-donut-central-label-font-size': fontSizes.xl,\n '--vis-donut-central-sub-label-text-color': colors.textMuted,\n '--vis-donut-central-sub-label-font-size': fontSizes.xs,\n // 目标线:虚线,标签是小号的次要文字(颜色由各条线自己给)\n '--vis-plotline-label-font-size': fontSizes.xs,\n '--vis-plotline-label-color': colors.textMuted,\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '_md',\n minHeight: '1.5em',\n },\n unit: { color: '_textMuted', fontSize: '_xs' },\n legend: {\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'flex-end',\n gap: `${t.space.xs} ${t.space.md}`,\n marginInlineStart: 'auto',\n },\n // 图例项:ButtonBase 给出焦点环与按下的反馈,这里只定文字\n legendItem: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '_xs',\n color: { default: '_textMuted', ':hover': '_text' },\n fontSize: '_xs',\n borderRadius: '_sm',\n },\n // 隐藏的系列:划线、色块变空心;不降低不透明度,文字仍要满足对比度\n legendItemHidden: { textDecorationLine: 'line-through' },\n swatch: {\n width: '0.625em',\n height: '0.625em',\n borderRadius: '_sm',\n flexShrink: 0,\n },\n swatchColor: (color: string) => ({ backgroundColor: color }),\n swatchHidden: (color: string) => ({\n backgroundColor: 'transparent',\n boxShadow: `inset 0 0 0 ${borderWidths.md} ${color}`,\n }),\n // contain: inline-size:画好的 SVG 写死了宽度,不能让它反过来撑住按内容定宽的外层(表格式的滚动区、\n // 起始对齐的弹性布局);不然容器变窄时图表还是原来那么宽,Unovis 量不到变化也就不重画\n plot: { position: 'relative', minWidth: 0, contain: 'inline-size' },\n // 点了能下钻:手形指针\n plotClickable: { cursor: 'pointer' },\n plotHeight: (height: string) => ({ height }),\n center: { display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' },\n tooltip: { display: 'flex', flexDirection: 'column', gap: '_xs', fontSize: '_xs' },\n tooltipTitle: { fontWeight: '_semibold' },\n tooltipRow: { display: 'flex', alignItems: 'center', gap: '_sm' },\n tooltipLabel: { color: '_textMuted', flexGrow: 1 },\n tooltipValue: {\n fontVariantNumeric: 'tabular-nums',\n fontWeight: '_medium',\n marginInlineStart: '_lg',\n },\n});\n\n/** 提示框的一行 */\nexport interface ChartTooltipItem {\n /** 系列或数值的名字 */\n label: string;\n /** 色块的 CSS 颜色;transparent 时不画色块 */\n color: string;\n /** 格式化好的数值 */\n value: string;\n}\n\n/** 提示框的内容:标题(类目、扇区名)+ 每个系列一行;Unovis 定位,Vue 渲染 */\nexport function chartTooltip(title: string, items: readonly ChartTooltipItem[]) {\n return (\n <div {...css.attrs(chartStyles.tooltip)}>\n {title && <div {...css.attrs(chartStyles.tooltipTitle)}>{title}</div>}\n {items.map((item) => (\n <div key={item.label} {...css.attrs(chartStyles.tooltipRow)}>\n <span {...css.attrs(chartStyles.swatch, chartStyles.swatchColor(item.color))} />\n <span {...css.attrs(chartStyles.tooltipLabel)}>{item.label}</span>\n <span {...css.attrs(chartStyles.tooltipValue)}>{item.value}</span>\n </div>\n ))}\n </div>\n );\n}\n\n/**\n * 图表里数值的文字(提示框、读屏数据表、扇区标签):按 valueFormat 格式化、带上单位;\n * 没有值时是语言包的 emptyValue。setup 里调用,返回的函数在渲染里用\n */\nexport function useChartValueText(read: () => { valueFormat?: NumericFormat; unit?: string }) {\n const lang = useLang();\n const format = useFormat();\n return (value: NumericValue | undefined) => {\n if (value === undefined) return lang.emptyValue;\n const { valueFormat, unit } = read();\n return format.number(value, unit ? { ...valueFormat, suffix: unit } : valueFormat);\n };\n}\n\n/** 绘图区离视口多近就算看见了(px):滚到之前先画好,进来时已经是画好的 */\nconst SEEN_MARGIN = 200;\n\n/**\n * 绘图区进入过视口:之前不画,进来之后一直算看见(滚出去不拆掉)。一页很多图表时先画看得见的,\n * 其余的滚到附近再画(地图、网络图绘制很重)。在 setup 里调用,绘制的 effect 里读返回的函数。\n * 挂上时就在视口附近的立即算看见(不等观察器的第一次回调;没有布局的测试环境里框都在原点,也算看见);\n * 打印前全部画上;没有 IntersectionObserver 的环境当作看见了。\n */\nexport function usePlotSeen(plot: () => HTMLElement | null | undefined): () => boolean {\n const seen = shallowRef(typeof IntersectionObserver === 'undefined');\n const near = (element: Element) => {\n const box = element.getBoundingClientRect();\n return (\n box.top < window.innerHeight + SEEN_MARGIN &&\n box.bottom > -SEEN_MARGIN &&\n box.left < window.innerWidth + SEEN_MARGIN &&\n box.right > -SEEN_MARGIN\n );\n };\n watch(\n plot,\n (element) => {\n if (element && !seen.value && near(element)) seen.value = true;\n },\n { immediate: true, flush: 'post' },\n );\n useIntersectionObserver(\n () => (seen.value ? null : plot()),\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) seen.value = true;\n },\n () => ({ rootMargin: `${SEEN_MARGIN}px` }),\n );\n useEventListener(\n () => window,\n 'beforeprint',\n () => (seen.value = true),\n );\n return () => seen.value;\n}\n\n/** 主题的 lg 时长(毫秒),减少动态效果时为 0;读不到(元素不在主题范围内)时不要动画 */\nexport function chartDuration(element: Element): number {\n try {\n return themeTransition(element, { duration: 'lg' }).duration ?? 0;\n } catch {\n return 0;\n }\n}\n\n/**\n * Unovis 每个容器都插一个 id 固定为 saturate 的滤镜(悬停高亮用),一页多张图时 id 重复;\n * 改成每张图自己的 id,并让引用它的 CSS 变量指过去\n */\nexport function uniqueHighlightFilter(element: HTMLElement, id: string): void {\n const filter = element.querySelector<SVGFilterElement>('filter#saturate');\n if (!filter) return;\n filter.id = id;\n element.querySelector('svg')?.style.setProperty('--highlight-filter-id', `url(#${id})`);\n}\n\n/**\n * Unovis 实例表:组件、坐标轴、十字线只建一次,之后 setConfig + update(保留实例才有过渡动画)。\n * 容器 destroy 时会连带销毁这些实例:重建容器前 reset,下次取用时重新创建\n */\nexport function createChartInstances() {\n let instances = new Map<string, unknown>();\n return {\n /** 取一个实例:第一次调用时创建 */\n get: <C,>(key: string, create: () => C): C => {\n if (!instances.has(key)) instances.set(key, create());\n return instances.get(key) as C;\n },\n /** 容器销毁了:清空,之后重新创建 */\n reset() {\n instances = new Map();\n },\n };\n}\n\n/** ChartFrame 的属性:未声明的属性落到外层 div(role=\"figure\")上 */\nexport interface ChartFrameProps extends PartProps<'div', 'role' | 'aria-busy'>, ChartFrameParts {\n /** 单位:显示在左上方 */\n unit?: string;\n /** 第二数值轴的单位:显示在右上方(组合图) */\n unitEnd?: string;\n /** 绘图区的高度 */\n height: number | string;\n /** 图例的各项;空数组时不显示图例 */\n legend: readonly ChartLegendItem[];\n /** 图例里隐藏着的项 */\n hiddenKeys: readonly string[];\n /** 点了图例的一项 */\n onLegendToggle: (key: string) => void;\n /** 加载中:绘图区显示 skeleton,外层带 aria-busy */\n loading: boolean;\n /** 加载中显示的骨架 */\n skeleton: VNodeChild;\n /** 没有数据:绘图区显示空状态,没有数据表 */\n isEmpty: boolean;\n /** 空状态的内容,默认是“暂无数据” */\n empty?: VNodeChild;\n /** 给读屏的数据表 */\n table: ChartTable;\n /** 取得绘图区元素(Unovis 画在这里);加载、空状态之后重新出现时是新的元素 */\n plotRef?: (element: HTMLElement | null) => void;\n /** 绘图区里直接渲染的内容(不用 Unovis 的图,如漏斗图);同样对读屏隐藏 */\n plot?: VNodeChild;\n /** 绘图区下面的内容(缩放的滑块、地图的色带) */\n footer?: VNodeChild;\n /** 上方一行右端的操作(地图的缩放按钮),在导出菜单前面 */\n actions?: VNodeChild;\n /** 点了绘图区(下钻):写了它时指针是手形 */\n onPlotClick?: () => void;\n /** 图里的项能点(手形指针),点击由图自己处理(环形图的扇区、网络图的节点) */\n clickable?: boolean;\n}\n\n/** 图表的外层结构 */\nexport const ChartFrame = _component(\n ({\n unit,\n unitEnd,\n height,\n legend,\n hiddenKeys,\n onLegendToggle,\n loading,\n skeleton,\n isEmpty,\n empty,\n table,\n plotRef,\n footer,\n actions,\n plot,\n onPlotClick,\n clickable = false,\n propsHeader,\n propsUnit,\n propsLegend,\n propsLegendItem,\n propsPlot,\n propsTable,\n exportable = false,\n exportName,\n ...rest\n }: ChartFrameProps) => {\n const lang = useLang();\n const format = useFormat();\n let plotElement: HTMLElement | null = null;\n const fileName = () => exportName ?? rest['aria-label'] ?? lang.chartExportName;\n /** 导出菜单:图片要绘图区里有 SVG(漏斗图这类直接用 HTML 画的没有) */\n const exportMenu = () => (\n <Menu\n trigger={(props) => (\n <IconButton\n {...props}\n icon={Download}\n variant=\"ghost\"\n tone=\"neutral\"\n size=\"sm\"\n aria-label={lang.chartExport}\n />\n )}\n >\n <MenuItem\n icon={ImageDown}\n onAction={() => {\n const svg = plotElement?.querySelector('svg');\n if (svg) void exportChartImage(svg, fileName());\n }}\n >\n {lang.chartExportImage}\n </MenuItem>\n <MenuItem\n icon={FileSpreadsheet}\n onAction={() => exportChartData(table, format, fileName())}\n >\n {lang.chartExportData}\n </MenuItem>\n </Menu>\n );\n return () => {\n const plotHeight = typeof height === 'number' ? `${height}px` : height;\n const body = loading ? (\n skeleton\n ) : isEmpty ? (\n <div {...css.attrs(chartStyles.center)}>\n {empty ?? <Empty size=\"sm\" title={lang.chartEmpty} />}\n </div>\n ) : null;\n return (\n <div\n {...mergeAttrs<'div'>({ sx: chartStyles.root }, rest, {\n role: 'figure',\n 'aria-busy': loading || undefined,\n })}\n >\n {(unit || unitEnd || legend.length > 0 || exportable || actions) && (\n <div {...mergeAttrs<'div'>({ sx: chartStyles.header }, propsHeader)}>\n {unit && (\n <span {...mergeAttrs<'span'>({ sx: chartStyles.unit }, propsUnit)}>{unit}</span>\n )}\n {legend.length > 0 && (\n <div\n {...mergeAttrs<'div'>({ sx: chartStyles.legend }, propsLegend, { role: 'group' })}\n >\n {legend.map((item) => {\n const off = hiddenKeys.includes(item.key);\n return (\n <ButtonBase\n key={item.key}\n {...mergePartProps<ButtonBaseProps>(\n {\n sx: [chartStyles.legendItem, off && chartStyles.legendItemHidden],\n ripple: false,\n },\n propsLegendItem,\n { 'aria-pressed': !off, onClick: () => onLegendToggle(item.key) },\n )}\n >\n <span\n {...css.attrs(\n chartStyles.swatch,\n off\n ? chartStyles.swatchHidden(item.color)\n : chartStyles.swatchColor(item.color),\n )}\n />\n {item.label}\n </ButtonBase>\n );\n })}\n </div>\n )}\n {unitEnd && (\n <span {...mergeAttrs<'span'>({ sx: chartStyles.unit }, propsUnit)}>{unitEnd}</span>\n )}\n {!isEmpty && !loading && actions}\n {exportable && !isEmpty && !loading && exportMenu()}\n </div>\n )}\n {/* key 不同:两种状态不复用同一个 div,否则 Unovis 画进去的 svg 会留在骨架、空状态里 */}\n {body ? (\n <div key=\"state\" {...css.attrs(chartStyles.plot, chartStyles.plotHeight(plotHeight))}>\n {body}\n </div>\n ) : (\n <div\n key=\"plot\"\n {...mergeAttrs<'div'>(\n {\n sx: [\n chartStyles.plot,\n chartStyles.plotHeight(plotHeight),\n (clickable || onPlotClick) && chartStyles.plotClickable,\n ],\n },\n propsPlot,\n {\n 'aria-hidden': true,\n ref: (element: unknown) => {\n plotElement = element instanceof HTMLElement ? element : null;\n plotRef?.(plotElement);\n },\n onClick: onPlotClick,\n },\n )}\n >\n {plot}\n </div>\n )}\n {!body && footer}\n {!isEmpty && (\n <table {...mergeAttrs<'table'>({ sx: visuallyHiddenStyles.hidden }, propsTable)}>\n <thead>\n <tr>\n {table.columns.map((column) => (\n <th key={column} scope=\"col\">\n {column}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {table.rows.map((row, position) => (\n <tr key={position}>\n <th scope=\"row\">{row.header}</th>\n {row.cells.map((cell, column) => (\n <td key={column}>{cell}</td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n )}\n </div>\n );\n };\n },\n);\n"],"mappings":"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"}