@krizaka/charts 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (388) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +59 -2
  3. package/dist/bar.d.ts +17 -0
  4. package/dist/bar.js +17 -0
  5. package/dist/bar.js.map +1 -0
  6. package/dist/candlestick-IG626XL4.js +13 -0
  7. package/dist/candlestick-IG626XL4.js.map +1 -0
  8. package/dist/candlestick.d.ts +42 -0
  9. package/dist/candlestick.js +13 -0
  10. package/dist/candlestick.js.map +1 -0
  11. package/dist/canvas-4MSYDVFO.js +14 -0
  12. package/dist/canvas-4MSYDVFO.js.map +1 -0
  13. package/dist/cartesian-BRhNQ3ib.d.ts +34 -0
  14. package/dist/chart.d.ts +58 -0
  15. package/dist/chart.js +11 -0
  16. package/dist/chart.js.map +1 -0
  17. package/dist/chunk-3CJHBJXA.js +186 -0
  18. package/dist/chunk-3CJHBJXA.js.map +1 -0
  19. package/dist/chunk-4LBXEAGC.js +133 -0
  20. package/dist/chunk-4LBXEAGC.js.map +1 -0
  21. package/dist/chunk-6FINSUOS.js +49 -0
  22. package/dist/chunk-6FINSUOS.js.map +1 -0
  23. package/dist/chunk-AA5EWWYV.js +38 -0
  24. package/dist/chunk-AA5EWWYV.js.map +1 -0
  25. package/dist/chunk-ANUCSRUN.js +43 -0
  26. package/dist/chunk-ANUCSRUN.js.map +1 -0
  27. package/dist/chunk-ARARFMNE.js +88 -0
  28. package/dist/chunk-ARARFMNE.js.map +1 -0
  29. package/dist/chunk-BISL7DYW.js +66 -0
  30. package/dist/chunk-BISL7DYW.js.map +1 -0
  31. package/dist/chunk-BV4DBGN7.js +178 -0
  32. package/dist/chunk-BV4DBGN7.js.map +1 -0
  33. package/dist/chunk-C4MFZLJM.js +19 -0
  34. package/dist/chunk-C4MFZLJM.js.map +1 -0
  35. package/dist/chunk-CSSZLFLO.js +116 -0
  36. package/dist/chunk-CSSZLFLO.js.map +1 -0
  37. package/dist/chunk-CVWSMUUB.js +378 -0
  38. package/dist/chunk-CVWSMUUB.js.map +1 -0
  39. package/dist/chunk-E5DKBSWX.js +2 -0
  40. package/dist/chunk-E5DKBSWX.js.map +1 -0
  41. package/dist/chunk-EEP7PS2L.js +54 -0
  42. package/dist/chunk-EEP7PS2L.js.map +1 -0
  43. package/dist/chunk-EQLC2QVN.js +73 -0
  44. package/dist/chunk-EQLC2QVN.js.map +1 -0
  45. package/dist/chunk-FINOPIDN.js +2 -0
  46. package/dist/chunk-FINOPIDN.js.map +1 -0
  47. package/dist/chunk-G2KF2WL4.js +2 -0
  48. package/dist/chunk-G2KF2WL4.js.map +1 -0
  49. package/dist/chunk-I3D7KUGN.js +205 -0
  50. package/dist/chunk-I3D7KUGN.js.map +1 -0
  51. package/dist/chunk-IKQV3NSL.js +76 -0
  52. package/dist/chunk-IKQV3NSL.js.map +1 -0
  53. package/dist/chunk-JTKR7ZWP.js +468 -0
  54. package/dist/chunk-JTKR7ZWP.js.map +1 -0
  55. package/dist/chunk-KNDHO67X.js +78 -0
  56. package/dist/chunk-KNDHO67X.js.map +1 -0
  57. package/dist/chunk-L2EKYWVI.js +94 -0
  58. package/dist/chunk-L2EKYWVI.js.map +1 -0
  59. package/dist/chunk-MXLITIGU.js +92 -0
  60. package/dist/chunk-MXLITIGU.js.map +1 -0
  61. package/dist/chunk-NCIQMRV3.js +155 -0
  62. package/dist/chunk-NCIQMRV3.js.map +1 -0
  63. package/dist/chunk-OB5EFDDH.js +118 -0
  64. package/dist/chunk-OB5EFDDH.js.map +1 -0
  65. package/dist/chunk-OIRHLJBC.js +83 -0
  66. package/dist/chunk-OIRHLJBC.js.map +1 -0
  67. package/dist/chunk-PBQV3B6O.js +145 -0
  68. package/dist/chunk-PBQV3B6O.js.map +1 -0
  69. package/dist/chunk-POQIHFAZ.js +2 -0
  70. package/dist/chunk-POQIHFAZ.js.map +1 -0
  71. package/dist/chunk-PWMMXRMC.js +234 -0
  72. package/dist/chunk-PWMMXRMC.js.map +1 -0
  73. package/dist/chunk-SLEJDQ3A.js +81 -0
  74. package/dist/chunk-SLEJDQ3A.js.map +1 -0
  75. package/dist/chunk-TPJDOB7R.js +15 -0
  76. package/dist/chunk-TPJDOB7R.js.map +1 -0
  77. package/dist/chunk-VKZZY2QD.js +103 -0
  78. package/dist/chunk-VKZZY2QD.js.map +1 -0
  79. package/dist/chunk-W5FX4TU3.js +102 -0
  80. package/dist/chunk-W5FX4TU3.js.map +1 -0
  81. package/dist/chunk-W5ILLSPK.js +107 -0
  82. package/dist/chunk-W5ILLSPK.js.map +1 -0
  83. package/dist/chunk-WBHFVBSK.js +25 -0
  84. package/dist/chunk-WBHFVBSK.js.map +1 -0
  85. package/dist/chunk-WNUFGMS7.js +113 -0
  86. package/dist/chunk-WNUFGMS7.js.map +1 -0
  87. package/dist/chunk-WVTIKOII.js +15 -0
  88. package/dist/chunk-WVTIKOII.js.map +1 -0
  89. package/dist/chunk-XDDALY4C.js +166 -0
  90. package/dist/chunk-XDDALY4C.js.map +1 -0
  91. package/dist/chunk-XLLYNNC6.js +89 -0
  92. package/dist/chunk-XLLYNNC6.js.map +1 -0
  93. package/dist/context-BgYUymEO.d.ts +163 -0
  94. package/dist/credits.d.ts +42 -0
  95. package/dist/credits.js +21 -0
  96. package/dist/credits.js.map +1 -0
  97. package/dist/earnings.d.ts +29 -0
  98. package/dist/earnings.js +22 -0
  99. package/dist/earnings.js.map +1 -0
  100. package/dist/frame-I7_xYGy5.d.ts +45 -0
  101. package/dist/full-S2MBPEEP.js +11 -0
  102. package/dist/full-S2MBPEEP.js.map +1 -0
  103. package/dist/funnel-QU5ZPC52.js +13 -0
  104. package/dist/funnel-QU5ZPC52.js.map +1 -0
  105. package/dist/funnel.d.ts +26 -0
  106. package/dist/funnel.js +13 -0
  107. package/dist/funnel.js.map +1 -0
  108. package/dist/gauge.d.ts +38 -0
  109. package/dist/gauge.js +13 -0
  110. package/dist/gauge.js.map +1 -0
  111. package/dist/geo.d.ts +37 -0
  112. package/dist/geo.js +13 -0
  113. package/dist/geo.js.map +1 -0
  114. package/dist/globe.d.ts +36 -0
  115. package/dist/globe.js +12 -0
  116. package/dist/globe.js.map +1 -0
  117. package/dist/goal.d.ts +26 -0
  118. package/dist/goal.js +17 -0
  119. package/dist/goal.js.map +1 -0
  120. package/dist/heatmap-JWQOKUGM.js +13 -0
  121. package/dist/heatmap-JWQOKUGM.js.map +1 -0
  122. package/dist/heatmap.d.ts +47 -0
  123. package/dist/heatmap.js +15 -0
  124. package/dist/heatmap.js.map +1 -0
  125. package/dist/host-_F8RgiIz.d.ts +15 -0
  126. package/dist/index.d.ts +29 -0
  127. package/dist/index.js +148 -0
  128. package/dist/index.js.map +1 -0
  129. package/dist/labels-DE_743fQ.d.ts +72 -0
  130. package/dist/latency.d.ts +33 -0
  131. package/dist/latency.js +24 -0
  132. package/dist/latency.js.map +1 -0
  133. package/dist/line.d.ts +25 -0
  134. package/dist/line.js +19 -0
  135. package/dist/line.js.map +1 -0
  136. package/dist/native.d.ts +494 -0
  137. package/dist/native.js +1244 -0
  138. package/dist/native.js.map +1 -0
  139. package/dist/pie.d.ts +37 -0
  140. package/dist/pie.js +16 -0
  141. package/dist/pie.js.map +1 -0
  142. package/dist/provider.d.ts +73 -0
  143. package/dist/provider.js +24 -0
  144. package/dist/provider.js.map +1 -0
  145. package/dist/radar-75GRJ2IK.js +13 -0
  146. package/dist/radar-75GRJ2IK.js.map +1 -0
  147. package/dist/radar.d.ts +22 -0
  148. package/dist/radar.js +13 -0
  149. package/dist/radar.js.map +1 -0
  150. package/dist/sankey-XQTX2EG6.js +13 -0
  151. package/dist/sankey-XQTX2EG6.js.map +1 -0
  152. package/dist/sankey.d.ts +28 -0
  153. package/dist/sankey.js +13 -0
  154. package/dist/sankey.js.map +1 -0
  155. package/dist/scatter-XSNG4OKD.js +13 -0
  156. package/dist/scatter-XSNG4OKD.js.map +1 -0
  157. package/dist/scatter.d.ts +41 -0
  158. package/dist/scatter.js +15 -0
  159. package/dist/scatter.js.map +1 -0
  160. package/dist/sparkline.d.ts +26 -0
  161. package/dist/sparkline.js +16 -0
  162. package/dist/sparkline.js.map +1 -0
  163. package/dist/svg-BJUHYX3B.js +14 -0
  164. package/dist/svg-BJUHYX3B.js.map +1 -0
  165. package/dist/throughput.d.ts +37 -0
  166. package/dist/throughput.js +24 -0
  167. package/dist/throughput.js.map +1 -0
  168. package/dist/ticker.d.ts +38 -0
  169. package/dist/ticker.js +22 -0
  170. package/dist/ticker.js.map +1 -0
  171. package/dist/treemap-OMGGGB5U.js +13 -0
  172. package/dist/treemap-OMGGGB5U.js.map +1 -0
  173. package/dist/treemap.d.ts +24 -0
  174. package/dist/treemap.js +14 -0
  175. package/dist/treemap.js.map +1 -0
  176. package/dist/world-110m-DVFWXS42.js +18 -0
  177. package/dist/world-110m-DVFWXS42.js.map +1 -0
  178. package/package.json +614 -3
  179. package/registry/area-chart.json +785 -0
  180. package/registry/bar-chart.json +784 -0
  181. package/registry/calendar-heatmap.json +460 -0
  182. package/registry/candlestick.json +553 -0
  183. package/registry/chart.json +441 -0
  184. package/registry/charts-provider.json +191 -0
  185. package/registry/credit-usage.json +473 -0
  186. package/registry/earnings-chart.json +703 -0
  187. package/registry/examples/area-chart/credits-usage.d.ts +4 -0
  188. package/registry/examples/area-chart/credits-usage.js +38 -0
  189. package/registry/examples/area-chart/credits-usage.tsx +32 -0
  190. package/registry/examples/area-chart/native/credits-usage.d.ts +4 -0
  191. package/registry/examples/area-chart/native/credits-usage.dark.png +0 -0
  192. package/registry/examples/area-chart/native/credits-usage.js +33 -0
  193. package/registry/examples/area-chart/native/credits-usage.light.png +0 -0
  194. package/registry/examples/area-chart/native/credits-usage.tsx +27 -0
  195. package/registry/examples/area-chart/storage.d.ts +4 -0
  196. package/registry/examples/area-chart/storage.js +27 -0
  197. package/registry/examples/area-chart/storage.tsx +21 -0
  198. package/registry/examples/bar-chart/jobs-by-status.d.ts +4 -0
  199. package/registry/examples/bar-chart/jobs-by-status.js +37 -0
  200. package/registry/examples/bar-chart/jobs-by-status.tsx +31 -0
  201. package/registry/examples/bar-chart/native/jobs-by-status.d.ts +4 -0
  202. package/registry/examples/bar-chart/native/jobs-by-status.dark.png +0 -0
  203. package/registry/examples/bar-chart/native/jobs-by-status.js +32 -0
  204. package/registry/examples/bar-chart/native/jobs-by-status.light.png +0 -0
  205. package/registry/examples/bar-chart/native/jobs-by-status.tsx +26 -0
  206. package/registry/examples/bar-chart/plans-by-quarter.d.ts +4 -0
  207. package/registry/examples/bar-chart/plans-by-quarter.js +31 -0
  208. package/registry/examples/bar-chart/plans-by-quarter.tsx +26 -0
  209. package/registry/examples/bar-chart/top-supporters.d.ts +4 -0
  210. package/registry/examples/bar-chart/top-supporters.js +32 -0
  211. package/registry/examples/bar-chart/top-supporters.tsx +27 -0
  212. package/registry/examples/calendar-heatmap/publishing.d.ts +4 -0
  213. package/registry/examples/calendar-heatmap/publishing.js +28 -0
  214. package/registry/examples/calendar-heatmap/publishing.tsx +23 -0
  215. package/registry/examples/candlestick/auction-bids.d.ts +4 -0
  216. package/registry/examples/candlestick/auction-bids.js +37 -0
  217. package/registry/examples/candlestick/auction-bids.tsx +32 -0
  218. package/registry/examples/chart/polar-uploads.d.ts +4 -0
  219. package/registry/examples/chart/polar-uploads.js +34 -0
  220. package/registry/examples/chart/polar-uploads.tsx +30 -0
  221. package/registry/examples/charts-provider/french-orazaka.d.ts +4 -0
  222. package/registry/examples/charts-provider/french-orazaka.js +26 -0
  223. package/registry/examples/charts-provider/french-orazaka.tsx +22 -0
  224. package/registry/examples/charts-provider/native/french-orazaka.d.ts +4 -0
  225. package/registry/examples/charts-provider/native/french-orazaka.dark.png +0 -0
  226. package/registry/examples/charts-provider/native/french-orazaka.js +17 -0
  227. package/registry/examples/charts-provider/native/french-orazaka.light.png +0 -0
  228. package/registry/examples/charts-provider/native/french-orazaka.tsx +17 -0
  229. package/registry/examples/credit-usage/monthly-credits.d.ts +4 -0
  230. package/registry/examples/credit-usage/monthly-credits.js +24 -0
  231. package/registry/examples/credit-usage/monthly-credits.tsx +19 -0
  232. package/registry/examples/credit-usage/native/monthly-credits.d.ts +4 -0
  233. package/registry/examples/credit-usage/native/monthly-credits.dark.png +0 -0
  234. package/registry/examples/credit-usage/native/monthly-credits.js +23 -0
  235. package/registry/examples/credit-usage/native/monthly-credits.light.png +0 -0
  236. package/registry/examples/credit-usage/native/monthly-credits.tsx +18 -0
  237. package/registry/examples/credit-usage/storage-plan.d.ts +4 -0
  238. package/registry/examples/credit-usage/storage-plan.js +21 -0
  239. package/registry/examples/credit-usage/storage-plan.tsx +15 -0
  240. package/registry/examples/earnings-chart/creator-month.d.ts +4 -0
  241. package/registry/examples/earnings-chart/creator-month.js +29 -0
  242. package/registry/examples/earnings-chart/creator-month.tsx +24 -0
  243. package/registry/examples/earnings-chart/gross-and-net.d.ts +4 -0
  244. package/registry/examples/earnings-chart/gross-and-net.js +29 -0
  245. package/registry/examples/earnings-chart/gross-and-net.tsx +24 -0
  246. package/registry/examples/earnings-chart/native/creator-month.d.ts +4 -0
  247. package/registry/examples/earnings-chart/native/creator-month.dark.png +0 -0
  248. package/registry/examples/earnings-chart/native/creator-month.js +29 -0
  249. package/registry/examples/earnings-chart/native/creator-month.light.png +0 -0
  250. package/registry/examples/earnings-chart/native/creator-month.tsx +24 -0
  251. package/registry/examples/funnel/signup.d.ts +4 -0
  252. package/registry/examples/funnel/signup.js +30 -0
  253. package/registry/examples/funnel/signup.tsx +24 -0
  254. package/registry/examples/gauge/challenge-goal.d.ts +4 -0
  255. package/registry/examples/gauge/challenge-goal.js +24 -0
  256. package/registry/examples/gauge/challenge-goal.tsx +18 -0
  257. package/registry/examples/gauge/credits-quota.d.ts +4 -0
  258. package/registry/examples/gauge/credits-quota.js +26 -0
  259. package/registry/examples/gauge/credits-quota.tsx +19 -0
  260. package/registry/examples/gauge/native/credits-quota.d.ts +4 -0
  261. package/registry/examples/gauge/native/credits-quota.dark.png +0 -0
  262. package/registry/examples/gauge/native/credits-quota.js +25 -0
  263. package/registry/examples/gauge/native/credits-quota.light.png +0 -0
  264. package/registry/examples/gauge/native/credits-quota.tsx +18 -0
  265. package/registry/examples/geo-map/viewers.d.ts +4 -0
  266. package/registry/examples/geo-map/viewers.js +43 -0
  267. package/registry/examples/geo-map/viewers.tsx +29 -0
  268. package/registry/examples/globe/deployment-regions.d.ts +4 -0
  269. package/registry/examples/globe/deployment-regions.js +36 -0
  270. package/registry/examples/globe/deployment-regions.tsx +30 -0
  271. package/registry/examples/goal-progress/challenge-pot.d.ts +4 -0
  272. package/registry/examples/goal-progress/challenge-pot.js +22 -0
  273. package/registry/examples/goal-progress/challenge-pot.tsx +16 -0
  274. package/registry/examples/goal-progress/goal-reached.d.ts +4 -0
  275. package/registry/examples/goal-progress/goal-reached.js +11 -0
  276. package/registry/examples/goal-progress/goal-reached.tsx +6 -0
  277. package/registry/examples/goal-progress/native/challenge-pot.d.ts +4 -0
  278. package/registry/examples/goal-progress/native/challenge-pot.dark.png +0 -0
  279. package/registry/examples/goal-progress/native/challenge-pot.js +11 -0
  280. package/registry/examples/goal-progress/native/challenge-pot.light.png +0 -0
  281. package/registry/examples/goal-progress/native/challenge-pot.tsx +6 -0
  282. package/registry/examples/heatmap/upload-activity.d.ts +4 -0
  283. package/registry/examples/heatmap/upload-activity.js +30 -0
  284. package/registry/examples/heatmap/upload-activity.tsx +25 -0
  285. package/registry/examples/job-throughput/live-hours.d.ts +4 -0
  286. package/registry/examples/job-throughput/live-hours.js +33 -0
  287. package/registry/examples/job-throughput/live-hours.tsx +28 -0
  288. package/registry/examples/job-throughput/native/week-of-jobs.d.ts +4 -0
  289. package/registry/examples/job-throughput/native/week-of-jobs.dark.png +0 -0
  290. package/registry/examples/job-throughput/native/week-of-jobs.js +20 -0
  291. package/registry/examples/job-throughput/native/week-of-jobs.light.png +0 -0
  292. package/registry/examples/job-throughput/native/week-of-jobs.tsx +16 -0
  293. package/registry/examples/job-throughput/week-of-jobs.d.ts +4 -0
  294. package/registry/examples/job-throughput/week-of-jobs.js +20 -0
  295. package/registry/examples/job-throughput/week-of-jobs.tsx +16 -0
  296. package/registry/examples/latency-chart/by-capability.d.ts +4 -0
  297. package/registry/examples/latency-chart/by-capability.js +26 -0
  298. package/registry/examples/latency-chart/by-capability.tsx +21 -0
  299. package/registry/examples/latency-chart/native/by-capability.d.ts +4 -0
  300. package/registry/examples/latency-chart/native/by-capability.dark.png +0 -0
  301. package/registry/examples/latency-chart/native/by-capability.js +17 -0
  302. package/registry/examples/latency-chart/native/by-capability.light.png +0 -0
  303. package/registry/examples/latency-chart/native/by-capability.tsx +13 -0
  304. package/registry/examples/latency-chart/time-to-result.d.ts +4 -0
  305. package/registry/examples/latency-chart/time-to-result.js +27 -0
  306. package/registry/examples/latency-chart/time-to-result.tsx +22 -0
  307. package/registry/examples/line-chart/creator-earnings.d.ts +4 -0
  308. package/registry/examples/line-chart/creator-earnings.js +35 -0
  309. package/registry/examples/line-chart/creator-earnings.tsx +30 -0
  310. package/registry/examples/line-chart/forecast.d.ts +4 -0
  311. package/registry/examples/line-chart/forecast.js +36 -0
  312. package/registry/examples/line-chart/forecast.tsx +30 -0
  313. package/registry/examples/line-chart/live-jobs.d.ts +4 -0
  314. package/registry/examples/line-chart/live-jobs.js +21 -0
  315. package/registry/examples/line-chart/live-jobs.tsx +23 -0
  316. package/registry/examples/line-chart/native/creator-earnings.d.ts +4 -0
  317. package/registry/examples/line-chart/native/creator-earnings.dark.png +0 -0
  318. package/registry/examples/line-chart/native/creator-earnings.js +32 -0
  319. package/registry/examples/line-chart/native/creator-earnings.light.png +0 -0
  320. package/registry/examples/line-chart/native/creator-earnings.tsx +26 -0
  321. package/registry/examples/line-chart/states.d.ts +4 -0
  322. package/registry/examples/line-chart/states.js +16 -0
  323. package/registry/examples/line-chart/states.tsx +13 -0
  324. package/registry/examples/pie-chart/credit-spend.d.ts +4 -0
  325. package/registry/examples/pie-chart/credit-spend.js +30 -0
  326. package/registry/examples/pie-chart/credit-spend.tsx +24 -0
  327. package/registry/examples/pie-chart/native/credit-spend.d.ts +4 -0
  328. package/registry/examples/pie-chart/native/credit-spend.dark.png +0 -0
  329. package/registry/examples/pie-chart/native/credit-spend.js +17 -0
  330. package/registry/examples/pie-chart/native/credit-spend.light.png +0 -0
  331. package/registry/examples/pie-chart/native/credit-spend.tsx +12 -0
  332. package/registry/examples/pie-chart/storage-by-kind.d.ts +4 -0
  333. package/registry/examples/pie-chart/storage-by-kind.js +31 -0
  334. package/registry/examples/pie-chart/storage-by-kind.tsx +26 -0
  335. package/registry/examples/price-ticker/auction-room.d.ts +4 -0
  336. package/registry/examples/price-ticker/auction-room.js +21 -0
  337. package/registry/examples/price-ticker/auction-room.tsx +17 -0
  338. package/registry/examples/price-ticker/native/auction-room.d.ts +4 -0
  339. package/registry/examples/price-ticker/native/auction-room.dark.png +0 -0
  340. package/registry/examples/price-ticker/native/auction-room.js +19 -0
  341. package/registry/examples/price-ticker/native/auction-room.light.png +0 -0
  342. package/registry/examples/price-ticker/native/auction-room.tsx +15 -0
  343. package/registry/examples/price-ticker/no-bid-yet.d.ts +4 -0
  344. package/registry/examples/price-ticker/no-bid-yet.js +11 -0
  345. package/registry/examples/price-ticker/no-bid-yet.tsx +6 -0
  346. package/registry/examples/radar-chart/model-comparison.d.ts +4 -0
  347. package/registry/examples/radar-chart/model-comparison.js +33 -0
  348. package/registry/examples/radar-chart/model-comparison.tsx +28 -0
  349. package/registry/examples/sankey/credit-flow.d.ts +4 -0
  350. package/registry/examples/sankey/credit-flow.js +37 -0
  351. package/registry/examples/sankey/credit-flow.tsx +32 -0
  352. package/registry/examples/scatter-chart/watch-time.d.ts +4 -0
  353. package/registry/examples/scatter-chart/watch-time.js +36 -0
  354. package/registry/examples/scatter-chart/watch-time.tsx +31 -0
  355. package/registry/examples/sparkline/bars.d.ts +4 -0
  356. package/registry/examples/sparkline/bars.js +12 -0
  357. package/registry/examples/sparkline/bars.tsx +7 -0
  358. package/registry/examples/sparkline/native/stat-trend.d.ts +4 -0
  359. package/registry/examples/sparkline/native/stat-trend.dark.png +0 -0
  360. package/registry/examples/sparkline/native/stat-trend.js +12 -0
  361. package/registry/examples/sparkline/native/stat-trend.light.png +0 -0
  362. package/registry/examples/sparkline/native/stat-trend.tsx +7 -0
  363. package/registry/examples/sparkline/stat-trend.d.ts +4 -0
  364. package/registry/examples/sparkline/stat-trend.js +18 -0
  365. package/registry/examples/sparkline/stat-trend.tsx +15 -0
  366. package/registry/examples/sparkline/table-rows.d.ts +4 -0
  367. package/registry/examples/sparkline/table-rows.js +23 -0
  368. package/registry/examples/sparkline/table-rows.tsx +26 -0
  369. package/registry/examples/treemap/storage.d.ts +4 -0
  370. package/registry/examples/treemap/storage.js +17 -0
  371. package/registry/examples/treemap/storage.tsx +13 -0
  372. package/registry/funnel.json +487 -0
  373. package/registry/gauge.json +600 -0
  374. package/registry/geo-map.json +484 -0
  375. package/registry/globe.json +469 -0
  376. package/registry/goal-progress.json +520 -0
  377. package/registry/heatmap.json +531 -0
  378. package/registry/index.json +582 -0
  379. package/registry/job-throughput.json +654 -0
  380. package/registry/latency-chart.json +671 -0
  381. package/registry/line-chart.json +793 -0
  382. package/registry/pie-chart.json +1288 -0
  383. package/registry/price-ticker.json +684 -0
  384. package/registry/radar-chart.json +459 -0
  385. package/registry/sankey.json +503 -0
  386. package/registry/scatter-chart.json +559 -0
  387. package/registry/sparkline.json +563 -0
  388. package/registry/treemap.json +432 -0
@@ -0,0 +1,186 @@
1
+ "use client";
2
+
3
+ // src/core/labels.ts
4
+ var DEFAULT_LABELS = {
5
+ showData: "Show data",
6
+ hideData: "Hide data",
7
+ tableCaption: "{title} \u2014 data",
8
+ exportPng: "PNG",
9
+ exportSvg: "SVG",
10
+ exportCsv: "CSV",
11
+ loading: "Loading chart\u2026",
12
+ empty: "No data for this period yet.",
13
+ error: "The chart could not be loaded.",
14
+ keyboardHint: "Use the arrow keys to move between points, Home and End to jump to the ends.",
15
+ roleDescription: "chart",
16
+ summaryIntro: "{kind}, {count}.",
17
+ summarySeries: "{label}: from {first} to {last}",
18
+ summaryRange: "lowest {min} ({minAt}), highest {max} ({maxAt})",
19
+ summaryTrendUp: "up {change}",
20
+ summaryTrendDown: "down {change}",
21
+ summaryTrendFlat: "stable",
22
+ summaryTotal: "total {total}",
23
+ summaryThreshold: "{label} at {value}",
24
+ summaryShare: "{label} {value} ({share})",
25
+ summaryCorrelation: "correlation {r}",
26
+ summaryConversion: "{from} \u2192 {to} {rate}",
27
+ summaryOverall: "overall {rate}",
28
+ summaryPeak: "peak {value} ({at})",
29
+ summaryActive: "{count} with a value",
30
+ summaryOhlc: "opened at {open}, closed at {close}, low {low}, high {high}",
31
+ kinds: {
32
+ line: "Line chart",
33
+ area: "Area chart",
34
+ bar: "Bar chart",
35
+ pie: "Pie chart",
36
+ donut: "Donut chart",
37
+ gauge: "Gauge",
38
+ sparkline: "Sparkline",
39
+ radar: "Radar chart",
40
+ heatmap: "Heatmap",
41
+ calendar: "Calendar heatmap",
42
+ sankey: "Flow diagram",
43
+ funnel: "Funnel",
44
+ candlestick: "Candlestick chart",
45
+ treemap: "Treemap",
46
+ scatter: "Scatter chart",
47
+ map: "Map",
48
+ globe: "Globe",
49
+ chart: "Chart"
50
+ },
51
+ category: "Category",
52
+ value: "Value",
53
+ total: "Total",
54
+ noValue: "\u2014"
55
+ };
56
+ function mergeLabels(...layers) {
57
+ let out = DEFAULT_LABELS;
58
+ for (const layer of layers) {
59
+ if (!layer) continue;
60
+ out = { ...out, ...layer, kinds: { ...out.kinds, ...layer.kinds } };
61
+ }
62
+ return out;
63
+ }
64
+ function capitalize(text) {
65
+ return text.charAt(0).toLocaleUpperCase() + text.slice(1);
66
+ }
67
+ function fill(template, values) {
68
+ return template.replace(/\{(\w+)\}/g, (match, name) => name in values ? String(values[name]) : match);
69
+ }
70
+
71
+ // src/web/context.tsx
72
+ import { createContext, useContext, useMemo } from "react";
73
+ import { jsx } from "react/jsx-runtime";
74
+ var DEFAULTS = { locale: "en-US", labels: mergeLabels() };
75
+ var Context = createContext(DEFAULTS);
76
+ function ChartsProvider({ locale, brand, labels, children }) {
77
+ const parent = useContext(Context);
78
+ const value = useMemo(() => {
79
+ const raw = labels ? { ...parent.raw, ...labels, kinds: { ...parent.raw?.kinds, ...labels.kinds } } : parent.raw;
80
+ return { locale: locale ?? parent.locale, brand: brand ?? parent.brand, labels: mergeLabels(raw), raw };
81
+ }, [locale, brand, labels, parent]);
82
+ return /* @__PURE__ */ jsx(Context.Provider, { value, children });
83
+ }
84
+ function useChartSettings(own) {
85
+ const shared = useContext(Context);
86
+ return useMemo(
87
+ () => ({ locale: own.locale ?? shared.locale, brand: own.brand ?? shared.brand, labels: own.labels ? mergeLabels(shared.raw, own.labels) : shared.labels }),
88
+ [own.locale, own.brand, own.labels, shared]
89
+ );
90
+ }
91
+
92
+ // src/core/palette.ts
93
+ var HUES = {
94
+ blue: { light: "#2a78d6", dark: "#3987e5" },
95
+ orange: { light: "#eb6834", dark: "#d95926" },
96
+ aqua: { light: "#1baf7a", dark: "#199e70" },
97
+ yellow: { light: "#eda100", dark: "#c98500" },
98
+ magenta: { light: "#e87ba4", dark: "#d55181" },
99
+ green: { light: "#008300", dark: "#008300" },
100
+ violet: { light: "#6250d6", dark: "#9085e9" },
101
+ red: { light: "#e34948", dark: "#e66767" }
102
+ };
103
+ var ORDERS = {
104
+ krizaka: ["blue", "green", "magenta", "yellow", "aqua", "orange", "violet", "red"],
105
+ orazaka: ["orange", "aqua", "blue", "yellow", "magenta", "green", "violet", "red"],
106
+ orochia: ["violet", "magenta", "yellow", "aqua", "orange", "blue", "green", "red"]
107
+ };
108
+ function palette(brand, mode) {
109
+ return ORDERS[brand].map((hue) => HUES[hue][mode]);
110
+ }
111
+ var DIVERGING = {
112
+ light: { low: HUES.blue.light, high: HUES.red.light },
113
+ dark: { low: HUES.blue.dark, high: HUES.red.dark }
114
+ };
115
+ function parseColor(color) {
116
+ const hex2 = color.trim().match(/^#([\da-f]{3}|[\da-f]{6})$/i);
117
+ if (hex2) {
118
+ const h = hex2[1].length === 3 ? [...hex2[1]].map((c) => c + c).join("") : hex2[1];
119
+ return [0, 2, 4].map((i) => Number.parseInt(h.slice(i, i + 2), 16));
120
+ }
121
+ const rgb = color.trim().match(/^rgba?\(\s*([\d.]+)[\s,]+([\d.]+)[\s,]+([\d.]+)/i);
122
+ if (rgb) return [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])];
123
+ return null;
124
+ }
125
+ var toLinear = (c) => {
126
+ const v = c / 255;
127
+ return v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
128
+ };
129
+ var fromLinear = (v) => {
130
+ const c = v <= 31308e-7 ? v * 12.92 : 1.055 * v ** (1 / 2.4) - 0.055;
131
+ return Math.round(Math.min(1, Math.max(0, c)) * 255);
132
+ };
133
+ function toOklab([r8, g8, b8]) {
134
+ const [r, g, b] = [toLinear(r8), toLinear(g8), toLinear(b8)];
135
+ const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
136
+ const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
137
+ const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
138
+ return [0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s, 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s, 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s];
139
+ }
140
+ function fromOklab([L, a, b]) {
141
+ const l = (L + 0.3963377774 * a + 0.2158037573 * b) ** 3;
142
+ const m = (L - 0.1055613458 * a - 0.0638541728 * b) ** 3;
143
+ const s = (L - 0.0894841775 * a - 1.291485548 * b) ** 3;
144
+ return [
145
+ fromLinear(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s),
146
+ fromLinear(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s),
147
+ fromLinear(-0.0041960863 * l - 0.7034186147 * m + 1.707614031 * s)
148
+ ];
149
+ }
150
+ var hex = ([r, g, b]) => `#${[r, g, b].map((c) => c.toString(16).padStart(2, "0")).join("")}`;
151
+ function mix(a, b, t) {
152
+ const ca = parseColor(a);
153
+ const cb = parseColor(b);
154
+ if (!ca || !cb) return b;
155
+ const la = toOklab(ca);
156
+ const lb = toOklab(cb);
157
+ return hex(fromOklab([0, 1, 2].map((i) => la[i] + (lb[i] - la[i]) * t)));
158
+ }
159
+ function sequential(hue, surface, steps = 5) {
160
+ return Array.from({ length: steps }, (_, i) => mix(surface, hue, 0.22 + 0.78 * i / Math.max(1, steps - 1)));
161
+ }
162
+ function contrast(a, b) {
163
+ const lum = (c) => {
164
+ const rgb = parseColor(c);
165
+ if (!rgb) return 0;
166
+ const [r, g, bl] = rgb.map(toLinear);
167
+ return 0.2126 * r + 0.7152 * g + 0.0722 * bl;
168
+ };
169
+ const [hi, lo] = [lum(a), lum(b)].sort((x, y) => y - x);
170
+ return (hi + 0.05) / (lo + 0.05);
171
+ }
172
+
173
+ export {
174
+ DEFAULT_LABELS,
175
+ capitalize,
176
+ fill,
177
+ ChartsProvider,
178
+ useChartSettings,
179
+ HUES,
180
+ ORDERS,
181
+ palette,
182
+ DIVERGING,
183
+ sequential,
184
+ contrast
185
+ };
186
+ //# sourceMappingURL=chunk-3CJHBJXA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/labels.ts","../src/web/context.tsx","../src/core/palette.ts"],"sourcesContent":["// The words a chart says on its own: its controls, its states and its written summary. English by default; an app\n// passes its own (translated through its catalogue) once, to `ChartsProvider labels`, or to one chart's `labels`.\n// Placeholders are written `{name}`.\n\nexport interface ChartLabels {\n /** The button that shows the data table. */\n showData: string;\n /** The button that hides it. */\n hideData: string;\n /** The caption of the data table: `{title}`. */\n tableCaption: string;\n /** The export buttons. */\n exportPng: string;\n exportSvg: string;\n exportCsv: string;\n /** Announced while the data loads. */\n loading: string;\n /** Shown when there is nothing to draw. */\n empty: string;\n /** Shown when the data could not be loaded. */\n error: string;\n /** The keyboard hint, read once when the plot takes the focus. */\n keyboardHint: string;\n /** The role description of the plot (`chart`). */\n roleDescription: string;\n /** Summary pieces. `{kind}` is the chart's name (`Line chart`), `{count}` a number of points or series. */\n summaryIntro: string;\n summarySeries: string;\n summaryRange: string;\n summaryTrendUp: string;\n summaryTrendDown: string;\n summaryTrendFlat: string;\n summaryTotal: string;\n summaryThreshold: string;\n summaryShare: string;\n /** Scatter: the correlation of x and y (Pearson's r). */\n summaryCorrelation: string;\n /** Funnel: from one stage to the next, and from the first to the last. */\n summaryConversion: string;\n summaryOverall: string;\n /** Heatmap, calendar: the largest cell and the number of cells with a value. */\n summaryPeak: string;\n summaryActive: string;\n /** Candlestick: the period's range. */\n summaryOhlc: string;\n /** The names of the charts, read first in the summary. */\n kinds: Record<ChartKind, string>;\n /** The column of the values, when the chart has no value label. */\n value: string;\n /** The column of the categories in the data table, when the chart has no x label. */\n category: string;\n /** The total row of a stacked chart, a pie, a funnel. */\n total: string;\n /** What a missing value reads as. */\n noValue: string;\n}\n\nexport type ChartKind =\n | \"line\"\n | \"area\"\n | \"bar\"\n | \"pie\"\n | \"donut\"\n | \"gauge\"\n | \"sparkline\"\n | \"radar\"\n | \"heatmap\"\n | \"calendar\"\n | \"sankey\"\n | \"funnel\"\n | \"candlestick\"\n | \"treemap\"\n | \"scatter\"\n | \"map\"\n | \"globe\"\n | \"chart\";\n\nexport const DEFAULT_LABELS: ChartLabels = {\n showData: \"Show data\",\n hideData: \"Hide data\",\n tableCaption: \"{title} — data\",\n exportPng: \"PNG\",\n exportSvg: \"SVG\",\n exportCsv: \"CSV\",\n loading: \"Loading chart…\",\n empty: \"No data for this period yet.\",\n error: \"The chart could not be loaded.\",\n keyboardHint: \"Use the arrow keys to move between points, Home and End to jump to the ends.\",\n roleDescription: \"chart\",\n summaryIntro: \"{kind}, {count}.\",\n summarySeries: \"{label}: from {first} to {last}\",\n summaryRange: \"lowest {min} ({minAt}), highest {max} ({maxAt})\",\n summaryTrendUp: \"up {change}\",\n summaryTrendDown: \"down {change}\",\n summaryTrendFlat: \"stable\",\n summaryTotal: \"total {total}\",\n summaryThreshold: \"{label} at {value}\",\n summaryShare: \"{label} {value} ({share})\",\n summaryCorrelation: \"correlation {r}\",\n summaryConversion: \"{from} → {to} {rate}\",\n summaryOverall: \"overall {rate}\",\n summaryPeak: \"peak {value} ({at})\",\n summaryActive: \"{count} with a value\",\n summaryOhlc: \"opened at {open}, closed at {close}, low {low}, high {high}\",\n kinds: {\n line: \"Line chart\",\n area: \"Area chart\",\n bar: \"Bar chart\",\n pie: \"Pie chart\",\n donut: \"Donut chart\",\n gauge: \"Gauge\",\n sparkline: \"Sparkline\",\n radar: \"Radar chart\",\n heatmap: \"Heatmap\",\n calendar: \"Calendar heatmap\",\n sankey: \"Flow diagram\",\n funnel: \"Funnel\",\n candlestick: \"Candlestick chart\",\n treemap: \"Treemap\",\n scatter: \"Scatter chart\",\n map: \"Map\",\n globe: \"Globe\",\n chart: \"Chart\",\n },\n category: \"Category\",\n value: \"Value\",\n total: \"Total\",\n noValue: \"—\",\n};\n\n/** The words an app or a chart passes: any of them, and any of the chart names. */\nexport type ChartLabelsInput = Partial<Omit<ChartLabels, \"kinds\">> & { kinds?: Partial<Record<ChartKind, string>> };\n\n/** The default labels with an app's and a chart's on top (`kinds` merged too). */\nexport function mergeLabels(...layers: (ChartLabelsInput | undefined)[]): ChartLabels {\n let out = DEFAULT_LABELS;\n for (const layer of layers) {\n if (!layer) continue;\n out = { ...out, ...layer, kinds: { ...out.kinds, ...layer.kinds } };\n }\n return out;\n}\n\n/** A sentence's first letter in upper case (a template that may open a sentence: `total {total}`). */\nexport function capitalize(text: string): string {\n return text.charAt(0).toLocaleUpperCase() + text.slice(1);\n}\n\n/** `{name}` → its value; an unknown placeholder stays as written. */\nexport function fill(template: string, values: Record<string, string | number>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) => (name in values ? String(values[name]) : match));\n}\n","\"use client\";\n// One place for what every chart of an app shares: the locale its figures are written in, the brand its palette\n// leads with, and the words it says (translated once, from the app's catalogue). Each chart may still override them.\nimport { createContext, type ReactNode, useContext, useMemo } from \"react\";\n\nimport { type ChartLabels, type ChartLabelsInput, mergeLabels } from \"../core/labels\";\nimport type { BrandId, Locale } from \"../core/types\";\n\nexport interface ChartsSettings {\n /** The locale of every figure and date (`\"fr-FR\"`). Default `\"en-US\"`. */\n locale?: Locale;\n /**\n * The brand whose palette the charts use. Without it, a chart follows a `.brand-<id>` ancestor, else Krizaka. Set it\n * when the app loads a brand stylesheet on `:root` (`@krizaka/tokens/brands/orazaka.css`).\n */\n brand?: BrandId;\n /** The words, translated: the buttons, the states, the written summary. */\n labels?: ChartLabelsInput;\n}\n\ninterface ResolvedSettings {\n readonly locale: Locale;\n readonly brand?: BrandId;\n readonly labels: ChartLabels;\n readonly raw?: ChartLabelsInput;\n}\n\nconst DEFAULTS: ResolvedSettings = { locale: \"en-US\", labels: mergeLabels() };\nconst Context = createContext<ResolvedSettings>(DEFAULTS);\n\nexport interface ChartsProviderProps extends ChartsSettings {\n children: ReactNode;\n}\n\n/** Sets the locale, the brand and the words of every chart below it. */\nexport function ChartsProvider({ locale, brand, labels, children }: ChartsProviderProps) {\n const parent = useContext(Context);\n const value = useMemo<ResolvedSettings>(() => {\n const raw: ChartLabelsInput | undefined = labels ? { ...parent.raw, ...labels, kinds: { ...parent.raw?.kinds, ...labels.kinds } } : parent.raw;\n return { locale: locale ?? parent.locale, brand: brand ?? parent.brand, labels: mergeLabels(raw), raw };\n }, [locale, brand, labels, parent]);\n return <Context.Provider value={value}>{children}</Context.Provider>;\n}\n\n/** The settings of a chart: its own props over the provider's over the defaults. */\nexport function useChartSettings(own: ChartsSettings): { locale: Locale; brand?: BrandId; labels: ChartLabels } {\n const shared = useContext(Context);\n return useMemo(\n () => ({ locale: own.locale ?? shared.locale, brand: own.brand ?? shared.brand, labels: own.labels ? mergeLabels(shared.raw, own.labels) : shared.labels }),\n [own.locale, own.brand, own.labels, shared],\n );\n}\n","// The data palettes. One categorical set of eight hues, stepped for each theme (the dark steps are chosen for the\n// dark surface, not flipped), ordered per brand so that the first series wears the brand's own hue — Krizaka blue,\n// Orazaka orange, Orochia violet then magenta, its gradient. Every order was chosen among the ones that pass the\n// colour-vision checks (scripts/palette.test: lightness band, chroma floor, adjacent ΔE under protan/deutan ≥ 8 —\n// Orochia light 7.2, inside the 6–8 band that requires the secondary encoding every chart carries: legend, direct\n// labels, data table —, normal-vision ΔE ≥ 15, ≥ 3:1 on the surface, the first three slots distinct all-pairs).\n// A 9th series never gets a generated hue: it folds into “Other” or a second chart.\nimport type { BrandId } from \"./types\";\n\nexport type Mode = \"dark\" | \"light\";\n\n/** The eight hues, light and dark steps. */\nexport const HUES = {\n blue: { light: \"#2a78d6\", dark: \"#3987e5\" },\n orange: { light: \"#eb6834\", dark: \"#d95926\" },\n aqua: { light: \"#1baf7a\", dark: \"#199e70\" },\n yellow: { light: \"#eda100\", dark: \"#c98500\" },\n magenta: { light: \"#e87ba4\", dark: \"#d55181\" },\n green: { light: \"#008300\", dark: \"#008300\" },\n violet: { light: \"#6250d6\", dark: \"#9085e9\" },\n red: { light: \"#e34948\", dark: \"#e66767\" },\n} as const;\n\nexport type Hue = keyof typeof HUES;\n\n/** The order of the hues for each brand: slot 1 is the brand. */\nexport const ORDERS: Record<BrandId, readonly Hue[]> = {\n krizaka: [\"blue\", \"green\", \"magenta\", \"yellow\", \"aqua\", \"orange\", \"violet\", \"red\"],\n orazaka: [\"orange\", \"aqua\", \"blue\", \"yellow\", \"magenta\", \"green\", \"violet\", \"red\"],\n orochia: [\"violet\", \"magenta\", \"yellow\", \"aqua\", \"orange\", \"blue\", \"green\", \"red\"],\n};\n\n/** The categorical palette of a brand in a theme: eight hex colours, slot 1 first. */\nexport function palette(brand: BrandId, mode: Mode): string[] {\n return ORDERS[brand].map((hue) => HUES[hue][mode]);\n}\n\n/** The diverging poles (below / above the midpoint): blue ↔ red, a neutral grey between them. */\nexport const DIVERGING = {\n light: { low: HUES.blue.light, high: HUES.red.light },\n dark: { low: HUES.blue.dark, high: HUES.red.dark },\n} as const;\n\n// --- Colour arithmetic (OKLab), for the sequential ramps the canvas engine needs as plain colours. ---------------\n\ntype Rgb = [number, number, number];\n\n/** `#rrggbb`, `#rgb`, `rgb(r, g, b)` / `rgba(…)` or `rgb(r g b / a)` → [r, g, b] in 0–255; null otherwise. */\nexport function parseColor(color: string): Rgb | null {\n const hex = color.trim().match(/^#([\\da-f]{3}|[\\da-f]{6})$/i);\n if (hex) {\n const h = hex[1]!.length === 3 ? [...hex[1]!].map((c) => c + c).join(\"\") : hex[1]!;\n return [0, 2, 4].map((i) => Number.parseInt(h.slice(i, i + 2), 16)) as Rgb;\n }\n const rgb = color.trim().match(/^rgba?\\(\\s*([\\d.]+)[\\s,]+([\\d.]+)[\\s,]+([\\d.]+)/i);\n if (rgb) return [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])];\n return null;\n}\n\nconst toLinear = (c: number) => {\n const v = c / 255;\n return v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;\n};\nconst fromLinear = (v: number) => {\n const c = v <= 0.0031308 ? v * 12.92 : 1.055 * v ** (1 / 2.4) - 0.055;\n return Math.round(Math.min(1, Math.max(0, c)) * 255);\n};\n\nfunction toOklab([r8, g8, b8]: Rgb): Rgb {\n const [r, g, b] = [toLinear(r8), toLinear(g8), toLinear(b8)];\n const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);\n const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);\n const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);\n return [0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s, 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s, 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s];\n}\n\nfunction fromOklab([L, a, b]: Rgb): Rgb {\n const l = (L + 0.3963377774 * a + 0.2158037573 * b) ** 3;\n const m = (L - 0.1055613458 * a - 0.0638541728 * b) ** 3;\n const s = (L - 0.0894841775 * a - 1.291485548 * b) ** 3;\n return [\n fromLinear(4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s),\n fromLinear(-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s),\n fromLinear(-0.0041960863 * l - 0.7034186147 * m + 1.707614031 * s),\n ];\n}\n\nconst hex = ([r, g, b]: Rgb) => `#${[r, g, b].map((c) => c.toString(16).padStart(2, \"0\")).join(\"\")}`;\n\n/** `a` → `b` at `t` (0–1), interpolated in OKLab (even steps to the eye). Unparseable colours return `b`. */\nexport function mix(a: string, b: string, t: number): string {\n const ca = parseColor(a);\n const cb = parseColor(b);\n if (!ca || !cb) return b;\n const la = toOklab(ca);\n const lb = toOklab(cb);\n return hex(fromOklab([0, 1, 2].map((i) => la[i]! + (lb[i]! - la[i]!) * t) as Rgb));\n}\n\n/**\n * A sequential ramp of `steps` colours, one hue from near the surface (`0`, “almost nothing”) to the full hue: the\n * magnitude of a heatmap, a calendar or a choropleth. The first step is still distinct from the surface.\n */\nexport function sequential(hue: string, surface: string, steps = 5): string[] {\n return Array.from({ length: steps }, (_, i) => mix(surface, hue, 0.22 + (0.78 * i) / Math.max(1, steps - 1)));\n}\n\n/** WCAG contrast ratio between two colours (for the tests and the labels drawn inside a mark). */\nexport function contrast(a: string, b: string): number {\n const lum = (c: string) => {\n const rgb = parseColor(c);\n if (!rgb) return 0;\n const [r, g, bl] = rgb.map(toLinear) as Rgb;\n return 0.2126 * r + 0.7152 * g + 0.0722 * bl;\n };\n const [hi, lo] = [lum(a), lum(b)].sort((x, y) => y - x) as [number, number];\n return (hi + 0.05) / (lo + 0.05);\n}\n"],"mappings":"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","names":["hex"]}
@@ -0,0 +1,133 @@
1
+ "use client";
2
+ import {
3
+ EChartHost,
4
+ baseOption,
5
+ tooltipHtml,
6
+ valueAxis
7
+ } from "./chunk-PWMMXRMC.js";
8
+ import {
9
+ read
10
+ } from "./chunk-W5FX4TU3.js";
11
+ import {
12
+ valueFormatter
13
+ } from "./chunk-XLLYNNC6.js";
14
+ import {
15
+ Legend,
16
+ useSettings
17
+ } from "./chunk-JTKR7ZWP.js";
18
+ import {
19
+ fill
20
+ } from "./chunk-3CJHBJXA.js";
21
+
22
+ // src/scatter/scatter-chart.tsx
23
+ import { formatNumber } from "@krizaka/intl";
24
+ import { useCallback, useMemo } from "react";
25
+ import { jsx } from "react/jsx-runtime";
26
+ var engine = () => import("./scatter-XSNG4OKD.js");
27
+ function correlation(points) {
28
+ const n = points.length;
29
+ if (n < 3) return null;
30
+ const mx = points.reduce((s, p) => s + p.x, 0) / n;
31
+ const my = points.reduce((s, p) => s + p.y, 0) / n;
32
+ let sxy = 0;
33
+ let sxx = 0;
34
+ let syy = 0;
35
+ for (const p of points) {
36
+ sxy += (p.x - mx) * (p.y - my);
37
+ sxx += (p.x - mx) ** 2;
38
+ syy += (p.y - my) ** 2;
39
+ }
40
+ return sxx && syy ? sxy / Math.sqrt(sxx * syy) : null;
41
+ }
42
+ function ScatterChart(props) {
43
+ const { data, x, y, size, group, name, xFormat, yFormat, sizeFormat, xLabel, yLabel, sizeLabel, thresholds = [] } = props;
44
+ const { locale, labels } = useSettings(props);
45
+ const fmt = useMemo(
46
+ () => ({
47
+ x: valueFormatter(xFormat, locale, labels.noValue),
48
+ xAxis: valueFormatter(xFormat, locale, labels.noValue, true),
49
+ y: valueFormatter(yFormat, locale, labels.noValue),
50
+ yAxis: valueFormatter(yFormat, locale, labels.noValue, true),
51
+ size: valueFormatter(sizeFormat, locale, labels.noValue)
52
+ }),
53
+ [xFormat, yFormat, sizeFormat, locale, labels.noValue]
54
+ );
55
+ const points = useMemo(
56
+ () => data.map((d, i) => ({ x: Number(read(x, d, i)), y: Number(read(y, d, i)), s: size ? Number(read(size, d, i)) : null, g: group ? String(read(group, d, i)) : "", n: name ? String(read(name, d, i)) : "" })).filter((p) => Number.isFinite(p.x) && Number.isFinite(p.y)),
57
+ [data, x, y, size, group, name]
58
+ );
59
+ const groups = useMemo(() => [...new Set(points.map((p) => p.g))], [points]);
60
+ const isEmpty = points.length === 0;
61
+ const r = correlation(points);
62
+ const range = (values, write) => `${write(Math.min(...values))} \u2013 ${write(Math.max(...values))}`;
63
+ const summary = isEmpty ? labels.empty : [
64
+ fill(labels.summaryIntro, { kind: labels.kinds.scatter, count: points.length }),
65
+ `${xLabel}: ${range(points.map((p) => p.x), fmt.x)}; ${yLabel}: ${range(points.map((p) => p.y), fmt.y)}${r === null ? "" : `; ${fill(labels.summaryCorrelation, { r: formatNumber(r, { locale, maximumFractionDigits: 2, minimumFractionDigits: 2 }) })}`}.`
66
+ ].join(" ");
67
+ const bySeries = useMemo(() => groups.map((g) => points.filter((p) => p.g === g)), [groups, points]);
68
+ const items = bySeries.flatMap(
69
+ (list, s) => list.map((p, i) => ({ seriesIndex: s, dataIndex: i, text: `${p.n || p.g}${p.n || p.g ? ": " : ""}${xLabel} ${fmt.x(p.x)}, ${yLabel} ${fmt.y(p.y)}${p.s != null && sizeLabel ? `, ${sizeLabel} ${fmt.size(p.s)}` : ""}` }))
70
+ );
71
+ const maxSize = Math.max(0, ...points.map((p) => p.s ?? 0));
72
+ const build = useCallback(
73
+ (theme) => {
74
+ const base = baseOption(theme, true);
75
+ return {
76
+ ...base,
77
+ tooltip: {
78
+ ...base.tooltip,
79
+ trigger: "item",
80
+ formatter: (p) => {
81
+ const point = bySeries[p.seriesIndex][p.dataIndex];
82
+ return tooltipHtml(point.n || point.g || void 0, [
83
+ { label: xLabel, value: fmt.x(point.x), color: theme.palette[p.seriesIndex % 8] },
84
+ { label: yLabel, value: fmt.y(point.y) },
85
+ ...point.s != null && sizeLabel ? [{ label: sizeLabel, value: fmt.size(point.s) }] : []
86
+ ]);
87
+ }
88
+ },
89
+ grid: { left: 8, right: 16, top: 16, bottom: 28, containLabel: true },
90
+ xAxis: { ...valueAxis(theme, (v) => fmt.xAxis(v)), scale: true, name: xLabel, nameLocation: "middle", nameGap: 26, nameTextStyle: { color: theme.text2 } },
91
+ yAxis: { ...valueAxis(theme, (v) => fmt.yAxis(v)), scale: true },
92
+ series: bySeries.map((list, s) => ({
93
+ type: "scatter",
94
+ name: groups[s],
95
+ data: list.map((p) => [p.x, p.y, p.s ?? 0]),
96
+ symbolSize: (value) => size && maxSize ? 6 + Math.sqrt((value[2] ?? 0) / maxSize) * 30 : 9,
97
+ itemStyle: { color: theme.palette[s % 8], opacity: size ? 0.7 : 0.9, borderColor: theme.surface, borderWidth: 1.5 },
98
+ emphasis: { itemStyle: { opacity: 1, borderColor: theme.text, borderWidth: 2 } },
99
+ markLine: s === 0 && thresholds.length ? {
100
+ symbol: "none",
101
+ silent: true,
102
+ data: thresholds.map((t) => ({ yAxis: t.value, label: { formatter: fill(labels.summaryThreshold, { label: t.label, value: fmt.y(t.value) }), color: theme.text, position: "insideEndTop", fontWeight: 600 }, lineStyle: { color: theme.text2, type: [6, 4], width: 1.5 } }))
103
+ } : void 0
104
+ }))
105
+ };
106
+ },
107
+ [bySeries, groups, fmt, xLabel, yLabel, sizeLabel, size, maxSize, thresholds, labels.summaryThreshold]
108
+ );
109
+ return /* @__PURE__ */ jsx(
110
+ EChartHost,
111
+ {
112
+ kind: "scatter",
113
+ frame: props,
114
+ defaultHeight: 320,
115
+ table: {
116
+ columns: [labels.category, xLabel, yLabel, ...size ? [sizeLabel ?? labels.value] : []],
117
+ rows: points.map((p, i) => [p.n || p.g || String(i + 1), fmt.x(p.x), fmt.y(p.y), ...size ? [fmt.size(p.s)] : []])
118
+ },
119
+ summary,
120
+ isEmpty,
121
+ legend: group ? /* @__PURE__ */ jsx(Legend, { items: groups.map((g, i) => ({ label: g, color: `var(--kzc-${i % 8 + 1})` })) }) : null,
122
+ engine,
123
+ build,
124
+ items
125
+ }
126
+ );
127
+ }
128
+
129
+ export {
130
+ correlation,
131
+ ScatterChart
132
+ };
133
+ //# sourceMappingURL=chunk-4LBXEAGC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/scatter/scatter-chart.tsx"],"sourcesContent":["\"use client\";\n// The relation between two measures — a video's length against its watch time, a job's input size against its\n// duration — a bubble's area for a third, a colour per group. The summary says what the eye looks for: the ranges and\n// the correlation (Pearson's r). The canvas renderer takes tens of thousands of points. ECharts, loaded when the chart\n// nears the screen.\nimport { formatNumber } from \"@krizaka/intl\";\nimport { useCallback, useMemo } from \"react\";\n\nimport { read } from \"../core/data\";\nimport { valueFormatter } from \"../core/format\";\nimport { fill } from \"../core/labels\";\nimport type { Accessor, Datum, Threshold, ValueFormat } from \"../core/types\";\nimport { EChartHost, type EngineProps, type WalkItem } from \"../echarts/host\";\nimport { baseOption, type ResolvedTheme, tooltipHtml, valueAxis } from \"../echarts/theme\";\nimport type { ChartFrameProps } from \"../web/frame\";\nimport { useSettings } from \"../web/frame\";\nimport { Legend } from \"../web/parts\";\n\nconst engine = () => import(\"../echarts/engines/scatter\");\n\nexport interface ScatterChartProps<T extends Datum> extends ChartFrameProps, EngineProps {\n /** One row per point. */\n data: readonly T[];\n /** The fields of the two measures. */\n x: Accessor<T, number>;\n/** The field of the vertical measure. */\n y: Accessor<T, number>;\n /** A third measure, drawn as the bubble's area. */\n size?: Accessor<T, number>;\n /** The field of a point's group: one colour per group (three at most read apart for everyone). */\n group?: Accessor<T, string>;\n /** The field naming a point (the tooltip's title). */\n name?: Accessor<T, string>;\n /** How each measure is written. */\n xFormat?: ValueFormat;\n/** How the vertical measure is written. */\n yFormat?: ValueFormat;\n/** How the third measure (the bubbles) is written. */\n sizeFormat?: ValueFormat;\n /** The names of the measures: the axes, the tooltip, the table. */\n xLabel: string;\n/** The name of the vertical measure. */\n yLabel: string;\n/** The name of the third measure. */\n sizeLabel?: string;\n /** Horizontal lines at a y value. */\n thresholds?: readonly Threshold[];\n}\n\n/** Pearson's correlation coefficient, or null under three points or without variance. */\nexport function correlation(points: readonly { x: number; y: number }[]): number | null {\n const n = points.length;\n if (n < 3) return null;\n const mx = points.reduce((s, p) => s + p.x, 0) / n;\n const my = points.reduce((s, p) => s + p.y, 0) / n;\n let sxy = 0;\n let sxx = 0;\n let syy = 0;\n for (const p of points) {\n sxy += (p.x - mx) * (p.y - my);\n sxx += (p.x - mx) ** 2;\n syy += (p.y - my) ** 2;\n }\n return sxx && syy ? sxy / Math.sqrt(sxx * syy) : null;\n}\n\nexport function ScatterChart<T extends Datum>(props: ScatterChartProps<T>) {\n const { data, x, y, size, group, name, xFormat, yFormat, sizeFormat, xLabel, yLabel, sizeLabel, thresholds = [] } = props;\n const { locale, labels } = useSettings(props);\n const fmt = useMemo(\n () => ({\n x: valueFormatter(xFormat, locale, labels.noValue),\n xAxis: valueFormatter(xFormat, locale, labels.noValue, true),\n y: valueFormatter(yFormat, locale, labels.noValue),\n yAxis: valueFormatter(yFormat, locale, labels.noValue, true),\n size: valueFormatter(sizeFormat, locale, labels.noValue),\n }),\n [xFormat, yFormat, sizeFormat, locale, labels.noValue],\n );\n const points = useMemo(\n () =>\n data\n .map((d, i) => ({ x: Number(read(x, d, i)), y: Number(read(y, d, i)), s: size ? Number(read(size, d, i)) : null, g: group ? String(read(group, d, i)) : \"\", n: name ? String(read(name, d, i)) : \"\" }))\n .filter((p) => Number.isFinite(p.x) && Number.isFinite(p.y)),\n [data, x, y, size, group, name],\n );\n const groups = useMemo(() => [...new Set(points.map((p) => p.g))], [points]);\n const isEmpty = points.length === 0;\n const r = correlation(points);\n const range = (values: number[], write: (v: number) => string) => `${write(Math.min(...values))} – ${write(Math.max(...values))}`;\n const summary = isEmpty\n ? labels.empty\n : [\n fill(labels.summaryIntro, { kind: labels.kinds.scatter, count: points.length }),\n `${xLabel}: ${range(points.map((p) => p.x), fmt.x)}; ${yLabel}: ${range(points.map((p) => p.y), fmt.y)}${r === null ? \"\" : `; ${fill(labels.summaryCorrelation, { r: formatNumber(r, { locale, maximumFractionDigits: 2, minimumFractionDigits: 2 }) })}`}.`,\n ].join(\" \");\n const bySeries = useMemo(() => groups.map((g) => points.filter((p) => p.g === g)), [groups, points]);\n const items: WalkItem[] = bySeries.flatMap((list, s) =>\n list.map((p, i) => ({ seriesIndex: s, dataIndex: i, text: `${p.n || p.g}${p.n || p.g ? \": \" : \"\"}${xLabel} ${fmt.x(p.x)}, ${yLabel} ${fmt.y(p.y)}${p.s != null && sizeLabel ? `, ${sizeLabel} ${fmt.size(p.s)}` : \"\"}` })),\n );\n const maxSize = Math.max(0, ...points.map((p) => p.s ?? 0));\n\n const build = useCallback(\n (theme: ResolvedTheme) => {\n const base = baseOption(theme, true);\n return {\n ...base,\n tooltip: {\n ...(base.tooltip as object),\n trigger: \"item\",\n formatter: (p: { seriesIndex: number; dataIndex: number }) => {\n const point = bySeries[p.seriesIndex]![p.dataIndex]!;\n return tooltipHtml(point.n || point.g || undefined, [\n { label: xLabel, value: fmt.x(point.x), color: theme.palette[p.seriesIndex % 8] },\n { label: yLabel, value: fmt.y(point.y) },\n ...(point.s != null && sizeLabel ? [{ label: sizeLabel, value: fmt.size(point.s) }] : []),\n ]);\n },\n },\n grid: { left: 8, right: 16, top: 16, bottom: 28, containLabel: true },\n xAxis: { ...valueAxis(theme, (v: number) => fmt.xAxis(v)), scale: true, name: xLabel, nameLocation: \"middle\", nameGap: 26, nameTextStyle: { color: theme.text2 } },\n yAxis: { ...valueAxis(theme, (v: number) => fmt.yAxis(v)), scale: true },\n series: bySeries.map((list, s) => ({\n type: \"scatter\",\n name: groups[s],\n data: list.map((p) => [p.x, p.y, p.s ?? 0]),\n symbolSize: (value: number[]) => (size && maxSize ? 6 + Math.sqrt((value[2] ?? 0) / maxSize) * 30 : 9),\n itemStyle: { color: theme.palette[s % 8], opacity: size ? 0.7 : 0.9, borderColor: theme.surface, borderWidth: 1.5 },\n emphasis: { itemStyle: { opacity: 1, borderColor: theme.text, borderWidth: 2 } },\n markLine:\n s === 0 && thresholds.length\n ? {\n symbol: \"none\",\n silent: true,\n data: thresholds.map((t) => ({ yAxis: t.value, label: { formatter: fill(labels.summaryThreshold, { label: t.label, value: fmt.y(t.value) }), color: theme.text, position: \"insideEndTop\", fontWeight: 600 }, lineStyle: { color: theme.text2, type: [6, 4], width: 1.5 } })),\n }\n : undefined,\n })),\n };\n },\n [bySeries, groups, fmt, xLabel, yLabel, sizeLabel, size, maxSize, thresholds, labels.summaryThreshold],\n );\n\n return (\n <EChartHost\n kind=\"scatter\"\n frame={props}\n defaultHeight={320}\n table={{\n columns: [labels.category, xLabel, yLabel, ...(size ? [sizeLabel ?? labels.value] : [])],\n rows: points.map((p, i) => [p.n || p.g || String(i + 1), fmt.x(p.x), fmt.y(p.y), ...(size ? [fmt.size(p.s)] : [])]),\n }}\n summary={summary}\n isEmpty={isEmpty}\n legend={group ? <Legend items={groups.map((g, i) => ({ label: g, color: `var(--kzc-${(i % 8) + 1})` }))} /> : null}\n engine={engine}\n build={build}\n items={items}\n />\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,49 @@
1
+ "use client";
2
+
3
+ // src/geo/world.ts
4
+ import { useEffect, useState } from "react";
5
+ import { feature } from "topojson-client";
6
+ var world = null;
7
+ function loadWorld() {
8
+ world ??= import("./world-110m-DVFWXS42.js").then((module) => {
9
+ const topology = module.default ?? module;
10
+ return feature(topology, topology.objects.countries);
11
+ });
12
+ return world;
13
+ }
14
+ function useWorld(enabled) {
15
+ const [state, setState] = useState({ world: null, failed: false });
16
+ useEffect(() => {
17
+ if (!enabled) return void 0;
18
+ let alive = true;
19
+ loadWorld().then(
20
+ (w) => alive && setState({ world: w, failed: false }),
21
+ () => alive && setState({ world: null, failed: true })
22
+ );
23
+ return () => {
24
+ alive = false;
25
+ };
26
+ }, [enabled]);
27
+ return state;
28
+ }
29
+ var displayNames = /* @__PURE__ */ new Map();
30
+ function regionName(code, fallback, locale) {
31
+ if (!code) return fallback;
32
+ try {
33
+ const key = String(locale);
34
+ let names = displayNames.get(key);
35
+ if (!names) {
36
+ names = new Intl.DisplayNames(locale, { type: "region" });
37
+ displayNames.set(key, names);
38
+ }
39
+ return names.of(code) ?? fallback;
40
+ } catch {
41
+ return fallback;
42
+ }
43
+ }
44
+
45
+ export {
46
+ useWorld,
47
+ regionName
48
+ };
49
+ //# sourceMappingURL=chunk-6FINSUOS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/geo/world.ts"],"sourcesContent":["\"use client\";\n// The world the maps draw: Natural Earth 1:110m countries (public domain) through world-atlas, keyed by ISO 3166-1\n// alpha-2 (scripts/world.mjs). ~38 kB gzipped, loaded on demand — only by GeoMap and Globe3D, once per page.\nimport type { Feature, FeatureCollection, Geometry } from \"geojson\";\nimport { useEffect, useState } from \"react\";\nimport { feature } from \"topojson-client\";\nimport type { GeometryCollection, Topology } from \"topojson-specification\";\n\nexport type Country = Omit<Feature<Geometry, { name: string }>, \"id\"> & { id?: string };\nexport type World = Omit<FeatureCollection<Geometry, { name: string }>, \"features\"> & { features: Country[] };\n\nlet world: Promise<World> | null = null;\n\n/** The countries, decoded once (a lazy chunk of the package). */\nexport function loadWorld(): Promise<World> {\n world ??= import(\"./world-110m.json\").then((module) => {\n const topology = (module.default ?? module) as unknown as Topology<{ countries: GeometryCollection<{ name: string }> }>;\n return feature(topology, topology.objects.countries) as unknown as World;\n });\n return world;\n}\n\n/** The world once loaded (null before, or when `enabled` is false); an error leaves it null and says so. */\nexport function useWorld(enabled: boolean): { world: World | null; failed: boolean } {\n const [state, setState] = useState<{ world: World | null; failed: boolean }>({ world: null, failed: false });\n useEffect(() => {\n if (!enabled) return undefined;\n let alive = true;\n loadWorld().then(\n (w) => alive && setState({ world: w, failed: false }),\n () => alive && setState({ world: null, failed: true }),\n );\n return () => {\n alive = false;\n };\n }, [enabled]);\n return state;\n}\n\nconst displayNames = new Map<string, Intl.DisplayNames>();\n\n/** A region's name in the reader's language (`Intl.DisplayNames`), else Natural Earth's English one. */\nexport function regionName(code: string | undefined, fallback: string, locale: string | readonly string[]): string {\n if (!code) return fallback;\n try {\n const key = String(locale);\n let names = displayNames.get(key);\n if (!names) {\n names = new Intl.DisplayNames(locale as string[], { type: \"region\" });\n displayNames.set(key, names);\n }\n return names.of(code) ?? fallback;\n } catch {\n return fallback;\n }\n}\n"],"mappings":";;;AAIA,SAAS,WAAW,gBAAgB;AACpC,SAAS,eAAe;AAMxB,IAAI,QAA+B;AAG5B,SAAS,YAA4B;AAC1C,YAAU,OAAO,0BAAmB,EAAE,KAAK,CAAC,WAAW;AACrD,UAAM,WAAY,OAAO,WAAW;AACpC,WAAO,QAAQ,UAAU,SAAS,QAAQ,SAAS;AAAA,EACrD,CAAC;AACD,SAAO;AACT;AAGO,SAAS,SAAS,SAA4D;AACnF,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAmD,EAAE,OAAO,MAAM,QAAQ,MAAM,CAAC;AAC3G,YAAU,MAAM;AACd,QAAI,CAAC,QAAS,QAAO;AACrB,QAAI,QAAQ;AACZ,cAAU,EAAE;AAAA,MACV,CAAC,MAAM,SAAS,SAAS,EAAE,OAAO,GAAG,QAAQ,MAAM,CAAC;AAAA,MACpD,MAAM,SAAS,SAAS,EAAE,OAAO,MAAM,QAAQ,KAAK,CAAC;AAAA,IACvD;AACA,WAAO,MAAM;AACX,cAAQ;AAAA,IACV;AAAA,EACF,GAAG,CAAC,OAAO,CAAC;AACZ,SAAO;AACT;AAEA,IAAM,eAAe,oBAAI,IAA+B;AAGjD,SAAS,WAAW,MAA0B,UAAkB,QAA4C;AACjH,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI;AACF,UAAM,MAAM,OAAO,MAAM;AACzB,QAAI,QAAQ,aAAa,IAAI,GAAG;AAChC,QAAI,CAAC,OAAO;AACV,cAAQ,IAAI,KAAK,aAAa,QAAoB,EAAE,MAAM,SAAS,CAAC;AACpE,mBAAa,IAAI,KAAK,KAAK;AAAA,IAC7B;AACA,WAAO,MAAM,GAAG,IAAI,KAAK;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,38 @@
1
+ "use client";
2
+ import {
3
+ EChartHost,
4
+ baseOption
5
+ } from "./chunk-PWMMXRMC.js";
6
+
7
+ // src/chart/chart.tsx
8
+ import { useCallback } from "react";
9
+ import { jsx } from "react/jsx-runtime";
10
+ var fullEngine = () => import("./full-S2MBPEEP.js");
11
+ function Chart({ option, modules = fullEngine, summaryText, table, items, onItem, ...frame }) {
12
+ const build = useCallback(
13
+ (theme, size) => {
14
+ const own = typeof option === "function" ? option(theme, size) : option;
15
+ return { ...baseOption(theme, true), ...own };
16
+ },
17
+ [option]
18
+ );
19
+ return /* @__PURE__ */ jsx(
20
+ EChartHost,
21
+ {
22
+ kind: "chart",
23
+ frame: { ...frame, summaryText },
24
+ table,
25
+ summary: summaryText,
26
+ isEmpty: table.rows.length === 0,
27
+ engine: modules,
28
+ build,
29
+ items,
30
+ onItem
31
+ }
32
+ );
33
+ }
34
+
35
+ export {
36
+ Chart
37
+ };
38
+ //# sourceMappingURL=chunk-AA5EWWYV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chart/chart.tsx"],"sourcesContent":["\"use client\";\n// The way out for what the typed charts do not cover: any ECharts option, on the same frame — the theme (palette, text,\n// tooltip surface resolved from the tokens, re-applied on a theme switch), the lazy engine, the states, the export —\n// and the same duty: a title, a summary and the data as a table, written by you since the option is opaque.\nimport type { EChartsCoreOption } from \"echarts/core\";\nimport { useCallback } from \"react\";\n\nimport { EChartHost, type EngineProps, type WalkItem } from \"../echarts/host\";\nimport { baseOption, type ResolvedTheme } from \"../echarts/theme\";\nimport type { ChartFrameProps, TableModel } from \"../web/frame\";\n\nconst fullEngine = () => import(\"../echarts/engines/full\");\n\nexport type { ResolvedTheme };\n\nexport interface ChartProps extends ChartFrameProps, EngineProps {\n /** The ECharts option, or a function of the resolved theme (colours as plain strings, the palette, the ramp). */\n option: EChartsCoreOption | ((theme: ResolvedTheme, size: { width: number; height: number }) => EChartsCoreOption);\n /**\n * Registers what the option needs, from `echarts/charts` and `echarts/components` (tree-shaken):\n * `() => import(\"./my-echarts\")` where that module calls `use([...])`. Default: all of ECharts (~380 kB gzip).\n */\n modules?: () => Promise<unknown>;\n /** The written summary: an option says nothing on its own. */\n summaryText: string;\n /** The data as a table: the alternative of every chart. */\n table: TableModel;\n /** What the arrow keys walk (series and data indexes, and what each one says). */\n items?: readonly WalkItem[];\n /** A click (or Enter) on a data item. */\n onItem?: (item: { seriesIndex: number; dataIndex: number }) => void;\n}\n\n/** Any ECharts option, themed and framed like the typed charts. Memoise `option` when it is a function. */\nexport function Chart({ option, modules = fullEngine, summaryText, table, items, onItem, ...frame }: ChartProps) {\n const build = useCallback(\n (theme: ResolvedTheme, size: { width: number; height: number }) => {\n const own = typeof option === \"function\" ? option(theme, size) : option;\n return { ...baseOption(theme, true), ...own };\n },\n [option],\n );\n return (\n <EChartHost\n kind=\"chart\"\n frame={{ ...frame, summaryText }}\n table={table}\n summary={summaryText}\n isEmpty={table.rows.length === 0}\n engine={modules}\n build={build}\n items={items}\n onItem={onItem}\n />\n );\n}\n"],"mappings":";;;;;;;AAKA,SAAS,mBAAmB;AAsCxB;AAhCJ,IAAM,aAAa,MAAM,OAAO,oBAAyB;AAuBlD,SAAS,MAAM,EAAE,QAAQ,UAAU,YAAY,aAAa,OAAO,OAAO,QAAQ,GAAG,MAAM,GAAe;AAC/G,QAAM,QAAQ;AAAA,IACZ,CAAC,OAAsB,SAA4C;AACjE,YAAM,MAAM,OAAO,WAAW,aAAa,OAAO,OAAO,IAAI,IAAI;AACjE,aAAO,EAAE,GAAG,WAAW,OAAO,IAAI,GAAG,GAAG,IAAI;AAAA,IAC9C;AAAA,IACA,CAAC,MAAM;AAAA,EACT;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,OAAO,EAAE,GAAG,OAAO,YAAY;AAAA,MAC/B;AAAA,MACA,SAAS;AAAA,MACT,SAAS,MAAM,KAAK,WAAW;AAAA,MAC/B,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;","names":[]}
@@ -0,0 +1,43 @@
1
+ "use client";
2
+ import {
3
+ summarize
4
+ } from "./chunk-W5FX4TU3.js";
5
+ import {
6
+ capitalize,
7
+ fill
8
+ } from "./chunk-3CJHBJXA.js";
9
+
10
+ // src/core/describe.ts
11
+ function describeSeries(table, { kind, labels, value, category, share, thresholds = [] }) {
12
+ const points = table.categories.length;
13
+ const first = points ? category(table.categories[0]) : "";
14
+ const last = points ? category(table.categories[points - 1]) : "";
15
+ const count = table.series.length > 1 ? `${table.series.length} \xD7 ${points}` : String(points);
16
+ const intro = fill(labels.summaryIntro, { kind: labels.kinds[kind], count: points > 1 ? `${count} (${first} \u2013 ${last})` : count });
17
+ const sentences = table.series.map((series) => {
18
+ const s = summarize(series, table.categories, category);
19
+ if (!s.count) return `${s.label}: ${labels.noValue}.`;
20
+ const parts = [fill(labels.summarySeries, { label: s.label, first: value(s.first), last: value(s.last) })];
21
+ if (s.min && s.max && s.count > 2) parts.push(fill(labels.summaryRange, { min: value(s.min.value), minAt: s.min.category, max: value(s.max.value), maxAt: s.max.category }));
22
+ if (s.trend === "up" || s.trend === "down") {
23
+ const template = s.trend === "up" ? labels.summaryTrendUp : labels.summaryTrendDown;
24
+ if (s.change !== null) parts.push(fill(template, { change: share(Math.abs(s.change)) }));
25
+ } else if (s.trend === "flat") parts.push(labels.summaryTrendFlat);
26
+ return `${parts.join(", ")}.`;
27
+ });
28
+ const marks = thresholds.map((t) => fill(labels.summaryThreshold, { label: t.label, value: value(t.value) }));
29
+ return [intro, ...sentences, ...marks.length ? [`${marks.join(", ")}.`] : []].join(" ");
30
+ }
31
+ function describeParts(kind, parts, { labels, value, share }) {
32
+ const total = parts.reduce((sum, p) => sum + Math.max(0, p.value), 0);
33
+ const intro = fill(labels.summaryIntro, { kind: labels.kinds[kind], count: parts.length });
34
+ const sorted = [...parts].sort((a, b) => b.value - a.value);
35
+ const items = sorted.map((p) => fill(labels.summaryShare, { label: p.label, value: value(p.value), share: share(total ? p.value / total : 0) }));
36
+ return `${intro} ${items.join(", ")}. ${capitalize(fill(labels.summaryTotal, { total: value(total) }))}.`;
37
+ }
38
+
39
+ export {
40
+ describeSeries,
41
+ describeParts
42
+ };
43
+ //# sourceMappingURL=chunk-ANUCSRUN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/describe.ts"],"sourcesContent":["// The written summary of a chart — what a sighted reader takes in at a glance, said in words for a screen reader (and\n// shown under the chart when `summary=\"visible\"`): the kind, the size, then per series its range, extremes and trend.\nimport { summarize, type Table } from \"./data\";\nimport type { CategoryFormatter, ValueFormatter } from \"./format\";\nimport { capitalize, type ChartKind, type ChartLabels, fill } from \"./labels\";\nimport type { Threshold } from \"./types\";\n\nexport interface DescribeOptions {\n readonly kind: ChartKind;\n readonly labels: ChartLabels;\n readonly value: ValueFormatter;\n readonly category: CategoryFormatter;\n readonly share: (ratio: number) => string;\n readonly thresholds?: readonly Threshold[];\n}\n\n/** A cartesian chart (line, area, bar, sparkline): one sentence per series. */\nexport function describeSeries(table: Table, { kind, labels, value, category, share, thresholds = [] }: DescribeOptions): string {\n const points = table.categories.length;\n const first = points ? category(table.categories[0]) : \"\";\n const last = points ? category(table.categories[points - 1]) : \"\";\n const count = table.series.length > 1 ? `${table.series.length} × ${points}` : String(points);\n const intro = fill(labels.summaryIntro, { kind: labels.kinds[kind], count: points > 1 ? `${count} (${first} – ${last})` : count });\n const sentences = table.series.map((series) => {\n const s = summarize(series, table.categories, category);\n if (!s.count) return `${s.label}: ${labels.noValue}.`;\n const parts = [fill(labels.summarySeries, { label: s.label, first: value(s.first), last: value(s.last) })];\n if (s.min && s.max && s.count > 2) parts.push(fill(labels.summaryRange, { min: value(s.min.value), minAt: s.min.category, max: value(s.max.value), maxAt: s.max.category }));\n if (s.trend === \"up\" || s.trend === \"down\") {\n const template = s.trend === \"up\" ? labels.summaryTrendUp : labels.summaryTrendDown;\n if (s.change !== null) parts.push(fill(template, { change: share(Math.abs(s.change)) }));\n } else if (s.trend === \"flat\") parts.push(labels.summaryTrendFlat);\n return `${parts.join(\", \")}.`;\n });\n const marks = thresholds.map((t) => fill(labels.summaryThreshold, { label: t.label, value: value(t.value) }));\n return [intro, ...sentences, ...(marks.length ? [`${marks.join(\", \")}.`] : [])].join(\" \");\n}\n\n/** A part-to-whole chart (pie, donut, funnel, treemap): the parts, largest first, with their share. */\nexport function describeParts(kind: ChartKind, parts: readonly { label: string; value: number }[], { labels, value, share }: Omit<DescribeOptions, \"kind\" | \"category\">): string {\n const total = parts.reduce((sum, p) => sum + Math.max(0, p.value), 0);\n const intro = fill(labels.summaryIntro, { kind: labels.kinds[kind], count: parts.length });\n const sorted = [...parts].sort((a, b) => b.value - a.value);\n const items = sorted.map((p) => fill(labels.summaryShare, { label: p.label, value: value(p.value), share: share(total ? p.value / total : 0) }));\n return `${intro} ${items.join(\", \")}. ${capitalize(fill(labels.summaryTotal, { total: value(total) }))}.`;\n}\n"],"mappings":";;;;;;;;;;AAiBO,SAAS,eAAe,OAAc,EAAE,MAAM,QAAQ,OAAO,UAAU,OAAO,aAAa,CAAC,EAAE,GAA4B;AAC/H,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,QAAQ,SAAS,SAAS,MAAM,WAAW,CAAC,CAAC,IAAI;AACvD,QAAM,OAAO,SAAS,SAAS,MAAM,WAAW,SAAS,CAAC,CAAC,IAAI;AAC/D,QAAM,QAAQ,MAAM,OAAO,SAAS,IAAI,GAAG,MAAM,OAAO,MAAM,SAAM,MAAM,KAAK,OAAO,MAAM;AAC5F,QAAM,QAAQ,KAAK,OAAO,cAAc,EAAE,MAAM,OAAO,MAAM,IAAI,GAAG,OAAO,SAAS,IAAI,GAAG,KAAK,KAAK,KAAK,WAAM,IAAI,MAAM,MAAM,CAAC;AACjI,QAAM,YAAY,MAAM,OAAO,IAAI,CAAC,WAAW;AAC7C,UAAM,IAAI,UAAU,QAAQ,MAAM,YAAY,QAAQ;AACtD,QAAI,CAAC,EAAE,MAAO,QAAO,GAAG,EAAE,KAAK,KAAK,OAAO,OAAO;AAClD,UAAM,QAAQ,CAAC,KAAK,OAAO,eAAe,EAAE,OAAO,EAAE,OAAO,OAAO,MAAM,EAAE,KAAK,GAAG,MAAM,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AACzG,QAAI,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAG,OAAM,KAAK,KAAK,OAAO,cAAc,EAAE,KAAK,MAAM,EAAE,IAAI,KAAK,GAAG,OAAO,EAAE,IAAI,UAAU,KAAK,MAAM,EAAE,IAAI,KAAK,GAAG,OAAO,EAAE,IAAI,SAAS,CAAC,CAAC;AAC3K,QAAI,EAAE,UAAU,QAAQ,EAAE,UAAU,QAAQ;AAC1C,YAAM,WAAW,EAAE,UAAU,OAAO,OAAO,iBAAiB,OAAO;AACnE,UAAI,EAAE,WAAW,KAAM,OAAM,KAAK,KAAK,UAAU,EAAE,QAAQ,MAAM,KAAK,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAAA,IACzF,WAAW,EAAE,UAAU,OAAQ,OAAM,KAAK,OAAO,gBAAgB;AACjE,WAAO,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA,EAC5B,CAAC;AACD,QAAM,QAAQ,WAAW,IAAI,CAAC,MAAM,KAAK,OAAO,kBAAkB,EAAE,OAAO,EAAE,OAAO,OAAO,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5G,SAAO,CAAC,OAAO,GAAG,WAAW,GAAI,MAAM,SAAS,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,CAAE,EAAE,KAAK,GAAG;AAC1F;AAGO,SAAS,cAAc,MAAiB,OAAoD,EAAE,QAAQ,OAAO,MAAM,GAAuD;AAC/K,QAAM,QAAQ,MAAM,OAAO,CAAC,KAAK,MAAM,MAAM,KAAK,IAAI,GAAG,EAAE,KAAK,GAAG,CAAC;AACpE,QAAM,QAAQ,KAAK,OAAO,cAAc,EAAE,MAAM,OAAO,MAAM,IAAI,GAAG,OAAO,MAAM,OAAO,CAAC;AACzF,QAAM,SAAS,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAC1D,QAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,KAAK,OAAO,cAAc,EAAE,OAAO,EAAE,OAAO,OAAO,MAAM,EAAE,KAAK,GAAG,OAAO,MAAM,QAAQ,EAAE,QAAQ,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC/I,SAAO,GAAG,KAAK,IAAI,MAAM,KAAK,IAAI,CAAC,KAAK,WAAW,KAAK,OAAO,cAAc,EAAE,OAAO,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC;AACxG;","names":[]}
@@ -0,0 +1,88 @@
1
+ "use client";
2
+ import {
3
+ niceDomain
4
+ } from "./chunk-BISL7DYW.js";
5
+ import {
6
+ describeSeries
7
+ } from "./chunk-ANUCSRUN.js";
8
+ import {
9
+ areaPath,
10
+ barPath,
11
+ linePath,
12
+ segments
13
+ } from "./chunk-OB5EFDDH.js";
14
+ import {
15
+ categoryFormatter,
16
+ shareFormatter,
17
+ valueFormatter
18
+ } from "./chunk-XLLYNNC6.js";
19
+ import {
20
+ ChartFrame,
21
+ colorOf,
22
+ useSettings
23
+ } from "./chunk-JTKR7ZWP.js";
24
+
25
+ // src/sparkline/sparkline.tsx
26
+ import { useMemo } from "react";
27
+ import { jsx, jsxs } from "react/jsx-runtime";
28
+ function Sparkline(props) {
29
+ const { data, categories, variant = "line", color, trendTone, threshold, format, width: fixed, height = 32 } = props;
30
+ const { locale, labels } = useSettings(props);
31
+ const table = useMemo(() => ({ categories: categories ?? data.map((_, i) => i + 1), series: [{ id: "v", label: props.title, values: data, slot: 1 }] }), [data, categories, props.title]);
32
+ const fmt = useMemo(() => ({ value: valueFormatter(format, locale, labels.noValue), category: categoryFormatter(void 0, locale), share: shareFormatter(locale) }), [format, locale, labels.noValue]);
33
+ const values = data.filter((v) => v != null);
34
+ const isEmpty = values.length === 0;
35
+ const summary = isEmpty ? labels.empty : describeSeries(table, { kind: "sparkline", labels, value: fmt.value, category: fmt.category, share: fmt.share, thresholds: threshold ? [threshold] : [] });
36
+ const first = values[0] ?? 0;
37
+ const last = values[values.length - 1] ?? 0;
38
+ const up = last >= first;
39
+ const tone = trendTone ? (trendTone === "inverse" ? !up : up) ? "success" : "danger" : void 0;
40
+ const stroke = colorOf(color ?? tone, 1);
41
+ return /* @__PURE__ */ jsx(
42
+ ChartFrame,
43
+ {
44
+ kind: "sparkline",
45
+ frame: { ...props, hideTitle: true, dataTable: false, height, style: { ...fixed ? { width: fixed, display: "inline-flex" } : {}, ...props.style } },
46
+ defaultHeight: 32,
47
+ table: { columns: [labels.category, props.title], rows: table.categories.map((c, i) => [fmt.category(c), fmt.value(data[i])]) },
48
+ summary,
49
+ isEmpty,
50
+ navigable: false,
51
+ ssrWidth: fixed,
52
+ compact: true,
53
+ children: (width, h) => {
54
+ let lo = Math.min(...values, threshold?.value ?? Number.POSITIVE_INFINITY);
55
+ let hi = Math.max(...values, threshold?.value ?? Number.NEGATIVE_INFINITY);
56
+ if (variant === "bar") {
57
+ lo = Math.min(0, lo);
58
+ hi = Math.max(0, hi);
59
+ }
60
+ const [d0, d1] = lo === hi ? niceDomain(lo, hi).domain : [lo, hi];
61
+ const pad = variant === "bar" ? 0 : 3;
62
+ const yOf = (v) => pad + (1 - (v - d0) / (d1 - d0 || 1)) * (h - pad * 2);
63
+ const n = data.length;
64
+ const xOf = (i) => variant === "bar" ? (i + 0.5) * (width / n) : n > 1 ? pad + i / (n - 1) * (width - pad * 2) : width / 2;
65
+ const pts = data.map((v, i) => v == null ? null : [xOf(i), yOf(v)]);
66
+ const lastPoint = [...pts].reverse().find(Boolean);
67
+ return /* @__PURE__ */ jsxs("svg", { className: "kzc-svg", width, height: h, viewBox: `0 0 ${width} ${h}`, "aria-hidden": true, children: [
68
+ threshold && /* @__PURE__ */ jsx("line", { x1: 0, x2: width, y1: yOf(threshold.value), y2: yOf(threshold.value), "data-tone": threshold.tone ?? "neutral", className: "kzc-threshold", style: { strokeWidth: 1 } }),
69
+ variant === "bar" ? data.map((v, i) => {
70
+ if (v == null || v === 0) return null;
71
+ const bw = Math.max(1, Math.min(8, width / n * 0.7));
72
+ const top = Math.min(yOf(v), yOf(0));
73
+ return /* @__PURE__ */ jsx("path", { d: barPath(xOf(i) - bw / 2, top, bw, Math.abs(yOf(v) - yOf(0)), 1.5, false, v < 0), style: { fill: stroke } }, i);
74
+ }) : segments(pts).map((seg) => /* @__PURE__ */ jsxs("g", { children: [
75
+ variant === "area" && /* @__PURE__ */ jsx("path", { d: areaPath(seg, h, "monotone"), className: "kzc-area", style: { fill: stroke } }),
76
+ /* @__PURE__ */ jsx("path", { d: linePath(seg, "monotone"), className: "kzc-line", style: { stroke, strokeWidth: 1.75 } })
77
+ ] }, seg[0][0])),
78
+ variant !== "bar" && lastPoint && /* @__PURE__ */ jsx("circle", { cx: lastPoint[0], cy: lastPoint[1], r: 2.75, style: { fill: stroke } })
79
+ ] });
80
+ }
81
+ }
82
+ );
83
+ }
84
+
85
+ export {
86
+ Sparkline
87
+ };
88
+ //# sourceMappingURL=chunk-ARARFMNE.js.map