@krizaka/charts 0.0.0-stage → 0.1.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 (273) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +47 -2
  3. package/dist/bar.d.ts +17 -0
  4. package/dist/bar.js +16 -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-6FINSUOS.js +49 -0
  20. package/dist/chunk-6FINSUOS.js.map +1 -0
  21. package/dist/chunk-7CSAGFBW.js +166 -0
  22. package/dist/chunk-7CSAGFBW.js.map +1 -0
  23. package/dist/chunk-7TIFCK5E.js +103 -0
  24. package/dist/chunk-7TIFCK5E.js.map +1 -0
  25. package/dist/chunk-AHQXJSAQ.js +38 -0
  26. package/dist/chunk-AHQXJSAQ.js.map +1 -0
  27. package/dist/chunk-ANUCSRUN.js +43 -0
  28. package/dist/chunk-ANUCSRUN.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-BZ5CQFPH.js +19 -0
  32. package/dist/chunk-BZ5CQFPH.js.map +1 -0
  33. package/dist/chunk-DWJPPEMC.js +455 -0
  34. package/dist/chunk-DWJPPEMC.js.map +1 -0
  35. package/dist/chunk-DZB6HEVO.js +73 -0
  36. package/dist/chunk-DZB6HEVO.js.map +1 -0
  37. package/dist/chunk-EK3Z647J.js +133 -0
  38. package/dist/chunk-EK3Z647J.js.map +1 -0
  39. package/dist/chunk-I5QUZVU2.js +234 -0
  40. package/dist/chunk-I5QUZVU2.js.map +1 -0
  41. package/dist/chunk-OB5EFDDH.js +118 -0
  42. package/dist/chunk-OB5EFDDH.js.map +1 -0
  43. package/dist/chunk-OER6ETT4.js +155 -0
  44. package/dist/chunk-OER6ETT4.js.map +1 -0
  45. package/dist/chunk-PTSB3H5Q.js +205 -0
  46. package/dist/chunk-PTSB3H5Q.js.map +1 -0
  47. package/dist/chunk-TPJDOB7R.js +15 -0
  48. package/dist/chunk-TPJDOB7R.js.map +1 -0
  49. package/dist/chunk-UNK4MJVG.js +378 -0
  50. package/dist/chunk-UNK4MJVG.js.map +1 -0
  51. package/dist/chunk-VKO2OYYM.js +88 -0
  52. package/dist/chunk-VKO2OYYM.js.map +1 -0
  53. package/dist/chunk-VKTZD7UT.js +107 -0
  54. package/dist/chunk-VKTZD7UT.js.map +1 -0
  55. package/dist/chunk-W5FX4TU3.js +102 -0
  56. package/dist/chunk-W5FX4TU3.js.map +1 -0
  57. package/dist/chunk-WBH2QU77.js +178 -0
  58. package/dist/chunk-WBH2QU77.js.map +1 -0
  59. package/dist/chunk-WIRCIOLH.js +145 -0
  60. package/dist/chunk-WIRCIOLH.js.map +1 -0
  61. package/dist/chunk-XAJ3KCC4.js +116 -0
  62. package/dist/chunk-XAJ3KCC4.js.map +1 -0
  63. package/dist/chunk-XC6BQ3RN.js +92 -0
  64. package/dist/chunk-XC6BQ3RN.js.map +1 -0
  65. package/dist/chunk-XLLYNNC6.js +89 -0
  66. package/dist/chunk-XLLYNNC6.js.map +1 -0
  67. package/dist/chunk-XR4ZJDOV.js +15 -0
  68. package/dist/chunk-XR4ZJDOV.js.map +1 -0
  69. package/dist/context-BgYUymEO.d.ts +163 -0
  70. package/dist/frame-I7_xYGy5.d.ts +45 -0
  71. package/dist/full-S2MBPEEP.js +11 -0
  72. package/dist/full-S2MBPEEP.js.map +1 -0
  73. package/dist/funnel-QU5ZPC52.js +13 -0
  74. package/dist/funnel-QU5ZPC52.js.map +1 -0
  75. package/dist/funnel.d.ts +26 -0
  76. package/dist/funnel.js +13 -0
  77. package/dist/funnel.js.map +1 -0
  78. package/dist/gauge.d.ts +38 -0
  79. package/dist/gauge.js +12 -0
  80. package/dist/gauge.js.map +1 -0
  81. package/dist/geo.d.ts +37 -0
  82. package/dist/geo.js +13 -0
  83. package/dist/geo.js.map +1 -0
  84. package/dist/globe.d.ts +36 -0
  85. package/dist/globe.js +12 -0
  86. package/dist/globe.js.map +1 -0
  87. package/dist/heatmap-JWQOKUGM.js +13 -0
  88. package/dist/heatmap-JWQOKUGM.js.map +1 -0
  89. package/dist/heatmap.d.ts +47 -0
  90. package/dist/heatmap.js +15 -0
  91. package/dist/heatmap.js.map +1 -0
  92. package/dist/host-_F8RgiIz.d.ts +15 -0
  93. package/dist/index.d.ts +22 -0
  94. package/dist/index.js +101 -0
  95. package/dist/index.js.map +1 -0
  96. package/dist/line.d.ts +25 -0
  97. package/dist/line.js +18 -0
  98. package/dist/line.js.map +1 -0
  99. package/dist/native.d.ts +300 -0
  100. package/dist/native.js +875 -0
  101. package/dist/native.js.map +1 -0
  102. package/dist/pie.d.ts +37 -0
  103. package/dist/pie.js +16 -0
  104. package/dist/pie.js.map +1 -0
  105. package/dist/provider.d.ts +73 -0
  106. package/dist/provider.js +24 -0
  107. package/dist/provider.js.map +1 -0
  108. package/dist/radar-75GRJ2IK.js +13 -0
  109. package/dist/radar-75GRJ2IK.js.map +1 -0
  110. package/dist/radar.d.ts +22 -0
  111. package/dist/radar.js +13 -0
  112. package/dist/radar.js.map +1 -0
  113. package/dist/sankey-XQTX2EG6.js +13 -0
  114. package/dist/sankey-XQTX2EG6.js.map +1 -0
  115. package/dist/sankey.d.ts +28 -0
  116. package/dist/sankey.js +13 -0
  117. package/dist/sankey.js.map +1 -0
  118. package/dist/scatter-XSNG4OKD.js +13 -0
  119. package/dist/scatter-XSNG4OKD.js.map +1 -0
  120. package/dist/scatter.d.ts +41 -0
  121. package/dist/scatter.js +15 -0
  122. package/dist/scatter.js.map +1 -0
  123. package/dist/sparkline.d.ts +26 -0
  124. package/dist/sparkline.js +15 -0
  125. package/dist/sparkline.js.map +1 -0
  126. package/dist/svg-BJUHYX3B.js +14 -0
  127. package/dist/svg-BJUHYX3B.js.map +1 -0
  128. package/dist/treemap-OMGGGB5U.js +13 -0
  129. package/dist/treemap-OMGGGB5U.js.map +1 -0
  130. package/dist/treemap.d.ts +24 -0
  131. package/dist/treemap.js +14 -0
  132. package/dist/treemap.js.map +1 -0
  133. package/dist/world-110m-DVFWXS42.js +18 -0
  134. package/dist/world-110m-DVFWXS42.js.map +1 -0
  135. package/package.json +518 -3
  136. package/registry/area-chart.json +784 -0
  137. package/registry/bar-chart.json +783 -0
  138. package/registry/calendar-heatmap.json +459 -0
  139. package/registry/candlestick.json +552 -0
  140. package/registry/chart.json +440 -0
  141. package/registry/charts-provider.json +190 -0
  142. package/registry/examples/area-chart/credits-usage.d.ts +4 -0
  143. package/registry/examples/area-chart/credits-usage.js +38 -0
  144. package/registry/examples/area-chart/credits-usage.tsx +32 -0
  145. package/registry/examples/area-chart/native/credits-usage.d.ts +4 -0
  146. package/registry/examples/area-chart/native/credits-usage.dark.png +0 -0
  147. package/registry/examples/area-chart/native/credits-usage.js +33 -0
  148. package/registry/examples/area-chart/native/credits-usage.light.png +0 -0
  149. package/registry/examples/area-chart/native/credits-usage.tsx +27 -0
  150. package/registry/examples/area-chart/storage.d.ts +4 -0
  151. package/registry/examples/area-chart/storage.js +27 -0
  152. package/registry/examples/area-chart/storage.tsx +21 -0
  153. package/registry/examples/bar-chart/jobs-by-status.d.ts +4 -0
  154. package/registry/examples/bar-chart/jobs-by-status.js +37 -0
  155. package/registry/examples/bar-chart/jobs-by-status.tsx +31 -0
  156. package/registry/examples/bar-chart/native/jobs-by-status.d.ts +4 -0
  157. package/registry/examples/bar-chart/native/jobs-by-status.dark.png +0 -0
  158. package/registry/examples/bar-chart/native/jobs-by-status.js +32 -0
  159. package/registry/examples/bar-chart/native/jobs-by-status.light.png +0 -0
  160. package/registry/examples/bar-chart/native/jobs-by-status.tsx +26 -0
  161. package/registry/examples/bar-chart/plans-by-quarter.d.ts +4 -0
  162. package/registry/examples/bar-chart/plans-by-quarter.js +31 -0
  163. package/registry/examples/bar-chart/plans-by-quarter.tsx +26 -0
  164. package/registry/examples/bar-chart/top-supporters.d.ts +4 -0
  165. package/registry/examples/bar-chart/top-supporters.js +32 -0
  166. package/registry/examples/bar-chart/top-supporters.tsx +27 -0
  167. package/registry/examples/calendar-heatmap/publishing.d.ts +4 -0
  168. package/registry/examples/calendar-heatmap/publishing.js +28 -0
  169. package/registry/examples/calendar-heatmap/publishing.tsx +23 -0
  170. package/registry/examples/candlestick/auction-bids.d.ts +4 -0
  171. package/registry/examples/candlestick/auction-bids.js +37 -0
  172. package/registry/examples/candlestick/auction-bids.tsx +32 -0
  173. package/registry/examples/chart/polar-uploads.d.ts +4 -0
  174. package/registry/examples/chart/polar-uploads.js +34 -0
  175. package/registry/examples/chart/polar-uploads.tsx +30 -0
  176. package/registry/examples/charts-provider/french-orazaka.d.ts +4 -0
  177. package/registry/examples/charts-provider/french-orazaka.js +26 -0
  178. package/registry/examples/charts-provider/french-orazaka.tsx +22 -0
  179. package/registry/examples/charts-provider/native/french-orazaka.d.ts +4 -0
  180. package/registry/examples/charts-provider/native/french-orazaka.dark.png +0 -0
  181. package/registry/examples/charts-provider/native/french-orazaka.js +17 -0
  182. package/registry/examples/charts-provider/native/french-orazaka.light.png +0 -0
  183. package/registry/examples/charts-provider/native/french-orazaka.tsx +17 -0
  184. package/registry/examples/funnel/signup.d.ts +4 -0
  185. package/registry/examples/funnel/signup.js +30 -0
  186. package/registry/examples/funnel/signup.tsx +24 -0
  187. package/registry/examples/gauge/challenge-goal.d.ts +4 -0
  188. package/registry/examples/gauge/challenge-goal.js +24 -0
  189. package/registry/examples/gauge/challenge-goal.tsx +18 -0
  190. package/registry/examples/gauge/credits-quota.d.ts +4 -0
  191. package/registry/examples/gauge/credits-quota.js +26 -0
  192. package/registry/examples/gauge/credits-quota.tsx +19 -0
  193. package/registry/examples/gauge/native/credits-quota.d.ts +4 -0
  194. package/registry/examples/gauge/native/credits-quota.dark.png +0 -0
  195. package/registry/examples/gauge/native/credits-quota.js +25 -0
  196. package/registry/examples/gauge/native/credits-quota.light.png +0 -0
  197. package/registry/examples/gauge/native/credits-quota.tsx +18 -0
  198. package/registry/examples/geo-map/viewers.d.ts +4 -0
  199. package/registry/examples/geo-map/viewers.js +43 -0
  200. package/registry/examples/geo-map/viewers.tsx +29 -0
  201. package/registry/examples/globe/deployment-regions.d.ts +4 -0
  202. package/registry/examples/globe/deployment-regions.js +36 -0
  203. package/registry/examples/globe/deployment-regions.tsx +30 -0
  204. package/registry/examples/heatmap/upload-activity.d.ts +4 -0
  205. package/registry/examples/heatmap/upload-activity.js +30 -0
  206. package/registry/examples/heatmap/upload-activity.tsx +25 -0
  207. package/registry/examples/line-chart/creator-earnings.d.ts +4 -0
  208. package/registry/examples/line-chart/creator-earnings.js +35 -0
  209. package/registry/examples/line-chart/creator-earnings.tsx +30 -0
  210. package/registry/examples/line-chart/forecast.d.ts +4 -0
  211. package/registry/examples/line-chart/forecast.js +36 -0
  212. package/registry/examples/line-chart/forecast.tsx +30 -0
  213. package/registry/examples/line-chart/live-jobs.d.ts +4 -0
  214. package/registry/examples/line-chart/live-jobs.js +21 -0
  215. package/registry/examples/line-chart/live-jobs.tsx +23 -0
  216. package/registry/examples/line-chart/native/creator-earnings.d.ts +4 -0
  217. package/registry/examples/line-chart/native/creator-earnings.dark.png +0 -0
  218. package/registry/examples/line-chart/native/creator-earnings.js +32 -0
  219. package/registry/examples/line-chart/native/creator-earnings.light.png +0 -0
  220. package/registry/examples/line-chart/native/creator-earnings.tsx +26 -0
  221. package/registry/examples/line-chart/states.d.ts +4 -0
  222. package/registry/examples/line-chart/states.js +16 -0
  223. package/registry/examples/line-chart/states.tsx +13 -0
  224. package/registry/examples/pie-chart/credit-spend.d.ts +4 -0
  225. package/registry/examples/pie-chart/credit-spend.js +30 -0
  226. package/registry/examples/pie-chart/credit-spend.tsx +24 -0
  227. package/registry/examples/pie-chart/native/credit-spend.d.ts +4 -0
  228. package/registry/examples/pie-chart/native/credit-spend.dark.png +0 -0
  229. package/registry/examples/pie-chart/native/credit-spend.js +17 -0
  230. package/registry/examples/pie-chart/native/credit-spend.light.png +0 -0
  231. package/registry/examples/pie-chart/native/credit-spend.tsx +12 -0
  232. package/registry/examples/pie-chart/storage-by-kind.d.ts +4 -0
  233. package/registry/examples/pie-chart/storage-by-kind.js +31 -0
  234. package/registry/examples/pie-chart/storage-by-kind.tsx +26 -0
  235. package/registry/examples/radar-chart/model-comparison.d.ts +4 -0
  236. package/registry/examples/radar-chart/model-comparison.js +33 -0
  237. package/registry/examples/radar-chart/model-comparison.tsx +28 -0
  238. package/registry/examples/sankey/credit-flow.d.ts +4 -0
  239. package/registry/examples/sankey/credit-flow.js +37 -0
  240. package/registry/examples/sankey/credit-flow.tsx +32 -0
  241. package/registry/examples/scatter-chart/watch-time.d.ts +4 -0
  242. package/registry/examples/scatter-chart/watch-time.js +36 -0
  243. package/registry/examples/scatter-chart/watch-time.tsx +31 -0
  244. package/registry/examples/sparkline/bars.d.ts +4 -0
  245. package/registry/examples/sparkline/bars.js +12 -0
  246. package/registry/examples/sparkline/bars.tsx +7 -0
  247. package/registry/examples/sparkline/native/stat-trend.d.ts +4 -0
  248. package/registry/examples/sparkline/native/stat-trend.dark.png +0 -0
  249. package/registry/examples/sparkline/native/stat-trend.js +12 -0
  250. package/registry/examples/sparkline/native/stat-trend.light.png +0 -0
  251. package/registry/examples/sparkline/native/stat-trend.tsx +7 -0
  252. package/registry/examples/sparkline/stat-trend.d.ts +4 -0
  253. package/registry/examples/sparkline/stat-trend.js +18 -0
  254. package/registry/examples/sparkline/stat-trend.tsx +15 -0
  255. package/registry/examples/sparkline/table-rows.d.ts +4 -0
  256. package/registry/examples/sparkline/table-rows.js +23 -0
  257. package/registry/examples/sparkline/table-rows.tsx +26 -0
  258. package/registry/examples/treemap/storage.d.ts +4 -0
  259. package/registry/examples/treemap/storage.js +17 -0
  260. package/registry/examples/treemap/storage.tsx +13 -0
  261. package/registry/funnel.json +486 -0
  262. package/registry/gauge.json +599 -0
  263. package/registry/geo-map.json +483 -0
  264. package/registry/globe.json +468 -0
  265. package/registry/heatmap.json +530 -0
  266. package/registry/index.json +420 -0
  267. package/registry/line-chart.json +792 -0
  268. package/registry/pie-chart.json +1287 -0
  269. package/registry/radar-chart.json +458 -0
  270. package/registry/sankey.json +502 -0
  271. package/registry/scatter-chart.json +558 -0
  272. package/registry/sparkline.json +562 -0
  273. package/registry/treemap.json +431 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/gauge/gauge.tsx"],"sourcesContent":["\"use client\";\n// One value against its range: a 240° arc, the value written in the middle, an optional target tick and coloured\n// zones (a quota that turns to warning, then danger). Plain SVG; exposed as a `meter` (value, range and its words).\nimport { useMemo } from \"react\";\n\nimport { valueFormatter } from \"../core/format\";\nimport { fill } from \"../core/labels\";\nimport { polar, strokeArcPath } from \"../core/shape\";\nimport type { Threshold, Tone, ValueFormat } from \"../core/types\";\nimport { ChartFrame, type ChartFrameProps, useSettings } from \"../web/frame\";\nimport { colorOf } from \"../web/parts\";\n\nexport interface GaugeZone {\n /** The zone runs from the previous one's end (or `min`) to this value. */\n readonly to: number;\n readonly tone: Tone;\n /** Its name, in the summary and the table (“Over quota”). */\n readonly label?: string;\n}\n\nexport interface GaugeProps extends Omit<ChartFrameProps, \"dataTable\" | \"exportable\"> {\n /** The value. */\n/** The value. */\n value: number;\n /** The start of the range. Default 0. */\n/** The start of the range. Default 0. */\n min?: number;\n /** The end of the range. Default 100. */\n/** The end of the range. Default 100. */\n max?: number;\n /** How the value is written. */\n/** How the value and the range are written. */\n format?: ValueFormat;\n /** The words under the value (“of 50 000 credits”). */\n caption?: string;\n /** A tick on the arc: the objective. */\n target?: Threshold;\n /** Coloured zones along the arc: the value takes the tone of the zone it is in. */\n zones?: readonly GaugeZone[];\n /** The tone of the value without zones. Default `\"accent\"`. */\n/** The tone of the value without zones. Default `\"accent\"`. */\n tone?: Tone;\n}\n\nconst START = (-120 * Math.PI) / 180;\nconst END = (120 * Math.PI) / 180;\n\n/** One figure against its range — credits used of a plan, a challenge's progress, a load. */\nexport function Gauge(props: GaugeProps) {\n const { value, min = 0, max = 100, format, caption, target, zones = [], tone = \"accent\" } = props;\n const { locale, labels } = useSettings(props);\n const fmt = useMemo(() => valueFormatter(format, locale, labels.noValue), [format, locale, labels.noValue]);\n const clamped = Math.min(max, Math.max(min, value));\n const ratio = max > min ? (clamped - min) / (max - min) : 0;\n const zone = zones.find((z) => clamped <= z.to) ?? zones[zones.length - 1];\n const color = colorOf(zone?.tone ?? tone, 1);\n const text = fmt(value);\n const summary = [\n `${labels.kinds.gauge}: ${text} (${min === 0 ? \"\" : `${fmt(min)} – `}${fmt(max)})${zone?.label ? `, ${zone.label}` : \"\"}.`,\n target ? `${fill(labels.summaryThreshold, { label: target.label, value: fmt(target.value) })}.` : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n const table = { columns: [labels.category, labels.value], rows: [[props.title, text], [\"min\", fmt(min)], [\"max\", fmt(max)], ...(target ? [[target.label, fmt(target.value)]] : [])] };\n const at = (v: number) => START + ((Math.min(max, Math.max(min, v)) - min) / (max - min || 1)) * (END - START);\n\n return (\n <ChartFrame kind=\"gauge\" frame={{ ...props, dataTable: false }} defaultHeight={180} table={table} summary={summary} isEmpty={false} navigable={false}>\n {(width, height) => {\n // The arc spans 240°: its lowest points sit at half the radius below the centre, the range labels under them.\n const radius = Math.max(20, Math.min(width / 2 - 12, (height - 30) / 1.58));\n const cx = width / 2;\n const cy = 8 + radius;\n const stroke = Math.max(8, radius * 0.16);\n let from = min;\n return (\n <div role=\"meter\" aria-label={props.title} aria-valuemin={min} aria-valuemax={max} aria-valuenow={clamped} aria-valuetext={caption ? `${text} ${caption}` : text} style={{ height: \"100%\" }}>\n <svg className=\"kzc-svg\" width={width} height={height} viewBox={`0 0 ${width} ${height}`} aria-hidden>\n <path d={strokeArcPath(cx, cy, radius, START, END)} style={{ fill: \"none\", stroke: \"var(--kz-surface-3)\", strokeWidth: stroke, strokeLinecap: \"round\" }} />\n {zones.map((z, i) => {\n const d = strokeArcPath(cx, cy, radius + stroke / 2 + 4, at(from), at(z.to));\n from = z.to;\n return <path key={i} d={d} data-tone={z.tone} style={{ fill: \"none\", stroke: \"var(--kzc-tone)\", strokeWidth: 3, opacity: 0.7 }} />;\n })}\n {ratio > 0 && (\n <path d={strokeArcPath(cx, cy, radius, START, at(clamped))} pathLength={1} className=\"kzc-line kzc-enter-line\" style={{ stroke: color, strokeWidth: stroke }} />\n )}\n {target && (\n <g data-tone={target.tone ?? \"neutral\"}>\n <line\n x1={polar(cx, cy, radius - stroke, at(target.value))[0]}\n y1={polar(cx, cy, radius - stroke, at(target.value))[1]}\n x2={polar(cx, cy, radius + stroke, at(target.value))[0]}\n y2={polar(cx, cy, radius + stroke, at(target.value))[1]}\n style={{ stroke: \"var(--kzc-text)\", strokeWidth: 2, strokeLinecap: \"round\" }}\n />\n </g>\n )}\n <text x={cx} y={cy} textAnchor=\"middle\" dominantBaseline=\"central\" className=\"kzc-strong\" style={{ fontSize: Math.max(12, Math.min(32, radius / 2.6, (radius * 1.45) / (text.length * 0.58))) }}>\n {text}\n </text>\n {caption && (\n <text x={cx} y={cy + Math.max(16, radius / 3.2)} textAnchor=\"middle\" dominantBaseline=\"central\">\n {caption}\n </text>\n )}\n <text x={polar(cx, cy, radius, START)[0]} y={polar(cx, cy, radius, START)[1] + stroke + 6} textAnchor=\"middle\">\n {fmt(min)}\n </text>\n <text x={polar(cx, cy, radius, END)[0]} y={polar(cx, cy, radius, END)[1] + stroke + 6} textAnchor=\"middle\">\n {fmt(max)}\n </text>\n </svg>\n </div>\n );\n }}\n </ChartFrame>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAGA,SAAS,eAAe;AA0EZ,SACE,KADF;AAjCZ,IAAM,QAAS,OAAO,KAAK,KAAM;AACjC,IAAM,MAAO,MAAM,KAAK,KAAM;AAGvB,SAAS,MAAM,OAAmB;AACvC,QAAM,EAAE,OAAO,MAAM,GAAG,MAAM,KAAK,QAAQ,SAAS,QAAQ,QAAQ,CAAC,GAAG,OAAO,SAAS,IAAI;AAC5F,QAAM,EAAE,QAAQ,OAAO,IAAI,YAAY,KAAK;AAC5C,QAAM,MAAM,QAAQ,MAAM,eAAe,QAAQ,QAAQ,OAAO,OAAO,GAAG,CAAC,QAAQ,QAAQ,OAAO,OAAO,CAAC;AAC1G,QAAM,UAAU,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK,CAAC;AAClD,QAAM,QAAQ,MAAM,OAAO,UAAU,QAAQ,MAAM,OAAO;AAC1D,QAAM,OAAO,MAAM,KAAK,CAAC,MAAM,WAAW,EAAE,EAAE,KAAK,MAAM,MAAM,SAAS,CAAC;AACzE,QAAM,QAAQ,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAC3C,QAAM,OAAO,IAAI,KAAK;AACtB,QAAM,UAAU;AAAA,IACd,GAAG,OAAO,MAAM,KAAK,KAAK,IAAI,KAAK,QAAQ,IAAI,KAAK,GAAG,IAAI,GAAG,CAAC,UAAK,GAAG,IAAI,GAAG,CAAC,IAAI,MAAM,QAAQ,KAAK,KAAK,KAAK,KAAK,EAAE;AAAA,IACvH,SAAS,GAAG,KAAK,OAAO,kBAAkB,EAAE,OAAO,OAAO,OAAO,OAAO,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC,MAAM;AAAA,EACpG,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AACX,QAAM,QAAQ,EAAE,SAAS,CAAC,OAAO,UAAU,OAAO,KAAK,GAAG,MAAM,CAAC,CAAC,MAAM,OAAO,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,GAAG,GAAI,SAAS,CAAC,CAAC,OAAO,OAAO,IAAI,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,CAAE,EAAE;AACpL,QAAM,KAAK,CAAC,MAAc,SAAU,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,CAAC,CAAC,IAAI,QAAQ,MAAM,OAAO,MAAO,MAAM;AAExG,SACE,oBAAC,cAAW,MAAK,SAAQ,OAAO,EAAE,GAAG,OAAO,WAAW,MAAM,GAAG,eAAe,KAAK,OAAc,SAAkB,SAAS,OAAO,WAAW,OAC5I,WAAC,OAAO,WAAW;AAElB,UAAM,SAAS,KAAK,IAAI,IAAI,KAAK,IAAI,QAAQ,IAAI,KAAK,SAAS,MAAM,IAAI,CAAC;AAC1E,UAAM,KAAK,QAAQ;AACnB,UAAM,KAAK,IAAI;AACf,UAAM,SAAS,KAAK,IAAI,GAAG,SAAS,IAAI;AACxC,QAAI,OAAO;AACX,WACE,oBAAC,SAAI,MAAK,SAAQ,cAAY,MAAM,OAAO,iBAAe,KAAK,iBAAe,KAAK,iBAAe,SAAS,kBAAgB,UAAU,GAAG,IAAI,IAAI,OAAO,KAAK,MAAM,OAAO,EAAE,QAAQ,OAAO,GACxL,+BAAC,SAAI,WAAU,WAAU,OAAc,QAAgB,SAAS,OAAO,KAAK,IAAI,MAAM,IAAI,eAAW,MACnG;AAAA,0BAAC,UAAK,GAAG,cAAc,IAAI,IAAI,QAAQ,OAAO,GAAG,GAAG,OAAO,EAAE,MAAM,QAAQ,QAAQ,uBAAuB,aAAa,QAAQ,eAAe,QAAQ,GAAG;AAAA,MACxJ,MAAM,IAAI,CAAC,GAAG,MAAM;AACnB,cAAM,IAAI,cAAc,IAAI,IAAI,SAAS,SAAS,IAAI,GAAG,GAAG,IAAI,GAAG,GAAG,EAAE,EAAE,CAAC;AAC3E,eAAO,EAAE;AACT,eAAO,oBAAC,UAAa,GAAM,aAAW,EAAE,MAAM,OAAO,EAAE,MAAM,QAAQ,QAAQ,mBAAmB,aAAa,GAAG,SAAS,IAAI,KAA3G,CAA8G;AAAA,MAClI,CAAC;AAAA,MACA,QAAQ,KACP,oBAAC,UAAK,GAAG,cAAc,IAAI,IAAI,QAAQ,OAAO,GAAG,OAAO,CAAC,GAAG,YAAY,GAAG,WAAU,2BAA0B,OAAO,EAAE,QAAQ,OAAO,aAAa,OAAO,GAAG;AAAA,MAE/J,UACC,oBAAC,OAAE,aAAW,OAAO,QAAQ,WAC3B;AAAA,QAAC;AAAA;AAAA,UACC,IAAI,MAAM,IAAI,IAAI,SAAS,QAAQ,GAAG,OAAO,KAAK,CAAC,EAAE,CAAC;AAAA,UACtD,IAAI,MAAM,IAAI,IAAI,SAAS,QAAQ,GAAG,OAAO,KAAK,CAAC,EAAE,CAAC;AAAA,UACtD,IAAI,MAAM,IAAI,IAAI,SAAS,QAAQ,GAAG,OAAO,KAAK,CAAC,EAAE,CAAC;AAAA,UACtD,IAAI,MAAM,IAAI,IAAI,SAAS,QAAQ,GAAG,OAAO,KAAK,CAAC,EAAE,CAAC;AAAA,UACtD,OAAO,EAAE,QAAQ,mBAAmB,aAAa,GAAG,eAAe,QAAQ;AAAA;AAAA,MAC7E,GACF;AAAA,MAEF,oBAAC,UAAK,GAAG,IAAI,GAAG,IAAI,YAAW,UAAS,kBAAiB,WAAU,WAAU,cAAa,OAAO,EAAE,UAAU,KAAK,IAAI,IAAI,KAAK,IAAI,IAAI,SAAS,KAAM,SAAS,QAAS,KAAK,SAAS,KAAK,CAAC,EAAE,GAC3L,gBACH;AAAA,MACC,WACC,oBAAC,UAAK,GAAG,IAAI,GAAG,KAAK,KAAK,IAAI,IAAI,SAAS,GAAG,GAAG,YAAW,UAAS,kBAAiB,WACnF,mBACH;AAAA,MAEF,oBAAC,UAAK,GAAG,MAAM,IAAI,IAAI,QAAQ,KAAK,EAAE,CAAC,GAAG,GAAG,MAAM,IAAI,IAAI,QAAQ,KAAK,EAAE,CAAC,IAAI,SAAS,GAAG,YAAW,UACnG,cAAI,GAAG,GACV;AAAA,MACA,oBAAC,UAAK,GAAG,MAAM,IAAI,IAAI,QAAQ,GAAG,EAAE,CAAC,GAAG,GAAG,MAAM,IAAI,IAAI,QAAQ,GAAG,EAAE,CAAC,IAAI,SAAS,GAAG,YAAW,UAC/F,cAAI,GAAG,GACV;AAAA,OACF,GACF;AAAA,EAEJ,GACF;AAEJ;","names":[]}
@@ -0,0 +1,133 @@
1
+ "use client";
2
+ import {
3
+ EChartHost,
4
+ baseOption,
5
+ tooltipHtml,
6
+ valueAxis
7
+ } from "./chunk-I5QUZVU2.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-DWJPPEMC.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-EK3Z647J.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,234 @@
1
+ "use client";
2
+ import {
3
+ ChartFrame,
4
+ resolveColor,
5
+ useInView,
6
+ useReducedMotion,
7
+ useThemeVersion
8
+ } from "./chunk-DWJPPEMC.js";
9
+ import {
10
+ sequential
11
+ } from "./chunk-3CJHBJXA.js";
12
+
13
+ // src/echarts/theme.ts
14
+ var ROLES = {
15
+ text: "--kz-text-primary",
16
+ text2: "--kz-text-secondary",
17
+ text3: "--kz-text-muted",
18
+ grid: "--kz-border-subtle",
19
+ axis: "--kz-border-default",
20
+ surface: "--kz-surface-1",
21
+ surface2: "--kz-surface-2",
22
+ surface3: "--kz-surface-3",
23
+ border: "--kz-border-default",
24
+ accent: "--kz-accent",
25
+ success: "--kz-success",
26
+ warning: "--kz-warning",
27
+ danger: "--kz-danger",
28
+ info: "--kz-info",
29
+ low: "--kzc-low",
30
+ high: "--kzc-high"
31
+ };
32
+ function resolveTheme(el) {
33
+ const color = (name) => resolveColor(`var(${name})`, el);
34
+ const roles = Object.fromEntries(Object.entries(ROLES).map(([key, name]) => [key, color(name)]));
35
+ const palette = Array.from({ length: 8 }, (_, i) => color(`--kzc-${i + 1}`));
36
+ const font = getComputedStyle(el).fontFamily || "system-ui, sans-serif";
37
+ return { ...roles, palette, ramp: sequential(palette[0], roles.surface, 5), font };
38
+ }
39
+ function baseOption(theme, animate) {
40
+ return {
41
+ color: [...theme.palette],
42
+ backgroundColor: "transparent",
43
+ textStyle: { color: theme.text2, fontFamily: theme.font, fontSize: 11 },
44
+ animation: animate,
45
+ animationDuration: 700,
46
+ animationEasing: "cubicOut",
47
+ animationDurationUpdate: 300,
48
+ tooltip: {
49
+ confine: true,
50
+ backgroundColor: theme.surface2,
51
+ borderColor: theme.border,
52
+ borderWidth: 1,
53
+ padding: [8, 10],
54
+ textStyle: { color: theme.text, fontFamily: theme.font, fontSize: 12 },
55
+ extraCssText: "border-radius:10px;box-shadow:var(--kz-shadow-lg);min-width:140px;"
56
+ }
57
+ };
58
+ }
59
+ function valueAxis(theme, formatter) {
60
+ return {
61
+ type: "value",
62
+ axisLine: { show: false },
63
+ axisTick: { show: false },
64
+ splitLine: { lineStyle: { color: theme.grid, width: 1 } },
65
+ axisLabel: { color: theme.text2, formatter }
66
+ };
67
+ }
68
+ function categoryAxis(theme, data) {
69
+ return {
70
+ type: "category",
71
+ data,
72
+ axisLine: { lineStyle: { color: theme.axis } },
73
+ axisTick: { show: false },
74
+ axisLabel: { color: theme.text2, hideOverlap: true },
75
+ splitLine: { show: false }
76
+ };
77
+ }
78
+ var escape = (text) => text.replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" })[c]);
79
+ function tooltipHtml(title, rows, note) {
80
+ const head = title ? `<p class="kzc-tip-title">${escape(title)}</p>` : "";
81
+ const body = rows.map((row) => `<p class="kzc-tip-row">${row.color ? `<span class="kzc-key" style="background:${escape(row.color)}"></span>` : "<span></span>"}<span>${escape(row.label)}</span><b>${escape(row.value)}</b></p>`).join("");
82
+ return `${head}${body}${note ? `<p class="kzc-tip-note">${escape(note)}</p>` : ""}`;
83
+ }
84
+
85
+ // src/echarts/host.tsx
86
+ import { useEffect, useRef, useState } from "react";
87
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
88
+ var RENDERERS = {
89
+ svg: () => import("./svg-BJUHYX3B.js"),
90
+ canvas: () => import("./canvas-4MSYDVFO.js")
91
+ };
92
+ var install = (module) => {
93
+ const fn = module?.install;
94
+ if (typeof fn === "function") fn();
95
+ };
96
+ function EChartHost({ kind, frame, defaultHeight, table, summary, isEmpty, legend, engine, build, items = [], onItem }) {
97
+ const instance = useRef(null);
98
+ const [active, setActive] = useState(null);
99
+ const [failed, setFailed] = useState(false);
100
+ const renderer = frame.renderer ?? "svg";
101
+ const onKeyDown = (event) => {
102
+ const n = items.length;
103
+ if (!n) return;
104
+ if (event.key === "Enter" && active !== null && onItem) {
105
+ onItem(items[active]);
106
+ return;
107
+ }
108
+ const moves = {
109
+ ArrowRight: () => ((active ?? -1) + 1) % n,
110
+ ArrowDown: () => ((active ?? -1) + 1) % n,
111
+ ArrowLeft: () => ((active ?? 0) - 1 + n) % n,
112
+ ArrowUp: () => ((active ?? 0) - 1 + n) % n,
113
+ Home: () => 0,
114
+ End: () => n - 1,
115
+ Escape: () => null
116
+ };
117
+ const move = moves[event.key];
118
+ if (!move) return;
119
+ event.preventDefault();
120
+ setActive(move());
121
+ };
122
+ const exportImage = (format) => {
123
+ const chart = instance.current;
124
+ if (!chart) return null;
125
+ const dom = chart.getDom();
126
+ const background = resolveTheme(dom).surface;
127
+ return chart.getDataURL({ type: format === "svg" && renderer === "svg" ? "svg" : "png", pixelRatio: 2, backgroundColor: background });
128
+ };
129
+ return /* @__PURE__ */ jsx(
130
+ ChartFrame,
131
+ {
132
+ kind,
133
+ frame: { ...frame, error: frame.error ?? (failed || void 0) },
134
+ defaultHeight,
135
+ table,
136
+ summary,
137
+ isEmpty,
138
+ legend,
139
+ announcement: active === null ? "" : items[active]?.text ?? "",
140
+ handlers: { onKeyDown, onBlur: () => setActive(null) },
141
+ navigable: items.length > 0,
142
+ exportImage,
143
+ children: (width, height) => /* @__PURE__ */ jsx(
144
+ Host,
145
+ {
146
+ width,
147
+ height,
148
+ renderer,
149
+ engine,
150
+ build,
151
+ active: active === null ? null : items[active] ?? null,
152
+ instance,
153
+ onItem,
154
+ onFail: () => setFailed(true)
155
+ }
156
+ )
157
+ }
158
+ );
159
+ }
160
+ function Host({ width, height, renderer, engine, build, active, instance, onItem, onFail }) {
161
+ const ref = useRef(null);
162
+ const near = useInView(ref, { once: true, margin: "200px" });
163
+ const reduced = useReducedMotion();
164
+ const themeVersion = useThemeVersion();
165
+ const [ready, setReady] = useState(false);
166
+ const [drawn, setDrawn] = useState(false);
167
+ const size = useRef({ width, height });
168
+ const itemRef = useRef(onItem);
169
+ const failRef = useRef(onFail);
170
+ useEffect(() => {
171
+ size.current = { width, height };
172
+ itemRef.current = onItem;
173
+ failRef.current = onFail;
174
+ });
175
+ useEffect(() => {
176
+ if (!near) return void 0;
177
+ let alive = true;
178
+ Promise.all([engine(), RENDERERS[renderer]()]).then(
179
+ ([module, painter]) => {
180
+ if (!alive || !ref.current) return;
181
+ install(module);
182
+ painter.install();
183
+ const { init } = painter;
184
+ const chart = init(ref.current, null, { renderer, ...size.current });
185
+ chart.on("finished", () => setDrawn(true));
186
+ chart.on("click", (params) => {
187
+ const p = params;
188
+ if (p.seriesIndex != null && p.dataIndex != null) itemRef.current?.({ seriesIndex: p.seriesIndex, dataIndex: p.dataIndex });
189
+ });
190
+ instance.current = chart;
191
+ setReady(true);
192
+ },
193
+ () => alive && failRef.current()
194
+ );
195
+ return () => {
196
+ alive = false;
197
+ instance.current?.dispose();
198
+ instance.current = null;
199
+ setReady(false);
200
+ };
201
+ }, [near, renderer, engine, instance]);
202
+ useEffect(() => {
203
+ if (ready) instance.current?.resize({ width, height });
204
+ }, [ready, width, height, instance]);
205
+ useEffect(() => {
206
+ const chart = instance.current;
207
+ if (!ready || !chart || !ref.current) return;
208
+ const option = build(resolveTheme(ref.current), { width, height });
209
+ chart.setOption({ ...option, animation: !reduced && option.animation !== false }, { notMerge: true });
210
+ }, [ready, build, themeVersion, reduced, width, height, instance]);
211
+ useEffect(() => {
212
+ const chart = instance.current;
213
+ if (!ready || !chart) return;
214
+ chart.dispatchAction({ type: "downplay" });
215
+ if (active) {
216
+ const target = { seriesIndex: active.seriesIndex, dataIndex: active.dataIndex, ...active.dataType ? { dataType: active.dataType } : {} };
217
+ chart.dispatchAction({ type: "highlight", ...target });
218
+ chart.dispatchAction({ type: "showTip", ...target });
219
+ } else chart.dispatchAction({ type: "hideTip" });
220
+ }, [ready, active, instance]);
221
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
222
+ !drawn && /* @__PURE__ */ jsx("div", { className: "kzc-skeleton", "aria-hidden": true, children: [0.55, 0.8, 0.45, 0.95, 0.7, 0.6].map((h, i) => /* @__PURE__ */ jsx("i", { style: { height: `${h * 100}%` } }, i)) }),
223
+ /* @__PURE__ */ jsx("div", { ref, className: "kzc-host", "data-pending": drawn ? void 0 : "", "aria-hidden": true })
224
+ ] });
225
+ }
226
+
227
+ export {
228
+ baseOption,
229
+ valueAxis,
230
+ categoryAxis,
231
+ tooltipHtml,
232
+ EChartHost
233
+ };
234
+ //# sourceMappingURL=chunk-I5QUZVU2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/echarts/theme.ts","../src/echarts/host.tsx"],"sourcesContent":["\"use client\";\n// The ECharts side of the theme: the --kz-* roles and the palette's variables resolved to plain colours on the chart's\n// own element (a canvas has no CSS variables) — so a `.brand-<id>` ancestor, a `.theme-light` island and the\n// chart's `data-brand` all apply — and the option pieces every chart shares (text, axes, grid, tooltip).\nimport type { EChartsCoreOption } from \"echarts/core\";\n\nimport { sequential } from \"../core/palette\";\nimport { resolveColor } from \"../web/frame\";\n\nexport interface ResolvedTheme {\n readonly text: string;\n readonly text2: string;\n readonly text3: string;\n readonly grid: string;\n readonly axis: string;\n readonly surface: string;\n readonly surface2: string;\n readonly surface3: string;\n readonly border: string;\n readonly accent: string;\n readonly success: string;\n readonly warning: string;\n readonly danger: string;\n readonly info: string;\n /** The categorical palette, slot 1 first. */\n readonly palette: readonly string[];\n /** A sequential ramp of the brand hue (5 steps, near the surface → full). */\n readonly ramp: readonly string[];\n /** The diverging poles. */\n readonly low: string;\n readonly high: string;\n readonly font: string;\n}\n\nconst ROLES = {\n text: \"--kz-text-primary\",\n text2: \"--kz-text-secondary\",\n text3: \"--kz-text-muted\",\n grid: \"--kz-border-subtle\",\n axis: \"--kz-border-default\",\n surface: \"--kz-surface-1\",\n surface2: \"--kz-surface-2\",\n surface3: \"--kz-surface-3\",\n border: \"--kz-border-default\",\n accent: \"--kz-accent\",\n success: \"--kz-success\",\n warning: \"--kz-warning\",\n danger: \"--kz-danger\",\n info: \"--kz-info\",\n low: \"--kzc-low\",\n high: \"--kzc-high\",\n} as const;\n\n/** The theme as the browser resolves it on `el` (call again after a theme change). */\nexport function resolveTheme(el: Element): ResolvedTheme {\n const color = (name: string) => resolveColor(`var(${name})`, el);\n const roles = Object.fromEntries(Object.entries(ROLES).map(([key, name]) => [key, color(name)])) as Record<keyof typeof ROLES, string>;\n const palette = Array.from({ length: 8 }, (_, i) => color(`--kzc-${i + 1}`));\n const font = getComputedStyle(el).fontFamily || \"system-ui, sans-serif\";\n return { ...roles, palette, ramp: sequential(palette[0]!, roles.surface, 5), font };\n}\n\n/** The option every ECharts chart starts from: colours, text, the tooltip's surface, motion. */\nexport function baseOption(theme: ResolvedTheme, animate: boolean): EChartsCoreOption {\n return {\n color: [...theme.palette],\n backgroundColor: \"transparent\",\n textStyle: { color: theme.text2, fontFamily: theme.font, fontSize: 11 },\n animation: animate,\n animationDuration: 700,\n animationEasing: \"cubicOut\",\n animationDurationUpdate: 300,\n tooltip: {\n confine: true,\n backgroundColor: theme.surface2,\n borderColor: theme.border,\n borderWidth: 1,\n padding: [8, 10],\n textStyle: { color: theme.text, fontFamily: theme.font, fontSize: 12 },\n extraCssText: \"border-radius:10px;box-shadow:var(--kz-shadow-lg);min-width:140px;\",\n },\n };\n}\n\n/** A value axis: recessive, hairline grid, text-secondary labels. */\nexport function valueAxis(theme: ResolvedTheme, formatter: (v: number) => string): Record<string, unknown> {\n return {\n type: \"value\",\n axisLine: { show: false },\n axisTick: { show: false },\n splitLine: { lineStyle: { color: theme.grid, width: 1 } },\n axisLabel: { color: theme.text2, formatter },\n };\n}\n\n/** A category axis: a baseline in the axis colour, no ticks. */\nexport function categoryAxis(theme: ResolvedTheme, data: readonly string[]): Record<string, unknown> {\n return {\n type: \"category\",\n data,\n axisLine: { lineStyle: { color: theme.axis } },\n axisTick: { show: false },\n axisLabel: { color: theme.text2, hideOverlap: true },\n splitLine: { show: false },\n };\n}\n\nconst escape = (text: string) => text.replace(/[&<>\"]/g, (c) => ({ \"&\": \"&amp;\", \"<\": \"&lt;\", \">\": \"&gt;\", '\"': \"&quot;\" })[c]!);\n\n/** The tooltip's content in the package's markup (`kzc-tip-*`): a title, rows of key · name · value, a note. */\nexport function tooltipHtml(title: string | undefined, rows: readonly { label: string; value: string; color?: string }[], note?: string): string {\n const head = title ? `<p class=\"kzc-tip-title\">${escape(title)}</p>` : \"\";\n const body = rows\n .map((row) => `<p class=\"kzc-tip-row\">${row.color ? `<span class=\"kzc-key\" style=\"background:${escape(row.color)}\"></span>` : \"<span></span>\"}<span>${escape(row.label)}</span><b>${escape(row.value)}</b></p>`)\n .join(\"\");\n return `${head}${body}${note ? `<p class=\"kzc-tip-note\">${escape(note)}</p>` : \"\"}`;\n}\n","\"use client\";\n// The ECharts host behind Radar, Heatmap, Calendar, Sankey, Funnel, Candlestick, Treemap, Scatter and <Chart>: the same\n// frame as the SVG charts (title, summary, data table, keyboard, states, export), and an engine that is loaded only\n// when the chart comes near the screen — `echarts/core`, the one chart type and its components, one renderer (SVG by\n// default; canvas for large volumes). The option is rebuilt from the resolved theme on every theme change; motion\n// follows the reader's preference; the chart is disposed with the component.\nimport type { EChartsCoreOption, EChartsType } from \"echarts/core\";\nimport { type KeyboardEvent, type ReactNode, type RefObject, useEffect, useRef, useState } from \"react\";\n\nimport type { ChartKind } from \"../core/labels\";\nimport { ChartFrame, type ChartFrameProps, type TableModel } from \"../web/frame\";\nimport { useInView, useReducedMotion, useThemeVersion } from \"../web/hooks\";\nimport { type ResolvedTheme, resolveTheme } from \"./theme\";\n\nexport type Renderer = \"svg\" | \"canvas\";\n\n/** What the keyboard walks: one ECharts data item, and what it says. */\nexport interface WalkItem {\n readonly seriesIndex: number;\n readonly dataIndex: number;\n /** A graph's link (`edge`) rather than its node: Sankey's flows. */\n readonly dataType?: \"node\" | \"edge\";\n readonly text: string;\n}\n\nexport interface EngineProps {\n /** `svg` (default): sharp, exportable as SVG. `canvas`: for tens of thousands of marks. */\n renderer?: Renderer;\n}\n\ninterface HostProps {\n readonly kind: ChartKind;\n readonly frame: ChartFrameProps & EngineProps;\n readonly defaultHeight?: number;\n readonly table: TableModel;\n readonly summary: string;\n readonly isEmpty: boolean;\n readonly legend?: ReactNode;\n /** Loads the chart type and its components (a dynamic import of `./engines/<type>`), whose `install` registers them. */\n readonly engine: () => Promise<unknown>;\n /** The option, from the resolved theme and the size. Memoise it: a new function redraws. */\n readonly build: (theme: ResolvedTheme, size: { width: number; height: number }) => EChartsCoreOption;\n readonly items?: readonly WalkItem[];\n /** A click (or Enter) on an item. */\n readonly onItem?: (item: { seriesIndex: number; dataIndex: number }) => void;\n}\n\ntype Init = (el: HTMLElement, theme: null, options: { renderer: Renderer; width: number; height: number }) => EChartsType;\ntype RendererModule = { init: Init; install: () => void };\n\nconst RENDERERS: Record<Renderer, () => Promise<RendererModule>> = {\n svg: () => import(\"./engines/svg\") as Promise<RendererModule>,\n canvas: () => import(\"./engines/canvas\") as Promise<RendererModule>,\n};\n\n/** Calls the `install` of an engine module (a typed chart's), if it has one (a `<Chart modules>` function may not). */\nconst install = (module: unknown) => {\n const fn = (module as { install?: unknown } | null)?.install;\n if (typeof fn === \"function\") fn();\n};\n\nexport function EChartHost({ kind, frame, defaultHeight, table, summary, isEmpty, legend, engine, build, items = [], onItem }: HostProps) {\n const instance = useRef<EChartsType | null>(null);\n const [active, setActive] = useState<number | null>(null);\n const [failed, setFailed] = useState(false);\n const renderer = frame.renderer ?? \"svg\";\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const n = items.length;\n if (!n) return;\n if (event.key === \"Enter\" && active !== null && onItem) {\n onItem(items[active]!);\n return;\n }\n const moves: Record<string, () => number | null> = {\n ArrowRight: () => ((active ?? -1) + 1) % n,\n ArrowDown: () => ((active ?? -1) + 1) % n,\n ArrowLeft: () => ((active ?? 0) - 1 + n) % n,\n ArrowUp: () => ((active ?? 0) - 1 + n) % n,\n Home: () => 0,\n End: () => n - 1,\n Escape: () => null,\n };\n const move = moves[event.key];\n if (!move) return;\n event.preventDefault();\n setActive(move());\n };\n\n const exportImage = (format: \"png\" | \"svg\") => {\n const chart = instance.current;\n if (!chart) return null;\n const dom = chart.getDom();\n const background = resolveTheme(dom).surface;\n return chart.getDataURL({ type: format === \"svg\" && renderer === \"svg\" ? \"svg\" : \"png\", pixelRatio: 2, backgroundColor: background });\n };\n\n return (\n <ChartFrame\n kind={kind}\n frame={{ ...frame, error: frame.error ?? (failed || undefined) }}\n defaultHeight={defaultHeight}\n table={table}\n summary={summary}\n isEmpty={isEmpty}\n legend={legend}\n announcement={active === null ? \"\" : (items[active]?.text ?? \"\")}\n handlers={{ onKeyDown, onBlur: () => setActive(null) }}\n navigable={items.length > 0}\n exportImage={exportImage}\n >\n {(width, height) => (\n <Host\n width={width}\n height={height}\n renderer={renderer}\n engine={engine}\n build={build}\n active={active === null ? null : (items[active] ?? null)}\n instance={instance}\n onItem={onItem}\n onFail={() => setFailed(true)}\n />\n )}\n </ChartFrame>\n );\n}\n\ninterface InnerProps {\n width: number;\n height: number;\n renderer: Renderer;\n engine: () => Promise<unknown>;\n build: HostProps[\"build\"];\n active: WalkItem | null;\n instance: RefObject<EChartsType | null>;\n onItem?: HostProps[\"onItem\"];\n onFail: () => void;\n}\n\nfunction Host({ width, height, renderer, engine, build, active, instance, onItem, onFail }: InnerProps) {\n const ref = useRef<HTMLDivElement | null>(null);\n const near = useInView(ref, { once: true, margin: \"200px\" });\n const reduced = useReducedMotion();\n const themeVersion = useThemeVersion();\n const [ready, setReady] = useState(false);\n const [drawn, setDrawn] = useState(false);\n // The latest size and callbacks, read by the loader without restarting it.\n const size = useRef({ width, height });\n const itemRef = useRef(onItem);\n const failRef = useRef(onFail);\n useEffect(() => {\n size.current = { width, height };\n itemRef.current = onItem;\n failRef.current = onFail;\n });\n\n // Load the engine once the chart is near the screen; init; dispose with the component.\n useEffect(() => {\n if (!near) return undefined;\n let alive = true;\n Promise.all([engine(), RENDERERS[renderer]()]).then(\n ([module, painter]) => {\n if (!alive || !ref.current) return;\n install(module);\n painter.install();\n const { init } = painter;\n const chart = init(ref.current, null, { renderer, ...size.current });\n chart.on(\"finished\", () => setDrawn(true));\n chart.on(\"click\", (params) => {\n const p = params as { seriesIndex?: number; dataIndex?: number };\n if (p.seriesIndex != null && p.dataIndex != null) itemRef.current?.({ seriesIndex: p.seriesIndex, dataIndex: p.dataIndex });\n });\n instance.current = chart;\n setReady(true);\n },\n () => alive && failRef.current(),\n );\n return () => {\n alive = false;\n instance.current?.dispose();\n instance.current = null;\n setReady(false);\n };\n }, [near, renderer, engine, instance]);\n\n useEffect(() => {\n if (ready) instance.current?.resize({ width, height });\n }, [ready, width, height, instance]);\n\n // The option: rebuilt from the theme resolved on the chart's element, on every change of data, size or theme.\n useEffect(() => {\n const chart = instance.current;\n if (!ready || !chart || !ref.current) return;\n const option = build(resolveTheme(ref.current), { width, height });\n chart.setOption({ ...option, animation: !reduced && (option.animation as boolean | undefined) !== false }, { notMerge: true });\n }, [ready, build, themeVersion, reduced, width, height, instance]);\n\n // The keyboard's active item: ECharts' own tooltip and highlight.\n useEffect(() => {\n const chart = instance.current;\n if (!ready || !chart) return;\n chart.dispatchAction({ type: \"downplay\" });\n if (active) {\n const target = { seriesIndex: active.seriesIndex, dataIndex: active.dataIndex, ...(active.dataType ? { dataType: active.dataType } : {}) };\n chart.dispatchAction({ type: \"highlight\", ...target });\n chart.dispatchAction({ type: \"showTip\", ...target });\n } else chart.dispatchAction({ type: \"hideTip\" });\n }, [ready, active, instance]);\n\n return (\n <>\n {!drawn && (\n <div className=\"kzc-skeleton\" aria-hidden>\n {[0.55, 0.8, 0.45, 0.95, 0.7, 0.6].map((h, i) => (\n <i key={i} style={{ height: `${h * 100}%` }} />\n ))}\n </div>\n )}\n <div ref={ref} className=\"kzc-host\" data-pending={drawn ? undefined : \"\"} aria-hidden />\n </>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,118 @@
1
+ "use client";
2
+
3
+ // src/core/shape.ts
4
+ var r = (n) => Math.round(n * 100) / 100;
5
+ function segments(points) {
6
+ const out = [];
7
+ let current = [];
8
+ for (const point of points) {
9
+ if (point) current.push(point);
10
+ else if (current.length) {
11
+ out.push(current);
12
+ current = [];
13
+ }
14
+ }
15
+ if (current.length) out.push(current);
16
+ return out;
17
+ }
18
+ function linePath(points, curve = "monotone") {
19
+ if (points.length === 0) return "";
20
+ const [x0, y0] = points[0];
21
+ if (points.length === 1) return `M${r(x0)},${r(y0)}`;
22
+ if (curve === "step") {
23
+ let d2 = `M${r(x0)},${r(y0)}`;
24
+ for (let i = 1; i < points.length; i += 1) {
25
+ const [px] = points[i - 1];
26
+ const [x, y] = points[i];
27
+ const mid = (px + x) / 2;
28
+ d2 += `H${r(mid)}V${r(y)}H${r(x)}`;
29
+ }
30
+ return d2;
31
+ }
32
+ if (curve === "linear" || points.length === 2) return points.map(([x, y], i) => `${i ? "L" : "M"}${r(x)},${r(y)}`).join("");
33
+ const tangents = monotoneTangents(points);
34
+ let d = `M${r(x0)},${r(y0)}`;
35
+ for (let i = 1; i < points.length; i += 1) {
36
+ const [xa, ya] = points[i - 1];
37
+ const [xb, yb] = points[i];
38
+ const h = (xb - xa) / 3;
39
+ d += `C${r(xa + h)},${r(ya + h * tangents[i - 1])} ${r(xb - h)},${r(yb - h * tangents[i])} ${r(xb)},${r(yb)}`;
40
+ }
41
+ return d;
42
+ }
43
+ function monotoneTangents(points) {
44
+ const n = points.length;
45
+ const slopes = [];
46
+ for (let i = 0; i < n - 1; i += 1) {
47
+ const [xa, ya] = points[i];
48
+ const [xb, yb] = points[i + 1];
49
+ slopes.push(xb === xa ? 0 : (yb - ya) / (xb - xa));
50
+ }
51
+ const tangents = [slopes[0]];
52
+ for (let i = 1; i < n - 1; i += 1) {
53
+ const a = slopes[i - 1];
54
+ const b = slopes[i];
55
+ tangents.push(a * b <= 0 ? 0 : 3 * a * b / (Math.max(a, b) * 2 + Math.min(a, b)) || 0);
56
+ }
57
+ tangents.push(slopes[n - 2]);
58
+ return tangents;
59
+ }
60
+ function areaPath(top, base, curve = "monotone") {
61
+ if (top.length === 0) return "";
62
+ const line = linePath(top, curve);
63
+ const bottom = typeof base === "number" ? [top[top.length - 1], top[0]].map(([x]) => [x, base]) : [...base].reverse();
64
+ if (typeof base === "number") return `${line}L${r(bottom[0][0])},${r(base)}L${r(bottom[1][0])},${r(base)}Z`;
65
+ return `${line}L${linePath(bottom, curve).slice(1)}Z`;
66
+ }
67
+ function barPath(x, y, width, height, radius = 4, horizontal = false, negative = false) {
68
+ if (width <= 0 || height <= 0) return "";
69
+ const rad = Math.min(radius, horizontal ? height / 2 : width / 2, horizontal ? width : height);
70
+ if (!horizontal) {
71
+ if (!negative) {
72
+ return `M${r(x)},${r(y + height)}V${r(y + rad)}Q${r(x)},${r(y)} ${r(x + rad)},${r(y)}H${r(x + width - rad)}Q${r(x + width)},${r(y)} ${r(x + width)},${r(y + rad)}V${r(y + height)}Z`;
73
+ }
74
+ return `M${r(x)},${r(y)}V${r(y + height - rad)}Q${r(x)},${r(y + height)} ${r(x + rad)},${r(y + height)}H${r(x + width - rad)}Q${r(x + width)},${r(y + height)} ${r(x + width)},${r(y + height - rad)}V${r(y)}Z`;
75
+ }
76
+ if (!negative) {
77
+ return `M${r(x)},${r(y)}H${r(x + width - rad)}Q${r(x + width)},${r(y)} ${r(x + width)},${r(y + rad)}V${r(y + height - rad)}Q${r(x + width)},${r(y + height)} ${r(x + width - rad)},${r(y + height)}H${r(x)}Z`;
78
+ }
79
+ return `M${r(x + width)},${r(y)}H${r(x + rad)}Q${r(x)},${r(y)} ${r(x)},${r(y + rad)}V${r(y + height - rad)}Q${r(x)},${r(y + height)} ${r(x + rad)},${r(y + height)}H${r(x + width)}Z`;
80
+ }
81
+ function polar(cx, cy, radius, angle) {
82
+ return [cx + radius * Math.sin(angle), cy - radius * Math.cos(angle)];
83
+ }
84
+ function arcPath(cx, cy, inner, outer, start, end) {
85
+ const sweep = end - start;
86
+ if (sweep <= 0 || outer <= 0) return "";
87
+ if (sweep >= Math.PI * 2 - 1e-6) {
88
+ const mid = start + Math.PI;
89
+ return `${arcPath(cx, cy, inner, outer, start, mid)}${arcPath(cx, cy, inner, outer, mid, start + Math.PI * 2)}`;
90
+ }
91
+ const large = sweep > Math.PI ? 1 : 0;
92
+ const [ox0, oy0] = polar(cx, cy, outer, start);
93
+ const [ox1, oy1] = polar(cx, cy, outer, end);
94
+ let d = `M${r(ox0)},${r(oy0)}A${r(outer)},${r(outer)} 0 ${large} 1 ${r(ox1)},${r(oy1)}`;
95
+ if (inner > 0) {
96
+ const [ix1, iy1] = polar(cx, cy, inner, end);
97
+ const [ix0, iy0] = polar(cx, cy, inner, start);
98
+ d += `L${r(ix1)},${r(iy1)}A${r(inner)},${r(inner)} 0 ${large} 0 ${r(ix0)},${r(iy0)}Z`;
99
+ } else d += `L${r(cx)},${r(cy)}Z`;
100
+ return d;
101
+ }
102
+ function strokeArcPath(cx, cy, radius, start, end) {
103
+ if (end - start <= 0) return "";
104
+ const [x0, y0] = polar(cx, cy, radius, start);
105
+ const [x1, y1] = polar(cx, cy, radius, end);
106
+ return `M${r(x0)},${r(y0)}A${r(radius)},${r(radius)} 0 ${end - start > Math.PI ? 1 : 0} 1 ${r(x1)},${r(y1)}`;
107
+ }
108
+
109
+ export {
110
+ segments,
111
+ linePath,
112
+ areaPath,
113
+ barPath,
114
+ polar,
115
+ arcPath,
116
+ strokeArcPath
117
+ };
118
+ //# sourceMappingURL=chunk-OB5EFDDH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/shape.ts"],"sourcesContent":["// SVG path data for the marks: lines (linear, monotone, step), areas, bars with a rounded data end, arcs. Shared by\n// the web (`<path d>`) and React Native (react-native-svg's `<Path d>`): the same geometry on both platforms.\n\nexport type Point = readonly [number, number];\nexport type Curve = \"linear\" | \"monotone\" | \"step\";\n\nconst r = (n: number) => Math.round(n * 100) / 100;\n\n/** The segments of a line, split where a value is missing (a gap stays a gap, never a fake zero). */\nexport function segments(points: readonly (Point | null)[]): Point[][] {\n const out: Point[][] = [];\n let current: Point[] = [];\n for (const point of points) {\n if (point) current.push(point);\n else if (current.length) {\n out.push(current);\n current = [];\n }\n }\n if (current.length) out.push(current);\n return out;\n}\n\n/** The path of one segment. `monotone` (Fritsch–Carlson) never overshoots: a curve that never invents a peak. */\nexport function linePath(points: readonly Point[], curve: Curve = \"monotone\"): string {\n if (points.length === 0) return \"\";\n const [x0, y0] = points[0]!;\n if (points.length === 1) return `M${r(x0)},${r(y0)}`;\n if (curve === \"step\") {\n let d = `M${r(x0)},${r(y0)}`;\n for (let i = 1; i < points.length; i += 1) {\n const [px] = points[i - 1]!;\n const [x, y] = points[i]!;\n const mid = (px + x) / 2;\n d += `H${r(mid)}V${r(y)}H${r(x)}`;\n }\n return d;\n }\n if (curve === \"linear\" || points.length === 2) return points.map(([x, y], i) => `${i ? \"L\" : \"M\"}${r(x)},${r(y)}`).join(\"\");\n const tangents = monotoneTangents(points);\n let d = `M${r(x0)},${r(y0)}`;\n for (let i = 1; i < points.length; i += 1) {\n const [xa, ya] = points[i - 1]!;\n const [xb, yb] = points[i]!;\n const h = (xb - xa) / 3;\n d += `C${r(xa + h)},${r(ya + h * tangents[i - 1]!)} ${r(xb - h)},${r(yb - h * tangents[i]!)} ${r(xb)},${r(yb)}`;\n }\n return d;\n}\n\nfunction monotoneTangents(points: readonly Point[]): number[] {\n const n = points.length;\n const slopes: number[] = [];\n for (let i = 0; i < n - 1; i += 1) {\n const [xa, ya] = points[i]!;\n const [xb, yb] = points[i + 1]!;\n slopes.push(xb === xa ? 0 : (yb - ya) / (xb - xa));\n }\n const tangents = [slopes[0]!];\n for (let i = 1; i < n - 1; i += 1) {\n const a = slopes[i - 1]!;\n const b = slopes[i]!;\n tangents.push(a * b <= 0 ? 0 : (3 * a * b) / (Math.max(a, b) * 2 + Math.min(a, b)) || 0);\n }\n tangents.push(slopes[n - 2]!);\n return tangents;\n}\n\n/** An area under (or between) lines: the top points left to right, then the base right to left. */\nexport function areaPath(top: readonly Point[], base: readonly Point[] | number, curve: Curve = \"monotone\"): string {\n if (top.length === 0) return \"\";\n const line = linePath(top, curve);\n const bottom: Point[] = typeof base === \"number\" ? [top[top.length - 1]!, top[0]!].map(([x]) => [x, base] as Point) : [...base].reverse();\n if (typeof base === \"number\") return `${line}L${r(bottom[0]![0])},${r(base)}L${r(bottom[1]![0])},${r(base)}Z`;\n return `${line}L${linePath(bottom, curve).slice(1)}Z`;\n}\n\n/**\n * A bar from its baseline to its value, the data end rounded (`radius`, 4 px by default), square on the baseline.\n * `horizontal` bars grow to the right (or left for a negative value).\n */\nexport function barPath(x: number, y: number, width: number, height: number, radius = 4, horizontal = false, negative = false): string {\n if (width <= 0 || height <= 0) return \"\";\n const rad = Math.min(radius, horizontal ? height / 2 : width / 2, horizontal ? width : height);\n if (!horizontal) {\n if (!negative) {\n // Rounded at the top, square at the baseline (bottom).\n return `M${r(x)},${r(y + height)}V${r(y + rad)}Q${r(x)},${r(y)} ${r(x + rad)},${r(y)}H${r(x + width - rad)}Q${r(x + width)},${r(y)} ${r(x + width)},${r(y + rad)}V${r(y + height)}Z`;\n }\n return `M${r(x)},${r(y)}V${r(y + height - rad)}Q${r(x)},${r(y + height)} ${r(x + rad)},${r(y + height)}H${r(x + width - rad)}Q${r(x + width)},${r(y + height)} ${r(x + width)},${r(y + height - rad)}V${r(y)}Z`;\n }\n if (!negative) {\n return `M${r(x)},${r(y)}H${r(x + width - rad)}Q${r(x + width)},${r(y)} ${r(x + width)},${r(y + rad)}V${r(y + height - rad)}Q${r(x + width)},${r(y + height)} ${r(x + width - rad)},${r(y + height)}H${r(x)}Z`;\n }\n return `M${r(x + width)},${r(y)}H${r(x + rad)}Q${r(x)},${r(y)} ${r(x)},${r(y + rad)}V${r(y + height - rad)}Q${r(x)},${r(y + height)} ${r(x + rad)},${r(y + height)}H${r(x + width)}Z`;\n}\n\n/** A point on a circle, the angle in radians from twelve o'clock, clockwise. */\nexport function polar(cx: number, cy: number, radius: number, angle: number): Point {\n return [cx + radius * Math.sin(angle), cy - radius * Math.cos(angle)];\n}\n\n/**\n * A ring sector (a pie slice when `inner` is 0), from `start` to `end` (radians, clockwise from twelve o'clock).\n * A full turn is drawn as two halves: an SVG arc cannot start and end on the same point.\n */\nexport function arcPath(cx: number, cy: number, inner: number, outer: number, start: number, end: number): string {\n const sweep = end - start;\n if (sweep <= 0 || outer <= 0) return \"\";\n if (sweep >= Math.PI * 2 - 1e-6) {\n const mid = start + Math.PI;\n return `${arcPath(cx, cy, inner, outer, start, mid)}${arcPath(cx, cy, inner, outer, mid, start + Math.PI * 2)}`;\n }\n const large = sweep > Math.PI ? 1 : 0;\n const [ox0, oy0] = polar(cx, cy, outer, start);\n const [ox1, oy1] = polar(cx, cy, outer, end);\n let d = `M${r(ox0)},${r(oy0)}A${r(outer)},${r(outer)} 0 ${large} 1 ${r(ox1)},${r(oy1)}`;\n if (inner > 0) {\n const [ix1, iy1] = polar(cx, cy, inner, end);\n const [ix0, iy0] = polar(cx, cy, inner, start);\n d += `L${r(ix1)},${r(iy1)}A${r(inner)},${r(inner)} 0 ${large} 0 ${r(ix0)},${r(iy0)}Z`;\n } else d += `L${r(cx)},${r(cy)}Z`;\n return d;\n}\n\n/** An open arc (a gauge's track), stroked rather than filled. */\nexport function strokeArcPath(cx: number, cy: number, radius: number, start: number, end: number): string {\n if (end - start <= 0) return \"\";\n const [x0, y0] = polar(cx, cy, radius, start);\n const [x1, y1] = polar(cx, cy, radius, end);\n return `M${r(x0)},${r(y0)}A${r(radius)},${r(radius)} 0 ${end - start > Math.PI ? 1 : 0} 1 ${r(x1)},${r(y1)}`;\n}\n"],"mappings":"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","names":["d"]}