@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,579 @@
1
+ import { scatterHitTest } from './chunk-LKC7MZKK.mjs';
2
+ import { collectScatterMarkerOverlays } from './chunk-X4D7FKUS.mjs';
3
+ import { registerDatasetLayers, triggerCompositorRepaint } from './chunk-Q6PPVIHU.mjs';
4
+ import { resolveScatterLabels } from './chunk-66T4MRC5.mjs';
5
+ import { renderResolvedLabels } from './chunk-QQBXUDM4.mjs';
6
+ import { AnimatedScene, resolveAnimatedProps, SCATTER_ANIMATABLE_PROPS } from './chunk-VN7CKCSE.mjs';
7
+ import { calculateScatterLayout } from './chunk-DTWTCFRG.mjs';
8
+ import { reconcileSvgChildren } from './chunk-KP2TWD4Z.mjs';
9
+ import { parseAnimationConfig } from './chunk-3WEMHXZI.mjs';
10
+ import { raf, cancelRaf } from './chunk-EDAKJLNA.mjs';
11
+ import { buildAccessibilityRenderContext, generateSeriesDescription } from './chunk-OGJ6IIBW.mjs';
12
+ import { collectItems } from './chunk-FFMT6OCO.mjs';
13
+ import { SCATTER_BOOST_AUTO_THRESHOLD, DEFAULT_HOVER_DIM_OPACITY, DEFAULT_HOVER_BRIGHTNESS, SCATTER_SPATIAL_INDEX_THRESHOLD, DEFAULT_FALLBACK_COLOR } from './chunk-NKUYIWAP.mjs';
14
+ import { ScatterDecimator } from './chunk-OWW3K55O.mjs';
15
+ import { buildQuadtree } from './chunk-C36VWQ7A.mjs';
16
+ import { defaultLightTheme } from './chunk-O2X6FF45.mjs';
17
+ import { materializeSvgNode, setAttr, createSvgGroup } from './chunk-SSLTFJ3U.mjs';
18
+
19
+ // src/series/scatter/controller/index.ts
20
+ function scatterHoverInteraction(base, dsId, hover) {
21
+ const anyHovered = hover.datasetId !== null;
22
+ const isThisSeries = hover.datasetId === dsId;
23
+ return {
24
+ ...base.interaction ?? {},
25
+ hoveredIndex: isThisSeries ? hover.index : null,
26
+ isSeriesDimmed: anyHovered && !isThisSeries
27
+ };
28
+ }
29
+ function buildScatterSvgChildren(params) {
30
+ const { paint, renderLayouts, activeRenderProps, visibleLayouts, visibleRenderProps, context, hover, labelConfig, datasetVisibility } = params;
31
+ const children = [];
32
+ for (const [dsId, scatterLayout] of renderLayouts) {
33
+ const props = activeRenderProps.get(dsId);
34
+ if (!props || props.renderMarker) continue;
35
+ const propsWithHover = {
36
+ ...props,
37
+ interaction: scatterHoverInteraction(props, dsId, hover)
38
+ };
39
+ const node = paint.renderSvg(propsWithHover, scatterLayout, context);
40
+ setAttr(node, "data-dataset", dsId);
41
+ if (context.accessibility?.enabled && context.accessibility.landmarkVerbosity === "all") {
42
+ setAttr(node, "role", "region");
43
+ setAttr(node, "aria-label", generateSeriesDescription(props.name ?? dsId, "scatter", scatterLayout.visiblePoints.length));
44
+ }
45
+ children.push(node);
46
+ }
47
+ if (labelConfig && !labelConfig.render) {
48
+ const labelGroup = createSvgGroup();
49
+ setAttr(labelGroup, "data-layer", "labels");
50
+ for (const [dsId, scatterLayout] of visibleLayouts) {
51
+ if (datasetVisibility?.get(dsId) === false) continue;
52
+ const props = visibleRenderProps.get(dsId);
53
+ const seriesColor = typeof props?.color === "string" ? props.color : DEFAULT_FALLBACK_COLOR;
54
+ renderResolvedLabels(resolveScatterLabels(scatterLayout.visiblePoints, seriesColor, labelConfig, props?.name, props?.data), labelConfig, {
55
+ renderer: "svg",
56
+ svgGroup: labelGroup,
57
+ theme: context.theme
58
+ });
59
+ }
60
+ children.push(labelGroup);
61
+ }
62
+ return children;
63
+ }
64
+ var SCATTER_DATASET_REGISTRY = {
65
+ number: ["opacity"],
66
+ color: []
67
+ };
68
+ var ScatterRendererController = class {
69
+ constructor(paint) {
70
+ // Animation lifecycle — local raf clock + fingerprint for phase detection.
71
+ this._animRafId = null;
72
+ this._lastFingerprint = "";
73
+ // Canonical layout caches — VISIBLE entries only (exiting excluded).
74
+ // Used for hit-test, legend, and marker overlays. Per-design: users can't
75
+ // hover points that are fading out.
76
+ this.layoutCache = /* @__PURE__ */ new Map();
77
+ this.renderPropsCache = /* @__PURE__ */ new Map();
78
+ // Render-time caches — include visible + exiting entries. Canvas paint
79
+ // callbacks and SVG render read these so fading points stay on screen.
80
+ this.renderLayouts = /* @__PURE__ */ new Map();
81
+ this.activeRenderPropsCache = /* @__PURE__ */ new Map();
82
+ // Per-dataset property-animation overrides resolved from AnimatedPropertyStore.
83
+ // Set by `applyPropertyAnimations()` each property-animation tick and merged
84
+ // into the active render props at read time. Cleared by `destroy()`.
85
+ this._propertyOverrides = /* @__PURE__ */ new Map();
86
+ this.scatterDatasets = [];
87
+ this.decimator = new ScatterDecimator();
88
+ this._markerOverlays = [];
89
+ this.lastInput = null;
90
+ // Single source of truth for the current hover. Written ONLY by applyHover (never
91
+ // re-seeded from input.hover), read by renderFrame and the compositor paint callback.
92
+ // Hover is event-driven and always arrives via applyHover, so re-seeding from the
93
+ // swappable input would let a stale input.hover clobber the live hover. Mirrors
94
+ // candlestick/heatmap/radar/polar.
95
+ this.hover = { datasetId: null, index: null };
96
+ // DOM targets
97
+ this.svgGroup = null;
98
+ this.canvasEl = null;
99
+ this.onFrame = null;
100
+ this._paint = paint;
101
+ this._scene = new AnimatedScene({
102
+ // ENTER: series fades in from transparent.
103
+ emptyState: (target) => ({ ...target, opacity: 0 }),
104
+ // EXIT: series fades out to transparent.
105
+ exitEmptyState: (target) => ({ ...target, opacity: 0 }),
106
+ registry: SCATTER_DATASET_REGISTRY
107
+ });
108
+ }
109
+ // ================================================================
110
+ // PUBLIC API
111
+ // ================================================================
112
+ update(input) {
113
+ this.lastInput = input;
114
+ this.svgGroup = input.svgGroup ?? null;
115
+ this.canvasEl = input.canvasEl ?? null;
116
+ const { datasets, datasetVisibility, decimationConfig, zoomState, orientation = "vertical", compositor, features } = input;
117
+ const sortedDatasets = Array.from(datasets.entries()).sort(([, a], [, b]) => a.order - b.order);
118
+ const rawDatasets = collectItems(sortedDatasets, datasetVisibility).scatter;
119
+ if (decimationConfig && rawDatasets.length > 0) {
120
+ const zoomX = orientation === "vertical" ? zoomState?.x : zoomState?.y;
121
+ const zoomY = orientation === "vertical" ? zoomState?.y : zoomState?.x;
122
+ this.scatterDatasets = this.decimator.apply(rawDatasets, decimationConfig, zoomX, zoomY);
123
+ } else {
124
+ this.scatterDatasets = rawDatasets;
125
+ }
126
+ const hasScales = !!input.scatterXScales && !!input.valueScales && input.valueScales.size > 0;
127
+ if ((this.scatterDatasets.length === 0 || !hasScales) && this._scene.getElements().length === 0) {
128
+ this.layoutCache.clear();
129
+ this.renderPropsCache.clear();
130
+ this.renderLayouts.clear();
131
+ this.activeRenderPropsCache.clear();
132
+ this._markerOverlays = [];
133
+ this._cancelRaf();
134
+ this._scene.reset();
135
+ this._lastFingerprint = "";
136
+ if (input.renderer === "svg" && this.svgGroup) {
137
+ while (this.svgGroup.firstChild) this.svgGroup.removeChild(this.svgGroup.firstChild);
138
+ }
139
+ return;
140
+ }
141
+ if (input.renderer === "svg" && !this.svgGroup) return;
142
+ const visibleDatasets = this.scatterDatasets.filter((d) => d.visible);
143
+ const fingerprint = visibleDatasets.map((d) => d.id).sort().join("|");
144
+ const phase = this._lastFingerprint === "" ? "entrance" : fingerprint !== this._lastFingerprint ? "update" : "static";
145
+ const animConfig = features.get("animation")?.props;
146
+ const { enabled: animEnabled, duration, easing } = parseAnimationConfig(animConfig);
147
+ const shouldAnimate = animEnabled && duration > 0 && phase !== "static";
148
+ this._updateCachesAndLayout(visibleDatasets, input);
149
+ if (input.renderer === "canvas" && compositor) {
150
+ compositor.removeLayersByPrefix?.("scatter:");
151
+ const liveIds = /* @__PURE__ */ new Set();
152
+ for (const el of this._scene.getElements()) liveIds.add(el.current.datasetId);
153
+ for (const sd of visibleDatasets) liveIds.add(sd.id);
154
+ registerDatasetLayers(
155
+ compositor,
156
+ "scatter",
157
+ liveIds,
158
+ (dsId) => this._scene.getElement(dsId)?.current.stackOrder ?? datasets.get(dsId)?.order ?? 0,
159
+ (dsId) => (ctx) => this.paintCanvasLayer(ctx, dsId)
160
+ );
161
+ }
162
+ const sceneTargets = this._buildSceneTargets(visibleDatasets, input);
163
+ const opts = {
164
+ numbers: { duration: shouldAnimate ? duration : 0, easing },
165
+ colors: { duration: shouldAnimate ? duration : 0, easing }
166
+ };
167
+ if (phase === "static" && this._animRafId !== null) {
168
+ this._commit(fingerprint);
169
+ return;
170
+ }
171
+ this._cancelRaf();
172
+ this._scene.diff(sceneTargets, opts);
173
+ if (shouldAnimate) {
174
+ this._renderSceneFrame();
175
+ const tick = (now) => {
176
+ this._animRafId = null;
177
+ const { allIdle } = this._scene.tick(now);
178
+ this._renderSceneFrame();
179
+ if (allIdle && this.lastInput?.renderer === "canvas" && this.lastInput.compositor) {
180
+ const liveIds = new Set(Array.from(this._scene.getElements()).map((el) => el.current.datasetId));
181
+ this.lastInput.compositor.removeLayersByPrefix?.("scatter:");
182
+ registerDatasetLayers(
183
+ this.lastInput.compositor,
184
+ "scatter",
185
+ liveIds,
186
+ (dsId) => this._scene.getElement(dsId)?.current.stackOrder ?? 0,
187
+ (dsId) => (ctx) => this.paintCanvasLayer(ctx, dsId)
188
+ );
189
+ }
190
+ if (!allIdle) {
191
+ this._animRafId = raf(tick);
192
+ }
193
+ };
194
+ this._animRafId = raf(tick);
195
+ } else {
196
+ this._scene.tick(performance.now());
197
+ this._renderSceneFrame();
198
+ }
199
+ this._commit(fingerprint);
200
+ }
201
+ /**
202
+ * Re-project point positions through the chrome-animated scales each frame so the
203
+ * dots track the X/Y axis rescale in lockstep (the value-domain model — points stay
204
+ * glued to their gridlines because both derive from the same interpolating scale).
205
+ *
206
+ * Unlike the line controller, the scatter scene loop animates OPACITY only and reuses
207
+ * cached positions — so the position cache must be refreshed HERE every frame. Mirrors
208
+ * `LineRendererController.syncWithAnimatedScale`. `categoryScale` is unused (scatter X
209
+ * is a numeric value axis, not a band); the animated X scales arrive via `valueXScales`.
210
+ */
211
+ syncWithAnimatedScale(_categoryScale, valueScales, valueXScales) {
212
+ if (!this.lastInput || this.renderLayouts.size === 0) return;
213
+ if (this.allBoostActive()) return;
214
+ if (valueScales) this.lastInput.valueScales = valueScales;
215
+ if (valueXScales) this.lastInput.scatterXScales = valueXScales;
216
+ const visibleDatasets = this.scatterDatasets.filter((d) => d.visible);
217
+ this._updateCachesAndLayout(visibleDatasets, this.lastInput);
218
+ if (this._animRafId !== null) return;
219
+ if (this.lastInput.renderer === "svg") {
220
+ this._renderSceneFrame();
221
+ } else {
222
+ this._rebuildRenderLayouts();
223
+ }
224
+ }
225
+ applyHover(hover) {
226
+ this.hover = hover;
227
+ if (this.renderLayouts.size === 0 || !this.lastInput) return;
228
+ if (this.allBoostActive()) {
229
+ return;
230
+ }
231
+ if (this._animRafId !== null) {
232
+ return;
233
+ }
234
+ const input = this.lastInput;
235
+ if (input.renderer === "svg" && this.svgGroup) {
236
+ const context = {
237
+ chartId: input.chartId,
238
+ width: input.width,
239
+ height: input.height,
240
+ renderer: input.renderer,
241
+ chartArea: input.chartArea,
242
+ theme: input.theme,
243
+ accessibility: buildAccessibilityRenderContext(input.features)
244
+ };
245
+ const children = buildScatterSvgChildren({
246
+ paint: this._paint,
247
+ renderLayouts: this.renderLayouts,
248
+ activeRenderProps: this.activeRenderPropsCache,
249
+ visibleLayouts: this.layoutCache,
250
+ visibleRenderProps: this.renderPropsCache,
251
+ context,
252
+ hover,
253
+ labelConfig: input.labelConfig,
254
+ datasetVisibility: input.datasetVisibility
255
+ });
256
+ reconcileSvgChildren(this.svgGroup, children);
257
+ return;
258
+ }
259
+ for (const sd of this.scatterDatasets) {
260
+ const baseProps = this.renderPropsCache.get(sd.id);
261
+ if (!baseProps) continue;
262
+ const updated = this.buildRenderProps(sd, input);
263
+ this.renderPropsCache.set(sd.id, updated);
264
+ const liveOpacity = this._scene.getElement(sd.id)?.current.opacity ?? this.activeRenderPropsCache.get(sd.id)?.animationOpacity ?? 1;
265
+ const overrides = this._propertyOverrides.get(sd.id);
266
+ const merged = overrides ? { ...updated, ...overrides, animationOpacity: liveOpacity } : { ...updated, animationOpacity: liveOpacity };
267
+ this.activeRenderPropsCache.set(sd.id, merged);
268
+ }
269
+ triggerCompositorRepaint(input.renderer, this.canvasEl, input.compositor);
270
+ }
271
+ /** True when every visible scatter series is in boost mode (explicit or auto above 50k). */
272
+ get boostActive() {
273
+ return this.allBoostActive();
274
+ }
275
+ allBoostActive() {
276
+ if (this.renderLayouts.size === 0) return false;
277
+ for (const [datasetId, layout] of this.renderLayouts) {
278
+ const props = this.renderPropsCache.get(datasetId) ?? this.activeRenderPropsCache.get(datasetId);
279
+ const boost = props?.boost;
280
+ if (boost === true) continue;
281
+ if (boost === false) return false;
282
+ if (layout.visiblePoints.length < SCATTER_BOOST_AUTO_THRESHOLD) return false;
283
+ }
284
+ return true;
285
+ }
286
+ hitTest(x, y) {
287
+ return scatterHitTest(x, y, { layouts: this.layoutCache, renderPropsCache: this.renderPropsCache, theme: this.lastInput?.theme ?? defaultLightTheme });
288
+ }
289
+ getSvgOutput() {
290
+ return null;
291
+ }
292
+ get hasData() {
293
+ return this.scatterDatasets.length > 0;
294
+ }
295
+ get layouts() {
296
+ return this.layoutCache;
297
+ }
298
+ get markerOverlays() {
299
+ return this._markerOverlays;
300
+ }
301
+ destroy() {
302
+ this._cancelRaf();
303
+ this._scene.reset();
304
+ this._lastFingerprint = "";
305
+ this._propertyOverrides.clear();
306
+ this.lastInput?.compositor?.removeLayersByPrefix("scatter:");
307
+ }
308
+ /**
309
+ * Apply animated property values without triggering a full layout cycle.
310
+ * Called from the property-animation framework wrapper each animation tick.
311
+ *
312
+ * Per-dataset: writes overrides into `_propertyOverrides` (or deletes the
313
+ * entry when the store has no live values for it), then patches downstream
314
+ * caches and triggers a repaint.
315
+ *
316
+ * SVG: scatter renders points imperatively each frame from
317
+ * `activeRenderPropsCache`, so a `renderFrameCycle()` call replays the merged
318
+ * props onto the DOM. Canvas: refreshes the cache then triggers compositor
319
+ * repaint so the layer paint callback reads the merged props.
320
+ */
321
+ applyPropertyAnimations(store) {
322
+ const input = this.lastInput;
323
+ if (!input) return;
324
+ let appliedAny = false;
325
+ for (const [dsId, baseProps] of this.activeRenderPropsCache) {
326
+ const overrides = resolveAnimatedProps(store, "scatter", dsId, SCATTER_ANIMATABLE_PROPS);
327
+ if (Object.keys(overrides).length === 0) {
328
+ if (this._propertyOverrides.delete(dsId)) appliedAny = true;
329
+ continue;
330
+ }
331
+ appliedAny = true;
332
+ this._propertyOverrides.set(dsId, overrides);
333
+ this.activeRenderPropsCache.set(dsId, { ...baseProps, ...overrides });
334
+ }
335
+ if (!appliedAny) return;
336
+ if (triggerCompositorRepaint(input.renderer, this.canvasEl, input.compositor)) return;
337
+ if (input.renderer === "svg") {
338
+ this.renderFrame();
339
+ }
340
+ }
341
+ /**
342
+ * Full re-render of the current scene state.
343
+ *
344
+ * Used by the property-animation framework wrapper: when a property
345
+ * animation completes and its override is released from the store,
346
+ * `_renderSceneFrame()` rebuilds `activeRenderPropsCache` from the now-empty
347
+ * overrides map, then `renderFrame()` projects the cleaned props to DOM /
348
+ * canvas so SVG attributes snap back to base values.
349
+ */
350
+ renderFrameCycle() {
351
+ this._renderSceneFrame();
352
+ }
353
+ // ================================================================
354
+ // PRIVATE HELPERS
355
+ // ================================================================
356
+ /**
357
+ * Build per-dataset scene targets from visible scatter datasets.
358
+ * Element id format: datasetId. One element per series (opacity-only v1).
359
+ */
360
+ _buildSceneTargets(visibleDatasets, input) {
361
+ const targets = /* @__PURE__ */ new Map();
362
+ for (const sd of visibleDatasets) {
363
+ const stackOrder = input.datasets.get(sd.id)?.order ?? 0;
364
+ const axisId = sd.props.yAxisId ?? input.firstValueAxisId;
365
+ targets.set(sd.id, {
366
+ opacity: 1,
367
+ stackOrder,
368
+ axisId: axisId ?? "",
369
+ datasetId: sd.id
370
+ });
371
+ }
372
+ return targets;
373
+ }
374
+ /**
375
+ * Walk the scene and rebuild per-dataset render state (renderLayouts +
376
+ * activeRenderPropsCache) from element opacities — WITHOUT painting. Split out so
377
+ * `syncWithAnimatedScale` can refresh the layouts during an in-flight compositor
378
+ * repaint (canvas) without triggering a nested repaint (which would recurse).
379
+ *
380
+ * Mirrors Heatmap's scene-derived render path but at dataset granularity.
381
+ */
382
+ _rebuildRenderLayouts() {
383
+ const elements = Array.from(this._scene.getElements()).sort((a, b) => (a.current.stackOrder ?? 0) - (b.current.stackOrder ?? 0));
384
+ const newRenderLayouts = /* @__PURE__ */ new Map();
385
+ const newActiveProps = /* @__PURE__ */ new Map();
386
+ for (const el of elements) {
387
+ const dsId = el.current.datasetId;
388
+ const layout = this.layoutCache.get(dsId) ?? this.renderLayouts.get(dsId);
389
+ if (!layout) continue;
390
+ const baseProps = this.renderPropsCache.get(dsId) ?? this.activeRenderPropsCache.get(dsId);
391
+ if (!baseProps) continue;
392
+ const overrides = this._propertyOverrides.get(dsId);
393
+ const renderProps = overrides ? { ...baseProps, ...overrides, animationOpacity: el.current.opacity } : {
394
+ ...baseProps,
395
+ animationOpacity: el.current.opacity
396
+ };
397
+ newRenderLayouts.set(dsId, layout);
398
+ newActiveProps.set(dsId, renderProps);
399
+ }
400
+ this.renderLayouts = newRenderLayouts;
401
+ this.activeRenderPropsCache = newActiveProps;
402
+ }
403
+ /** Rebuild render state, then paint (canvas: triggers a compositor repaint). */
404
+ _renderSceneFrame() {
405
+ this._rebuildRenderLayouts();
406
+ this.renderFrame();
407
+ }
408
+ /**
409
+ * Update visible-only caches (layoutCache, renderPropsCache) and marker
410
+ * overlays from the current set of visible scatter datasets.
411
+ */
412
+ _updateCachesAndLayout(visibleDatasets, input) {
413
+ const newLayoutCache = /* @__PURE__ */ new Map();
414
+ const newRenderPropsCache = /* @__PURE__ */ new Map();
415
+ const sortedVisible = [...visibleDatasets].sort((a, b) => (input.datasets.get(a.id)?.order ?? 0) - (input.datasets.get(b.id)?.order ?? 0));
416
+ let dsIdx = 0;
417
+ for (const sd of sortedVisible) {
418
+ const props = sd.props;
419
+ const targetXAxisId = props.xAxisId ?? input.firstCategoryAxisId;
420
+ const targetYAxisId = props.yAxisId ?? input.firstValueAxisId;
421
+ const xScale = input.scatterXScales?.get(targetXAxisId);
422
+ const sharedValueScale = input.valueScales?.values().next().value;
423
+ const yScale = input.valueScales?.get(targetYAxisId) ?? sharedValueScale;
424
+ if (!xScale || !yScale) continue;
425
+ const baseLayout = calculateScatterLayout(props, input.chartArea, {
426
+ xScale,
427
+ yScale,
428
+ stackBases: input.scatterStackBasesMap?.get(sd.id)
429
+ });
430
+ const layout = { ...baseLayout, datasetIndex: dsIdx++ };
431
+ newLayoutCache.set(sd.id, layout);
432
+ newRenderPropsCache.set(sd.id, this.buildRenderProps(sd, input));
433
+ }
434
+ this.layoutCache = newLayoutCache;
435
+ this.renderPropsCache = newRenderPropsCache;
436
+ this._markerOverlays = collectScatterMarkerOverlays(newLayoutCache, newRenderPropsCache);
437
+ }
438
+ /** Cancel any in-flight raf. */
439
+ _cancelRaf() {
440
+ if (this._animRafId !== null) {
441
+ cancelRaf(this._animRafId);
442
+ this._animRafId = null;
443
+ }
444
+ }
445
+ _commit(fingerprint) {
446
+ this._lastFingerprint = fingerprint;
447
+ }
448
+ buildRenderProps(sd, input) {
449
+ const anyHovered = this.hover.datasetId !== null;
450
+ const isThisSeries = this.hover.datasetId === sd.id;
451
+ const hoverConfig = input.hoverConfig;
452
+ return {
453
+ ...sd.props,
454
+ interaction: {
455
+ hoveredIndex: isThisSeries ? this.hover.index : null,
456
+ isSeriesDimmed: anyHovered && !isThisSeries
457
+ },
458
+ effects: {
459
+ hoverBrightness: hoverConfig?.brightness ?? DEFAULT_HOVER_BRIGHTNESS,
460
+ dimOpacity: hoverConfig?.dimOpacity ?? DEFAULT_HOVER_DIM_OPACITY,
461
+ hoverRadiusMultiplier: hoverConfig?.radiusMultiplier,
462
+ // Per-point hover accessors stay on props.pointHoverBackgroundColor / pointHoverBorderColor;
463
+ // the renderer resolves them per-point and falls back to effects.* (global <Chart.Hover>).
464
+ hoverBackgroundColor: sd.props.hoverColor ?? hoverConfig?.backgroundColor,
465
+ hoverBorderColor: sd.props.hoverBorderColor ?? hoverConfig?.borderColor,
466
+ hoverBorderStrokeWidth: hoverConfig?.borderStrokeWidth,
467
+ hoverPointRadius: sd.props.hoverPointRadius
468
+ }
469
+ };
470
+ }
471
+ /**
472
+ * Paint a frame using already-populated render-time caches.
473
+ * Cache population is the responsibility of `_updateCachesAndLayout`
474
+ * (visible-only caches) and `_renderSceneFrame` (animation-time render caches).
475
+ */
476
+ renderFrame() {
477
+ if (!this.lastInput) return;
478
+ const input = this.lastInput;
479
+ const renderLayouts = this.renderLayouts;
480
+ const activeRenderProps = this.activeRenderPropsCache;
481
+ const visibleLayouts = this.layoutCache;
482
+ const visibleRenderProps = this.renderPropsCache;
483
+ for (const [, layout] of visibleLayouts) {
484
+ if (layout.visiblePoints.length > SCATTER_SPATIAL_INDEX_THRESHOLD && !layout.spatialIndex) {
485
+ const area = layout.chartArea;
486
+ const pts = layout.visiblePoints;
487
+ const quadPoints = new Array(pts.length);
488
+ const map = /* @__PURE__ */ new Map();
489
+ for (let i = 0; i < pts.length; i++) {
490
+ const pt = pts[i];
491
+ quadPoints[i] = { x: pt.px, y: pt.py, idx: pt.dataIndex, r: pt.radius };
492
+ map.set(pt.dataIndex, pt);
493
+ }
494
+ layout.spatialIndex = buildQuadtree(quadPoints, { x0: area.x, y0: area.y, x1: area.x + area.width, y1: area.y + area.height });
495
+ layout.pointByDataIndex = map;
496
+ }
497
+ }
498
+ const context = {
499
+ chartId: input.chartId,
500
+ width: input.width,
501
+ height: input.height,
502
+ renderer: input.renderer,
503
+ chartArea: input.chartArea,
504
+ theme: input.theme,
505
+ accessibility: buildAccessibilityRenderContext(input.features)
506
+ };
507
+ if (triggerCompositorRepaint(input.renderer, this.canvasEl, input.compositor)) {
508
+ this.onFrame?.();
509
+ return;
510
+ }
511
+ if (input.renderer === "svg" && this.svgGroup) {
512
+ const group = this.svgGroup;
513
+ const children = buildScatterSvgChildren({
514
+ paint: this._paint,
515
+ renderLayouts,
516
+ activeRenderProps,
517
+ visibleLayouts,
518
+ visibleRenderProps,
519
+ context,
520
+ hover: this.hover,
521
+ labelConfig: input.labelConfig,
522
+ datasetVisibility: input.datasetVisibility
523
+ });
524
+ group.replaceChildren(...children.map(materializeSvgNode));
525
+ } else if (input.renderer === "canvas") {
526
+ const ctx = this.canvasEl?.getContext("2d");
527
+ if (ctx) {
528
+ for (const [, scatterLayout] of renderLayouts) {
529
+ const props = activeRenderProps.get(scatterLayout.datasetId);
530
+ if (!props) continue;
531
+ this._paint.renderCanvas(props, scatterLayout, ctx, context);
532
+ }
533
+ if (input.labelConfig && !input.labelConfig.render) {
534
+ for (const [dsId, scatterLayout] of visibleLayouts) {
535
+ if (input.datasetVisibility?.get(dsId) === false) continue;
536
+ const props = visibleRenderProps.get(dsId);
537
+ const seriesColor = typeof props?.color === "string" ? props.color : DEFAULT_FALLBACK_COLOR;
538
+ renderResolvedLabels(resolveScatterLabels(scatterLayout.visiblePoints, seriesColor, input.labelConfig, props?.name, props?.data), input.labelConfig, {
539
+ renderer: "canvas",
540
+ ctx,
541
+ theme: input.theme
542
+ });
543
+ }
544
+ }
545
+ }
546
+ }
547
+ this.onFrame?.();
548
+ }
549
+ /**
550
+ * Canvas compositor layer paint callback. Reads the current `renderLayouts`
551
+ * + `activeRenderPropsCache` so every repaint (line-triggered, chrome-triggered,
552
+ * or scatter-triggered) draws the current animated opacity without needing
553
+ * pre-mutated state.
554
+ */
555
+ paintCanvasLayer(ctx, dsId) {
556
+ const layout = this.renderLayouts.get(dsId);
557
+ const props = this.activeRenderPropsCache.get(dsId);
558
+ if (!layout || !props || props.renderMarker || !this.lastInput) return;
559
+ const context = {
560
+ chartId: this.lastInput.chartId,
561
+ width: this.lastInput.width,
562
+ height: this.lastInput.height,
563
+ renderer: "canvas",
564
+ chartArea: this.lastInput.chartArea,
565
+ theme: this.lastInput.theme
566
+ };
567
+ this._paint.renderCanvas(props, layout, ctx, context);
568
+ if (this.lastInput?.labelConfig && !this.lastInput.labelConfig.render && this.lastInput.datasetVisibility?.get(dsId) !== false) {
569
+ const seriesColor = typeof props.color === "string" ? props.color : DEFAULT_FALLBACK_COLOR;
570
+ renderResolvedLabels(resolveScatterLabels(layout.visiblePoints, seriesColor, this.lastInput.labelConfig, props.name, props.data), this.lastInput.labelConfig, {
571
+ renderer: "canvas",
572
+ ctx,
573
+ theme: this.lastInput.theme
574
+ });
575
+ }
576
+ }
577
+ };
578
+
579
+ export { ScatterRendererController };