@primeui/chart-core 0.0.1-alpha.1

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 (299) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +1 -0
  3. package/dist/animations/index.d.mts +136 -0
  4. package/dist/animations/index.mjs +18 -0
  5. package/dist/annotation.utils-Bm0lOO1o.d.mts +290 -0
  6. package/dist/borderRadius.utils-Cz73LLR_.d.mts +54 -0
  7. package/dist/canvas-D4vigq47.d.mts +34 -0
  8. package/dist/canvas.utils-D2WHi2gL.d.mts +167 -0
  9. package/dist/cartesian/index.d.mts +94 -0
  10. package/dist/cartesian/index.mjs +93 -0
  11. package/dist/chunk-22ST6YPP.mjs +304 -0
  12. package/dist/chunk-2QK2KOBN.mjs +10 -0
  13. package/dist/chunk-2QRS4YQ5.mjs +18 -0
  14. package/dist/chunk-3FFJEX4A.mjs +261 -0
  15. package/dist/chunk-3IYSJ2U7.mjs +567 -0
  16. package/dist/chunk-3OZLP4I4.mjs +190 -0
  17. package/dist/chunk-3WEMHXZI.mjs +198 -0
  18. package/dist/chunk-3Z62EUJN.mjs +138 -0
  19. package/dist/chunk-4C6EVJ54.mjs +362 -0
  20. package/dist/chunk-53HW45JB.mjs +102 -0
  21. package/dist/chunk-55Y3WI6S.mjs +186 -0
  22. package/dist/chunk-5JCI2DEB.mjs +97 -0
  23. package/dist/chunk-66T4MRC5.mjs +113 -0
  24. package/dist/chunk-6HSEJLSR.mjs +376 -0
  25. package/dist/chunk-6STOLMCA.mjs +187 -0
  26. package/dist/chunk-7CMVDIOU.mjs +54 -0
  27. package/dist/chunk-7QQ6ETB4.mjs +228 -0
  28. package/dist/chunk-A6ZQZFL2.mjs +272 -0
  29. package/dist/chunk-ADKLH73T.mjs +1 -0
  30. package/dist/chunk-AGU3NG6D.mjs +22 -0
  31. package/dist/chunk-AHYIS6EB.mjs +230 -0
  32. package/dist/chunk-AP3UYWYT.mjs +4 -0
  33. package/dist/chunk-ARB5T6MP.mjs +326 -0
  34. package/dist/chunk-ARRGOEFX.mjs +585 -0
  35. package/dist/chunk-AUF4CHDP.mjs +422 -0
  36. package/dist/chunk-B4FTADAZ.mjs +561 -0
  37. package/dist/chunk-BABQKA6K.mjs +339 -0
  38. package/dist/chunk-BETFQBM2.mjs +197 -0
  39. package/dist/chunk-BKP26M4K.mjs +413 -0
  40. package/dist/chunk-BZN2QHGP.mjs +200 -0
  41. package/dist/chunk-C36VWQ7A.mjs +86 -0
  42. package/dist/chunk-CHW4RKY3.mjs +16 -0
  43. package/dist/chunk-CINXJIRR.mjs +120 -0
  44. package/dist/chunk-DN6AXQYZ.mjs +667 -0
  45. package/dist/chunk-DP2IZNN3.mjs +92 -0
  46. package/dist/chunk-DTWTCFRG.mjs +119 -0
  47. package/dist/chunk-EAMUNLRU.mjs +172 -0
  48. package/dist/chunk-EDAKJLNA.mjs +17 -0
  49. package/dist/chunk-ERVQB2VZ.mjs +59 -0
  50. package/dist/chunk-FFMT6OCO.mjs +92 -0
  51. package/dist/chunk-FHTC2YDB.mjs +102 -0
  52. package/dist/chunk-FRST55HY.mjs +16 -0
  53. package/dist/chunk-HDFGCN2F.mjs +132 -0
  54. package/dist/chunk-IEGLX7VL.mjs +42 -0
  55. package/dist/chunk-ILUWFYGY.mjs +220 -0
  56. package/dist/chunk-IXOWSEHO.mjs +114 -0
  57. package/dist/chunk-J4RI2C2G.mjs +172 -0
  58. package/dist/chunk-J65DBT4R.mjs +13 -0
  59. package/dist/chunk-JGOVWSKH.mjs +179 -0
  60. package/dist/chunk-JO7VACY2.mjs +25 -0
  61. package/dist/chunk-JWFBOPM6.mjs +122 -0
  62. package/dist/chunk-KNDZP446.mjs +895 -0
  63. package/dist/chunk-KP2TWD4Z.mjs +90 -0
  64. package/dist/chunk-KQIFO5I3.mjs +225 -0
  65. package/dist/chunk-KVDEROP6.mjs +59 -0
  66. package/dist/chunk-LKC7MZKK.mjs +87 -0
  67. package/dist/chunk-LVMDQ4OJ.mjs +305 -0
  68. package/dist/chunk-M7B3JF43.mjs +90 -0
  69. package/dist/chunk-MTGMXRNF.mjs +136 -0
  70. package/dist/chunk-N3TIT3OH.mjs +1040 -0
  71. package/dist/chunk-NHRK5KU2.mjs +890 -0
  72. package/dist/chunk-NKUYIWAP.mjs +243 -0
  73. package/dist/chunk-NPDZLYIF.mjs +238 -0
  74. package/dist/chunk-O2X6FF45.mjs +499 -0
  75. package/dist/chunk-OGJ6IIBW.mjs +176 -0
  76. package/dist/chunk-OHGCZZPZ.mjs +403 -0
  77. package/dist/chunk-OWW3K55O.mjs +351 -0
  78. package/dist/chunk-OXTFAWSK.mjs +60 -0
  79. package/dist/chunk-PLSDU3C2.mjs +890 -0
  80. package/dist/chunk-PRDVPOZX.mjs +223 -0
  81. package/dist/chunk-Q6PPVIHU.mjs +21 -0
  82. package/dist/chunk-QQBXUDM4.mjs +885 -0
  83. package/dist/chunk-QS76E3TD.mjs +111 -0
  84. package/dist/chunk-QWQ6HY4I.mjs +209 -0
  85. package/dist/chunk-R6Y3R7EW.mjs +135 -0
  86. package/dist/chunk-RBLZRT5K.mjs +190 -0
  87. package/dist/chunk-RO4N6YFS.mjs +167 -0
  88. package/dist/chunk-RQ3CKQOX.mjs +984 -0
  89. package/dist/chunk-SALTGZFR.mjs +208 -0
  90. package/dist/chunk-SANZPAJ4.mjs +14 -0
  91. package/dist/chunk-SDBPQ5CF.mjs +624 -0
  92. package/dist/chunk-SSLTFJ3U.mjs +364 -0
  93. package/dist/chunk-SXHVDJGF.mjs +77 -0
  94. package/dist/chunk-TA4MVAEX.mjs +243 -0
  95. package/dist/chunk-TAHCOZHF.mjs +1772 -0
  96. package/dist/chunk-TQ6S34QZ.mjs +152 -0
  97. package/dist/chunk-UPRXABX5.mjs +90 -0
  98. package/dist/chunk-VGLSBZDN.mjs +71 -0
  99. package/dist/chunk-VN7CKCSE.mjs +364 -0
  100. package/dist/chunk-VVI3OBPJ.mjs +524 -0
  101. package/dist/chunk-VWF57TS3.mjs +62 -0
  102. package/dist/chunk-WA3OVISZ.mjs +179 -0
  103. package/dist/chunk-WCG35U6M.mjs +964 -0
  104. package/dist/chunk-WFTX4AQJ.mjs +194 -0
  105. package/dist/chunk-WFVOQ2QZ.mjs +18 -0
  106. package/dist/chunk-WH3C3Y7P.mjs +149 -0
  107. package/dist/chunk-WPFUV7K3.mjs +488 -0
  108. package/dist/chunk-WRULPWHD.mjs +492 -0
  109. package/dist/chunk-WS64BZXT.mjs +1 -0
  110. package/dist/chunk-WY4AURRE.mjs +2419 -0
  111. package/dist/chunk-WYLILAOO.mjs +167 -0
  112. package/dist/chunk-X4D7FKUS.mjs +62 -0
  113. package/dist/chunk-X7T34OLW.mjs +139 -0
  114. package/dist/chunk-XIHBK5D3.mjs +68 -0
  115. package/dist/chunk-XQQCGFYB.mjs +50 -0
  116. package/dist/chunk-XTVE4P3L.mjs +214 -0
  117. package/dist/chunk-XUAASRXW.mjs +579 -0
  118. package/dist/chunk-Y3L3D4GQ.mjs +685 -0
  119. package/dist/chunk-YBJ56XJS.mjs +132 -0
  120. package/dist/chunk-ZQFK6CAE.mjs +1 -0
  121. package/dist/chunk-ZT2Z7ERM.mjs +874 -0
  122. package/dist/chunk-ZTL2FQEW.mjs +714 -0
  123. package/dist/circular/arc/index.d.mts +8 -0
  124. package/dist/circular/arc/index.mjs +3 -0
  125. package/dist/circular/index.d.mts +44 -0
  126. package/dist/circular/index.mjs +13 -0
  127. package/dist/collect.utils-DiKB4ciO.d.mts +12 -0
  128. package/dist/computeChartState-BTVIqwyO.d.mts +304 -0
  129. package/dist/controller-BJE1AZ3q.d.mts +82 -0
  130. package/dist/controller-BoNigQJr.d.mts +63 -0
  131. package/dist/controllers/index.d.mts +16 -0
  132. package/dist/controllers/index.mjs +110 -0
  133. package/dist/datalabel.utils-CkjGeB8S.d.mts +122 -0
  134. package/dist/decimation.utils-CcvJVhI4.d.mts +244 -0
  135. package/dist/geometry-DUUQJXVM.d.mts +60 -0
  136. package/dist/index-DseIZa1j.d.mts +167 -0
  137. package/dist/index.d.mts +88 -0
  138. package/dist/index.mjs +110 -0
  139. package/dist/orchestrator/index.d.mts +264 -0
  140. package/dist/orchestrator/index.mjs +33 -0
  141. package/dist/plugins/index.d.mts +18 -0
  142. package/dist/plugins/index.mjs +1 -0
  143. package/dist/property-animations-D433wXzz.d.mts +580 -0
  144. package/dist/property-store-NORUWFND.d.mts +17 -0
  145. package/dist/radial/index.d.mts +14 -0
  146. package/dist/radial/index.mjs +37 -0
  147. package/dist/renderers/axis/index.d.mts +39 -0
  148. package/dist/renderers/axis/index.mjs +8 -0
  149. package/dist/renderers/circular/index.d.mts +13 -0
  150. package/dist/renderers/circular/index.mjs +13 -0
  151. package/dist/renderers/index.d.mts +83 -0
  152. package/dist/renderers/index.mjs +75 -0
  153. package/dist/renderers/navigator/index.d.mts +103 -0
  154. package/dist/renderers/navigator/index.mjs +8 -0
  155. package/dist/resize.utils-D_2qm6rv.d.mts +142 -0
  156. package/dist/ring.utils-DXvrxMkU.d.mts +138 -0
  157. package/dist/scale-KFv30jqZ.d.mts +307 -0
  158. package/dist/scales-Drf8AIhL.d.mts +75 -0
  159. package/dist/series/bar/canvas/index.d.mts +8 -0
  160. package/dist/series/bar/canvas/index.mjs +10 -0
  161. package/dist/series/bar/controller/index.d.mts +105 -0
  162. package/dist/series/bar/controller/index.mjs +44 -0
  163. package/dist/series/bar/controller-canvas/index.d.mts +7 -0
  164. package/dist/series/bar/controller-canvas/index.mjs +49 -0
  165. package/dist/series/bar/controller-svg/index.d.mts +7 -0
  166. package/dist/series/bar/controller-svg/index.mjs +49 -0
  167. package/dist/series/bar/index.d.mts +60 -0
  168. package/dist/series/bar/index.mjs +13 -0
  169. package/dist/series/bar/svg/index.d.mts +8 -0
  170. package/dist/series/bar/svg/index.mjs +11 -0
  171. package/dist/series/candlestick/canvas/index.d.mts +8 -0
  172. package/dist/series/candlestick/canvas/index.mjs +8 -0
  173. package/dist/series/candlestick/controller/index.d.mts +123 -0
  174. package/dist/series/candlestick/controller/index.mjs +40 -0
  175. package/dist/series/candlestick/controller-canvas/index.d.mts +7 -0
  176. package/dist/series/candlestick/controller-canvas/index.mjs +45 -0
  177. package/dist/series/candlestick/controller-svg/index.d.mts +7 -0
  178. package/dist/series/candlestick/controller-svg/index.mjs +45 -0
  179. package/dist/series/candlestick/index.d.mts +11 -0
  180. package/dist/series/candlestick/index.mjs +10 -0
  181. package/dist/series/candlestick/svg/index.d.mts +8 -0
  182. package/dist/series/candlestick/svg/index.mjs +8 -0
  183. package/dist/series/heatmap/canvas/index.d.mts +16 -0
  184. package/dist/series/heatmap/canvas/index.mjs +9 -0
  185. package/dist/series/heatmap/controller/index.d.mts +110 -0
  186. package/dist/series/heatmap/controller/index.mjs +23 -0
  187. package/dist/series/heatmap/controller-canvas/index.d.mts +7 -0
  188. package/dist/series/heatmap/controller-canvas/index.mjs +28 -0
  189. package/dist/series/heatmap/controller-svg/index.d.mts +7 -0
  190. package/dist/series/heatmap/controller-svg/index.mjs +28 -0
  191. package/dist/series/heatmap/index.d.mts +34 -0
  192. package/dist/series/heatmap/index.mjs +13 -0
  193. package/dist/series/heatmap/svg/index.d.mts +15 -0
  194. package/dist/series/heatmap/svg/index.mjs +10 -0
  195. package/dist/series/line/canvas/index.d.mts +6 -0
  196. package/dist/series/line/canvas/index.mjs +9 -0
  197. package/dist/series/line/controller/index.d.mts +111 -0
  198. package/dist/series/line/controller/index.mjs +47 -0
  199. package/dist/series/line/controller-canvas/index.d.mts +7 -0
  200. package/dist/series/line/controller-canvas/index.mjs +54 -0
  201. package/dist/series/line/controller-svg/index.d.mts +7 -0
  202. package/dist/series/line/controller-svg/index.mjs +54 -0
  203. package/dist/series/line/index.d.mts +49 -0
  204. package/dist/series/line/index.mjs +13 -0
  205. package/dist/series/line/svg/index.d.mts +6 -0
  206. package/dist/series/line/svg/index.mjs +9 -0
  207. package/dist/series/pie/canvas/index.d.mts +8 -0
  208. package/dist/series/pie/canvas/index.mjs +10 -0
  209. package/dist/series/pie/controller/index.d.mts +174 -0
  210. package/dist/series/pie/controller/index.mjs +110 -0
  211. package/dist/series/pie/controller-canvas/index.d.mts +8 -0
  212. package/dist/series/pie/controller-canvas/index.mjs +119 -0
  213. package/dist/series/pie/controller-svg/index.d.mts +8 -0
  214. package/dist/series/pie/controller-svg/index.mjs +118 -0
  215. package/dist/series/pie/index.d.mts +59 -0
  216. package/dist/series/pie/index.mjs +15 -0
  217. package/dist/series/pie/svg/index.d.mts +6 -0
  218. package/dist/series/pie/svg/index.mjs +11 -0
  219. package/dist/series/polar/canvas/index.d.mts +6 -0
  220. package/dist/series/polar/canvas/index.mjs +7 -0
  221. package/dist/series/polar/controller/index.d.mts +102 -0
  222. package/dist/series/polar/controller/index.mjs +46 -0
  223. package/dist/series/polar/controller-canvas/index.d.mts +8 -0
  224. package/dist/series/polar/controller-canvas/index.mjs +52 -0
  225. package/dist/series/polar/controller-svg/index.d.mts +8 -0
  226. package/dist/series/polar/controller-svg/index.mjs +52 -0
  227. package/dist/series/polar/index.d.mts +25 -0
  228. package/dist/series/polar/index.mjs +16 -0
  229. package/dist/series/polar/svg/index.d.mts +10 -0
  230. package/dist/series/polar/svg/index.mjs +8 -0
  231. package/dist/series/radar/canvas/index.d.mts +6 -0
  232. package/dist/series/radar/canvas/index.mjs +8 -0
  233. package/dist/series/radar/controller/index.d.mts +121 -0
  234. package/dist/series/radar/controller/index.mjs +43 -0
  235. package/dist/series/radar/controller-canvas/index.d.mts +8 -0
  236. package/dist/series/radar/controller-canvas/index.mjs +51 -0
  237. package/dist/series/radar/controller-svg/index.d.mts +8 -0
  238. package/dist/series/radar/controller-svg/index.mjs +51 -0
  239. package/dist/series/radar/index.d.mts +40 -0
  240. package/dist/series/radar/index.mjs +13 -0
  241. package/dist/series/radar/svg/index.d.mts +12 -0
  242. package/dist/series/radar/svg/index.mjs +9 -0
  243. package/dist/series/scatter/canvas/index.d.mts +8 -0
  244. package/dist/series/scatter/canvas/index.mjs +11 -0
  245. package/dist/series/scatter/controller/index.d.mts +124 -0
  246. package/dist/series/scatter/controller/index.mjs +44 -0
  247. package/dist/series/scatter/controller-canvas/index.d.mts +7 -0
  248. package/dist/series/scatter/controller-canvas/index.mjs +51 -0
  249. package/dist/series/scatter/controller-svg/index.d.mts +7 -0
  250. package/dist/series/scatter/controller-svg/index.mjs +51 -0
  251. package/dist/series/scatter/index.d.mts +25 -0
  252. package/dist/series/scatter/index.mjs +14 -0
  253. package/dist/series/scatter/svg/index.d.mts +8 -0
  254. package/dist/series/scatter/svg/index.mjs +12 -0
  255. package/dist/series/treemap/canvas/index.d.mts +50 -0
  256. package/dist/series/treemap/canvas/index.mjs +10 -0
  257. package/dist/series/treemap/controller/index.d.mts +130 -0
  258. package/dist/series/treemap/controller/index.mjs +20 -0
  259. package/dist/series/treemap/controller-canvas/index.d.mts +7 -0
  260. package/dist/series/treemap/controller-canvas/index.mjs +25 -0
  261. package/dist/series/treemap/controller-svg/index.d.mts +7 -0
  262. package/dist/series/treemap/controller-svg/index.mjs +25 -0
  263. package/dist/series/treemap/index.d.mts +15 -0
  264. package/dist/series/treemap/index.mjs +12 -0
  265. package/dist/series/treemap/svg/index.d.mts +15 -0
  266. package/dist/series/treemap/svg/index.mjs +9 -0
  267. package/dist/slices-DtewiwJx.d.mts +72 -0
  268. package/dist/spatialIndex.utils-B_GJkotZ.d.mts +5 -0
  269. package/dist/squarify.utils-B9CQBpa1.d.mts +50 -0
  270. package/dist/stacking-CChuAcLN.d.mts +319 -0
  271. package/dist/streaming.utils-DH-g1gNP.d.mts +49 -0
  272. package/dist/sync/index.d.mts +130 -0
  273. package/dist/sync/index.mjs +5 -0
  274. package/dist/tooltip.renderer-D5wpSlBa.d.mts +210 -0
  275. package/dist/utils/color/index.d.mts +58 -0
  276. package/dist/utils/color/index.mjs +4 -0
  277. package/dist/utils/data/index.d.mts +180 -0
  278. package/dist/utils/data/index.mjs +7 -0
  279. package/dist/utils/export/index.d.mts +14 -0
  280. package/dist/utils/export/index.mjs +6 -0
  281. package/dist/utils/index.d.mts +49 -0
  282. package/dist/utils/index.mjs +29 -0
  283. package/dist/utils/interaction/index.d.mts +255 -0
  284. package/dist/utils/interaction/index.mjs +9 -0
  285. package/dist/utils/layout/index.d.mts +3 -0
  286. package/dist/utils/layout/index.mjs +10 -0
  287. package/dist/utils/math/index.d.mts +162 -0
  288. package/dist/utils/math/index.mjs +1 -0
  289. package/dist/utils/render/index.d.mts +19 -0
  290. package/dist/utils/render/index.mjs +3 -0
  291. package/dist/utils/specialized/index.d.mts +37 -0
  292. package/dist/utils/specialized/index.mjs +66 -0
  293. package/dist/utils/text/index.d.mts +39 -0
  294. package/dist/utils/text/index.mjs +8 -0
  295. package/dist/utils/theme/index.d.mts +295 -0
  296. package/dist/utils/theme/index.mjs +5 -0
  297. package/dist/utils/zoom/index.d.mts +90 -0
  298. package/dist/utils/zoom/index.mjs +3 -0
  299. package/package.json +56 -0
@@ -0,0 +1,2419 @@
1
+ import { advanceCategoryLerp, initCategoryLerp, snapCategoryLerp, initTimeDomainLerp, initDomainLerp, initDomainLerpTickFade, snapDomainLerp, snapTimeDomainLerp, advanceDomainLerp, advanceTimeDomainLerp } from './chunk-KNDZP446.mjs';
2
+ import { transformValues, computeStackBases, detectCartesianMode, computeWaterfallBases } from './chunk-WFTX4AQJ.mjs';
3
+ import { renderCartesianOverlay } from './chunk-QQBXUDM4.mjs';
4
+ import { computeBarDatasetTotals } from './chunk-7QQ6ETB4.mjs';
5
+ import { calculateAxisSpace, calculateAxisLayout } from './chunk-ZTL2FQEW.mjs';
6
+ import { parseAnimationConfig } from './chunk-3WEMHXZI.mjs';
7
+ import { getResponsiveTier, getAdaptiveDefaults, getAdaptiveTickCount } from './chunk-YBJ56XJS.mjs';
8
+ import { cancelRaf, raf } from './chunk-EDAKJLNA.mjs';
9
+ import { computeCartesianDomain, selectGroupingInterval, groupTimeData, resolveIncludeZero, computeDomainContribution, mergeDomainContributions, expandScatterBubblePadding, expandDataLabelPadding, computeVisibleValues } from './chunk-22ST6YPP.mjs';
10
+ import { collectItems } from './chunk-FFMT6OCO.mjs';
11
+ import { measureTextWidth } from './chunk-XTVE4P3L.mjs';
12
+ import { resolveFontSize, DEFAULT_GROUP_LABEL_FONT_SIZE, DEFAULT_TICK_FONT_SIZE, DEFAULT_DATA_LABEL_FONT_SIZE, DEFAULT_BRACKET_GAP, DEFAULT_BRACKET_DEPTH_LAYER_SIZE } from './chunk-NKUYIWAP.mjs';
13
+ import { decimate } from './chunk-OWW3K55O.mjs';
14
+ import { batchResolveRequired, batchResolveAccessor, FIELD_DEFAULTS, resolveAccessor, makeItemContext } from './chunk-O2X6FF45.mjs';
15
+ import { generateNiceTicks, calculateNiceDomain, toTimestamp, generateTimeTicks, formatTimeTick, generateIntervalTicks, createBandScale, calculateNiceTimeDomain, MS, createOrdinalTimeScale, createOrdinalTimeBandAdapter, createTimeScale, createTimeBandAdapter, createVariwideBandScale, createLogScale, createLinearScale, calculateGroupedBarLayout, calculateNiceLogDomain } from './chunk-RQ3CKQOX.mjs';
16
+
17
+ // src/cartesian/chart-area.ts
18
+ function isLayoutCriticalFeature(type) {
19
+ return type.startsWith("axisGroup") || type === "stacking";
20
+ }
21
+ function computeNaturalAxisWidths(naturalArea, chartArea) {
22
+ return {
23
+ left: naturalArea.x - chartArea.x,
24
+ right: chartArea.x + chartArea.width - naturalArea.x - naturalArea.width
25
+ };
26
+ }
27
+ function needsAxisPadding(naturalArea, chartArea, maxWidths) {
28
+ const { left, right } = computeNaturalAxisWidths(naturalArea, chartArea);
29
+ return left < maxWidths.left || right < maxWidths.right;
30
+ }
31
+ function estimateStackedValueDomain(perDataset, distinctStackIds, tickCount, exactTickCount, includeZero) {
32
+ if (perDataset.length === 0) return null;
33
+ const series = perDataset.map((d) => ({
34
+ values: d.values,
35
+ categories: d.categoryField ? batchResolveRequired(d.categoryField, d.data, "categoryField") : d.values.map((_, i) => String(i)),
36
+ stackId: d.stackId
37
+ }));
38
+ const catIndex = /* @__PURE__ */ new Map();
39
+ for (const d of series) {
40
+ for (const c of d.categories) {
41
+ if (!catIndex.has(c)) catIndex.set(c, catIndex.size);
42
+ }
43
+ }
44
+ const categoryCount = Math.max(1, catIndex.size);
45
+ const align = (d) => {
46
+ const arr = new Array(categoryCount).fill(0);
47
+ for (let i = 0; i < d.values.length; i++) {
48
+ const ci = catIndex.get(d.categories[i] ?? String(i));
49
+ const v = d.values[i];
50
+ if (ci !== void 0 && typeof v === "number" && !Number.isNaN(v)) arr[ci] += v;
51
+ }
52
+ return arr;
53
+ };
54
+ if (distinctStackIds > 1) {
55
+ const groupSums = /* @__PURE__ */ new Map();
56
+ for (const d of series) {
57
+ const sid = d.stackId ?? "";
58
+ const sums = groupSums.get(sid) ?? new Array(categoryCount).fill(0);
59
+ const aligned = align(d);
60
+ for (let c = 0; c < categoryCount; c++) sums[c] += aligned[c];
61
+ groupSums.set(sid, sums);
62
+ }
63
+ const synthetic = [...groupSums.values()];
64
+ return computeCartesianDomain({
65
+ valuesPerDataset: synthetic,
66
+ visibleMask: synthetic.map(() => true),
67
+ categoryCount,
68
+ mode: { isStacked: false, isWaterfall: false, isPercentStacked: false },
69
+ tickCount,
70
+ exactTickCount,
71
+ includeZero
72
+ });
73
+ }
74
+ const valuesPerDataset = series.map(align);
75
+ return computeCartesianDomain({
76
+ valuesPerDataset,
77
+ visibleMask: valuesPerDataset.map(() => true),
78
+ categoryCount,
79
+ mode: { isStacked: true, isWaterfall: false, isPercentStacked: false },
80
+ tickCount,
81
+ exactTickCount,
82
+ includeZero
83
+ });
84
+ }
85
+ function calculateCartesianArea(outerArea, axes, datasets, features, globalFont, locale, renderersByType, minPadding) {
86
+ let orientation = "vertical";
87
+ for (const [, dataset] of datasets) {
88
+ if (dataset.type === "bar") {
89
+ orientation = dataset.props.orientation ?? "vertical";
90
+ break;
91
+ }
92
+ }
93
+ let groupLabelSpace = 0;
94
+ const categoryAxisGroupDefs = [];
95
+ const valueRangeGroupDefs = [];
96
+ for (const [key, feature] of features) {
97
+ const k = key;
98
+ if (k.startsWith("axisGroup:")) {
99
+ const props = feature.props;
100
+ const isCategoryAxis = orientation === "vertical" && k.startsWith("axisGroup:x") || orientation === "horizontal" && k.startsWith("axisGroup:y");
101
+ const isValueAxis = orientation === "vertical" && k.startsWith("axisGroup:y") || orientation === "horizontal" && k.startsWith("axisGroup:x");
102
+ if (isCategoryAxis) {
103
+ categoryAxisGroupDefs.push(...props.groups.filter((g) => g.categories && g.categories.length > 0));
104
+ }
105
+ if (isValueAxis) {
106
+ valueRangeGroupDefs.push(...props.groups.filter((g) => g.range !== void 0));
107
+ }
108
+ }
109
+ }
110
+ const legacyAxisGroup = features.get("axisGroup")?.props;
111
+ if (legacyAxisGroup && categoryAxisGroupDefs.length === 0) {
112
+ categoryAxisGroupDefs.push(...legacyAxisGroup.groups.filter((g) => g.categories && g.categories.length > 0));
113
+ }
114
+ if (categoryAxisGroupDefs.length > 0) {
115
+ const depthLevels = new Set(categoryAxisGroupDefs.map((g) => g.depth ?? 0)).size;
116
+ if (orientation === "horizontal") {
117
+ const resolvedGroupFontSize = resolveFontSize(DEFAULT_GROUP_LABEL_FONT_SIZE, globalFont);
118
+ let maxWidth = 0;
119
+ for (const g of categoryAxisGroupDefs) {
120
+ const w = measureTextWidth(g.label, g.labelStyle?.fontSize ?? resolvedGroupFontSize);
121
+ if (w > maxWidth) maxWidth = w;
122
+ }
123
+ groupLabelSpace = (maxWidth + 16) * depthLevels;
124
+ } else {
125
+ groupLabelSpace = 24 * depthLevels;
126
+ }
127
+ }
128
+ let rangeLabelSpace = 0;
129
+ if (valueRangeGroupDefs.length > 0) {
130
+ if (orientation === "vertical") {
131
+ const resolvedGroupFontSize = resolveFontSize(DEFAULT_GROUP_LABEL_FONT_SIZE, globalFont);
132
+ let maxWidth = 0;
133
+ for (const r of valueRangeGroupDefs) {
134
+ const w = measureTextWidth(r.label, r.labelStyle?.fontSize ?? resolvedGroupFontSize);
135
+ if (w > maxWidth) maxWidth = w;
136
+ }
137
+ rangeLabelSpace = maxWidth + 16;
138
+ } else {
139
+ rangeLabelSpace = 24;
140
+ }
141
+ }
142
+ let leftTotal = 0;
143
+ let rightTotal = 0;
144
+ let topTotal = 0;
145
+ let bottomTotal = 0;
146
+ let xEdgeLeft = 0;
147
+ let xEdgeRight = 0;
148
+ const stackingCfg = features.get("stacking")?.props;
149
+ const isPctStacking = stackingCfg?.mode === "percent";
150
+ const hasWaterfall = features.has("waterfall");
151
+ const firstYAxisId = axes.y.size > 0 ? axes.y.keys().next().value : void 0;
152
+ for (const [yAxisId, yAxisConfig] of axes.y) {
153
+ const yAxisProps = yAxisConfig.props;
154
+ const yPos = yAxisProps?.position ?? "left";
155
+ let yTickLabels;
156
+ if (orientation === "horizontal") {
157
+ for (const [, dataset] of datasets) {
158
+ if (!dataset.props.categoryField || !Array.isArray(dataset.props.data)) continue;
159
+ yTickLabels = batchResolveRequired(dataset.props.categoryField, dataset.props.data, "categoryField");
160
+ break;
161
+ }
162
+ } else {
163
+ if (isPctStacking) {
164
+ const tickCount = yAxisProps?.tickCount ?? 5;
165
+ const ticks = generateNiceTicks(0, 100, tickCount, yAxisProps?.tickCount !== void 0);
166
+ yTickLabels = ticks.map((v) => `${v}%`);
167
+ } else {
168
+ const allValues = [];
169
+ const perDatasetValues = [];
170
+ const valueDatasets = [];
171
+ const stackIdSet = /* @__PURE__ */ new Set();
172
+ for (const [, dataset] of datasets) {
173
+ if (!Array.isArray(dataset.props.data)) continue;
174
+ const targetId = dataset.props.yAxisId ?? firstYAxisId;
175
+ if (targetId !== yAxisId) continue;
176
+ const r = renderersByType?.get(dataset.type);
177
+ if (r?.getAxisHints) {
178
+ const hints = r.getAxisHints(dataset.props, dataset.props.data);
179
+ if (hints.domainValues?.length) {
180
+ for (const v of hints.domainValues) allValues.push(v);
181
+ perDatasetValues.push(hints.domainValues);
182
+ continue;
183
+ }
184
+ }
185
+ if (dataset.props.valueField) {
186
+ const values = batchResolveRequired(dataset.props.valueField, dataset.props.data, "valueField");
187
+ for (const v of values) allValues.push(v);
188
+ perDatasetValues.push(values);
189
+ const sid = dataset.props.stackId;
190
+ valueDatasets.push({ data: dataset.props.data, categoryField: dataset.props.categoryField, values, stackId: sid });
191
+ if (sid !== void 0) stackIdSet.add(sid);
192
+ }
193
+ }
194
+ const explicitMin = yAxisProps?.min;
195
+ const explicitMax = yAxisProps?.max;
196
+ const isStacked = stackIdSet.size > 0 && !hasWaterfall;
197
+ const stackedDomain = isStacked ? estimateStackedValueDomain(valueDatasets, stackIdSet.size, yAxisProps?.tickCount ?? 5, yAxisProps?.tickCount !== void 0, yAxisProps?.startFromZero ?? true) : null;
198
+ let domain = null;
199
+ if (typeof explicitMin === "number" && typeof explicitMax === "number") {
200
+ domain = [explicitMin, explicitMax];
201
+ } else if (stackedDomain) {
202
+ domain = [typeof explicitMin === "number" ? explicitMin : stackedDomain[0], typeof explicitMax === "number" ? explicitMax : stackedDomain[1]];
203
+ } else if (allValues.length > 0) {
204
+ const nice = calculateNiceDomain(allValues, { includeZero: true });
205
+ domain = [typeof explicitMin === "number" ? explicitMin : nice[0], typeof explicitMax === "number" ? explicitMax : nice[1]];
206
+ }
207
+ if (domain) {
208
+ const tickInterval = yAxisProps?.tickInterval;
209
+ const tickCount = yAxisProps?.tickCount ?? 5;
210
+ const formatter = yAxisProps?.tickFormat;
211
+ const labelsForDomain = (d) => {
212
+ const ticks = tickInterval !== void 0 ? generateIntervalTicks(d[0], d[1], tickInterval) : generateNiceTicks(d[0], d[1], tickCount, yAxisProps?.tickCount !== void 0);
213
+ return ticks.map((v, i) => formatter && typeof formatter === "function" ? formatter(v, i) : v.toLocaleString(locale, { maximumFractionDigits: 2 }));
214
+ };
215
+ const domainPinned = typeof explicitMin === "number" && typeof explicitMax === "number";
216
+ const labels = new Set(labelsForDomain(domain));
217
+ if (!domainPinned && !isStacked && perDatasetValues.length > 1) {
218
+ for (const vals of perDatasetValues) {
219
+ if (vals.length === 0) continue;
220
+ const nice = calculateNiceDomain(vals, { includeZero: true });
221
+ const candidate = [typeof explicitMin === "number" ? explicitMin : nice[0], typeof explicitMax === "number" ? explicitMax : nice[1]];
222
+ for (const label of labelsForDomain(candidate)) labels.add(label);
223
+ }
224
+ }
225
+ yTickLabels = [...labels];
226
+ }
227
+ }
228
+ }
229
+ const space = calculateAxisSpace(
230
+ yPos,
231
+ !!yAxisProps?.label,
232
+ {
233
+ tickLabels: yTickLabels,
234
+ tickRotation: yAxisProps?.tickRotation,
235
+ titleGap: yAxisProps?.titleGap,
236
+ showTicks: yAxisProps?.showTicks,
237
+ tickStyle: (() => {
238
+ const s = yAxisProps?.tickStyle;
239
+ return typeof s === "function" ? void 0 : s;
240
+ })()
241
+ },
242
+ void 0,
243
+ globalFont
244
+ );
245
+ if (yPos === "left") leftTotal += space;
246
+ else rightTotal += space;
247
+ }
248
+ const firstXAxisId = axes.x.size > 0 ? axes.x.keys().next().value : void 0;
249
+ for (const [xAxisId, xAxisConfig] of axes.x) {
250
+ const xAxisProps = xAxisConfig.props;
251
+ const xPos = xAxisProps?.position ?? "bottom";
252
+ let xTickLabels;
253
+ let xCategoryWeights;
254
+ if (orientation === "vertical") {
255
+ const isTimeAxis = xAxisProps?.type === "time";
256
+ if (isTimeAxis) {
257
+ const allTimestamps = [];
258
+ for (const [, dataset] of datasets) {
259
+ if (!Array.isArray(dataset.props.data) || !dataset.props.categoryField) continue;
260
+ const rawValues = batchResolveAccessor(dataset.props.categoryField, dataset.props.data);
261
+ for (const v of rawValues) {
262
+ const ts = toTimestamp(v);
263
+ if (!isNaN(ts)) allTimestamps.push(ts);
264
+ }
265
+ }
266
+ if (allTimestamps.length >= 2) {
267
+ let min = allTimestamps[0];
268
+ let max = allTimestamps[0];
269
+ for (let i = 1; i < allTimestamps.length; i++) {
270
+ if (allTimestamps[i] < min) min = allTimestamps[i];
271
+ if (allTimestamps[i] > max) max = allTimestamps[i];
272
+ }
273
+ const estimatedWidth = Math.max(200, outerArea.width - leftTotal - rightTotal);
274
+ const { ticks, interval } = generateTimeTicks(min, max, estimatedWidth);
275
+ xTickLabels = ticks.map((ts) => formatTimeTick(ts, interval.unit, xAxisProps?.timezone, xAxisProps?.dateTimeFormats, locale));
276
+ }
277
+ } else {
278
+ for (const [, dataset] of datasets) {
279
+ if (!Array.isArray(dataset.props.data)) continue;
280
+ const r = renderersByType?.get(dataset.type);
281
+ if (r?.getAxisHints) {
282
+ const hints = r.getAxisHints(dataset.props, dataset.props.data);
283
+ if (hints.categoryLabels?.length) {
284
+ xTickLabels = hints.categoryLabels;
285
+ xCategoryWeights = hints.categoryWeights;
286
+ break;
287
+ }
288
+ }
289
+ if (dataset.props.categoryField) {
290
+ xTickLabels = batchResolveRequired(dataset.props.categoryField, dataset.props.data, "categoryField");
291
+ break;
292
+ }
293
+ }
294
+ }
295
+ } else {
296
+ if (isPctStacking) {
297
+ const tickCount = xAxisProps?.tickCount ?? 5;
298
+ const ticks = generateNiceTicks(0, 100, tickCount, xAxisProps?.tickCount !== void 0);
299
+ xTickLabels = ticks.map((v) => `${v}%`);
300
+ } else {
301
+ const allValues = [];
302
+ const valueDatasets = [];
303
+ const stackIdSet = /* @__PURE__ */ new Set();
304
+ for (const [, dataset] of datasets) {
305
+ if (!dataset.props.valueField || !Array.isArray(dataset.props.data)) continue;
306
+ const targetId = dataset.props.xAxisId ?? firstXAxisId;
307
+ if (targetId !== xAxisId) continue;
308
+ const values = batchResolveRequired(dataset.props.valueField, dataset.props.data, "valueField");
309
+ for (const v of values) allValues.push(v);
310
+ const sid = dataset.props.stackId;
311
+ valueDatasets.push({ data: dataset.props.data, categoryField: dataset.props.categoryField, values, stackId: sid });
312
+ if (sid !== void 0) stackIdSet.add(sid);
313
+ }
314
+ const isStacked = stackIdSet.size > 0 && !hasWaterfall;
315
+ const stackedDomain = isStacked ? estimateStackedValueDomain(valueDatasets, stackIdSet.size, xAxisProps?.tickCount ?? 5, xAxisProps?.tickCount !== void 0, xAxisProps?.startFromZero ?? true) : null;
316
+ const domain = stackedDomain ?? (allValues.length > 0 ? calculateNiceDomain(allValues, { includeZero: true }) : null);
317
+ if (domain) {
318
+ const tickInterval = xAxisProps?.tickInterval;
319
+ const tickCount = xAxisProps?.tickCount ?? 5;
320
+ const ticks = tickInterval !== void 0 ? generateIntervalTicks(domain[0], domain[1], tickInterval) : generateNiceTicks(domain[0], domain[1], tickCount, xAxisProps?.tickCount !== void 0);
321
+ const formatter = xAxisProps?.tickFormat;
322
+ xTickLabels = ticks.map((v, i) => formatter && typeof formatter === "function" ? formatter(v, i) : v.toLocaleString(locale, { maximumFractionDigits: 2 }));
323
+ }
324
+ }
325
+ }
326
+ const xTickStyleRaw = xAxisProps?.tickStyle;
327
+ const xTickStyleComputed = typeof xTickStyleRaw === "function" ? void 0 : xTickStyleRaw;
328
+ const estimatedChartWidth = Math.max(0, outerArea.width - leftTotal - rightTotal);
329
+ const xAutoRotate = xAxisProps?.autoRotate ?? true;
330
+ const xAutoRotateAngle = xAxisProps?.autoRotateAngle ?? -45;
331
+ let xEstimatedPositions;
332
+ if (xAutoRotate && xTickLabels && xTickLabels.length > 1 && estimatedChartWidth > 0) {
333
+ if (xCategoryWeights && xCategoryWeights.length === xTickLabels.length) {
334
+ const totalWeight = xCategoryWeights.reduce((s, w) => s + Math.max(w, 0), 0) || xCategoryWeights.length;
335
+ let cursor = 0;
336
+ xEstimatedPositions = xCategoryWeights.map((w) => {
337
+ const bw = Math.max(w, 0) / totalWeight * estimatedChartWidth;
338
+ const center = cursor + bw / 2;
339
+ cursor += bw;
340
+ return center;
341
+ });
342
+ } else {
343
+ const bandScale = createBandScale(xTickLabels, [0, estimatedChartWidth]);
344
+ const halfBand = bandScale.bandwidth() / 2;
345
+ xEstimatedPositions = xTickLabels.map((label) => bandScale(label) + halfBand);
346
+ }
347
+ }
348
+ const space = calculateAxisSpace(
349
+ xPos,
350
+ !!xAxisProps?.label,
351
+ {
352
+ tickLabels: xTickLabels,
353
+ tickRotation: xAxisProps?.tickRotation,
354
+ titleGap: xAxisProps?.titleGap,
355
+ showTicks: xAxisProps?.showTicks,
356
+ tickStyle: xTickStyleComputed,
357
+ autoRotate: xAutoRotate,
358
+ autoRotateAngle: xAutoRotateAngle,
359
+ tickPositions: xEstimatedPositions,
360
+ axisLength: estimatedChartWidth,
361
+ labelMinSpacing: xAxisProps?.labelMinSpacing,
362
+ tickCount: xAxisProps?.tickCount,
363
+ autoSkip: xAxisProps?.autoSkip
364
+ },
365
+ void 0,
366
+ globalFont
367
+ );
368
+ if (xPos === "bottom") bottomTotal += space;
369
+ else topTotal += space;
370
+ if (xTickLabels && xTickLabels.length > 0) {
371
+ const xTickRotation = xAxisProps?.tickRotation ?? 0;
372
+ const xFontSize = xTickStyleComputed?.fontSize ?? DEFAULT_TICK_FONT_SIZE;
373
+ if (xTickRotation) {
374
+ const radians = Math.abs(xTickRotation * Math.PI / 180);
375
+ const textH = xFontSize * 1.2;
376
+ const firstW = measureTextWidth(xTickLabels[0], xFontSize);
377
+ const lastW = measureTextWidth(xTickLabels[xTickLabels.length - 1], xFontSize);
378
+ xEdgeLeft = Math.max(xEdgeLeft, Math.ceil((firstW * Math.cos(radians) + textH * Math.sin(radians)) / 2));
379
+ xEdgeRight = Math.max(xEdgeRight, Math.ceil((lastW * Math.cos(radians) + textH * Math.sin(radians)) / 2));
380
+ } else {
381
+ xEdgeLeft = Math.max(xEdgeLeft, Math.ceil(measureTextWidth(xTickLabels[0], xFontSize) / 2));
382
+ xEdgeRight = Math.max(xEdgeRight, Math.ceil(measureTextWidth(xTickLabels[xTickLabels.length - 1], xFontSize) / 2));
383
+ }
384
+ }
385
+ }
386
+ const extraLeft = Math.max(0, xEdgeLeft - leftTotal);
387
+ const extraRight = Math.max(0, xEdgeRight - rightTotal);
388
+ const groupLeft = orientation === "horizontal" ? groupLabelSpace : 0;
389
+ const groupBottom = orientation === "vertical" ? groupLabelSpace : 0;
390
+ const rangeLeft = orientation === "vertical" ? rangeLabelSpace : 0;
391
+ const rangeBottom = orientation === "horizontal" ? rangeLabelSpace : 0;
392
+ const finalLeft = Math.max(leftTotal + extraLeft + groupLeft + rangeLeft, minPadding?.left ?? 0);
393
+ const finalRight = Math.max(rightTotal + extraRight, minPadding?.right ?? 0);
394
+ return {
395
+ x: outerArea.x + finalLeft,
396
+ y: outerArea.y + topTotal,
397
+ width: Math.max(0, outerArea.width - finalLeft - finalRight),
398
+ height: Math.max(0, outerArea.height - topTotal - bottomTotal - groupBottom - rangeBottom)
399
+ };
400
+ }
401
+
402
+ // src/cartesian/frame.utils.ts
403
+ function createAnimationDriver() {
404
+ return {
405
+ domainLerpStates: /* @__PURE__ */ new Map(),
406
+ categorySortLerpState: /* @__PURE__ */ new Map(),
407
+ prevSortOrder: "",
408
+ cachedLayout: null,
409
+ lastFrame: null,
410
+ timeDomainLerp: null,
411
+ // NEW:
412
+ animRafId: null,
413
+ settleRafId: null,
414
+ isInitial: true,
415
+ lastFingerprint: "",
416
+ lastCategorySortProgress: 0
417
+ };
418
+ }
419
+ function buildFrameParams(ctx, cached, input) {
420
+ let yAxisLayout = cached.yAxisLayout;
421
+ let xAxisLayout = cached.xAxisLayout;
422
+ for (const [, info] of input.axisLayouts) {
423
+ if (info.isPrimary) {
424
+ if (info.axis === "y") yAxisLayout = info.layout;
425
+ else xAxisLayout = info.layout;
426
+ }
427
+ }
428
+ return {
429
+ renderer: ctx.renderer,
430
+ theme: ctx.theme,
431
+ group: ctx.group,
432
+ gridGroup: ctx.gridGroup,
433
+ canvas: ctx.canvas,
434
+ xAxisLayout,
435
+ yAxisLayout,
436
+ orientation: cached.orientation,
437
+ styledBoundaries: cached.styledBoundaries,
438
+ categoryScale: input.categoryScale ?? cached.sharedCategoryScale,
439
+ cartesianArea: cached.cartesianArea,
440
+ categoryAxisSpace: cached.categoryAxisSpace,
441
+ styledRangeBoundaries: cached.styledRangeBoundaries,
442
+ valueAxisSpace: cached.valueAxisSpace,
443
+ valueDomain: cached.valueDomain,
444
+ valueScaleRange: cached.valueScaleRange,
445
+ axisLayouts: input.axisLayouts,
446
+ valueScales: input.valueScales,
447
+ valueDomains: input.valueDomains,
448
+ valueXScales: input.valueXScales,
449
+ customTickOverlayRefs: ctx.customTickOverlayRefs,
450
+ referenceLines: cached.referenceLines,
451
+ referenceBands: cached.referenceBands,
452
+ isZoomed: ctx.isZoomed,
453
+ rtl: ctx.rtl,
454
+ globalFont: ctx.globalFont
455
+ };
456
+ }
457
+ function buildStaticFrame(ctx, cached, axisTransition) {
458
+ const transitioned = axisTransition.apply(cached.axisLayouts);
459
+ return buildFrameParams(ctx, cached, {
460
+ axisLayouts: transitioned,
461
+ valueScales: cached.valueScales,
462
+ valueDomains: cached.valueDomains,
463
+ valueXScales: cached.scatterXScales
464
+ });
465
+ }
466
+ function buildAnimatedFrame(ctx, cached, axisTransition, animatedInput) {
467
+ const transitioned = axisTransition.apply(animatedInput.axisLayouts);
468
+ return buildFrameParams(ctx, cached, {
469
+ axisLayouts: transitioned,
470
+ valueScales: animatedInput.valueScales,
471
+ valueDomains: animatedInput.valueDomains,
472
+ categoryScale: animatedInput.categoryScale,
473
+ valueXScales: animatedInput.valueXScales
474
+ });
475
+ }
476
+ function resolveHoverRepaintFrame(driver, ctx, buildStatic) {
477
+ return driver.lastFrame ? { ...driver.lastFrame, ...ctx } : buildStatic();
478
+ }
479
+ function renderWithCompositor(frameParams, renderFrameFn, options) {
480
+ const { renderer, canvas, compositor, overlayCanvas, registry, hover, markerOverlays, onImageLoad } = options;
481
+ if (renderer === "canvas" && compositor) {
482
+ compositor.setBackground(() => {
483
+ renderFrameFn({ ...frameParams, phase: "background" });
484
+ });
485
+ compositor.setForeground(() => {
486
+ renderFrameFn({ ...frameParams, phase: "foreground" });
487
+ });
488
+ if (compositor.hasLayers()) {
489
+ const ctx = canvas?.getContext("2d");
490
+ if (ctx) {
491
+ compositor.repaint(ctx);
492
+ }
493
+ } else {
494
+ renderFrameFn(frameParams);
495
+ }
496
+ } else {
497
+ renderFrameFn(frameParams);
498
+ }
499
+ if (overlayCanvas && registry) {
500
+ renderCartesianOverlay({
501
+ canvas: overlayCanvas,
502
+ axisLayouts: frameParams.axisLayouts,
503
+ hover: hover ?? { datasetId: null, index: null },
504
+ registry,
505
+ cartesianArea: frameParams.cartesianArea,
506
+ onImageLoad,
507
+ markerOverlays
508
+ });
509
+ }
510
+ }
511
+ function detectPhase(driver, fingerprint) {
512
+ if (driver.isInitial) return "entrance";
513
+ if (driver.lastFingerprint !== "" && fingerprint !== "" && fingerprint !== driver.lastFingerprint) return "update";
514
+ return "static";
515
+ }
516
+ function commitPhase(driver, fingerprint) {
517
+ driver.isInitial = false;
518
+ driver.lastFingerprint = fingerprint;
519
+ }
520
+ function cancelDriverRafs(driver) {
521
+ if (driver.animRafId !== null) {
522
+ cancelRaf(driver.animRafId);
523
+ driver.animRafId = null;
524
+ }
525
+ if (driver.settleRafId !== null) {
526
+ cancelRaf(driver.settleRafId);
527
+ driver.settleRafId = null;
528
+ }
529
+ }
530
+ function runTimedAnimation(driver, opts) {
531
+ if (driver.animRafId !== null) {
532
+ cancelRaf(driver.animRafId);
533
+ driver.animRafId = null;
534
+ }
535
+ const startAt = performance.now();
536
+ const tick = (now) => {
537
+ driver.animRafId = null;
538
+ const raw = (now - startAt) / opts.duration;
539
+ if (raw >= 1) {
540
+ opts.onFrame(opts.easing(1));
541
+ opts.onComplete?.();
542
+ return;
543
+ }
544
+ opts.onFrame(opts.easing(raw < 0 ? 0 : raw));
545
+ driver.animRafId = raf(tick);
546
+ };
547
+ driver.animRafId = raf(tick);
548
+ }
549
+ function runSettleLoop(driver, opts) {
550
+ if (driver.settleRafId !== null) {
551
+ cancelRaf(driver.settleRafId);
552
+ driver.settleRafId = null;
553
+ }
554
+ const loop = () => {
555
+ if (opts.tick()) {
556
+ opts.onFrame();
557
+ driver.settleRafId = raf(loop);
558
+ } else {
559
+ driver.settleRafId = null;
560
+ }
561
+ };
562
+ if (opts.tick()) {
563
+ driver.settleRafId = raf(loop);
564
+ }
565
+ }
566
+ function driveCartesianUpdate(layout, driver, axisTransition, animConfig, renderFrame, buildStatic, buildAnimated, globalFont, locale) {
567
+ const currentSortOrder = layout.sortedCategoryOrder?.join(",") ?? "";
568
+ const isSortChange = currentSortOrder !== driver.prevSortOrder && driver.prevSortOrder !== "" && currentSortOrder !== "";
569
+ if (isSortChange && driver.cachedLayout) {
570
+ const isCategoryLerpActive = driver.categorySortLerpState.size > 0;
571
+ const prevSourceLayouts = isCategoryLerpActive ? advanceCategoryLerp(driver.cachedLayout.axisLayouts, driver.categorySortLerpState, driver.lastCategorySortProgress, driver.cachedLayout.orientation) : driver.cachedLayout.axisLayouts;
572
+ driver.categorySortLerpState = initCategoryLerp(prevSourceLayouts, driver.cachedLayout.orientation);
573
+ } else if (!isSortChange) {
574
+ snapCategoryLerp(driver.categorySortLerpState);
575
+ }
576
+ driver.prevSortOrder = currentSortOrder;
577
+ driver.cachedLayout = layout;
578
+ axisTransition.setTargets(layout.axisLayouts);
579
+ const { enabled: animEnabled, duration, easing } = parseAnimationConfig(animConfig);
580
+ const timeDomainFp = layout.timeDomain ? `${layout.timeDomain[0]},${layout.timeDomain[1]}` : "";
581
+ const lerpTargets = new Map(layout.valueDomains);
582
+ if (layout.scatterXScales) {
583
+ for (const [id, scale] of layout.scatterXScales) lerpTargets.set(`x:${id}`, scale.domain());
584
+ }
585
+ const currentFingerprint = `${[...lerpTargets.entries()].map(([k, v]) => `${k}:${v[0]},${v[1]}`).join(";")}|${layout.orientation}|${currentSortOrder}|${timeDomainFp}`;
586
+ const phase = detectPhase(driver, currentFingerprint);
587
+ const hasTimeDomain = !!layout.timeDomain;
588
+ const prevTimeDomain = driver.timeDomainLerp ? [driver.timeDomainLerp.minTarget, driver.timeDomainLerp.maxTarget] : null;
589
+ if (hasTimeDomain) {
590
+ driver.timeDomainLerp = initTimeDomainLerp(driver.timeDomainLerp, layout.timeDomain);
591
+ } else {
592
+ driver.timeDomainLerp = null;
593
+ }
594
+ const hasDomains = layout.valueDomains.size > 0 || !!layout.scatterXScales?.size;
595
+ const animationActive = animEnabled && phase === "update" && (hasDomains || isSortChange || hasTimeDomain);
596
+ const isStreamingAppend = hasTimeDomain && (!prevTimeDomain || prevTimeDomain[0] !== layout.timeDomain[0] || prevTimeDomain[1] !== layout.timeDomain[1]);
597
+ if (animationActive) {
598
+ initDomainLerp(driver.domainLerpStates, lerpTargets, { expansionStart: isStreamingAppend });
599
+ initDomainLerpTickFade(driver.domainLerpStates, layout.axisLayouts, layout.valueScaleRange, layout.cartesianArea, layout.orientation, axisTransition, globalFont, locale);
600
+ cancelDriverRafs(driver);
601
+ runTimedAnimation(driver, {
602
+ duration,
603
+ easing,
604
+ onFrame: (progress) => {
605
+ axisTransition.tick();
606
+ const cached = driver.cachedLayout;
607
+ const frame = advanceDomainLerp(driver.domainLerpStates, progress, cached.axisLayouts, cached.valueScaleRange, cached.cartesianArea, cached.orientation, cached.valueScales, cached.valueDomains, globalFont, locale, axisTransition);
608
+ let animatedCategoryScale = void 0;
609
+ let mergedAxisLayouts = frame.axisLayouts;
610
+ if (driver.timeDomainLerp && cached.timeDomain) {
611
+ const timestamps = cached.sharedCategoryScale.domain().map(Number).filter((t) => !isNaN(t));
612
+ const timeFrame = advanceTimeDomainLerp(driver.timeDomainLerp, progress, frame.axisLayouts, {
613
+ orientation: cached.orientation,
614
+ cartesianArea: cached.cartesianArea,
615
+ timestamps
616
+ });
617
+ animatedCategoryScale = timeFrame.categoryScale;
618
+ mergedAxisLayouts = timeFrame.axisLayouts;
619
+ }
620
+ const sortedAxisLayouts = advanceCategoryLerp(mergedAxisLayouts, driver.categorySortLerpState, progress, cached.orientation);
621
+ driver.lastCategorySortProgress = progress;
622
+ renderFrame(buildAnimated(frame.valueScales, frame.valueDomains, sortedAxisLayouts, animatedCategoryScale, frame.valueXScales));
623
+ },
624
+ onComplete: () => {
625
+ snapCategoryLerp(driver.categorySortLerpState);
626
+ driver.lastCategorySortProgress = 0;
627
+ if (driver.timeDomainLerp) {
628
+ snapTimeDomainLerp(driver.timeDomainLerp);
629
+ }
630
+ runSettleLoop(driver, {
631
+ tick: () => axisTransition.tick(),
632
+ onFrame: () => renderFrame(buildStatic())
633
+ });
634
+ }
635
+ });
636
+ } else {
637
+ cancelDriverRafs(driver);
638
+ initDomainLerp(driver.domainLerpStates, lerpTargets);
639
+ snapDomainLerp(driver.domainLerpStates);
640
+ snapCategoryLerp(driver.categorySortLerpState);
641
+ driver.lastCategorySortProgress = 0;
642
+ if (driver.timeDomainLerp) {
643
+ snapTimeDomainLerp(driver.timeDomainLerp);
644
+ }
645
+ renderFrame(buildStatic());
646
+ runSettleLoop(driver, {
647
+ tick: () => axisTransition.tick(),
648
+ onFrame: () => renderFrame(buildStatic())
649
+ });
650
+ }
651
+ commitPhase(driver, currentFingerprint);
652
+ }
653
+
654
+ // src/cartesian/grouping.ts
655
+ function resolveStyleShorthand(value, defaultEnabled) {
656
+ if (value === void 0) {
657
+ return defaultEnabled ? {} : false;
658
+ }
659
+ if (typeof value === "boolean") {
660
+ return value ? {} : false;
661
+ }
662
+ return value;
663
+ }
664
+ function buildBoundariesFromAxisGroups(groups, dataCategories) {
665
+ const sortedCategories = [];
666
+ const styledBoundaries = [];
667
+ const usedCategories = /* @__PURE__ */ new Set();
668
+ const dataCategorySet = new Set(dataCategories);
669
+ const maxDepth = Math.max(0, ...groups.map((g) => g.depth ?? 0));
670
+ const leafGroups = groups.filter((g) => (g.depth ?? 0) === maxDepth);
671
+ const parentGroups = groups.filter((g) => (g.depth ?? 0) < maxDepth).sort((a, b) => (b.depth ?? 0) - (a.depth ?? 0));
672
+ for (const group of leafGroups) {
673
+ if (!group.categories) continue;
674
+ const startIdx = sortedCategories.length;
675
+ for (const cat of group.categories) {
676
+ if (dataCategorySet.has(cat)) {
677
+ sortedCategories.push(cat);
678
+ usedCategories.add(cat);
679
+ }
680
+ }
681
+ if (sortedCategories.length > startIdx) {
682
+ styledBoundaries.push({
683
+ label: group.label,
684
+ startIdx,
685
+ endIdx: sortedCategories.length - 1,
686
+ depth: group.depth ?? 0,
687
+ bracket: resolveStyleShorthand(group.bracket, false),
688
+ separator: resolveStyleShorthand(group.separator, false),
689
+ fill: resolveStyleShorthand(group.fill, false),
690
+ labelStyle: group.labelStyle,
691
+ tickSeparator: resolveStyleShorthand(group.tickSeparator, false),
692
+ render: group.render
693
+ });
694
+ }
695
+ }
696
+ for (const group of parentGroups) {
697
+ if (!group.categories || group.categories.length === 0) continue;
698
+ let startIdx = Infinity;
699
+ let endIdx = -Infinity;
700
+ for (const cat of group.categories) {
701
+ const idx = sortedCategories.indexOf(cat);
702
+ if (idx !== -1) {
703
+ startIdx = Math.min(startIdx, idx);
704
+ endIdx = Math.max(endIdx, idx);
705
+ }
706
+ }
707
+ if (startIdx <= endIdx) {
708
+ styledBoundaries.push({
709
+ label: group.label,
710
+ startIdx,
711
+ endIdx,
712
+ depth: group.depth ?? 0,
713
+ bracket: resolveStyleShorthand(group.bracket, false),
714
+ separator: resolveStyleShorthand(group.separator, false),
715
+ fill: resolveStyleShorthand(group.fill, false),
716
+ labelStyle: group.labelStyle,
717
+ tickSeparator: resolveStyleShorthand(group.tickSeparator, false),
718
+ render: group.render
719
+ });
720
+ }
721
+ }
722
+ for (const cat of dataCategories) {
723
+ if (!usedCategories.has(cat)) {
724
+ sortedCategories.push(cat);
725
+ }
726
+ }
727
+ return { sortedCategories, styledBoundaries };
728
+ }
729
+ function buildStyledRanges(groups) {
730
+ return groups.filter((g) => g.range !== void 0).map((g) => ({
731
+ label: g.label,
732
+ from: g.range[0],
733
+ to: g.range[1],
734
+ bracket: resolveStyleShorthand(g.bracket, false),
735
+ separator: resolveStyleShorthand(g.separator, false),
736
+ fill: resolveStyleShorthand(g.fill, false),
737
+ labelStyle: g.labelStyle,
738
+ tickSeparator: resolveStyleShorthand(g.tickSeparator, false),
739
+ render: g.render
740
+ }));
741
+ }
742
+
743
+ // src/cartesian/hittest-wrappers/shared.ts
744
+ function resolveNearestHit(hit1, hit2, x, y) {
745
+ const d1 = Math.sqrt((x - hit1.snapX) ** 2 + (y - hit1.snapY) ** 2);
746
+ const d2 = Math.sqrt((x - hit2.snapX) ** 2 + (y - hit2.snapY) ** 2);
747
+ return d1 <= d2 ? hit1 : hit2;
748
+ }
749
+ function mergeAllNearestResults(results, x, y) {
750
+ const valid = results.filter((r) => r !== null);
751
+ if (valid.length === 0) return null;
752
+ if (valid.length === 1) return valid[0];
753
+ const allSeries = valid.flatMap((r) => r.allSeries);
754
+ const primary = valid.reduce((best, r) => {
755
+ const d = Math.sqrt((x - r.primary.snapX) ** 2 + (y - r.primary.snapY) ** 2);
756
+ const bestD = Math.sqrt((x - best.primary.snapX) ** 2 + (y - best.primary.snapY) ** 2);
757
+ return d < bestD ? r : best;
758
+ }).primary;
759
+ return { primary, allSeries };
760
+ }
761
+
762
+ // src/cartesian/layout.helpers.ts
763
+ function findAxisGroupFeatures(features, prefix) {
764
+ const results = [];
765
+ for (const [key, feature] of features) {
766
+ if (key === prefix || key.startsWith(`${prefix}:`)) {
767
+ results.push(feature.props);
768
+ }
769
+ }
770
+ return results;
771
+ }
772
+ function createOffsetChartArea(area, position, offset) {
773
+ switch (position) {
774
+ case "left":
775
+ return { ...area, x: area.x - offset, width: area.width + offset };
776
+ case "right":
777
+ return { ...area, width: area.width + offset };
778
+ case "top":
779
+ return { ...area, y: area.y - offset, height: area.height + offset };
780
+ case "bottom":
781
+ return { ...area, height: area.height + offset };
782
+ default:
783
+ return area;
784
+ }
785
+ }
786
+ function computeHiddenValueAxes(params) {
787
+ const { barDatasets, lineDatasets, scatterDatasets, candlestickDatasets, datasetAxisMap, firstValueAxisId, axisIdProp, valueAxesSize } = params;
788
+ const hiddenValueAxes = /* @__PURE__ */ new Set();
789
+ const axisVisibility = /* @__PURE__ */ new Map();
790
+ const trackDataset = (axisId, visible) => {
791
+ const entry = axisVisibility.get(axisId) ?? { hasDataset: false, hasVisible: false };
792
+ entry.hasDataset = true;
793
+ if (visible) entry.hasVisible = true;
794
+ axisVisibility.set(axisId, entry);
795
+ };
796
+ for (const ds of barDatasets) {
797
+ trackDataset(datasetAxisMap.get(ds.id) ?? firstValueAxisId, ds.visible);
798
+ }
799
+ for (const ds of lineDatasets) {
800
+ trackDataset(ds.props[axisIdProp] ?? firstValueAxisId, ds.visible);
801
+ }
802
+ for (const ds of scatterDatasets) {
803
+ trackDataset(ds.props[axisIdProp] ?? firstValueAxisId, ds.visible);
804
+ }
805
+ for (const ds of candlestickDatasets) {
806
+ trackDataset(ds.props[axisIdProp] ?? firstValueAxisId, ds.visible);
807
+ }
808
+ for (const [axisId, info] of axisVisibility) {
809
+ if (info.hasDataset && !info.hasVisible) {
810
+ hiddenValueAxes.add(axisId);
811
+ }
812
+ }
813
+ if (valueAxesSize <= 1 && hiddenValueAxes.size > 0) {
814
+ const hasAnyVisible = [...axisVisibility.values()].some((v) => v.hasVisible);
815
+ if (!hasAnyVisible) {
816
+ hiddenValueAxes.clear();
817
+ }
818
+ }
819
+ return hiddenValueAxes;
820
+ }
821
+
822
+ // src/cartesian/layout.axis-layouts.ts
823
+ function computeAxisLayouts(params) {
824
+ const {
825
+ axes,
826
+ isRtl,
827
+ orientation,
828
+ valueScales,
829
+ sharedValueScale,
830
+ sharedTimeScale,
831
+ sharedCategoryScale,
832
+ scatterXScales,
833
+ valueDomains,
834
+ scatterXDomains,
835
+ mode,
836
+ adaptive,
837
+ cartesianArea,
838
+ styledBoundaries,
839
+ rangeLabelOffset,
840
+ hiddenValueAxes,
841
+ lastVisibleLayouts,
842
+ globalFont,
843
+ locale
844
+ } = params;
845
+ const axisLayouts = /* @__PURE__ */ new Map();
846
+ let xAxisLayout = null;
847
+ let yAxisLayout = null;
848
+ const sideOffsets = { left: 0, right: 0, top: 0, bottom: 0 };
849
+ const sidePrimarySet = /* @__PURE__ */ new Set();
850
+ for (const [yAxisId, yAxisConfig] of axes.y) {
851
+ const yPos = yAxisConfig.props.position ?? (isRtl ? "right" : "left");
852
+ const isPrimary = !sidePrimarySet.has(yPos);
853
+ if (isPrimary) sidePrimarySet.add(yPos);
854
+ const isValueAxis = orientation === "vertical";
855
+ const yScale = isValueAxis ? valueScales.get(yAxisId) ?? sharedValueScale : sharedTimeScale ?? sharedCategoryScale;
856
+ let yProps = yAxisConfig.props;
857
+ if (isValueAxis) {
858
+ if (mode.isPercentStacked && !yProps.tickFormat) {
859
+ yProps = { ...yProps, tickFormat: (v) => `${v}%` };
860
+ }
861
+ }
862
+ if (yProps.gridLines === void 0) {
863
+ yProps = { ...yProps, gridLines: isPrimary && isValueAxis };
864
+ }
865
+ {
866
+ const existingTickStyle = yProps?.tickStyle;
867
+ if (typeof existingTickStyle !== "function" && !existingTickStyle?.fontSize) {
868
+ yProps = { ...yProps, tickStyle: { ...existingTickStyle, fontSize: adaptive.tickFontSize } };
869
+ }
870
+ }
871
+ const offset = sideOffsets[yPos];
872
+ const offsetArea = offset > 0 ? createOffsetChartArea(cartesianArea, yPos, offset) : cartesianArea;
873
+ const yCatBracketOffset = isPrimary && !isValueAxis && styledBoundaries && styledBoundaries.length > 0 ? DEFAULT_BRACKET_GAP + (Math.max(0, ...styledBoundaries.map((b) => b.depth)) + 1) * DEFAULT_BRACKET_DEPTH_LAYER_SIZE : 0;
874
+ const yExtraTitleOffset = isPrimary ? isValueAxis && rangeLabelOffset > 0 ? rangeLabelOffset : yCatBracketOffset : 0;
875
+ let visibleLayout = calculateAxisLayout(yScale, yPos, offsetArea, yProps, yExtraTitleOffset || void 0, globalFont, locale);
876
+ let layout = visibleLayout;
877
+ const isAxisHidden = isValueAxis && hiddenValueAxes.has(yAxisId);
878
+ const axisKey = `y:${yAxisId}`;
879
+ if (!isAxisHidden) {
880
+ lastVisibleLayouts.set(axisKey, visibleLayout);
881
+ } else {
882
+ const stored = lastVisibleLayouts.get(axisKey);
883
+ if (stored) visibleLayout = stored;
884
+ }
885
+ if (isAxisHidden) {
886
+ const minTitleOffset = 16;
887
+ const { x, width } = offsetArea;
888
+ layout = {
889
+ ...layout,
890
+ // Hide axis line, ticks, and grid lines when all datasets on this axis are hidden
891
+ axisLine: { x1: 0, y1: 0, x2: 0, y2: 0 },
892
+ ticks: [],
893
+ gridLines: [],
894
+ ...layout.title && {
895
+ title: {
896
+ ...layout.title,
897
+ x: yPos === "left" ? x - minTitleOffset : x + width + minTitleOffset
898
+ }
899
+ }
900
+ };
901
+ }
902
+ const HIDDEN_AXIS_TITLE_SPACE = 30;
903
+ const space = yProps?.visible === false ? 0 : isAxisHidden ? yProps?.label ? HIDDEN_AXIS_TITLE_SPACE : 0 : calculateAxisSpace(
904
+ yPos,
905
+ !!yProps?.label,
906
+ {
907
+ tickLabels: layout.ticks.map((t) => t.label ?? ""),
908
+ tickRotation: layout.ticks.find((t) => t.label)?.rotation ?? yProps?.tickRotation ?? 0,
909
+ titleGap: yProps?.titleGap,
910
+ showTicks: yProps?.showTicks,
911
+ tickStyle: (() => {
912
+ const s = yProps?.tickStyle;
913
+ return typeof s === "function" ? void 0 : s;
914
+ })()
915
+ },
916
+ yExtraTitleOffset || void 0,
917
+ globalFont
918
+ );
919
+ sideOffsets[yPos] += space;
920
+ axisLayouts.set(`y:${yAxisId}`, {
921
+ id: yAxisId,
922
+ axis: "y",
923
+ position: yPos,
924
+ layout,
925
+ scale: yScale,
926
+ domain: isValueAxis ? valueDomains.get(yAxisId) : sharedTimeScale ? sharedTimeScale.domain() : void 0,
927
+ props: yProps,
928
+ isPrimary,
929
+ offset,
930
+ space,
931
+ isHidden: isAxisHidden,
932
+ visibleLayout,
933
+ extraTitleOffset: yExtraTitleOffset || void 0
934
+ });
935
+ if (!yAxisLayout) yAxisLayout = layout;
936
+ }
937
+ for (const [xAxisId, xAxisConfig] of axes.x) {
938
+ const xPos = xAxisConfig.props.position ?? "bottom";
939
+ const isPrimary = !sidePrimarySet.has(xPos);
940
+ if (isPrimary) sidePrimarySet.add(xPos);
941
+ const isValueAxis = orientation === "horizontal";
942
+ const xAxisType = xAxisConfig.props?.type;
943
+ const scatterXScale = scatterXScales.get(xAxisId);
944
+ const useScatterScale = !!scatterXScale && (xAxisType === "linear" || xAxisType === "logarithmic" || !xAxisType);
945
+ const xScale = isValueAxis ? valueScales.get(xAxisId) ?? sharedValueScale : useScatterScale ? scatterXScale : sharedTimeScale ?? sharedCategoryScale;
946
+ let xProps = xAxisConfig.props;
947
+ if (isValueAxis || useScatterScale) {
948
+ if (mode.isPercentStacked && !xProps.tickFormat) {
949
+ xProps = { ...xProps, tickFormat: (v) => `${v}%` };
950
+ }
951
+ }
952
+ if (xProps.gridLines === void 0) {
953
+ xProps = { ...xProps, gridLines: isPrimary && (isValueAxis || useScatterScale) };
954
+ }
955
+ {
956
+ const existingTickStyle = xProps?.tickStyle;
957
+ if (typeof existingTickStyle !== "function" && !existingTickStyle?.fontSize) {
958
+ xProps = { ...xProps, tickStyle: { ...existingTickStyle, fontSize: adaptive.tickFontSize } };
959
+ }
960
+ }
961
+ const offset = sideOffsets[xPos];
962
+ const offsetArea = offset > 0 ? createOffsetChartArea(cartesianArea, xPos, offset) : cartesianArea;
963
+ const xCatBracketOffset = isPrimary && !isValueAxis && styledBoundaries && styledBoundaries.length > 0 ? DEFAULT_BRACKET_GAP + (Math.max(0, ...styledBoundaries.map((b) => b.depth)) + 1) * DEFAULT_BRACKET_DEPTH_LAYER_SIZE : 0;
964
+ const xExtraTitleOffset = isPrimary ? isValueAxis && rangeLabelOffset > 0 ? rangeLabelOffset : xCatBracketOffset : 0;
965
+ const visibleXLayout = calculateAxisLayout(xScale, xPos, offsetArea, xProps, xExtraTitleOffset || void 0, globalFont, locale);
966
+ let layout = visibleXLayout;
967
+ const isAxisHidden = isValueAxis && hiddenValueAxes.has(xAxisId);
968
+ if (isAxisHidden) {
969
+ const minTitleOffset = 16;
970
+ const { y, height } = offsetArea;
971
+ layout = {
972
+ ...layout,
973
+ // Hide axis line, ticks, and grid lines when all datasets on this axis are hidden
974
+ axisLine: { x1: 0, y1: 0, x2: 0, y2: 0 },
975
+ ticks: [],
976
+ gridLines: [],
977
+ ...layout.title && {
978
+ title: {
979
+ ...layout.title,
980
+ y: xPos === "top" ? y - minTitleOffset : y + height + minTitleOffset
981
+ }
982
+ }
983
+ };
984
+ }
985
+ const HIDDEN_AXIS_TITLE_SPACE = 30;
986
+ const space = xProps?.visible === false ? 0 : isAxisHidden ? xProps?.label ? HIDDEN_AXIS_TITLE_SPACE : 0 : calculateAxisSpace(
987
+ xPos,
988
+ !!xProps?.label,
989
+ {
990
+ tickLabels: layout.ticks.map((t) => t.label ?? ""),
991
+ tickRotation: layout.ticks.find((t) => t.label)?.rotation ?? xProps?.tickRotation ?? 0,
992
+ titleGap: xProps?.titleGap,
993
+ showTicks: xProps?.showTicks,
994
+ tickStyle: (() => {
995
+ const s = xProps?.tickStyle;
996
+ return typeof s === "function" ? void 0 : s;
997
+ })()
998
+ },
999
+ xExtraTitleOffset || void 0,
1000
+ globalFont
1001
+ );
1002
+ sideOffsets[xPos] += space;
1003
+ axisLayouts.set(`x:${xAxisId}`, {
1004
+ id: xAxisId,
1005
+ axis: "x",
1006
+ position: xPos,
1007
+ layout,
1008
+ scale: xScale,
1009
+ domain: isValueAxis ? valueDomains.get(xAxisId) : scatterXDomains.get(xAxisId) ?? (sharedTimeScale ? sharedTimeScale.domain() : void 0),
1010
+ props: xProps,
1011
+ isPrimary,
1012
+ offset,
1013
+ space,
1014
+ isHidden: isAxisHidden,
1015
+ visibleLayout: visibleXLayout,
1016
+ extraTitleOffset: xExtraTitleOffset || void 0
1017
+ });
1018
+ if (!xAxisLayout) xAxisLayout = layout;
1019
+ }
1020
+ return { axisLayouts, xAxisLayout, yAxisLayout };
1021
+ }
1022
+
1023
+ // src/cartesian/category-sort.ts
1024
+ function sortCategories(cats, sort, aggregate, allCategories, valuesPerDataset, categoryTotals) {
1025
+ if (sort === "label-asc") return [...cats].sort((a, b) => a.localeCompare(b));
1026
+ if (sort === "label-desc") return [...cats].sort((a, b) => b.localeCompare(a));
1027
+ const catIndexMap = new Map(allCategories.map((c, i) => [c, i]));
1028
+ const getAggregateValue = (cat) => {
1029
+ const idx = catIndexMap.get(cat);
1030
+ if (idx === void 0) return 0;
1031
+ if (aggregate === "sum" && categoryTotals) return categoryTotals[idx] ?? 0;
1032
+ const vals = valuesPerDataset.map((ds) => ds[idx] ?? 0).filter((v) => !isNaN(v));
1033
+ if (vals.length === 0) return 0;
1034
+ switch (aggregate) {
1035
+ case "sum":
1036
+ return vals.reduce((a, b) => a + b, 0);
1037
+ case "max":
1038
+ return Math.max(...vals);
1039
+ case "min":
1040
+ return Math.min(...vals);
1041
+ case "first":
1042
+ return vals[0] ?? 0;
1043
+ }
1044
+ };
1045
+ return [...cats].sort((a, b) => {
1046
+ const va = getAggregateValue(a);
1047
+ const vb = getAggregateValue(b);
1048
+ return sort === "value-asc" ? va - vb : vb - va;
1049
+ });
1050
+ }
1051
+
1052
+ // src/cartesian/layout.bar-pipeline.ts
1053
+ function computeBarPipeline(params) {
1054
+ const { features, barDatasets, lineDatasets, orientation, categories, globalFont, isTimeAxis, axisIdProp, firstValueAxisId, valueAxes, cartesianArea, valueDomains, datasetAxisMap } = params;
1055
+ let mode = params.mode;
1056
+ let isVariwide = false;
1057
+ let valuesPerDataset = [];
1058
+ let waterfallBases;
1059
+ let effectiveScaleCategories = params.effectiveScaleCategories;
1060
+ let effectiveWeights;
1061
+ let sortedCategoryOrder;
1062
+ let styledBoundaries;
1063
+ let styledRangeBoundaries;
1064
+ let rangeLabelOffset = 0;
1065
+ const stackingConfig = features.get("stacking")?.props;
1066
+ const waterfallConfig = features.get("waterfall")?.props;
1067
+ const overlapFeature = features.get("overlap");
1068
+ mode = detectCartesianMode(barDatasets, {
1069
+ stacking: stackingConfig,
1070
+ waterfall: waterfallConfig,
1071
+ overlap: overlapFeature ? {} : void 0
1072
+ });
1073
+ const xAxisGroupFeatures = findAxisGroupFeatures(features, "axisGroup:x");
1074
+ const yAxisGroupFeatures = findAxisGroupFeatures(features, "axisGroup:y");
1075
+ const legacyAxisGroup = features.get("axisGroup")?.props;
1076
+ const categoryAxisGroups = orientation === "vertical" ? xAxisGroupFeatures : yAxisGroupFeatures;
1077
+ const valueAxisGroups = orientation === "vertical" ? yAxisGroupFeatures : xAxisGroupFeatures;
1078
+ const categoryGroupDefs = categoryAxisGroups.flatMap((f) => f.groups).filter((g) => g.categories && g.categories.length > 0);
1079
+ const valueRangeGroupDefs = valueAxisGroups.flatMap((f) => f.groups).filter((g) => g.range !== void 0);
1080
+ if (valueRangeGroupDefs.length > 0) {
1081
+ styledRangeBoundaries = buildStyledRanges(valueRangeGroupDefs);
1082
+ }
1083
+ if (styledRangeBoundaries && styledRangeBoundaries.length > 0) {
1084
+ if (orientation === "vertical") {
1085
+ const maxWidth = Math.max(...styledRangeBoundaries.map((r) => measureTextWidth(r.label, resolveFontSize(DEFAULT_GROUP_LABEL_FONT_SIZE, globalFont))));
1086
+ rangeLabelOffset = maxWidth + 16;
1087
+ } else {
1088
+ rangeLabelOffset = 24;
1089
+ }
1090
+ }
1091
+ let sortedCategories;
1092
+ if (categoryGroupDefs.length > 0) {
1093
+ const result = buildBoundariesFromAxisGroups(categoryGroupDefs, categories);
1094
+ sortedCategories = result.sortedCategories;
1095
+ styledBoundaries = result.styledBoundaries;
1096
+ } else if (legacyAxisGroup && legacyAxisGroup.groups.length > 0) {
1097
+ const result = buildBoundariesFromAxisGroups(legacyAxisGroup.groups, categories);
1098
+ sortedCategories = result.sortedCategories;
1099
+ styledBoundaries = result.styledBoundaries;
1100
+ }
1101
+ const variwideProps = barDatasets.find((d) => d.props.weightField)?.props;
1102
+ isVariwide = variwideProps?.weightField !== void 0;
1103
+ const weights = isVariwide ? batchResolveRequired(variwideProps.weightField, variwideProps.data, "weightField") : void 0;
1104
+ const rawResolvedPerDataset = barDatasets.map((d) => d.visible ? batchResolveAccessor(d.props.valueField, d.props.data) : []);
1105
+ const barRawResolved = rawResolvedPerDataset;
1106
+ const openResolvedPerDataset = barDatasets.map((d) => {
1107
+ const openAccessor = d.props.openField;
1108
+ if (!d.visible || !openAccessor) return void 0;
1109
+ return batchResolveAccessor(openAccessor, d.props.data);
1110
+ });
1111
+ const rawValues = barDatasets.map((d, i) => {
1112
+ if (!d.visible) return new Array(categories.length).fill(0);
1113
+ return rawResolvedPerDataset[i].map((v) => v === null || v === void 0 || Number.isNaN(v) ? 0 : v);
1114
+ });
1115
+ const openValuesPerDataset = openResolvedPerDataset.map((raw) => {
1116
+ if (!raw) return void 0;
1117
+ return raw.map((v) => v === null || v === void 0 || Number.isNaN(v) ? 0 : v);
1118
+ });
1119
+ const transformed = transformValues(rawValues, categories.length, mode);
1120
+ valuesPerDataset = transformed.transformed;
1121
+ const categoryTotals = transformed.categoryTotals;
1122
+ for (let i = 0; i < openValuesPerDataset.length; i++) {
1123
+ const openVals = openValuesPerDataset[i];
1124
+ if (openVals) {
1125
+ valuesPerDataset[i] = [...valuesPerDataset[i], ...openVals];
1126
+ }
1127
+ }
1128
+ const isSkipMode = (cn) => cn === void 0 || cn === "gap" || cn === false;
1129
+ const anySkipNull = barDatasets.some((d) => isSkipMode(d.props.connectNulls));
1130
+ effectiveWeights = weights;
1131
+ if (anySkipNull) {
1132
+ const keepMask = new Array(categories.length).fill(false);
1133
+ for (let dsIdx = 0; dsIdx < barDatasets.length; dsIdx++) {
1134
+ const ds = barDatasets[dsIdx];
1135
+ if (!ds.visible) continue;
1136
+ if (!isSkipMode(ds.props.connectNulls)) {
1137
+ keepMask.fill(true);
1138
+ break;
1139
+ }
1140
+ const raw = rawResolvedPerDataset[dsIdx];
1141
+ for (let i = 0; i < raw.length; i++) {
1142
+ const v = raw[i];
1143
+ if (v !== null && v !== void 0 && !Number.isNaN(v)) {
1144
+ keepMask[i] = true;
1145
+ }
1146
+ }
1147
+ }
1148
+ if (!keepMask.some(Boolean)) {
1149
+ keepMask.fill(true);
1150
+ } else if (!keepMask.every(Boolean)) {
1151
+ for (const ld of lineDatasets) {
1152
+ if (!ld.visible) continue;
1153
+ keepMask.fill(true);
1154
+ break;
1155
+ }
1156
+ }
1157
+ const filteredCategories = categories.filter((_, i) => keepMask[i]);
1158
+ if (sortedCategories) {
1159
+ const filteredSet = new Set(filteredCategories);
1160
+ effectiveScaleCategories = sortedCategories.filter((cat) => filteredSet.has(cat));
1161
+ } else {
1162
+ effectiveScaleCategories = filteredCategories;
1163
+ }
1164
+ if (weights) {
1165
+ effectiveWeights = weights.filter((_, i) => keepMask[i]);
1166
+ }
1167
+ } else {
1168
+ effectiveScaleCategories = sortedCategories ?? categories;
1169
+ }
1170
+ const sortSourceProps = barDatasets[0]?.props;
1171
+ const sortProp = !isTimeAxis ? sortSourceProps?.sort : void 0;
1172
+ if (sortProp) {
1173
+ const sortAggregate = sortSourceProps?.sortAggregate ?? "sum";
1174
+ effectiveScaleCategories = sortCategories(effectiveScaleCategories, sortProp, sortAggregate, categories, valuesPerDataset, categoryTotals);
1175
+ sortedCategoryOrder = effectiveScaleCategories.slice();
1176
+ }
1177
+ const firstBarProps = barDatasets[0].props;
1178
+ if (mode.isWaterfall && waterfallConfig) {
1179
+ waterfallBases = computeWaterfallBases(valuesPerDataset, categories.length, firstBarProps.data, waterfallConfig.totalField);
1180
+ }
1181
+ for (const ds of barDatasets) {
1182
+ const targetId = ds.props[axisIdProp] ?? firstValueAxisId;
1183
+ datasetAxisMap.set(ds.id, targetId);
1184
+ }
1185
+ const boundAxisIds = new Set(datasetAxisMap.values());
1186
+ for (const axisId of boundAxisIds) {
1187
+ const axisConfig = valueAxes.get(axisId);
1188
+ const userTickCount = axisConfig?.props?.tickCount;
1189
+ const valueAxisLength = orientation === "vertical" ? cartesianArea.height : cartesianArea.width;
1190
+ const axisTickCount = getAdaptiveTickCount(valueAxisLength, userTickCount);
1191
+ const axisType = axisConfig?.props?.type;
1192
+ const axisStartFromZero = axisConfig?.props?.startFromZero;
1193
+ const axisBoundMask = barDatasets.map((ds) => datasetAxisMap.get(ds.id) === axisId);
1194
+ if (!axisBoundMask.some((v) => v)) continue;
1195
+ const axisVisibleMask = barDatasets.map((ds, i) => axisBoundMask[i] && ds.visible);
1196
+ const hasVisibleDatasets = axisVisibleMask.some((v) => v);
1197
+ let domain;
1198
+ if (hasVisibleDatasets) {
1199
+ if (axisType === "logarithmic") {
1200
+ const logRawValues = [];
1201
+ for (let i = 0; i < barDatasets.length; i++) {
1202
+ if (!axisVisibleMask[i]) continue;
1203
+ for (const v of valuesPerDataset[i]) {
1204
+ if (v > 0) logRawValues.push(v);
1205
+ }
1206
+ }
1207
+ domain = calculateNiceLogDomain(logRawValues);
1208
+ } else if (mode.isGrouped && mode.isStacked) {
1209
+ const groupSumMap = /* @__PURE__ */ new Map();
1210
+ const groupVisibleMap = /* @__PURE__ */ new Map();
1211
+ for (let i = 0; i < barDatasets.length; i++) {
1212
+ const sid = barDatasets[i].stackId;
1213
+ const catSums = groupSumMap.get(sid) ?? new Array(categories.length).fill(0);
1214
+ const isVis = groupVisibleMap.get(sid) ?? false;
1215
+ if (axisVisibleMask[i]) {
1216
+ for (let c = 0; c < categories.length; c++) {
1217
+ catSums[c] += valuesPerDataset[i][c] ?? 0;
1218
+ }
1219
+ groupVisibleMap.set(sid, true);
1220
+ } else {
1221
+ if (!isVis) groupVisibleMap.set(sid, false);
1222
+ }
1223
+ groupSumMap.set(sid, catSums);
1224
+ }
1225
+ const syntheticValues = [...groupSumMap.values()];
1226
+ const syntheticVisible = [...groupSumMap.keys()].map((sid) => groupVisibleMap.get(sid) ?? false);
1227
+ domain = computeCartesianDomain({
1228
+ valuesPerDataset: syntheticValues,
1229
+ visibleMask: syntheticVisible,
1230
+ categoryCount: categories.length,
1231
+ mode: { isStacked: false, isWaterfall: false, isPercentStacked: false },
1232
+ tickCount: axisTickCount,
1233
+ exactTickCount: userTickCount !== void 0,
1234
+ includeZero: axisStartFromZero ?? true
1235
+ });
1236
+ } else {
1237
+ domain = computeCartesianDomain({
1238
+ valuesPerDataset,
1239
+ visibleMask: axisVisibleMask,
1240
+ categoryCount: categories.length,
1241
+ mode,
1242
+ waterfallBases,
1243
+ tickCount: axisTickCount,
1244
+ exactTickCount: userTickCount !== void 0,
1245
+ includeZero: axisStartFromZero ?? true
1246
+ });
1247
+ }
1248
+ } else {
1249
+ if (axisType === "logarithmic") {
1250
+ const logRawValues = [];
1251
+ for (let i = 0; i < barDatasets.length; i++) {
1252
+ if (!axisBoundMask[i]) continue;
1253
+ for (const v of rawResolvedPerDataset[i]) {
1254
+ if (v > 0) logRawValues.push(v);
1255
+ }
1256
+ }
1257
+ domain = calculateNiceLogDomain(logRawValues);
1258
+ } else {
1259
+ const originalValuesForDomain = barDatasets.map((_ds, i) => {
1260
+ if (!axisBoundMask[i]) return new Array(categories.length).fill(0);
1261
+ const vals = rawResolvedPerDataset[i].map((v) => v === null || v === void 0 || Number.isNaN(v) ? 0 : v);
1262
+ const openRaw = openResolvedPerDataset[i];
1263
+ if (openRaw) {
1264
+ const openVals = openRaw.map((v) => v === null || v === void 0 || Number.isNaN(v) ? 0 : v);
1265
+ return [...vals, ...openVals];
1266
+ }
1267
+ return vals;
1268
+ });
1269
+ domain = computeCartesianDomain({
1270
+ valuesPerDataset: originalValuesForDomain,
1271
+ visibleMask: axisBoundMask,
1272
+ categoryCount: categories.length,
1273
+ mode: { isStacked: false, isWaterfall: false, isPercentStacked: false },
1274
+ waterfallBases: void 0,
1275
+ tickCount: axisTickCount,
1276
+ exactTickCount: userTickCount !== void 0,
1277
+ includeZero: axisStartFromZero ?? true
1278
+ });
1279
+ }
1280
+ }
1281
+ valueDomains.set(axisId, domain);
1282
+ }
1283
+ return {
1284
+ mode,
1285
+ isVariwide,
1286
+ valuesPerDataset,
1287
+ categoryTotals,
1288
+ waterfallBases,
1289
+ effectiveScaleCategories,
1290
+ effectiveWeights,
1291
+ sortedCategoryOrder,
1292
+ styledBoundaries,
1293
+ styledRangeBoundaries,
1294
+ rangeLabelOffset,
1295
+ barRawResolved
1296
+ };
1297
+ }
1298
+
1299
+ // src/cartesian/layout.domain-contributions.ts
1300
+ function computeDomainContributions(params) {
1301
+ const {
1302
+ orientation,
1303
+ axes,
1304
+ barDatasets,
1305
+ lineDatasets,
1306
+ scatterDatasets,
1307
+ candlestickDatasets,
1308
+ datasetAxisMap,
1309
+ firstValueAxisId,
1310
+ valueAxes,
1311
+ categoryAxes,
1312
+ axisIdProp,
1313
+ lineStackBasesMap,
1314
+ lineTransformedValues,
1315
+ isLinePercentStacked,
1316
+ scatterStackBasesMap,
1317
+ cartesianArea,
1318
+ features,
1319
+ mode,
1320
+ styledRangeBoundaries,
1321
+ barRawResolved,
1322
+ primaryCategoryAxisConfig,
1323
+ isTimeAxis,
1324
+ timestamps,
1325
+ valuesPerDataset,
1326
+ zoomState,
1327
+ valueDomains
1328
+ } = params;
1329
+ const firstCategoryAxisId = (orientation === "vertical" ? axes.x : axes.y).keys().next().value ?? "default";
1330
+ const barAxisIds = /* @__PURE__ */ new Set();
1331
+ for (const ds of barDatasets) {
1332
+ if (ds.visible) barAxisIds.add(datasetAxisMap.get(ds.id) ?? firstValueAxisId);
1333
+ }
1334
+ const valueSeries = [];
1335
+ const categorySeries = [];
1336
+ const scatterLogYValues = /* @__PURE__ */ new Map();
1337
+ const collectLogValues = (axisId, values) => {
1338
+ if (valueAxes.get(axisId)?.props?.type !== "logarithmic") return;
1339
+ const bucket = scatterLogYValues.get(axisId) ?? [];
1340
+ for (const v of values) if (v > 0) bucket.push(v);
1341
+ scatterLogYValues.set(axisId, bucket);
1342
+ };
1343
+ for (const ld of lineDatasets) {
1344
+ if (!ld.visible) continue;
1345
+ const targetAxisId = ld.props[axisIdProp] ?? firstValueAxisId;
1346
+ const includeZero = resolveIncludeZero(targetAxisId, valueAxes, barAxisIds);
1347
+ const stackBases = lineStackBasesMap?.get(ld.id);
1348
+ if (stackBases) {
1349
+ if (isLinePercentStacked) {
1350
+ valueDomains.set(targetAxisId, [0, 100]);
1351
+ } else {
1352
+ const transformedVals = lineTransformedValues?.get(ld.id) ?? [];
1353
+ const cumulativeValues = transformedVals.map((v, i) => (stackBases[i] ?? 0) + v);
1354
+ valueSeries.push({ axisId: targetAxisId, values: [includeZero ? 0 : Math.min(...cumulativeValues), Math.max(...cumulativeValues)], includeZero });
1355
+ collectLogValues(targetAxisId, cumulativeValues);
1356
+ }
1357
+ } else {
1358
+ const lineValues = (lineTransformedValues?.get(ld.id) ?? []).filter((v) => !Number.isNaN(v));
1359
+ if (lineValues.length > 0) {
1360
+ valueSeries.push({ axisId: targetAxisId, values: lineValues, includeZero });
1361
+ collectLogValues(targetAxisId, lineValues);
1362
+ }
1363
+ }
1364
+ }
1365
+ const scatterLogXValues = /* @__PURE__ */ new Map();
1366
+ for (const sd of scatterDatasets) {
1367
+ if (!sd.visible) continue;
1368
+ const targetYAxisId = sd.props.yAxisId ?? firstValueAxisId;
1369
+ const rawYValues = batchResolveAccessor(sd.props.yField, sd.props.data ?? []);
1370
+ const stackBases = scatterStackBasesMap?.get(sd.id);
1371
+ const effectiveYValues = stackBases ? rawYValues.map((v, i) => v === null || v === void 0 || isNaN(Number(v)) ? null : Number(v) + (stackBases[i] ?? 0)) : rawYValues;
1372
+ const yValues = effectiveYValues.filter((v) => v !== null && v !== void 0 && !isNaN(Number(v))).map(Number);
1373
+ if (yValues.length > 0) {
1374
+ valueSeries.push({ axisId: targetYAxisId, values: yValues, includeZero: false });
1375
+ collectLogValues(targetYAxisId, yValues);
1376
+ }
1377
+ const targetXAxisId = sd.props.xAxisId ?? firstCategoryAxisId;
1378
+ const xValues = batchResolveAccessor(sd.props.xField, sd.props.data ?? []).filter((v) => v !== null && v !== void 0 && !isNaN(Number(v))).map(Number);
1379
+ if (xValues.length > 0) {
1380
+ categorySeries.push({ axisId: targetXAxisId, values: xValues, includeZero: false });
1381
+ if (categoryAxes.get(targetXAxisId)?.props?.type === "logarithmic") {
1382
+ const bucket = scatterLogXValues.get(targetXAxisId) ?? [];
1383
+ for (const v of xValues) if (v > 0) bucket.push(v);
1384
+ scatterLogXValues.set(targetXAxisId, bucket);
1385
+ }
1386
+ }
1387
+ }
1388
+ for (const cd of candlestickDatasets) {
1389
+ if (!cd.visible) continue;
1390
+ const targetAxisId = cd.props.yAxisId ?? firstValueAxisId;
1391
+ const lows = batchResolveAccessor(cd.props.lowField, cd.props.data ?? []);
1392
+ const highs = batchResolveAccessor(cd.props.highField, cd.props.data ?? []);
1393
+ const validValues = [...lows.filter((v) => v !== null && v !== void 0 && !isNaN(Number(v))).map(Number), ...highs.filter((v) => v !== null && v !== void 0 && !isNaN(Number(v))).map(Number)];
1394
+ if (validValues.length > 0) valueSeries.push({ axisId: targetAxisId, values: validValues, includeZero: false });
1395
+ }
1396
+ const domainContributions = [];
1397
+ if (valueSeries.length > 0 || categorySeries.length > 0) {
1398
+ domainContributions.push(computeDomainContribution(valueSeries, categorySeries.length > 0 ? categorySeries : void 0));
1399
+ }
1400
+ const scatterXDomains = mergeDomainContributions(valueDomains, domainContributions);
1401
+ for (const [axisId, positives] of scatterLogYValues) {
1402
+ if (positives.length > 0) valueDomains.set(axisId, calculateNiceLogDomain(positives));
1403
+ }
1404
+ for (const [axisId, positives] of scatterLogXValues) {
1405
+ if (positives.length > 0) scatterXDomains.set(axisId, calculateNiceLogDomain(positives));
1406
+ }
1407
+ if (scatterDatasets.length > 0) {
1408
+ expandScatterBubblePadding({
1409
+ scatterDatasets,
1410
+ valueDomains,
1411
+ scatterXDomains,
1412
+ firstValueAxisId,
1413
+ firstCategoryAxisId,
1414
+ chartArea: cartesianArea,
1415
+ isLogValueAxis: (axisId) => valueAxes.get(axisId)?.props?.type === "logarithmic",
1416
+ isLogCategoryAxis: (axisId) => categoryAxes.get(axisId)?.props?.type === "logarithmic"
1417
+ });
1418
+ }
1419
+ const dataLabelProps = features.get("dataLabels")?.props;
1420
+ if (dataLabelProps && !dataLabelProps.render) {
1421
+ const dataLabelFontSize = dataLabelProps.fontSize ?? DEFAULT_DATA_LABEL_FONT_SIZE;
1422
+ const dataLabelAxisIds = /* @__PURE__ */ new Set([...barAxisIds, ...lineDatasets.filter((d) => d.visible).map((d) => d.props[axisIdProp] ?? firstValueAxisId)]);
1423
+ expandDataLabelPadding({
1424
+ valueDomains,
1425
+ dataLabelFontSize,
1426
+ orientation,
1427
+ chartArea: cartesianArea,
1428
+ axisIds: dataLabelAxisIds,
1429
+ isLogAxis: (axisId) => valueAxes.get(axisId)?.props?.type === "logarithmic",
1430
+ isPercentStackedAxis: (axisId) => {
1431
+ if (mode.isPercentStacked && barAxisIds.has(axisId)) return true;
1432
+ if (isLinePercentStacked && lineDatasets.some((d) => d.visible && (d.props[axisIdProp] ?? firstValueAxisId) === axisId)) return true;
1433
+ return false;
1434
+ }
1435
+ });
1436
+ }
1437
+ for (const [axisId] of valueAxes) {
1438
+ if (!valueDomains.has(axisId)) {
1439
+ valueDomains.set(axisId, [0, 100]);
1440
+ }
1441
+ }
1442
+ for (const [axisId, domain] of valueDomains) {
1443
+ const axisConfig = valueAxes.get(axisId);
1444
+ const axisSoftMin = axisConfig?.props?.softMin;
1445
+ const axisSoftMax = axisConfig?.props?.softMax;
1446
+ if (axisSoftMin !== void 0 && domain[0] > axisSoftMin) {
1447
+ domain[0] = axisSoftMin;
1448
+ }
1449
+ if (axisSoftMax !== void 0 && domain[1] < axisSoftMax) {
1450
+ domain[1] = axisSoftMax;
1451
+ }
1452
+ }
1453
+ for (const [axisId, domain] of valueDomains) {
1454
+ const axisConfig = valueAxes.get(axisId);
1455
+ const axisMin = axisConfig?.props?.min;
1456
+ const axisMax = axisConfig?.props?.max;
1457
+ if (typeof axisMin === "number") domain[0] = axisMin;
1458
+ if (typeof axisMax === "number") domain[1] = axisMax;
1459
+ }
1460
+ for (const [axisId, domain] of scatterXDomains) {
1461
+ const axisConfig = categoryAxes.get(axisId);
1462
+ const axisMin = axisConfig?.props?.min;
1463
+ const axisMax = axisConfig?.props?.max;
1464
+ if (typeof axisMin === "number") domain[0] = axisMin;
1465
+ if (typeof axisMax === "number") domain[1] = axisMax;
1466
+ }
1467
+ for (const [axisId, domain] of valueDomains) {
1468
+ const axisConfig = valueAxes.get(axisId);
1469
+ if (typeof axisConfig?.props?.max === "number") continue;
1470
+ const userTickCount = axisConfig?.props?.tickCount;
1471
+ const valueAxisLength = orientation === "vertical" ? cartesianArea.height : cartesianArea.width;
1472
+ const axisTickCount = getAdaptiveTickCount(valueAxisLength, userTickCount);
1473
+ const ticks = generateNiceTicks(domain[0], domain[1], axisTickCount, userTickCount !== void 0);
1474
+ if (ticks.length >= 2) {
1475
+ const lastTick = ticks[ticks.length - 1];
1476
+ let rawMax = -Infinity;
1477
+ if (barRawResolved) {
1478
+ for (let idx = 0; idx < barDatasets.length; idx++) {
1479
+ const ds = barDatasets[idx];
1480
+ if (!ds.visible || (datasetAxisMap.get(ds.id) ?? firstValueAxisId) !== axisId) continue;
1481
+ if (idx < barRawResolved.length) {
1482
+ for (const v of barRawResolved[idx]) {
1483
+ if (typeof v === "number" && v > rawMax) rawMax = v;
1484
+ }
1485
+ }
1486
+ }
1487
+ }
1488
+ for (const ld of lineDatasets) {
1489
+ if (!ld.visible) continue;
1490
+ const targetAxisId = ld.props[axisIdProp] ?? firstValueAxisId;
1491
+ if (targetAxisId !== axisId) continue;
1492
+ const vals = lineTransformedValues?.get(ld.id);
1493
+ if (vals) {
1494
+ for (const v of vals) {
1495
+ if (!Number.isNaN(v) && v > rawMax) rawMax = v;
1496
+ }
1497
+ }
1498
+ }
1499
+ const tickStep = ticks[ticks.length - 1] - ticks[ticks.length - 2];
1500
+ if (rawMax > -Infinity && !isLinePercentStacked && !mode.isStacked && !mode.isPercentStacked && !mode.isWaterfall) {
1501
+ if (userTickCount === void 0 && tickStep > 0) {
1502
+ const eps = tickStep * 1e-9;
1503
+ let niceTop = Math.ceil((rawMax - eps) / tickStep) * tickStep;
1504
+ if (niceTop <= rawMax) niceTop += tickStep;
1505
+ domain[1] = niceTop;
1506
+ } else if (lastTick <= rawMax) {
1507
+ domain[1] = lastTick + tickStep;
1508
+ }
1509
+ }
1510
+ }
1511
+ }
1512
+ const scatterAxisLength = orientation === "vertical" ? cartesianArea.width : cartesianArea.height;
1513
+ for (const [axisId, domain] of scatterXDomains) {
1514
+ const axisProps = categoryAxes.get(axisId)?.props;
1515
+ if (axisProps?.type === "logarithmic") continue;
1516
+ const userTickCount = axisProps?.tickCount;
1517
+ if (userTickCount !== void 0) continue;
1518
+ const hasExplicitMin = typeof axisProps?.min === "number";
1519
+ const hasExplicitMax = typeof axisProps?.max === "number";
1520
+ if (hasExplicitMin && hasExplicitMax) continue;
1521
+ const ticks = generateNiceTicks(domain[0], domain[1], getAdaptiveTickCount(scatterAxisLength, userTickCount), false);
1522
+ if (ticks.length >= 2) {
1523
+ const tickStep = ticks[ticks.length - 1] - ticks[ticks.length - 2];
1524
+ if (tickStep > 0) {
1525
+ const eps = tickStep * 1e-9;
1526
+ if (!hasExplicitMax) {
1527
+ const niceTop = Math.ceil((domain[1] - eps) / tickStep) * tickStep;
1528
+ if (niceTop > domain[1]) domain[1] = niceTop;
1529
+ }
1530
+ if (!hasExplicitMin) {
1531
+ const niceFloor = Math.floor((domain[0] + eps) / tickStep) * tickStep;
1532
+ if (niceFloor < domain[0]) domain[0] = niceFloor;
1533
+ }
1534
+ }
1535
+ }
1536
+ }
1537
+ const valueDomain = (valueDomains.get(firstValueAxisId) ?? [0, 100]).slice();
1538
+ if (styledRangeBoundaries && styledRangeBoundaries.length > 0) {
1539
+ for (const rb of styledRangeBoundaries) {
1540
+ if (rb.from < valueDomain[0]) valueDomain[0] = rb.from;
1541
+ if (rb.to > valueDomain[1]) valueDomain[1] = rb.to;
1542
+ }
1543
+ valueDomains.set(firstValueAxisId, valueDomain);
1544
+ }
1545
+ const originalDomains = {};
1546
+ const minUnit = primaryCategoryAxisConfig?.props?.minUnit;
1547
+ let computedMinRange;
1548
+ if (minUnit) {
1549
+ computedMinRange = MS[minUnit] * 10;
1550
+ } else if (isTimeAxis && timestamps && timestamps.length >= 2) {
1551
+ const sorted = [...timestamps].filter((t) => !isNaN(t)).sort((a, b) => a - b);
1552
+ let minInterval = Infinity;
1553
+ for (let i = 1; i < sorted.length; i++) {
1554
+ const gap = sorted[i] - sorted[i - 1];
1555
+ if (gap > 0 && gap < minInterval) minInterval = gap;
1556
+ }
1557
+ if (isFinite(minInterval)) {
1558
+ computedMinRange = minInterval * 5;
1559
+ }
1560
+ }
1561
+ if (computedMinRange !== void 0) {
1562
+ if (orientation === "vertical") {
1563
+ originalDomains.minRangeX = computedMinRange;
1564
+ } else {
1565
+ originalDomains.minRangeY = computedMinRange;
1566
+ }
1567
+ }
1568
+ const primaryValueDomain = valueDomains.get(firstValueAxisId);
1569
+ if (primaryValueDomain) {
1570
+ if (orientation === "vertical") {
1571
+ originalDomains.y = [...primaryValueDomain];
1572
+ } else {
1573
+ originalDomains.x = [...primaryValueDomain];
1574
+ }
1575
+ }
1576
+ if (scatterXDomains.size > 0) {
1577
+ const firstScatterXDomain = scatterXDomains.values().next().value;
1578
+ if (firstScatterXDomain) {
1579
+ if (orientation === "vertical" && !originalDomains.x) {
1580
+ originalDomains.x = [...firstScatterXDomain];
1581
+ } else if (orientation !== "vertical" && !originalDomains.y) {
1582
+ originalDomains.y = [...firstScatterXDomain];
1583
+ }
1584
+ }
1585
+ }
1586
+ const zoomCategoryAxisForAdaptive = orientation === "vertical" ? zoomState?.x : zoomState?.y;
1587
+ const zoomValueAxisExplicit = orientation === "vertical" ? zoomState?.y : zoomState?.x;
1588
+ if (zoomCategoryAxisForAdaptive && !zoomValueAxisExplicit && (isTimeAxis && timestamps || scatterXDomains.size > 0)) {
1589
+ const xMin = zoomCategoryAxisForAdaptive.min;
1590
+ const xMax = zoomCategoryAxisForAdaptive.max;
1591
+ const adaptiveSeries = [];
1592
+ if (timestamps) {
1593
+ if (valuesPerDataset) {
1594
+ for (let di = 0; di < barDatasets.length; di++) {
1595
+ if (!barDatasets[di].visible) continue;
1596
+ adaptiveSeries.push({
1597
+ axisId: datasetAxisMap.get(barDatasets[di].id) ?? firstValueAxisId,
1598
+ xValues: timestamps,
1599
+ yValues: valuesPerDataset[di]
1600
+ });
1601
+ }
1602
+ }
1603
+ for (const ld of lineDatasets) {
1604
+ if (!ld.visible) continue;
1605
+ const resolved = lineTransformedValues?.get(ld.id);
1606
+ if (!resolved) continue;
1607
+ adaptiveSeries.push({
1608
+ axisId: ld.props[axisIdProp] ?? firstValueAxisId,
1609
+ xValues: timestamps,
1610
+ yValues: resolved
1611
+ });
1612
+ }
1613
+ }
1614
+ for (const sd of scatterDatasets) {
1615
+ if (!sd.visible) continue;
1616
+ adaptiveSeries.push({
1617
+ axisId: sd.props.yAxisId ?? firstValueAxisId,
1618
+ xValues: batchResolveAccessor(sd.props.xField, sd.props.data ?? []),
1619
+ yValues: batchResolveAccessor(sd.props.yField, sd.props.data ?? [])
1620
+ });
1621
+ }
1622
+ const adaptiveValues = computeVisibleValues(adaptiveSeries, xMin, xMax);
1623
+ for (const [axisId, vals] of adaptiveValues) {
1624
+ if (vals.length === 0) continue;
1625
+ const includeZero = resolveIncludeZero(axisId, valueAxes, barAxisIds);
1626
+ const adaptiveDomain = calculateNiceDomain(vals, { includeZero });
1627
+ valueDomains.set(axisId, adaptiveDomain);
1628
+ if (axisId === firstValueAxisId) {
1629
+ valueDomain[0] = adaptiveDomain[0];
1630
+ valueDomain[1] = adaptiveDomain[1];
1631
+ }
1632
+ }
1633
+ }
1634
+ if (zoomValueAxisExplicit) {
1635
+ valueDomains.set(firstValueAxisId, [zoomValueAxisExplicit.min, zoomValueAxisExplicit.max]);
1636
+ valueDomain[0] = zoomValueAxisExplicit.min;
1637
+ valueDomain[1] = zoomValueAxisExplicit.max;
1638
+ }
1639
+ const zoomCategoryAxis = orientation === "vertical" ? zoomState?.x : zoomState?.y;
1640
+ if (zoomCategoryAxis && scatterXDomains.size > 0) {
1641
+ for (const [axisId] of scatterXDomains) {
1642
+ scatterXDomains.set(axisId, [zoomCategoryAxis.min, zoomCategoryAxis.max]);
1643
+ }
1644
+ }
1645
+ return { scatterXDomains, valueDomain, originalDomains };
1646
+ }
1647
+
1648
+ // src/cartesian/layout.data-reduction.ts
1649
+ function applyDataGrouping(params) {
1650
+ const { groupingConfig, isTimeAxis, categoryDataSource, categoryKey, barDatasets, lineDatasets } = params;
1651
+ let { categories, timestamps, originalTimestamps, groupedDataOverride } = params;
1652
+ if (groupingConfig && isTimeAxis && timestamps && timestamps.length > 0) {
1653
+ const targetPoints = groupingConfig.targetPoints ?? 500;
1654
+ const method = groupingConfig.method ?? "average";
1655
+ const enabled = groupingConfig.enabled ?? categoryDataSource.length > targetPoints;
1656
+ if (enabled) {
1657
+ const interval = groupingConfig.interval ?? selectGroupingInterval(timestamps[timestamps.length - 1] - timestamps[0], categoryDataSource.length, targetPoints);
1658
+ const catKey = categoryKey;
1659
+ for (const ds of barDatasets) {
1660
+ if (!ds.props.data || ds.props.data.length === 0) continue;
1661
+ const valueKey = ds.props.valueField ?? FIELD_DEFAULTS.valueField;
1662
+ const grouped = groupTimeData(ds.props.data, catKey, valueKey, interval, method);
1663
+ if (grouped.length < ds.props.data.length) {
1664
+ ds.props = { ...ds.props, data: grouped };
1665
+ }
1666
+ }
1667
+ for (const ds of lineDatasets) {
1668
+ if (!ds.props.data || ds.props.data.length === 0) continue;
1669
+ const valueKey = ds.props.valueField ?? FIELD_DEFAULTS.valueField;
1670
+ const grouped = groupTimeData(ds.props.data, catKey, valueKey, interval, method);
1671
+ if (grouped.length < ds.props.data.length) {
1672
+ ds.props = { ...ds.props, data: grouped };
1673
+ if (!groupedDataOverride) groupedDataOverride = /* @__PURE__ */ new Map();
1674
+ groupedDataOverride.set(ds.id, ds.props.data);
1675
+ }
1676
+ }
1677
+ const groupedSource = barDatasets[0]?.props.data ?? lineDatasets[0]?.props.data ?? [];
1678
+ const groupedRaw = batchResolveAccessor(catKey, groupedSource);
1679
+ timestamps = groupedRaw.map(toTimestamp);
1680
+ originalTimestamps = timestamps;
1681
+ categories = timestamps.map(String);
1682
+ }
1683
+ }
1684
+ return { categories, timestamps, originalTimestamps, groupedDataOverride };
1685
+ }
1686
+ function applyDecimation(params) {
1687
+ const { decimationConfig, zoomX, barDatasets, lineDatasets, isTimeAxis } = params;
1688
+ let { categories, timestamps, groupedDataOverride } = params;
1689
+ let decimatedIndices;
1690
+ if (decimationConfig) {
1691
+ const samples = decimationConfig.samples ?? 500;
1692
+ const threshold = decimationConfig.threshold ?? samples;
1693
+ const algorithm = decimationConfig.algorithm ?? "lttb";
1694
+ const allBarLineDatasets = [...barDatasets, ...lineDatasets];
1695
+ const firstVisible = allBarLineDatasets.find((d) => d.visible) ?? allBarLineDatasets[0];
1696
+ if (firstVisible && firstVisible.props.data.length > threshold) {
1697
+ const yField = firstVisible.props.valueField;
1698
+ const sourceData = firstVisible.props.data;
1699
+ let keptIndicesArr;
1700
+ if (zoomX && timestamps) {
1701
+ const zoomIndices = [];
1702
+ const zoomYVals = [];
1703
+ for (let i = 0; i < timestamps.length; i++) {
1704
+ if (timestamps[i] >= zoomX.min && timestamps[i] <= zoomX.max) {
1705
+ zoomIndices.push(i);
1706
+ zoomYVals.push(resolveAccessor(yField, makeItemContext(sourceData[i], i)));
1707
+ }
1708
+ }
1709
+ if (zoomIndices.length <= samples) {
1710
+ keptIndicesArr = zoomIndices;
1711
+ } else {
1712
+ const relKept = decimate(zoomYVals, { algorithm, threshold, samples });
1713
+ keptIndicesArr = relKept.map((ri) => zoomIndices[ri]);
1714
+ }
1715
+ } else {
1716
+ const allYVals = batchResolveRequired(yField, sourceData, "yField");
1717
+ keptIndicesArr = decimate(allYVals, { algorithm, threshold, samples });
1718
+ }
1719
+ for (const ds of allBarLineDatasets) {
1720
+ const data = ds.props.data;
1721
+ ds.props = { ...ds.props, data: keptIndicesArr.map((i) => data[i]) };
1722
+ }
1723
+ categories = keptIndicesArr.map((i) => categories[i]);
1724
+ if (isTimeAxis && timestamps) {
1725
+ timestamps = keptIndicesArr.map((i) => timestamps[i]);
1726
+ }
1727
+ if (lineDatasets.length > 0) {
1728
+ if (!groupedDataOverride) groupedDataOverride = /* @__PURE__ */ new Map();
1729
+ for (const ld of lineDatasets) {
1730
+ groupedDataOverride.set(ld.id, ld.props.data);
1731
+ }
1732
+ }
1733
+ decimatedIndices = keptIndicesArr;
1734
+ }
1735
+ }
1736
+ return { categories, timestamps, groupedDataOverride, decimatedIndices };
1737
+ }
1738
+
1739
+ // src/cartesian/layout.ts
1740
+ function computeCartesianLayout(input, lastVisibleLayouts) {
1741
+ const { cartesianArea, datasets, axes, features, datasetVisibility, chartId, renderer, dimensions, zoomState, dir, font: globalFont, locale } = input;
1742
+ const isRtl = dir === "rtl";
1743
+ const sortedDatasets = Array.from(datasets.entries()).sort(([, a], [, b]) => a.order - b.order);
1744
+ const collected = collectItems(sortedDatasets, datasetVisibility);
1745
+ const barDatasets = collected.bar;
1746
+ const lineDatasets = collected.line;
1747
+ const scatterDatasets = collected.scatter;
1748
+ const candlestickDatasets = collected.candlestick;
1749
+ if (barDatasets.length === 0 && lineDatasets.length === 0 && scatterDatasets.length === 0 && candlestickDatasets.length === 0) {
1750
+ return null;
1751
+ }
1752
+ const visibleBarDatasets = barDatasets.filter((d) => d.visible);
1753
+ const { width, height } = dimensions;
1754
+ const responsiveFeature = features.get("responsive")?.props;
1755
+ const tier = getResponsiveTier(width, responsiveFeature?.breakpoints);
1756
+ const adaptive = responsiveFeature?.disableAutoAdaptive ? getAdaptiveDefaults("lg", globalFont) : getAdaptiveDefaults(tier, globalFont);
1757
+ const allCatSources = [];
1758
+ for (const ds of barDatasets) {
1759
+ const key = ds.props.categoryField ?? FIELD_DEFAULTS.categoryField;
1760
+ const data = ds.props.data ?? [];
1761
+ if (data.length > 0) allCatSources.push({ key, data, tier: 0 });
1762
+ }
1763
+ for (const ds of candlestickDatasets) {
1764
+ const key = ds.props.timeField;
1765
+ const data = ds.props.data ?? [];
1766
+ if (data.length > 0) allCatSources.push({ key, data, tier: 1 });
1767
+ }
1768
+ for (const ds of lineDatasets) {
1769
+ const key = ds.props.categoryField ?? FIELD_DEFAULTS.categoryField;
1770
+ const data = ds.props.data ?? [];
1771
+ if (data.length > 0) allCatSources.push({ key, data, tier: 2 });
1772
+ }
1773
+ allCatSources.sort((a, b) => b.data.length - a.data.length || a.tier - b.tier);
1774
+ const primaryCatSource = allCatSources[0];
1775
+ let categoryKey;
1776
+ let categoryDataSource;
1777
+ if (primaryCatSource) {
1778
+ categoryKey = primaryCatSource.key;
1779
+ categoryDataSource = primaryCatSource.data;
1780
+ } else {
1781
+ categoryKey = "__scatter_no_category__";
1782
+ categoryDataSource = [];
1783
+ }
1784
+ const orientation = barDatasets[0]?.props?.orientation ?? "vertical";
1785
+ const categoryAxes = orientation === "vertical" ? axes.x : axes.y;
1786
+ const primaryCategoryAxisConfig = categoryAxes.size > 0 ? categoryAxes.values().next().value : void 0;
1787
+ const isTimeAxis = primaryCategoryAxisConfig?.props?.type === "time";
1788
+ let categories;
1789
+ let timestamps;
1790
+ let originalTimestamps;
1791
+ let groupedDataOverride;
1792
+ if (isTimeAxis) {
1793
+ const seenTs = /* @__PURE__ */ new Set();
1794
+ const allTs = [];
1795
+ for (const src of allCatSources) {
1796
+ const rawValues = batchResolveAccessor(src.key, src.data);
1797
+ for (const v of rawValues) {
1798
+ const t = toTimestamp(v);
1799
+ if (!isNaN(t) && !seenTs.has(t)) {
1800
+ seenTs.add(t);
1801
+ allTs.push(t);
1802
+ }
1803
+ }
1804
+ }
1805
+ allTs.sort((a, b) => a - b);
1806
+ timestamps = allTs;
1807
+ originalTimestamps = timestamps;
1808
+ categories = timestamps.map(String);
1809
+ } else {
1810
+ const seenCats = /* @__PURE__ */ new Set();
1811
+ categories = [];
1812
+ for (const src of allCatSources) {
1813
+ const cats = batchResolveRequired(src.key, src.data, "categoryField");
1814
+ for (const cat of cats) {
1815
+ if (!seenCats.has(cat)) {
1816
+ seenCats.add(cat);
1817
+ categories.push(cat);
1818
+ }
1819
+ }
1820
+ }
1821
+ }
1822
+ const valueAxes = orientation === "vertical" ? axes.y : axes.x;
1823
+ const firstValueAxisId = valueAxes.size > 0 ? valueAxes.keys().next().value : "default";
1824
+ const axisIdProp = orientation === "vertical" ? "yAxisId" : "xAxisId";
1825
+ const datasetAxisMap = /* @__PURE__ */ new Map();
1826
+ let mode = { isStacked: false, isWaterfall: false, isPercentStacked: false, isGrouped: false, isOverlap: false };
1827
+ let isVariwide = false;
1828
+ let valuesPerDataset = [];
1829
+ let categoryTotals;
1830
+ let waterfallBases;
1831
+ let effectiveScaleCategories = categories.slice();
1832
+ let effectiveWeights;
1833
+ let sortedCategoryOrder;
1834
+ let styledBoundaries;
1835
+ let styledRangeBoundaries;
1836
+ let rangeLabelOffset = 0;
1837
+ const valueDomains = /* @__PURE__ */ new Map();
1838
+ const groupingConfig = isTimeAxis ? primaryCategoryAxisConfig?.props?.grouping : void 0;
1839
+ ({ categories, timestamps, originalTimestamps, groupedDataOverride } = applyDataGrouping({
1840
+ groupingConfig,
1841
+ isTimeAxis,
1842
+ timestamps,
1843
+ originalTimestamps,
1844
+ categories,
1845
+ categoryDataSource,
1846
+ categoryKey,
1847
+ barDatasets,
1848
+ lineDatasets,
1849
+ groupedDataOverride
1850
+ }));
1851
+ const decimationConfig = features.get("decimation")?.props;
1852
+ const decimationZoomX = orientation === "vertical" ? zoomState?.x : zoomState?.y;
1853
+ const decimation = applyDecimation({
1854
+ decimationConfig,
1855
+ zoomX: decimationZoomX,
1856
+ barDatasets,
1857
+ lineDatasets,
1858
+ timestamps,
1859
+ categories,
1860
+ isTimeAxis,
1861
+ groupedDataOverride
1862
+ });
1863
+ categories = decimation.categories;
1864
+ timestamps = decimation.timestamps;
1865
+ groupedDataOverride = decimation.groupedDataOverride;
1866
+ const decimatedIndices = decimation.decimatedIndices;
1867
+ let barRawResolved;
1868
+ if (barDatasets.length > 0) {
1869
+ ({ mode, isVariwide, valuesPerDataset, categoryTotals, waterfallBases, effectiveScaleCategories, effectiveWeights, sortedCategoryOrder, styledBoundaries, styledRangeBoundaries, rangeLabelOffset, barRawResolved } = computeBarPipeline({
1870
+ features,
1871
+ barDatasets,
1872
+ lineDatasets,
1873
+ orientation,
1874
+ categories,
1875
+ globalFont,
1876
+ isTimeAxis,
1877
+ axisIdProp,
1878
+ firstValueAxisId,
1879
+ valueAxes,
1880
+ cartesianArea,
1881
+ valueDomains,
1882
+ datasetAxisMap,
1883
+ mode,
1884
+ effectiveScaleCategories
1885
+ }));
1886
+ }
1887
+ let lineStackBasesMap;
1888
+ let lineTransformedValues;
1889
+ const stackedLineDatasets = lineDatasets.filter((d) => d.stackId !== void 0);
1890
+ const stackingConfig = features.get("stacking")?.props;
1891
+ const isLinePercentStacked = stackedLineDatasets.length > 0 && stackingConfig?.mode === "percent";
1892
+ if (stackedLineDatasets.length > 0) {
1893
+ const rawLineValues = stackedLineDatasets.map((ld) => {
1894
+ if (!ld.visible) return new Array(categories.length).fill(0);
1895
+ const valueKey = ld.props.valueField ?? FIELD_DEFAULTS.valueField;
1896
+ const raw = batchResolveAccessor(valueKey, ld.props.data ?? []);
1897
+ return raw.map((v) => v === null || v === void 0 || Number.isNaN(Number(v)) ? 0 : Number(v));
1898
+ });
1899
+ const lineMode = {
1900
+ isPercentStacked: stackingConfig?.mode === "percent"
1901
+ };
1902
+ const transformed = transformValues(rawLineValues, categories.length, lineMode);
1903
+ const lineValuesPerDataset = transformed.transformed;
1904
+ lineTransformedValues = /* @__PURE__ */ new Map();
1905
+ for (let i = 0; i < stackedLineDatasets.length; i++) {
1906
+ lineTransformedValues.set(stackedLineDatasets[i].id, lineValuesPerDataset[i]);
1907
+ }
1908
+ const lineSignsPerDataset = isLinePercentStacked ? void 0 : stackedLineDatasets.map((ld) => {
1909
+ const valueKey = ld.props.valueField ?? FIELD_DEFAULTS.valueField;
1910
+ const raw = batchResolveAccessor(valueKey, ld.props.data ?? []);
1911
+ return (raw ?? []).map((v) => typeof v === "number" && isFinite(v) && v < 0 ? -1 : v === 0 ? 0 : 1);
1912
+ });
1913
+ lineStackBasesMap = computeStackBases(
1914
+ stackedLineDatasets.map((d) => d.id),
1915
+ lineValuesPerDataset,
1916
+ categories.length,
1917
+ { isStacked: true, isWaterfall: false },
1918
+ void 0,
1919
+ lineSignsPerDataset
1920
+ );
1921
+ }
1922
+ for (const ld of lineDatasets) {
1923
+ if (ld.stackId !== void 0) continue;
1924
+ const valueKey = ld.props.valueField ?? FIELD_DEFAULTS.valueField;
1925
+ const raw = batchResolveAccessor(valueKey, ld.props.data ?? []);
1926
+ const resolved = raw.map((v) => v === null || v === void 0 || isNaN(Number(v)) ? NaN : Number(v));
1927
+ if (!lineTransformedValues) lineTransformedValues = /* @__PURE__ */ new Map();
1928
+ lineTransformedValues.set(ld.id, resolved);
1929
+ }
1930
+ let scatterStackBasesMap;
1931
+ const stackedScatterDatasets = scatterDatasets.filter((d) => d.stackId !== void 0);
1932
+ if (stackedScatterDatasets.length > 0) {
1933
+ const scatterPointCount = stackedScatterDatasets.reduce((max, sd) => Math.max(max, sd.props.data?.length ?? 0), 0);
1934
+ const rawScatterValues = stackedScatterDatasets.map((sd) => {
1935
+ if (!sd.visible) return new Array(scatterPointCount).fill(0);
1936
+ const raw = batchResolveAccessor(sd.props.yField, sd.props.data ?? []);
1937
+ const padded = new Array(scatterPointCount).fill(0);
1938
+ for (let i = 0; i < raw.length; i++) {
1939
+ const v = raw[i];
1940
+ padded[i] = v === null || v === void 0 || Number.isNaN(Number(v)) ? 0 : Number(v);
1941
+ }
1942
+ return padded;
1943
+ });
1944
+ const scatterSignsPerDataset = stackedScatterDatasets.map((sd) => {
1945
+ const raw = batchResolveAccessor(sd.props.yField, sd.props.data ?? []);
1946
+ const signs = new Array(scatterPointCount).fill(1);
1947
+ for (let i = 0; i < raw.length; i++) {
1948
+ const v = raw[i];
1949
+ signs[i] = typeof v === "number" && isFinite(v) && v < 0 ? -1 : v === 0 ? 0 : 1;
1950
+ }
1951
+ return signs;
1952
+ });
1953
+ scatterStackBasesMap = computeStackBases(
1954
+ stackedScatterDatasets.map((d) => d.id),
1955
+ rawScatterValues,
1956
+ scatterPointCount,
1957
+ { isStacked: true, isWaterfall: false },
1958
+ void 0,
1959
+ scatterSignsPerDataset
1960
+ );
1961
+ }
1962
+ const { scatterXDomains, valueDomain, originalDomains } = computeDomainContributions({
1963
+ orientation,
1964
+ axes,
1965
+ barDatasets,
1966
+ lineDatasets,
1967
+ scatterDatasets,
1968
+ candlestickDatasets,
1969
+ datasetAxisMap,
1970
+ firstValueAxisId,
1971
+ valueAxes,
1972
+ categoryAxes,
1973
+ axisIdProp,
1974
+ lineStackBasesMap,
1975
+ lineTransformedValues,
1976
+ isLinePercentStacked,
1977
+ scatterStackBasesMap,
1978
+ cartesianArea,
1979
+ features,
1980
+ mode,
1981
+ styledRangeBoundaries,
1982
+ barRawResolved,
1983
+ primaryCategoryAxisConfig,
1984
+ isTimeAxis,
1985
+ timestamps,
1986
+ valuesPerDataset,
1987
+ zoomState,
1988
+ valueDomains
1989
+ });
1990
+ const categoryScaleAxisProps = orientation === "vertical" ? axes.x.values().next().value?.props : axes.y.values().next().value?.props;
1991
+ const firstBarProps = barDatasets[0]?.props;
1992
+ const bandScaleOptions = categoryScaleAxisProps?.scale === "point" ? {
1993
+ categoryGap: 1,
1994
+ chartPaddingMin: categoryScaleAxisProps?.chartPaddingMin ?? 0.05,
1995
+ chartPaddingMax: categoryScaleAxisProps?.chartPaddingMax ?? 0.05
1996
+ } : {
1997
+ ...firstBarProps?.categoryGap !== void 0 && { categoryGap: firstBarProps.categoryGap },
1998
+ ...categoryScaleAxisProps?.chartPaddingMin !== void 0 && { chartPaddingMin: categoryScaleAxisProps.chartPaddingMin },
1999
+ ...categoryScaleAxisProps?.chartPaddingMax !== void 0 && { chartPaddingMax: categoryScaleAxisProps.chartPaddingMax }
2000
+ };
2001
+ const scaleCategories = effectiveScaleCategories;
2002
+ let sharedCategoryScale;
2003
+ let sharedTimeScale;
2004
+ let timeAxisTimezone;
2005
+ let rawStreamTimeDomain;
2006
+ const valueScaleRange = orientation === "vertical" ? [cartesianArea.y + cartesianArea.height, cartesianArea.y] : [cartesianArea.x, cartesianArea.x + cartesianArea.width];
2007
+ if (isTimeAxis && timestamps && timestamps.length > 0) {
2008
+ const validTs = timestamps.filter((t) => !isNaN(t));
2009
+ const domainTs = (originalTimestamps ?? timestamps).filter((t) => !isNaN(t));
2010
+ const timeAxisProps = primaryCategoryAxisConfig?.props;
2011
+ timeAxisTimezone = timeAxisProps?.timezone;
2012
+ let rawTsMin = Infinity;
2013
+ let rawTsMax = -Infinity;
2014
+ for (const t of domainTs) {
2015
+ if (t < rawTsMin) rawTsMin = t;
2016
+ if (t > rawTsMax) rawTsMax = t;
2017
+ }
2018
+ let [tsMin, tsMax] = calculateNiceTimeDomain(domainTs, {
2019
+ min: timeAxisProps?.min,
2020
+ max: timeAxisProps?.max
2021
+ });
2022
+ if (orientation === "vertical") {
2023
+ originalDomains.x = [tsMin, tsMax];
2024
+ } else {
2025
+ originalDomains.y = [tsMin, tsMax];
2026
+ }
2027
+ const zoomCategoryAxis = orientation === "vertical" ? zoomState?.x : zoomState?.y;
2028
+ if (zoomCategoryAxis) {
2029
+ tsMin = zoomCategoryAxis.min;
2030
+ tsMax = zoomCategoryAxis.max;
2031
+ }
2032
+ const timeReversed = primaryCategoryAxisConfig?.props?.reversed ?? false;
2033
+ const effectiveTimeReversed = orientation === "vertical" ? isRtl ? !timeReversed : timeReversed : timeReversed;
2034
+ const catRange = orientation === "vertical" ? effectiveTimeReversed ? [cartesianArea.x + cartesianArea.width, cartesianArea.x] : [cartesianArea.x, cartesianArea.x + cartesianArea.width] : effectiveTimeReversed ? [cartesianArea.y + cartesianArea.height, cartesianArea.y] : [cartesianArea.y, cartesianArea.y + cartesianArea.height];
2035
+ let minDataInterval = Infinity;
2036
+ if (validTs.length >= 2) {
2037
+ const sortedTs = [...validTs].sort((a, b) => a - b);
2038
+ for (let i = 1; i < sortedTs.length; i++) {
2039
+ const gap = sortedTs[i] - sortedTs[i - 1];
2040
+ if (gap > 0 && gap < minDataInterval) minDataInterval = gap;
2041
+ }
2042
+ }
2043
+ if (!zoomCategoryAxis && isFinite(rawTsMin) && isFinite(rawTsMax)) {
2044
+ const span = rawTsMax - rawTsMin;
2045
+ const padMin = (timeAxisProps?.chartPaddingMin ?? 0) * span;
2046
+ const padMax = (timeAxisProps?.chartPaddingMax ?? 0) * span;
2047
+ rawStreamTimeDomain = [rawTsMin - padMin, rawTsMax + padMax];
2048
+ }
2049
+ let effectiveTickConfig = timeAxisProps?.tickConfig;
2050
+ if (!effectiveTickConfig?.baseInterval && !effectiveTickConfig?.minInterval && isFinite(minDataInterval)) {
2051
+ const detectedUnit = minDataInterval >= MS.year ? { unit: "year", count: 1 } : minDataInterval >= MS.month ? { unit: "month", count: 1 } : minDataInterval >= MS.week ? { unit: "week", count: 1 } : minDataInterval >= MS.day ? { unit: "day", count: 1 } : minDataInterval >= MS.hour ? { unit: "hour", count: 1 } : minDataInterval >= MS.minute ? { unit: "minute", count: 1 } : minDataInterval >= MS.second ? { unit: "second", count: 1 } : { unit: "millisecond", count: 1 };
2052
+ effectiveTickConfig = { ...effectiveTickConfig, minInterval: detectedUnit };
2053
+ }
2054
+ const scaleDomain = rawStreamTimeDomain ?? [tsMin, tsMax];
2055
+ if (timeAxisProps?.gapless && validTs.length > 0) {
2056
+ const sortedUnique = [...new Set(validTs)].sort((a, b) => a - b);
2057
+ const gaplessDefaultPad = sortedUnique.length > 1 ? 0.5 / (sortedUnique.length - 1) : 0;
2058
+ const gaplessPadStart = zoomCategoryAxis ? 0 : timeAxisProps?.chartPaddingMin ?? gaplessDefaultPad;
2059
+ const gaplessPadEnd = zoomCategoryAxis ? 0 : timeAxisProps?.chartPaddingMax ?? gaplessDefaultPad;
2060
+ sharedTimeScale = createOrdinalTimeScale(sortedUnique, catRange, { visibleDomain: [tsMin, tsMax], tickConfig: effectiveTickConfig, padStart: gaplessPadStart, padEnd: gaplessPadEnd });
2061
+ sharedCategoryScale = createOrdinalTimeBandAdapter(sortedUnique, sharedTimeScale);
2062
+ } else {
2063
+ sharedTimeScale = createTimeScale(scaleDomain, catRange, { tickConfig: effectiveTickConfig });
2064
+ sharedCategoryScale = createTimeBandAdapter(validTs, sharedTimeScale);
2065
+ }
2066
+ } else {
2067
+ const totalCategories = scaleCategories.length;
2068
+ if (totalCategories > 0) {
2069
+ const catMinRange = Math.min(1, totalCategories - 1);
2070
+ if (orientation === "vertical") {
2071
+ if (!originalDomains.x) originalDomains.x = [0, totalCategories - 1];
2072
+ if (!originalDomains.minRangeX) originalDomains.minRangeX = catMinRange;
2073
+ } else {
2074
+ if (!originalDomains.y) originalDomains.y = [0, totalCategories - 1];
2075
+ if (!originalDomains.minRangeY) originalDomains.minRangeY = catMinRange;
2076
+ }
2077
+ }
2078
+ const zoomCatAxis = orientation === "vertical" ? zoomState?.x : zoomState?.y;
2079
+ let visibleCategories = scaleCategories;
2080
+ let visibleWeights = effectiveWeights;
2081
+ if (zoomCatAxis && totalCategories > 0) {
2082
+ const startIdx = Math.max(0, Math.floor(zoomCatAxis.min));
2083
+ const endIdx = Math.min(totalCategories - 1, Math.ceil(zoomCatAxis.max));
2084
+ visibleCategories = scaleCategories.slice(startIdx, endIdx + 1);
2085
+ if (visibleWeights) {
2086
+ visibleWeights = visibleWeights.slice(startIdx, endIdx + 1);
2087
+ }
2088
+ }
2089
+ if (orientation === "vertical") {
2090
+ const catReversed = primaryCategoryAxisConfig?.props?.reversed ?? false;
2091
+ const effectiveCatReversed = isRtl ? !catReversed : catReversed;
2092
+ const catRangeX = effectiveCatReversed ? [cartesianArea.x + cartesianArea.width, cartesianArea.x] : [cartesianArea.x, cartesianArea.x + cartesianArea.width];
2093
+ sharedCategoryScale = isVariwide && visibleWeights ? createVariwideBandScale(visibleCategories, catRangeX, { ...bandScaleOptions, weights: visibleWeights }) : createBandScale(visibleCategories, catRangeX, bandScaleOptions);
2094
+ } else {
2095
+ const catReversed = primaryCategoryAxisConfig?.props?.reversed ?? false;
2096
+ const catRangeY = catReversed ? [cartesianArea.y + cartesianArea.height, cartesianArea.y] : [cartesianArea.y, cartesianArea.y + cartesianArea.height];
2097
+ sharedCategoryScale = isVariwide && visibleWeights ? createVariwideBandScale(visibleCategories, catRangeY, { ...bandScaleOptions, weights: visibleWeights }) : createBandScale(visibleCategories, catRangeY, bandScaleOptions);
2098
+ }
2099
+ }
2100
+ for (const [axisId, domain] of valueDomains) {
2101
+ const axisProps = valueAxes.get(axisId)?.props;
2102
+ const padMin = axisProps?.chartPaddingMin ?? 0;
2103
+ const padMax = axisProps?.chartPaddingMax ?? 0;
2104
+ if (padMin === 0 && padMax === 0) continue;
2105
+ if (axisProps?.type === "logarithmic" && domain[0] > 0 && domain[1] > 0) {
2106
+ const lo = Math.log10(domain[0]);
2107
+ const hi = Math.log10(domain[1]);
2108
+ const span = hi - lo;
2109
+ domain[0] = Math.pow(10, lo - span * padMin);
2110
+ domain[1] = Math.pow(10, hi + span * padMax);
2111
+ } else {
2112
+ const span = domain[1] - domain[0];
2113
+ domain[0] = domain[0] - span * padMin;
2114
+ domain[1] = domain[1] + span * padMax;
2115
+ }
2116
+ }
2117
+ const valueScales = /* @__PURE__ */ new Map();
2118
+ for (const [axisId, domain] of valueDomains) {
2119
+ const axisConfig = valueAxes.get(axisId);
2120
+ const axisType = axisConfig?.props?.type;
2121
+ const axisReversed = axisConfig?.props?.reversed ?? false;
2122
+ const range = axisReversed ? [valueScaleRange[1], valueScaleRange[0]] : valueScaleRange;
2123
+ if (axisType === "logarithmic") {
2124
+ valueScales.set(axisId, createLogScale(domain, range));
2125
+ } else {
2126
+ valueScales.set(axisId, createLinearScale(domain, range));
2127
+ }
2128
+ }
2129
+ const primaryReversed = valueAxes.get(firstValueAxisId)?.props?.reversed ?? false;
2130
+ const primaryRange = primaryReversed ? [valueScaleRange[1], valueScaleRange[0]] : valueScaleRange;
2131
+ const sharedValueScale = valueScales.get(firstValueAxisId) ?? createLinearScale(valueDomain, primaryRange);
2132
+ const scatterXScales = /* @__PURE__ */ new Map();
2133
+ const categoryScaleRange = orientation === "vertical" ? [cartesianArea.x, cartesianArea.x + cartesianArea.width] : [cartesianArea.y, cartesianArea.y + cartesianArea.height];
2134
+ for (const [axisId, domain] of scatterXDomains) {
2135
+ const scatterAxisConfig = categoryAxes.get(axisId);
2136
+ const scatterAxisProps = scatterAxisConfig?.props;
2137
+ const scatterReversed = scatterAxisProps?.reversed ?? false;
2138
+ const effectiveScatterReversed = orientation === "vertical" ? isRtl ? !scatterReversed : scatterReversed : scatterReversed;
2139
+ const scatterRange = effectiveScatterReversed ? [categoryScaleRange[1], categoryScaleRange[0]] : categoryScaleRange;
2140
+ const scatterAxisType = scatterAxisProps?.type;
2141
+ const padMin = scatterAxisProps?.chartPaddingMin ?? 0;
2142
+ const padMax = scatterAxisProps?.chartPaddingMax ?? 0;
2143
+ let paddedDomain = domain;
2144
+ if (padMin !== 0 || padMax !== 0) {
2145
+ if (scatterAxisType === "logarithmic" && domain[0] > 0 && domain[1] > 0) {
2146
+ const lo = Math.log10(domain[0]);
2147
+ const hi = Math.log10(domain[1]);
2148
+ const span = hi - lo;
2149
+ paddedDomain = [Math.pow(10, lo - span * padMin), Math.pow(10, hi + span * padMax)];
2150
+ } else {
2151
+ const span = domain[1] - domain[0];
2152
+ paddedDomain = [domain[0] - span * padMin, domain[1] + span * padMax];
2153
+ }
2154
+ scatterXDomains.set(axisId, paddedDomain);
2155
+ }
2156
+ scatterXScales.set(axisId, scatterAxisType === "logarithmic" ? createLogScale(paddedDomain, scatterRange) : createLinearScale(paddedDomain, scatterRange));
2157
+ }
2158
+ let stackBasesMap;
2159
+ let groupLayout;
2160
+ if (mode.isStacked || mode.isWaterfall) {
2161
+ const signsPerDataset = mode.isPercentStacked ? void 0 : barDatasets.map((d, i) => {
2162
+ const raw = d.visible ? barRawResolved?.[i] : batchResolveAccessor(d.props.valueField, d.props.data);
2163
+ return (raw ?? []).map((v) => typeof v === "number" && isFinite(v) && v < 0 ? -1 : v === 0 ? 0 : 1);
2164
+ });
2165
+ if (mode.isGrouped) {
2166
+ const groupMap = /* @__PURE__ */ new Map();
2167
+ for (let dsIdx = 0; dsIdx < barDatasets.length; dsIdx++) {
2168
+ const sid = barDatasets[dsIdx].stackId;
2169
+ if (!groupMap.has(sid)) groupMap.set(sid, { dsIndices: [], dsIds: [], values: [] });
2170
+ const g = groupMap.get(sid);
2171
+ g.dsIndices.push(dsIdx);
2172
+ g.dsIds.push(barDatasets[dsIdx].id);
2173
+ g.values.push(valuesPerDataset[dsIdx]);
2174
+ }
2175
+ stackBasesMap = /* @__PURE__ */ new Map();
2176
+ for (const { dsIds, dsIndices, values } of groupMap.values()) {
2177
+ const groupSigns = signsPerDataset ? dsIndices.map((i) => signsPerDataset[i]) : void 0;
2178
+ const groupBases = computeStackBases(dsIds, values, categories.length, { isStacked: true, isWaterfall: false }, void 0, groupSigns);
2179
+ for (const [id, bases] of groupBases) stackBasesMap.set(id, bases);
2180
+ }
2181
+ } else {
2182
+ stackBasesMap = computeStackBases(
2183
+ barDatasets.map((d) => d.id),
2184
+ valuesPerDataset,
2185
+ categories.length,
2186
+ mode,
2187
+ waterfallBases,
2188
+ signsPerDataset
2189
+ );
2190
+ }
2191
+ }
2192
+ const barGap = barDatasets[0]?.props?.barGap;
2193
+ let fullGroupLayout = null;
2194
+ if (mode.isGrouped) {
2195
+ if (mode.isStacked) {
2196
+ const visibleStackIds = [...new Set(visibleBarDatasets.map((d) => d.stackId))];
2197
+ const allStackIds = [...new Set(barDatasets.map((d) => d.stackId))];
2198
+ groupLayout = calculateGroupedBarLayout(visibleStackIds.length, sharedCategoryScale.bandwidth(), barGap);
2199
+ fullGroupLayout = calculateGroupedBarLayout(allStackIds.length, sharedCategoryScale.bandwidth(), barGap);
2200
+ } else {
2201
+ groupLayout = calculateGroupedBarLayout(visibleBarDatasets.length, sharedCategoryScale.bandwidth(), barGap);
2202
+ fullGroupLayout = calculateGroupedBarLayout(barDatasets.length, sharedCategoryScale.bandwidth(), barGap);
2203
+ }
2204
+ }
2205
+ const hiddenValueAxes = computeHiddenValueAxes({
2206
+ barDatasets,
2207
+ lineDatasets,
2208
+ scatterDatasets,
2209
+ candlestickDatasets,
2210
+ datasetAxisMap,
2211
+ firstValueAxisId,
2212
+ axisIdProp,
2213
+ valueAxesSize: valueAxes.size
2214
+ });
2215
+ const { axisLayouts, xAxisLayout, yAxisLayout } = computeAxisLayouts({
2216
+ axes,
2217
+ isRtl,
2218
+ orientation,
2219
+ valueScales,
2220
+ sharedValueScale,
2221
+ sharedTimeScale,
2222
+ sharedCategoryScale,
2223
+ scatterXScales,
2224
+ valueDomains,
2225
+ scatterXDomains,
2226
+ mode,
2227
+ adaptive,
2228
+ cartesianArea,
2229
+ styledBoundaries,
2230
+ rangeLabelOffset,
2231
+ hiddenValueAxes,
2232
+ lastVisibleLayouts,
2233
+ globalFont,
2234
+ locale
2235
+ });
2236
+ let categoryAxisSpace = 0;
2237
+ const primaryCatAxisKey = orientation === "horizontal" ? `y:${axes.y.keys().next().value}` : `x:${axes.x.keys().next().value}`;
2238
+ const primaryCatAxis = axisLayouts.get(primaryCatAxisKey);
2239
+ if (styledBoundaries && primaryCatAxis) {
2240
+ const catBaseProps = primaryCatAxis.props;
2241
+ const catPosition = primaryCatAxis.position;
2242
+ const catIsHorizontal = catPosition === "top" || catPosition === "bottom";
2243
+ let catTickPositions;
2244
+ const catAutoRotate = catBaseProps?.autoRotate ?? true;
2245
+ const catAutoRotateAngle = catBaseProps?.autoRotateAngle ?? -45;
2246
+ if (catAutoRotate && catIsHorizontal && scaleCategories.length > 1 && sharedCategoryScale) {
2247
+ catTickPositions = scaleCategories.map((cat, i) => {
2248
+ const pos = sharedCategoryScale(cat);
2249
+ const bw = sharedCategoryScale.bandwidthAt?.(i) ?? sharedCategoryScale.bandwidth();
2250
+ return pos != null ? pos + bw / 2 : 0;
2251
+ });
2252
+ }
2253
+ const catAxisLength = catIsHorizontal ? cartesianArea.width : cartesianArea.height;
2254
+ categoryAxisSpace = calculateAxisSpace(
2255
+ catPosition,
2256
+ false,
2257
+ {
2258
+ tickLabels: scaleCategories,
2259
+ tickRotation: catBaseProps?.tickRotation,
2260
+ tickStyle: (() => {
2261
+ const s = catBaseProps?.tickStyle;
2262
+ return typeof s === "function" ? void 0 : s;
2263
+ })(),
2264
+ autoRotate: catAutoRotate,
2265
+ autoRotateAngle: catAutoRotateAngle,
2266
+ tickPositions: catTickPositions,
2267
+ axisLength: catAxisLength,
2268
+ labelMinSpacing: catBaseProps?.labelMinSpacing,
2269
+ tickCount: catBaseProps?.tickCount,
2270
+ autoSkip: catBaseProps?.autoSkip
2271
+ },
2272
+ void 0,
2273
+ globalFont
2274
+ );
2275
+ }
2276
+ let valueAxisSpace = 0;
2277
+ const primaryValAxisKey = orientation === "vertical" ? `y:${firstValueAxisId}` : `x:${firstValueAxisId}`;
2278
+ const primaryValAxis = axisLayouts.get(primaryValAxisKey);
2279
+ if (styledRangeBoundaries && styledRangeBoundaries.length > 0 && primaryValAxis) {
2280
+ const valBaseProps = primaryValAxis.props;
2281
+ const valTickFormat = typeof valBaseProps?.tickFormat === "function" ? valBaseProps.tickFormat : void 0;
2282
+ const valAxisLength = orientation === "vertical" ? cartesianArea.height : cartesianArea.width;
2283
+ const valTickCount = getAdaptiveTickCount(valAxisLength, valBaseProps?.tickCount);
2284
+ const step = (valueDomain[1] - valueDomain[0]) / valTickCount;
2285
+ const tickLabels = [];
2286
+ for (let i = 0; i <= valTickCount; i++) {
2287
+ const v = valueDomain[0] + step * i;
2288
+ tickLabels.push(valTickFormat ? valTickFormat(v, i) : String(v));
2289
+ }
2290
+ valueAxisSpace = calculateAxisSpace(
2291
+ primaryValAxis.position,
2292
+ !!primaryValAxis.props?.label,
2293
+ {
2294
+ tickLabels,
2295
+ tickRotation: valBaseProps?.tickRotation,
2296
+ titleGap: valBaseProps?.titleGap,
2297
+ tickStyle: (() => {
2298
+ const s = valBaseProps?.tickStyle;
2299
+ return typeof s === "function" ? void 0 : s;
2300
+ })()
2301
+ },
2302
+ void 0,
2303
+ globalFont
2304
+ );
2305
+ }
2306
+ const barIntermediate = barDatasets.length > 0 ? {
2307
+ barDatasets,
2308
+ visibleBarDatasets,
2309
+ mode,
2310
+ valuesPerDataset,
2311
+ stackBasesMap,
2312
+ groupLayout,
2313
+ fullGroupLayout: fullGroupLayout ?? void 0,
2314
+ isVariwide,
2315
+ barGap,
2316
+ datasetAxisMap: (() => {
2317
+ const m = /* @__PURE__ */ new Map();
2318
+ for (const ds of barDatasets) m.set(ds.id, datasetAxisMap.get(ds.id) ?? firstValueAxisId);
2319
+ return m;
2320
+ })(),
2321
+ firstValueAxisId
2322
+ } : null;
2323
+ let rangeGroups;
2324
+ for (const ld of lineDatasets) {
2325
+ if (!ld.rangeId) continue;
2326
+ if (!rangeGroups) rangeGroups = /* @__PURE__ */ new Map();
2327
+ if (!rangeGroups.has(ld.rangeId)) {
2328
+ const featureKey = `range:${ld.rangeId}`;
2329
+ const feat = features.get(featureKey);
2330
+ const featProps = feat?.props;
2331
+ rangeGroups.set(ld.rangeId, {
2332
+ datasetIds: [],
2333
+ color: featProps?.color,
2334
+ fillOpacity: featProps?.fillOpacity ?? 0.3
2335
+ });
2336
+ }
2337
+ rangeGroups.get(ld.rangeId).datasetIds.push(ld.id);
2338
+ }
2339
+ const datasetTotals = computeBarDatasetTotals(barDatasets, barRawResolved);
2340
+ const primaryYAxis = axisLayouts.get(`y:${axes.y.keys().next().value}`);
2341
+ const primaryXAxis = axisLayouts.get(`x:${axes.x.keys().next().value}`);
2342
+ const valueAxisPosition = primaryYAxis ? primaryYAxis.position : "left";
2343
+ const categoryAxisPosition = primaryXAxis ? primaryXAxis.position : "bottom";
2344
+ const a11yConfig = features.get("accessibility")?.props;
2345
+ const context = {
2346
+ chartId,
2347
+ width,
2348
+ height,
2349
+ renderer,
2350
+ chartArea: cartesianArea,
2351
+ theme: input.theme,
2352
+ accessibility: a11yConfig?.enabled !== false ? {
2353
+ enabled: true,
2354
+ pointDescriptionThreshold: a11yConfig?.pointDescriptionThreshold ?? 200,
2355
+ pointDescriptionFormatter: a11yConfig?.pointDescriptionFormatter,
2356
+ landmarkVerbosity: a11yConfig?.landmarkVerbosity ?? "all"
2357
+ } : void 0
2358
+ };
2359
+ let referenceLines;
2360
+ let referenceBands;
2361
+ for (const [key, feat] of features) {
2362
+ if (typeof key === "string" && key.startsWith("referenceLine:")) {
2363
+ if (!referenceLines) referenceLines = [];
2364
+ referenceLines.push(feat.props);
2365
+ }
2366
+ if (typeof key === "string" && key.startsWith("referenceBand:")) {
2367
+ if (!referenceBands) referenceBands = [];
2368
+ referenceBands.push(feat.props);
2369
+ }
2370
+ }
2371
+ const result = {
2372
+ barIntermediate,
2373
+ context,
2374
+ cartesianArea,
2375
+ xAxisLayout,
2376
+ yAxisLayout,
2377
+ datasetTotals,
2378
+ orientation,
2379
+ valueAxisPosition,
2380
+ categoryAxisPosition,
2381
+ valueScaleRange,
2382
+ sharedCategoryScale,
2383
+ isPercentStacked: mode.isPercentStacked,
2384
+ isStacked: mode.isStacked,
2385
+ isGrouped: mode.isGrouped,
2386
+ isWaterfall: mode.isWaterfall,
2387
+ isOverlap: mode.isOverlap,
2388
+ categoryTotals,
2389
+ styledBoundaries,
2390
+ categoryAxisSpace,
2391
+ styledRangeBoundaries,
2392
+ valueAxisSpace,
2393
+ valueDomain,
2394
+ axisLayouts,
2395
+ valueScales,
2396
+ valueDomains,
2397
+ // Line layouts/renderProps are computed by useLineRenderer (independent hook)
2398
+ lineStackBasesMap,
2399
+ lineTransformedValues,
2400
+ groupedDataOverride,
2401
+ decimatedIndices,
2402
+ // Scatter layouts are computed by useScatterRenderer (independent hook)
2403
+ scatterXScales: scatterXScales.size > 0 ? scatterXScales : void 0,
2404
+ scatterStackBasesMap,
2405
+ // Candlestick layouts are computed by useCandlestickRenderer (independent hook)
2406
+ // Heatmap layouts are computed by useHeatmapRenderer (independent hook)
2407
+ rangeGroups,
2408
+ referenceLines,
2409
+ referenceBands,
2410
+ sharedTimeScale,
2411
+ timeDomain: rawStreamTimeDomain,
2412
+ timeAxisTimezone,
2413
+ originalDomains,
2414
+ sortedCategoryOrder
2415
+ };
2416
+ return result;
2417
+ }
2418
+
2419
+ export { buildAnimatedFrame, buildBoundariesFromAxisGroups, buildFrameParams, buildStaticFrame, buildStyledRanges, calculateCartesianArea, cancelDriverRafs, computeCartesianLayout, computeNaturalAxisWidths, createAnimationDriver, createOffsetChartArea, driveCartesianUpdate, findAxisGroupFeatures, isLayoutCriticalFeature, mergeAllNearestResults, needsAxisPadding, renderWithCompositor, resolveHoverRepaintFrame, resolveNearestHit };