@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,362 @@
1
+ import { formatDataLabelText } from './chunk-OXTFAWSK.mjs';
2
+ import { wrapText, calculateWrappedTextWidth, calculateWrappedTextHeight } from './chunk-XTVE4P3L.mjs';
3
+ import { DEFAULT_FALLBACK_COLOR } from './chunk-NKUYIWAP.mjs';
4
+ import { makeItemContext, resolveAccessor } from './chunk-O2X6FF45.mjs';
5
+ import { withCanvasState } from './chunk-SSLTFJ3U.mjs';
6
+ import { toRad, pointOnCircle } from './chunk-RQ3CKQOX.mjs';
7
+
8
+ // src/circular/radial.helpers.ts
9
+ function computeSliceGeometry(slice, currentAngle, frame) {
10
+ const { outerRadius, innerRadius, willBeSingleSlice, currentRingRadii, hoverState, hoverOffset, hoverScale } = frame;
11
+ const ringRadii = currentRingRadii.get(String(slice.datasetIndex));
12
+ const baseOuterRadius = ringRadii?.outer ?? outerRadius;
13
+ const sliceInnerRadius = ringRadii?.inner ?? innerRadius;
14
+ const sliceOuterRadius = sliceInnerRadius + (baseOuterRadius - sliceInnerRadius) * slice.radiusRatio;
15
+ const spacing = slice.spacing ?? 0;
16
+ const spacingAngle = spacing > 0 && sliceOuterRadius > 0 ? spacing / sliceOuterRadius * (180 / Math.PI) : 0;
17
+ const halfSpacing = spacingAngle / 2;
18
+ const angle = slice.endAngle - slice.rotation;
19
+ const isFullCircleSlice = willBeSingleSlice || slice.targetAngle >= 355 || angle >= 355;
20
+ const midAngle = currentAngle + angle / 2;
21
+ const midRadius = (sliceOuterRadius + sliceInnerRadius) / 2;
22
+ const isHovered = hoverState.datasetIndex === slice.datasetIndex && hoverState.index === slice.originalIndex;
23
+ const sliceHoverOffset = isHovered && !isFullCircleSlice ? hoverOffset : 0;
24
+ const hoverOffsetX = sliceHoverOffset > 0 ? Math.cos(toRad(midAngle)) * sliceHoverOffset : 0;
25
+ const hoverOffsetY = sliceHoverOffset > 0 ? Math.sin(toRad(midAngle)) * sliceHoverOffset : 0;
26
+ const baseOffset = slice.baseOffset ?? 0;
27
+ const baseOffsetX = baseOffset !== 0 ? Math.cos(toRad(midAngle)) * baseOffset : 0;
28
+ const baseOffsetY = baseOffset !== 0 ? Math.sin(toRad(midAngle)) * baseOffset : 0;
29
+ const scale = isHovered && !isFullCircleSlice && hoverScale > 1 ? hoverScale : 1;
30
+ return {
31
+ sliceOuterRadius,
32
+ sliceInnerRadius,
33
+ isFullCircleSlice,
34
+ midAngle,
35
+ midRadius,
36
+ isHovered,
37
+ offsetX: hoverOffsetX + baseOffsetX,
38
+ offsetY: hoverOffsetY + baseOffsetY,
39
+ scale,
40
+ renderRotation: isFullCircleSlice ? currentAngle : currentAngle + halfSpacing,
41
+ renderAngle: isFullCircleSlice ? angle : Math.max(0, angle - spacingAngle)
42
+ };
43
+ }
44
+
45
+ // src/circular/label.utils.ts
46
+ function getLabelSide(angle) {
47
+ const normalized = (angle % 360 + 360) % 360;
48
+ return Math.cos(toRad(normalized)) >= 0 ? "right" : "left";
49
+ }
50
+ function drawCanvasLeaderLine(ctx, layout, centerX, centerY, strokeColor, strokeWidth) {
51
+ const { leaderLine } = layout;
52
+ ctx.beginPath();
53
+ ctx.moveTo(centerX + leaderLine.x1, centerY + leaderLine.y1);
54
+ ctx.lineTo(centerX + leaderLine.x2, centerY + leaderLine.y2);
55
+ ctx.lineTo(centerX + leaderLine.x3, centerY + leaderLine.y3);
56
+ ctx.strokeStyle = strokeColor;
57
+ ctx.lineWidth = strokeWidth;
58
+ ctx.stroke();
59
+ }
60
+ function drawCanvasStraightLeaderLine(ctx, layout, centerX, centerY, strokeColor, strokeWidth) {
61
+ const { leaderLine } = layout;
62
+ ctx.beginPath();
63
+ ctx.moveTo(centerX + leaderLine.x1, centerY + leaderLine.y1);
64
+ ctx.lineTo(centerX + leaderLine.x3, centerY + leaderLine.y3);
65
+ ctx.strokeStyle = strokeColor;
66
+ ctx.lineWidth = strokeWidth;
67
+ ctx.stroke();
68
+ }
69
+ function drawCanvasLabelLines(ctx, layout, centerX, centerY, textColor, options) {
70
+ const { lines, side, x, y } = layout;
71
+ const textX = options.centered ? centerX + x : centerX + x + (side === "right" ? options.textOffset : -options.textOffset);
72
+ const textY = centerY + y;
73
+ const lineHeight = options.fontSize * options.lineHeight;
74
+ const totalHeight = lines.length * lineHeight;
75
+ const startY = textY - totalHeight / 2 + lineHeight / 2;
76
+ withCanvasState(ctx, () => {
77
+ ctx.font = `${options.fontWeight} ${options.fontSize}px ${options.fontFamily}`;
78
+ ctx.fillStyle = textColor;
79
+ ctx.textAlign = options.centered ? "center" : side === "right" ? "left" : "right";
80
+ ctx.textBaseline = "middle";
81
+ for (let i = 0; i < lines.length; i++) {
82
+ ctx.fillText(lines[i], textX, startY + i * lineHeight);
83
+ }
84
+ });
85
+ }
86
+
87
+ // src/circular/labelLayout.utils.ts
88
+ var DEFAULT_LABEL_LAYOUT_OPTIONS = {
89
+ fontSize: 12,
90
+ fontWeight: "normal",
91
+ fontFamily: "Arial",
92
+ leaderOffset: 10,
93
+ horizontalOffset: 15,
94
+ textOffset: 4,
95
+ lineHeight: 1.2,
96
+ minRadius: 50,
97
+ alignTo: "labelLine",
98
+ lineStyle: "angled"
99
+ };
100
+ var radialOffset = (radius, angleDeg) => pointOnCircle(0, 0, angleDeg, radius);
101
+ function getAvailableLabelWidth(side, bounds, radius, options) {
102
+ const leaderLength = options.leaderOffset + options.horizontalOffset + options.textOffset;
103
+ if (side === "right") {
104
+ return bounds.right - bounds.centerX - radius - leaderLength;
105
+ }
106
+ return bounds.centerX - radius - leaderLength - bounds.left;
107
+ }
108
+ function createLabelLayoutItem(config, radius, bounds, maxWidth, options) {
109
+ const side = getLabelSide(config.angle);
110
+ const fontSize = config.fontSize ?? options.fontSize;
111
+ const lines = wrapText(config.text, maxWidth, fontSize, options.fontFamily, options.fontWeight);
112
+ const innerR = options.innerRadius ?? 0;
113
+ const sliceRadius = innerR + (radius - innerR) * (config.radiusRatio ?? 1);
114
+ const pieEdge = radialOffset(sliceRadius, config.angle);
115
+ const horizontalDir = side === "right" ? 1 : -1;
116
+ const textWidth = calculateWrappedTextWidth(lines, fontSize, options.fontFamily, options.fontWeight);
117
+ const textHeight = calculateWrappedTextHeight(lines, fontSize, options.lineHeight);
118
+ let elbow;
119
+ let textAnchor;
120
+ if (options.lineStyle === "none") {
121
+ const totalOffset = options.leaderOffset + options.horizontalOffset + options.textOffset;
122
+ const pos = radialOffset(radius + totalOffset, config.angle);
123
+ const absoluteX2 = bounds.centerX + pos.x - textWidth / 2;
124
+ const absoluteY2 = bounds.centerY + pos.y - textHeight / 2;
125
+ return {
126
+ text: config.text,
127
+ lines,
128
+ angle: config.angle,
129
+ side,
130
+ x: pos.x,
131
+ y: pos.y,
132
+ boundingBox: { x: absoluteX2, y: absoluteY2, width: textWidth, height: textHeight },
133
+ leaderLine: { x1: pieEdge.x, y1: pieEdge.y, x2: pos.x, y2: pos.y, x3: pos.x, y3: pos.y },
134
+ index: config.index,
135
+ value: config.value,
136
+ percentage: config.percentage,
137
+ color: config.color,
138
+ fontSize: config.fontSize,
139
+ textColor: config.textColor,
140
+ connectorColor: config.connectorColor,
141
+ connectorWidth: config.connectorWidth
142
+ };
143
+ }
144
+ if (options.lineStyle === "straight") {
145
+ const lineEnd = pieEdge.x + horizontalDir * (options.leaderOffset + options.horizontalOffset);
146
+ elbow = { x: pieEdge.x, y: pieEdge.y };
147
+ textAnchor = { x: lineEnd, y: pieEdge.y };
148
+ } else if (options.alignTo === "edge") {
149
+ elbow = radialOffset(radius + options.leaderOffset, config.angle);
150
+ const edgeX = side === "right" ? bounds.right - bounds.centerX - options.textOffset - textWidth : bounds.left - bounds.centerX + options.textOffset + textWidth;
151
+ textAnchor = { x: edgeX, y: elbow.y };
152
+ } else {
153
+ elbow = radialOffset(radius + options.leaderOffset, config.angle);
154
+ textAnchor = {
155
+ x: elbow.x + horizontalDir * options.horizontalOffset,
156
+ y: elbow.y
157
+ };
158
+ }
159
+ const absoluteX = bounds.centerX + textAnchor.x + (side === "right" ? options.textOffset : -options.textOffset - textWidth);
160
+ const absoluteY = bounds.centerY + textAnchor.y - textHeight / 2;
161
+ return {
162
+ text: config.text,
163
+ lines,
164
+ angle: config.angle,
165
+ side,
166
+ x: textAnchor.x,
167
+ y: textAnchor.y,
168
+ boundingBox: {
169
+ x: absoluteX,
170
+ y: absoluteY,
171
+ width: textWidth,
172
+ height: textHeight
173
+ },
174
+ leaderLine: {
175
+ x1: pieEdge.x,
176
+ y1: pieEdge.y,
177
+ x2: elbow.x,
178
+ y2: elbow.y,
179
+ x3: textAnchor.x,
180
+ y3: textAnchor.y
181
+ },
182
+ // Include original data for custom rendering
183
+ index: config.index,
184
+ value: config.value,
185
+ percentage: config.percentage,
186
+ color: config.color,
187
+ fontSize: config.fontSize,
188
+ textColor: config.textColor,
189
+ connectorColor: config.connectorColor,
190
+ connectorWidth: config.connectorWidth
191
+ };
192
+ }
193
+ function createLabelsAtRadius(labelConfigs, radius, bounds, opts) {
194
+ const availableWidthRight = getAvailableLabelWidth("right", bounds, radius, opts);
195
+ const availableWidthLeft = getAvailableLabelWidth("left", bounds, radius, opts);
196
+ return labelConfigs.map((config) => {
197
+ const side = getLabelSide(config.angle);
198
+ const maxWidth = side === "right" ? availableWidthRight : availableWidthLeft;
199
+ return createLabelLayoutItem(config, radius, bounds, Math.max(maxWidth, 30), opts);
200
+ });
201
+ }
202
+ function buildResult(labels, radius) {
203
+ const leftLabels = labels.filter((l) => l.side === "left");
204
+ const rightLabels = labels.filter((l) => l.side === "right");
205
+ return {
206
+ labels,
207
+ radius,
208
+ maxLabelWidthLeft: leftLabels.length > 0 ? Math.max(...leftLabels.map((l) => l.boundingBox.width)) : 0,
209
+ maxLabelWidthRight: rightLabels.length > 0 ? Math.max(...rightLabels.map((l) => l.boundingBox.width)) : 0
210
+ };
211
+ }
212
+ function computeLabelAwareRadius(labelConfigs, initialRadius, bounds, options = {}) {
213
+ if (labelConfigs.length === 0) return initialRadius;
214
+ const opts = { ...DEFAULT_LABEL_LAYOUT_OPTIONS, ...options };
215
+ const chartWidth = bounds.right - bounds.left;
216
+ const chartHeight = bounds.bottom - bounds.top;
217
+ const minChartDim = Math.min(chartWidth, chartHeight);
218
+ const scale = Math.min(1, minChartDim / 300);
219
+ const halfWidth = Math.min(bounds.centerX - bounds.left, bounds.right - bounds.centerX);
220
+ const halfHeight = Math.min(bounds.centerY - bounds.top, bounds.bottom - bounds.centerY);
221
+ if (opts.lineStyle === "none") {
222
+ const totalOffset = opts.leaderOffset * scale + opts.horizontalOffset * scale + opts.textOffset;
223
+ let maxTextWidth2 = 0;
224
+ let maxTextHeight = 0;
225
+ for (const config of labelConfigs) {
226
+ const fontSize = config.fontSize ?? opts.fontSize;
227
+ const lines = wrapText(config.text, halfWidth, fontSize, opts.fontFamily, opts.fontWeight);
228
+ maxTextWidth2 = Math.max(maxTextWidth2, calculateWrappedTextWidth(lines, fontSize, opts.fontFamily, opts.fontWeight));
229
+ maxTextHeight = Math.max(maxTextHeight, calculateWrappedTextHeight(lines, fontSize, opts.lineHeight));
230
+ }
231
+ const maxRadiusH = halfWidth - totalOffset - maxTextWidth2 / 2;
232
+ const maxRadiusV = halfHeight - totalOffset - maxTextHeight / 2;
233
+ return Math.max(Math.min(initialRadius, maxRadiusH, maxRadiusV), opts.minRadius);
234
+ }
235
+ const leaderLength = opts.leaderOffset * scale + opts.horizontalOffset * scale + opts.textOffset;
236
+ let maxTextWidth = 0;
237
+ for (const config of labelConfigs) {
238
+ const fontSize = config.fontSize ?? opts.fontSize;
239
+ const lines = wrapText(config.text, halfWidth, fontSize, opts.fontFamily, opts.fontWeight);
240
+ const w = calculateWrappedTextWidth(lines, fontSize, opts.fontFamily, opts.fontWeight);
241
+ maxTextWidth = Math.max(maxTextWidth, w);
242
+ }
243
+ const margin = 4;
244
+ const maxAllowableRadius = halfWidth - leaderLength - maxTextWidth - margin;
245
+ return Math.max(Math.min(initialRadius, maxAllowableRadius), opts.minRadius);
246
+ }
247
+ function calculateLabelLayout(labelConfigs, initialRadius, bounds, options = {}) {
248
+ const opts = { ...DEFAULT_LABEL_LAYOUT_OPTIONS, ...options };
249
+ if (labelConfigs.length === 0) {
250
+ return { labels: [], radius: initialRadius, maxLabelWidthLeft: 0, maxLabelWidthRight: 0 };
251
+ }
252
+ const chartWidth = bounds.right - bounds.left;
253
+ const chartHeight = bounds.bottom - bounds.top;
254
+ const minChartDim = Math.min(chartWidth, chartHeight);
255
+ const scale = Math.min(1, minChartDim / 300);
256
+ const effectiveOpts = {
257
+ ...opts,
258
+ leaderOffset: opts.leaderOffset * scale,
259
+ horizontalOffset: opts.horizontalOffset * scale
260
+ };
261
+ const labels = createLabelsAtRadius(labelConfigs, initialRadius, bounds, effectiveOpts);
262
+ if (opts.lineStyle === "angled" || opts.lineStyle === "none") {
263
+ const margin = 2;
264
+ const sides = ["left", "right"];
265
+ const extendByIndex = /* @__PURE__ */ new Map();
266
+ for (const side of sides) {
267
+ const sideLabels = labels.filter((l) => l.side === side).sort((a, b) => a.boundingBox.y - b.boundingBox.y);
268
+ for (let i = 1; i < sideLabels.length; i++) {
269
+ const prev = sideLabels[i - 1];
270
+ const curr = sideLabels[i];
271
+ const overlap = prev.boundingBox.y + prev.boundingBox.height + margin - curr.boundingBox.y;
272
+ if (overlap > 0) {
273
+ const target = Math.abs(curr.y) <= Math.abs(prev.y) ? curr : prev;
274
+ const existing = extendByIndex.get(target.index) ?? 0;
275
+ extendByIndex.set(target.index, Math.max(existing, overlap * 1.5));
276
+ }
277
+ }
278
+ }
279
+ if (extendByIndex.size > 0) {
280
+ const availableWidthRight = getAvailableLabelWidth("right", bounds, initialRadius, effectiveOpts);
281
+ const availableWidthLeft = getAvailableLabelWidth("left", bounds, initialRadius, effectiveOpts);
282
+ for (let i = 0; i < labels.length; i++) {
283
+ const extra = extendByIndex.get(labels[i].index);
284
+ if (!extra) continue;
285
+ const config = labelConfigs[i];
286
+ const side = getLabelSide(config.angle);
287
+ const maxW = side === "right" ? availableWidthRight : availableWidthLeft;
288
+ const extendedOpts = { ...effectiveOpts, horizontalOffset: effectiveOpts.horizontalOffset + extra };
289
+ labels[i] = createLabelLayoutItem(config, initialRadius, bounds, Math.max(maxW, 30), extendedOpts);
290
+ }
291
+ }
292
+ }
293
+ return buildResult(labels, initialRadius);
294
+ }
295
+ function boxAreaToBounds(area) {
296
+ return {
297
+ left: area.x,
298
+ right: area.x + area.width,
299
+ top: area.y,
300
+ bottom: area.y + area.height,
301
+ centerX: area.x + area.width / 2,
302
+ centerY: area.y + area.height / 2
303
+ };
304
+ }
305
+ function buildPieDataLabelLayout(frame, labelConfig, viewport, datasetPropsMap) {
306
+ const configs = [];
307
+ const labelSlices = /* @__PURE__ */ new Map();
308
+ for (const slice of frame.slices) {
309
+ const angle = slice.endAngle - slice.rotation;
310
+ if (angle < 0.5) continue;
311
+ const percentage = slice.targetPercentage;
312
+ if (percentage < (labelConfig.minPercentage ?? 0)) continue;
313
+ const datasetProps = datasetPropsMap.get(slice.datasetIndex);
314
+ const dataItem = datasetProps?.data?.[slice.originalIndex];
315
+ const labelCtx = makeItemContext(dataItem, slice.originalIndex);
316
+ const sliceLabel = String(resolveAccessor(datasetProps?.label, labelCtx) ?? `Item ${slice.originalIndex + 1}`);
317
+ const text = formatDataLabelText(slice.value, percentage, labelConfig.display, labelConfig.formatter, sliceLabel);
318
+ if (!text) continue;
319
+ const perLabelFontSize = labelConfig.fontSizeAccessor ? resolveAccessor(labelConfig.fontSizeAccessor, labelCtx, { arrayMode: "cycle" }) : void 0;
320
+ const perLabelColorRaw = labelConfig.colorAccessor ? resolveAccessor(labelConfig.colorAccessor, labelCtx, { arrayMode: "cycle" }) : void 0;
321
+ const perLabelColor = typeof perLabelColorRaw === "string" ? perLabelColorRaw : void 0;
322
+ const perLabelConnectorColorRaw = labelConfig.connectorColorAccessor ? resolveAccessor(labelConfig.connectorColorAccessor, labelCtx, { arrayMode: "cycle" }) : void 0;
323
+ const perLabelConnectorColor = typeof perLabelConnectorColorRaw === "string" ? perLabelConnectorColorRaw : void 0;
324
+ const perLabelConnectorWidth = labelConfig.connectorWidthAccessor ? resolveAccessor(labelConfig.connectorWidthAccessor, labelCtx, { arrayMode: "clip" }) : void 0;
325
+ configs.push({
326
+ text,
327
+ // Live animated midpoint — matches the drawn slice through entry/reorder animations.
328
+ angle: (slice.rotation + slice.endAngle) / 2,
329
+ index: slice.originalIndex,
330
+ value: slice.value,
331
+ percentage,
332
+ color: slice.color ?? DEFAULT_FALLBACK_COLOR,
333
+ label: sliceLabel,
334
+ radiusRatio: slice.radiusRatio,
335
+ fontSize: perLabelFontSize,
336
+ textColor: perLabelColor,
337
+ connectorColor: perLabelConnectorColor,
338
+ connectorWidth: perLabelConnectorWidth
339
+ });
340
+ labelSlices.set(slice.originalIndex, slice);
341
+ }
342
+ if (configs.length === 0) return null;
343
+ const bounds = { ...boxAreaToBounds({ x: 0, y: 0, width: viewport.width, height: viewport.height }), centerX: frame.center.x, centerY: frame.center.y };
344
+ const layoutOptions = {
345
+ fontSize: labelConfig.fontSize,
346
+ fontWeight: labelConfig.fontWeight,
347
+ fontFamily: labelConfig.fontFamily,
348
+ leaderOffset: labelConfig.leaderOffset,
349
+ horizontalOffset: labelConfig.horizontalOffset,
350
+ textOffset: labelConfig.textOffset,
351
+ lineHeight: labelConfig.lineHeight,
352
+ alignTo: labelConfig.alignTo,
353
+ lineStyle: labelConfig.lineStyle,
354
+ innerRadius: frame.innerRadius
355
+ };
356
+ const labelLayout = calculateLabelLayout(configs, frame.outerRadius, bounds, layoutOptions);
357
+ const configsByIndex = /* @__PURE__ */ new Map();
358
+ for (const config of configs) configsByIndex.set(config.index, config);
359
+ return { labelLayout, configsByIndex, labelSlices };
360
+ }
361
+
362
+ export { DEFAULT_LABEL_LAYOUT_OPTIONS, boxAreaToBounds, buildPieDataLabelLayout, calculateLabelLayout, computeLabelAwareRadius, computeSliceGeometry, drawCanvasLabelLines, drawCanvasLeaderLine, drawCanvasStraightLeaderLine, getLabelSide };
@@ -0,0 +1,102 @@
1
+ import { computeItemHoverState, applyHoverEffects } from './chunk-BZN2QHGP.mjs';
2
+ import { FIELD_DEFAULTS, getDefaultColor, resolveDash, resolveAccessor, makeItemContext } from './chunk-O2X6FF45.mjs';
3
+ import { toRad } from './chunk-RQ3CKQOX.mjs';
4
+
5
+ // src/series/pie/shared.ts
6
+ function computeSliceRenderStates(props, layout, theme) {
7
+ const { interaction, effects } = props;
8
+ const { visibleSlices, center, outerRadius, innerRadius, colors, borderColors, isFullCircle: fullCircle } = layout;
9
+ const borderWidth = typeof props.borderStrokeWidth === "number" ? props.borderStrokeWidth : 0;
10
+ const dataArr = props.data ?? [];
11
+ const seriesExtras = { seriesIndex: props.order ?? 0, seriesId: props.id ?? "" };
12
+ const valueAccessor = props.valueField ?? FIELD_DEFAULTS.valueField;
13
+ const categoryAccessor = props.categoryField ?? props.labelField ?? FIELD_DEFAULTS.categoryField;
14
+ const ctxFor = (i) => {
15
+ const value = valueAccessor ? resolveAccessor(valueAccessor, makeItemContext(dataArr[i], i)) ?? null : null;
16
+ const category = categoryAccessor ? resolveAccessor(categoryAccessor, makeItemContext(dataArr[i], i)) ?? void 0 : void 0;
17
+ return makeItemContext(dataArr[i], i, { value, category, ...seriesExtras });
18
+ };
19
+ const resolveSliceBorderDash = (i) => resolveDash(props.borderDash, ctxFor(i));
20
+ const resolveSliceBorderDashOffset = (i) => resolveAccessor(props.borderDashOffset, ctxFor(i), { arrayMode: "clip", fallback: 0 }) ?? 0;
21
+ const resolveSliceOpacity = (i) => resolveAccessor(props.opacity, ctxFor(i), { arrayMode: "clip" });
22
+ const resolveSliceHoverColor = (i) => resolveAccessor(props.hoverColor, ctxFor(i), { arrayMode: "cycle" });
23
+ const resolveSliceHoverBorderColor = (i) => resolveAccessor(props.hoverBorderColor, ctxFor(i), { arrayMode: "cycle" });
24
+ const resolveSliceOffset = (i) => resolveAccessor(props.offset, ctxFor(i), { arrayMode: "clip", fallback: 0 }) ?? 0;
25
+ const borderRadius = typeof props.borderRadius === "number" ? props.borderRadius : typeof props.borderRadius === "object" && props.borderRadius !== null && !Array.isArray(props.borderRadius) ? props.borderRadius : void 0;
26
+ const hoverEnabled = effects !== void 0;
27
+ const slices = visibleSlices.map((slice) => {
28
+ const dataIndex = slice.dataIndex;
29
+ const userFill = colors[dataIndex];
30
+ const borderColor = borderColors[dataIndex];
31
+ const canvasFill = userFill ?? getDefaultColor(dataIndex, theme);
32
+ const hoverState = computeItemHoverState(dataIndex, interaction?.hoveredIndex, hoverEnabled);
33
+ const isInactive = hoverState.hasAnyHover && !hoverState.isHovered;
34
+ const itemHoverColor = resolveSliceHoverColor(dataIndex);
35
+ const itemHoverBorderColor = resolveSliceHoverBorderColor(dataIndex);
36
+ const itemEffects = hoverEnabled && effects && (itemHoverColor !== void 0 || itemHoverBorderColor !== void 0) ? {
37
+ ...effects,
38
+ hoverBackgroundColor: itemHoverColor ?? effects.hoverBackgroundColor,
39
+ hoverBorderColor: itemHoverBorderColor ?? effects.hoverBorderColor
40
+ } : hoverEnabled ? effects : void 0;
41
+ const {
42
+ color: effectColor,
43
+ opacity: hoverOpacity,
44
+ borderColor: effectBorderColor,
45
+ borderStrokeWidth: effectBorderWidth,
46
+ borderDash: effectBorderDash,
47
+ borderDashOffset: effectBorderDashOffset
48
+ } = applyHoverEffects(canvasFill, borderColor, borderWidth, resolveSliceBorderDash(dataIndex), resolveSliceBorderDashOffset(dataIndex), hoverState, itemEffects, theme);
49
+ const userOpacity = resolveSliceOpacity(dataIndex);
50
+ const opacity = userOpacity !== void 0 ? hoverOpacity * userOpacity : hoverOpacity;
51
+ const finalEffectColor = effectColor;
52
+ const baseSliceOffset = resolveSliceOffset(dataIndex);
53
+ const offset = baseSliceOffset > 0 || hoverEnabled && effects ? calculateSliceOffset(slice, hoverState.isHovered, hoverEnabled ? effects : void 0, baseSliceOffset) : { dx: 0, dy: 0 };
54
+ const scale = hoverEnabled && hoverState.isHovered && effects?.hoverScale ? effects.hoverScale : 1;
55
+ const arcConfig = {
56
+ rotation: slice.rotation,
57
+ endAngle: slice.endAngle,
58
+ outerRadius,
59
+ innerRadius,
60
+ borderRadius
61
+ };
62
+ return {
63
+ slice,
64
+ dataIndex,
65
+ effectColor: finalEffectColor,
66
+ effectBorderColor,
67
+ effectBorderWidth,
68
+ effectBorderDash,
69
+ effectBorderDashOffset,
70
+ opacity,
71
+ // SVG state — class composition + inline overrides
72
+ userFill,
73
+ userBorder: borderColor === "transparent" ? void 0 : borderColor,
74
+ isInactive,
75
+ offset,
76
+ scale,
77
+ arcConfig,
78
+ isHovered: hoverState.isHovered
79
+ };
80
+ });
81
+ return {
82
+ slices,
83
+ center,
84
+ outerRadius,
85
+ innerRadius,
86
+ isFullCircle: fullCircle
87
+ };
88
+ }
89
+ function calculateSliceOffset(slice, isHovered, effects, baseOffset = 0) {
90
+ let offset = baseOffset;
91
+ if (isHovered && effects?.hoverOffset) {
92
+ offset = Math.max(offset, effects.hoverOffset);
93
+ }
94
+ if (offset === 0) return { dx: 0, dy: 0 };
95
+ const angleRad = toRad(slice.valueAngle);
96
+ return {
97
+ dx: Math.cos(angleRad) * offset,
98
+ dy: Math.sin(angleRad) * offset
99
+ };
100
+ }
101
+
102
+ export { computeSliceRenderStates };
@@ -0,0 +1,186 @@
1
+ import { getCellLabelInfo, buildCellExtras } from './chunk-VVI3OBPJ.mjs';
2
+ import { createDrawImage } from './chunk-7CMVDIOU.mjs';
3
+ import { resolveFontFamily, DEFAULT_TREEMAP_CELL_BORDER_COLOR, DEFAULT_TREEMAP_HEADER_TEXT_COLOR, DEFAULT_HOVER_DIM_OPACITY, DEFAULT_HOVER_BRIGHTNESS } from './chunk-NKUYIWAP.mjs';
4
+ import { getContrastColor } from './chunk-QS76E3TD.mjs';
5
+ import { resolveAccessor, makeItemContext, resolveDash } from './chunk-O2X6FF45.mjs';
6
+ import { withCanvasState, adjustBrightness } from './chunk-SSLTFJ3U.mjs';
7
+
8
+ // src/series/treemap/canvas/index.ts
9
+ function renderTreemapCanvas(props, layout, ctx, context) {
10
+ const fontFamily = resolveFontFamily(void 0, context?.font);
11
+ const interaction = context?.interaction;
12
+ const anyHovered = interaction?.hoveredIndex != null;
13
+ const treemapDataArr = props.data;
14
+ const defaultBorderColor = context?.theme.treemapCellBorder ?? DEFAULT_TREEMAP_CELL_BORDER_COLOR;
15
+ const cellExtras = (idx) => buildCellExtras(props, treemapDataArr?.[idx], layout, idx);
16
+ const resolveCellBorderColor = (idx) => {
17
+ const v = resolveAccessor(props.borderColor, makeItemContext(treemapDataArr?.[idx], idx, cellExtras(idx)), { fallback: defaultBorderColor });
18
+ return typeof v === "string" ? v : defaultBorderColor;
19
+ };
20
+ const resolveCellBorderWidth = (idx) => resolveAccessor(props.borderStrokeWidth, makeItemContext(treemapDataArr?.[idx], idx, cellExtras(idx)), { arrayMode: "clip", fallback: 1 }) ?? 1;
21
+ const resolveCellLabelColor = (idx) => {
22
+ const v = resolveAccessor(props.labelColor, makeItemContext(treemapDataArr?.[idx], idx, cellExtras(idx)));
23
+ return typeof v === "string" ? v : void 0;
24
+ };
25
+ const resolveCellBorderDash = (idx) => resolveDash(props.borderDash, makeItemContext(treemapDataArr?.[idx], idx, cellExtras(idx)));
26
+ const resolveCellBorderDashOffset = (idx) => resolveAccessor(props.borderDashOffset, makeItemContext(treemapDataArr?.[idx], idx, cellExtras(idx)), { arrayMode: "clip" });
27
+ const resolveCellOpacity = (idx) => resolveAccessor(props.opacity, makeItemContext(treemapDataArr?.[idx], idx, cellExtras(idx)), { arrayMode: "clip" });
28
+ const resolveCellHoverColor = (idx) => {
29
+ const v = resolveAccessor(props.hoverColor, makeItemContext(treemapDataArr?.[idx], idx, cellExtras(idx)), { arrayMode: "cycle" });
30
+ return typeof v === "string" ? v : void 0;
31
+ };
32
+ const resolveCellHoverBorderColor = (idx) => {
33
+ const v = resolveAccessor(props.hoverBorderColor, makeItemContext(treemapDataArr?.[idx], idx, cellExtras(idx)), { arrayMode: "cycle" });
34
+ return typeof v === "string" ? v : void 0;
35
+ };
36
+ const borderJoinStyle = props.borderJoinStyle;
37
+ const borderAlign = props.borderAlign ?? "center";
38
+ const borderRadius = props.borderRadius ?? 2;
39
+ for (const gh of layout.groupHeaders) {
40
+ withCanvasState(ctx, () => {
41
+ ctx.fillStyle = gh.color;
42
+ ctx.beginPath();
43
+ ctx.roundRect(gh.x, gh.y, gh.width, gh.height, 2);
44
+ ctx.fill();
45
+ const headerText = gh.label.toUpperCase();
46
+ const maxChars = Math.floor((gh.width - 16) / 6.5);
47
+ if (maxChars >= 2) {
48
+ const displayText = headerText.length <= maxChars ? headerText : headerText.slice(0, maxChars - 1) + "\u2026";
49
+ ctx.fillStyle = context?.theme.treemapHeaderText ?? DEFAULT_TREEMAP_HEADER_TEXT_COLOR;
50
+ ctx.font = `700 10px ${fontFamily}`;
51
+ ctx.textAlign = "left";
52
+ ctx.textBaseline = "middle";
53
+ ctx.fillText(displayText, gh.x + 8, gh.y + gh.height / 2);
54
+ }
55
+ });
56
+ }
57
+ for (const cell of layout.cells) {
58
+ if (cell.width < 1 || cell.height < 1) continue;
59
+ const isHovered = anyHovered && cell.index === interaction.hoveredIndex;
60
+ const userCellOpacity = resolveCellOpacity(cell.index);
61
+ const cellOpacity = (anyHovered && !isHovered ? context?.effects?.dimOpacity ?? context?.theme.dimOpacity ?? DEFAULT_HOVER_DIM_OPACITY : 1) * (userCellOpacity ?? 1);
62
+ const cellHoverColor = isHovered ? resolveCellHoverColor(cell.index) : void 0;
63
+ const cellColor = cellHoverColor ?? (isHovered && (context?.effects?.hoverBrightness ?? context?.theme.hoverBrightness) ? adjustBrightness(cell.color, context?.effects?.hoverBrightness ?? context?.theme.hoverBrightness ?? DEFAULT_HOVER_BRIGHTNESS) : cell.color);
64
+ const cellBorderWidth = resolveCellBorderWidth(cell.index);
65
+ const cellBorderColor = (isHovered ? resolveCellHoverBorderColor(cell.index) : void 0) ?? resolveCellBorderColor(cell.index);
66
+ withCanvasState(ctx, () => {
67
+ if (cellOpacity < 1) ctx.globalAlpha = cellOpacity;
68
+ const inset = borderAlign === "inner" ? cellBorderWidth / 2 : 0;
69
+ const cx = cell.x + inset;
70
+ const cy = cell.y + inset;
71
+ const cw = cell.width - inset * 2;
72
+ const ch = cell.height - inset * 2;
73
+ const r = Math.min(borderRadius, cw / 2, ch / 2);
74
+ ctx.fillStyle = cellColor;
75
+ ctx.beginPath();
76
+ ctx.roundRect(cx, cy, cw, ch, r);
77
+ ctx.fill();
78
+ if (cellBorderWidth > 0) {
79
+ const cellBorderDash = resolveCellBorderDash(cell.index);
80
+ const cellBorderDashOffset = resolveCellBorderDashOffset(cell.index);
81
+ ctx.strokeStyle = cellBorderColor;
82
+ ctx.lineWidth = cellBorderWidth;
83
+ ctx.setLineDash(cellBorderDash ?? []);
84
+ if (cellBorderDashOffset) ctx.lineDashOffset = cellBorderDashOffset;
85
+ if (borderJoinStyle) ctx.lineJoin = borderJoinStyle;
86
+ ctx.stroke();
87
+ }
88
+ });
89
+ if (!props.renderContent) {
90
+ const info = getCellLabelInfo(cell, props.labelMinSize);
91
+ if (info.showPrimary) {
92
+ const labelFill = resolveCellLabelColor(cell.index) ?? getContrastColor(cellColor);
93
+ withCanvasState(ctx, () => {
94
+ if (cellOpacity < 1) ctx.globalAlpha = cellOpacity;
95
+ ctx.fillStyle = labelFill;
96
+ ctx.font = `700 ${info.fontSize}px ${fontFamily}`;
97
+ ctx.textAlign = "center";
98
+ ctx.textBaseline = "middle";
99
+ ctx.fillText(cell.label, info.cx, info.primaryY);
100
+ if (info.showSecondary) {
101
+ ctx.globalAlpha = (cellOpacity < 1 ? cellOpacity : 1) * 0.85;
102
+ ctx.fillStyle = labelFill;
103
+ ctx.font = `500 ${info.secondaryFontSize}px ${fontFamily}`;
104
+ ctx.fillText(cell.secondaryLabel, info.cx, info.secondaryY);
105
+ }
106
+ });
107
+ }
108
+ }
109
+ }
110
+ }
111
+ function renderCanvasTreemapContent(ctx, layouts, onImageLoad) {
112
+ for (const [, { props, layout }] of layouts) {
113
+ const renderFn = props.renderContent;
114
+ if (!renderFn || !props.data) continue;
115
+ const drawImage = createDrawImage(ctx, onImageLoad ?? (() => {
116
+ }));
117
+ for (const cell of layout.cells) {
118
+ const dataItem = props.data[cell.index];
119
+ if (!dataItem) continue;
120
+ ctx.save();
121
+ ctx.beginPath();
122
+ ctx.rect(cell.x, cell.y, cell.width, cell.height);
123
+ ctx.clip();
124
+ renderFn({
125
+ data: dataItem,
126
+ index: cell.index,
127
+ label: cell.label,
128
+ secondaryLabel: cell.secondaryLabel,
129
+ value: cell.value,
130
+ color: cell.color,
131
+ x: cell.x,
132
+ y: cell.y,
133
+ width: cell.width,
134
+ height: cell.height,
135
+ nodeId: cell.nodeId,
136
+ parentId: cell.parentId,
137
+ hasChildren: cell.hasChildren,
138
+ depth: cell.depth,
139
+ drilldownParentId: props.drilldownParentId ?? null,
140
+ ctx,
141
+ drawImage
142
+ });
143
+ ctx.restore();
144
+ }
145
+ }
146
+ }
147
+ function renderTreemapCanvasClipped(ctx, area, transform, draw) {
148
+ if (transform?.zoom) {
149
+ const { tx, ty, sx, sy, progress, direction } = transform.zoom;
150
+ ctx.save();
151
+ ctx.beginPath();
152
+ ctx.rect(area.x, area.y, area.width, area.height);
153
+ ctx.clip();
154
+ ctx.translate(tx, ty);
155
+ ctx.scale(sx, sy);
156
+ if (direction === "out") ctx.globalAlpha = progress;
157
+ draw();
158
+ ctx.restore();
159
+ return;
160
+ }
161
+ if (transform?.wipe) {
162
+ ctx.save();
163
+ ctx.beginPath();
164
+ ctx.rect(area.x, area.y, area.width * transform.wipe.progress, area.height);
165
+ ctx.clip();
166
+ draw();
167
+ ctx.restore();
168
+ return;
169
+ }
170
+ draw();
171
+ }
172
+ function renderTreemapGroupHoverCanvas(ctx, bg) {
173
+ ctx.save();
174
+ ctx.fillStyle = "rgba(0,0,0,0.15)";
175
+ ctx.beginPath();
176
+ ctx.roundRect(bg.x, bg.y, bg.width, bg.height, 2);
177
+ ctx.fill();
178
+ ctx.strokeStyle = "rgba(255,255,255,0.6)";
179
+ ctx.lineWidth = 2;
180
+ ctx.beginPath();
181
+ ctx.roundRect(bg.x, bg.y, bg.width, bg.height, 2);
182
+ ctx.stroke();
183
+ ctx.restore();
184
+ }
185
+
186
+ export { renderCanvasTreemapContent, renderTreemapCanvas, renderTreemapCanvasClipped, renderTreemapGroupHoverCanvas };