@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
package/dist/native.js ADDED
@@ -0,0 +1,875 @@
1
+ // src/core/labels.ts
2
+ var DEFAULT_LABELS = {
3
+ showData: "Show data",
4
+ hideData: "Hide data",
5
+ tableCaption: "{title} \u2014 data",
6
+ exportPng: "PNG",
7
+ exportSvg: "SVG",
8
+ exportCsv: "CSV",
9
+ loading: "Loading chart\u2026",
10
+ empty: "No data for this period yet.",
11
+ error: "The chart could not be loaded.",
12
+ keyboardHint: "Use the arrow keys to move between points, Home and End to jump to the ends.",
13
+ roleDescription: "chart",
14
+ summaryIntro: "{kind}, {count}.",
15
+ summarySeries: "{label}: from {first} to {last}",
16
+ summaryRange: "lowest {min} ({minAt}), highest {max} ({maxAt})",
17
+ summaryTrendUp: "up {change}",
18
+ summaryTrendDown: "down {change}",
19
+ summaryTrendFlat: "stable",
20
+ summaryTotal: "total {total}",
21
+ summaryThreshold: "{label} at {value}",
22
+ summaryShare: "{label} {value} ({share})",
23
+ summaryCorrelation: "correlation {r}",
24
+ summaryConversion: "{from} \u2192 {to} {rate}",
25
+ summaryOverall: "overall {rate}",
26
+ summaryPeak: "peak {value} ({at})",
27
+ summaryActive: "{count} with a value",
28
+ summaryOhlc: "opened at {open}, closed at {close}, low {low}, high {high}",
29
+ kinds: {
30
+ line: "Line chart",
31
+ area: "Area chart",
32
+ bar: "Bar chart",
33
+ pie: "Pie chart",
34
+ donut: "Donut chart",
35
+ gauge: "Gauge",
36
+ sparkline: "Sparkline",
37
+ radar: "Radar chart",
38
+ heatmap: "Heatmap",
39
+ calendar: "Calendar heatmap",
40
+ sankey: "Flow diagram",
41
+ funnel: "Funnel",
42
+ candlestick: "Candlestick chart",
43
+ treemap: "Treemap",
44
+ scatter: "Scatter chart",
45
+ map: "Map",
46
+ globe: "Globe",
47
+ chart: "Chart"
48
+ },
49
+ category: "Category",
50
+ value: "Value",
51
+ total: "Total",
52
+ noValue: "\u2014"
53
+ };
54
+ function mergeLabels(...layers) {
55
+ let out = DEFAULT_LABELS;
56
+ for (const layer of layers) {
57
+ if (!layer) continue;
58
+ out = { ...out, ...layer, kinds: { ...out.kinds, ...layer.kinds } };
59
+ }
60
+ return out;
61
+ }
62
+ function capitalize(text) {
63
+ return text.charAt(0).toLocaleUpperCase() + text.slice(1);
64
+ }
65
+ function fill(template, values) {
66
+ return template.replace(/\{(\w+)\}/g, (match, name) => name in values ? String(values[name]) : match);
67
+ }
68
+
69
+ // src/native/cartesian.tsx
70
+ import { useMemo as useMemo2, useState as useState2 } from "react";
71
+ import Svg, { Circle, G, Line, Path, Text as SvgText } from "react-native-svg";
72
+
73
+ // src/core/data.ts
74
+ function read(accessor, datum, index) {
75
+ return typeof accessor === "function" ? accessor(datum, index) : datum[accessor];
76
+ }
77
+ var toNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
78
+ function normalizeSeries(series, y, label) {
79
+ if (series?.length) return series;
80
+ if (y !== void 0) return [{ key: y, label: label ?? (typeof y === "string" ? y : "") }];
81
+ return [];
82
+ }
83
+ function tabulate(data, x, series) {
84
+ return {
85
+ categories: data.map((datum, i) => x === void 0 ? i + 1 : read(x, datum, i)),
86
+ series: series.map((spec, s) => ({
87
+ id: typeof spec.key === "string" ? spec.key : `series-${s}`,
88
+ label: spec.label,
89
+ values: data.map((datum, i) => toNumber(read(spec.key, datum, i))),
90
+ color: spec.color,
91
+ dashed: spec.dashed,
92
+ slot: s % 8 + 1
93
+ }))
94
+ };
95
+ }
96
+ function extent(series, stacked = false) {
97
+ let min = Number.POSITIVE_INFINITY;
98
+ let max = Number.NEGATIVE_INFINITY;
99
+ const count = series[0]?.values.length ?? 0;
100
+ if (stacked) {
101
+ for (let i = 0; i < count; i += 1) {
102
+ let pos = 0;
103
+ let neg = 0;
104
+ for (const s of series) {
105
+ const v = s.values[i] ?? 0;
106
+ if (v >= 0) pos += v;
107
+ else neg += v;
108
+ }
109
+ min = Math.min(min, neg);
110
+ max = Math.max(max, pos);
111
+ }
112
+ } else {
113
+ for (const s of series) {
114
+ for (const v of s.values) {
115
+ if (v == null) continue;
116
+ min = Math.min(min, v);
117
+ max = Math.max(max, v);
118
+ }
119
+ }
120
+ }
121
+ if (min === Number.POSITIVE_INFINITY) return [0, 0];
122
+ return [min, max];
123
+ }
124
+ function stack(series) {
125
+ const count = series[0]?.values.length ?? 0;
126
+ const out = series.map(() => []);
127
+ for (let i = 0; i < count; i += 1) {
128
+ let pos = 0;
129
+ let neg = 0;
130
+ series.forEach((s, k) => {
131
+ const v = s.values[i] ?? 0;
132
+ if (v >= 0) {
133
+ out[k].push({ base: pos, top: pos + v });
134
+ pos += v;
135
+ } else {
136
+ out[k].push({ base: neg, top: neg + v });
137
+ neg += v;
138
+ }
139
+ });
140
+ }
141
+ return out;
142
+ }
143
+ function summarize(series, categories, writeCategory) {
144
+ let min = null;
145
+ let max = null;
146
+ let first = null;
147
+ let last = null;
148
+ let total = 0;
149
+ let count = 0;
150
+ series.values.forEach((v, i) => {
151
+ if (v == null) return;
152
+ count += 1;
153
+ total += v;
154
+ if (first === null) first = v;
155
+ last = v;
156
+ if (!min || v < min.value) min = { value: v, category: writeCategory(categories[i]) };
157
+ if (!max || v > max.value) max = { value: v, category: writeCategory(categories[i]) };
158
+ });
159
+ const change = first !== null && last !== null && first !== 0 && count > 1 ? last / first - 1 : null;
160
+ const trend = count < 2 || change === null ? count < 2 ? "none" : last > first ? "up" : last < first ? "down" : "flat" : Math.abs(change) < 0.01 ? "flat" : change > 0 ? "up" : "down";
161
+ return { label: series.label, count, min, max, first, last, total, change, trend };
162
+ }
163
+
164
+ // src/core/describe.ts
165
+ function describeSeries(table, { kind, labels, value, category, share, thresholds = [] }) {
166
+ const points = table.categories.length;
167
+ const first = points ? category(table.categories[0]) : "";
168
+ const last = points ? category(table.categories[points - 1]) : "";
169
+ const count = table.series.length > 1 ? `${table.series.length} \xD7 ${points}` : String(points);
170
+ const intro = fill(labels.summaryIntro, { kind: labels.kinds[kind], count: points > 1 ? `${count} (${first} \u2013 ${last})` : count });
171
+ const sentences = table.series.map((series) => {
172
+ const s = summarize(series, table.categories, category);
173
+ if (!s.count) return `${s.label}: ${labels.noValue}.`;
174
+ const parts = [fill(labels.summarySeries, { label: s.label, first: value(s.first), last: value(s.last) })];
175
+ 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 }));
176
+ if (s.trend === "up" || s.trend === "down") {
177
+ const template = s.trend === "up" ? labels.summaryTrendUp : labels.summaryTrendDown;
178
+ if (s.change !== null) parts.push(fill(template, { change: share(Math.abs(s.change)) }));
179
+ } else if (s.trend === "flat") parts.push(labels.summaryTrendFlat);
180
+ return `${parts.join(", ")}.`;
181
+ });
182
+ const marks = thresholds.map((t) => fill(labels.summaryThreshold, { label: t.label, value: value(t.value) }));
183
+ return [intro, ...sentences, ...marks.length ? [`${marks.join(", ")}.`] : []].join(" ");
184
+ }
185
+ function describeParts(kind, parts, { labels, value, share }) {
186
+ const total = parts.reduce((sum, p) => sum + Math.max(0, p.value), 0);
187
+ const intro = fill(labels.summaryIntro, { kind: labels.kinds[kind], count: parts.length });
188
+ const sorted = [...parts].sort((a, b) => b.value - a.value);
189
+ const items = sorted.map((p) => fill(labels.summaryShare, { label: p.label, value: value(p.value), share: share(total ? p.value / total : 0) }));
190
+ return `${intro} ${items.join(", ")}. ${capitalize(fill(labels.summaryTotal, { total: value(total) }))}.`;
191
+ }
192
+
193
+ // src/core/format.ts
194
+ import { currencyDigits, formatCompact, formatDate, formatMoney, formatNumber, formatPercent, getDateTimeFormat, getNumberFormat } from "@krizaka/intl";
195
+ function valueFormatter(format = "number", locale, noValue = "\u2014", axis = false) {
196
+ const write = writerOf(format, locale, axis);
197
+ return (value) => value == null || Number.isNaN(value) ? noValue : write(value);
198
+ }
199
+ function writerOf(format, locale, axis) {
200
+ if (typeof format === "function") return (value) => format(value, locale);
201
+ if (format === "integer") return (value) => formatNumber(Math.round(value), { locale, maximumFractionDigits: 0 });
202
+ if (format === "compact") return (value) => formatCompact(value, { locale });
203
+ if (format === "percent") return (value) => formatPercent(value, { locale, maximumFractionDigits: axis ? 0 : 1 });
204
+ if (format === "number") {
205
+ return (value) => axis && Math.abs(value) >= 1e4 ? formatCompact(value, { locale }) : formatNumber(value, { locale, maximumFractionDigits: 2 });
206
+ }
207
+ if (format.style === "money") {
208
+ const { currency } = format;
209
+ const digits = currencyDigits(currency);
210
+ return (value) => {
211
+ const minor = Math.round(value);
212
+ if ((axis || format.compact) && Math.abs(minor) >= 1e6) {
213
+ const options2 = { style: "currency", currency, currencyDisplay: "narrowSymbol", notation: "compact", minimumFractionDigits: 0, maximumFractionDigits: 1 };
214
+ return getNumberFormat(locale, options2).format(minor / 10 ** digits);
215
+ }
216
+ if (axis && minor % 10 ** digits === 0) {
217
+ return getNumberFormat(locale, { style: "currency", currency, minimumFractionDigits: 0, maximumFractionDigits: 0 }).format(minor / 10 ** digits);
218
+ }
219
+ return formatMoney(minor, { currency, locale });
220
+ };
221
+ }
222
+ if (format.style === "unit") {
223
+ const { unit } = format;
224
+ const compact = axis || format.compact;
225
+ const options2 = { style: "unit", unit, unitDisplay: "short", ...compact ? { notation: "compact" } : {}, maximumFractionDigits: compact ? 1 : 2 };
226
+ return (value) => getNumberFormat(locale, options2).format(value);
227
+ }
228
+ const { options } = format;
229
+ return (value) => formatNumber(value, { locale, ...options });
230
+ }
231
+ function asDate(value) {
232
+ if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value;
233
+ if (typeof value === "number" && value > 1e10) return new Date(value);
234
+ if (typeof value === "string" && /^\d{4}-\d{2}(-\d{2})?([T ][\d:.]+(Z|[+-]\d{2}:?\d{2})?)?$/.test(value)) {
235
+ const iso = value.length === 7 ? `${value}-01T00:00:00Z` : value.length === 10 ? `${value}T00:00:00Z` : value;
236
+ const date = new Date(iso);
237
+ return Number.isNaN(date.getTime()) ? null : date;
238
+ }
239
+ return null;
240
+ }
241
+ var DATE_OPTIONS = {
242
+ year: { year: "numeric", timeZone: "UTC" },
243
+ month: { month: "short", year: "numeric", timeZone: "UTC" },
244
+ day: { month: "short", day: "numeric", timeZone: "UTC" },
245
+ date: { dateStyle: "medium", timeZone: "UTC" },
246
+ time: { timeStyle: "short", timeZone: "UTC" },
247
+ datetime: { dateStyle: "medium", timeStyle: "short", timeZone: "UTC" }
248
+ };
249
+ function categoryFormatter(format, locale) {
250
+ if (typeof format === "function") return (category) => format(category, locale);
251
+ if (format === "text") return (category) => String(category ?? "");
252
+ return (category) => {
253
+ const date = asDate(category);
254
+ if (!date) return String(category ?? "");
255
+ const kind = format ?? guessPrecision(category);
256
+ if (kind === "date") return formatDate(date, { locale, style: "medium", timeZone: "UTC" });
257
+ return getDateTimeFormat(locale, DATE_OPTIONS[kind]).format(date);
258
+ };
259
+ }
260
+ function guessPrecision(category) {
261
+ if (typeof category === "string") {
262
+ if (category.length === 7) return "month";
263
+ if (category.length === 10) return "date";
264
+ return "datetime";
265
+ }
266
+ const date = asDate(category);
267
+ return date && date.getUTCHours() === 0 && date.getUTCMinutes() === 0 ? "date" : "datetime";
268
+ }
269
+ function shareFormatter(locale) {
270
+ return (ratio) => formatPercent(ratio, { locale, maximumFractionDigits: Math.abs(ratio) < 0.1 ? 1 : 0 });
271
+ }
272
+
273
+ // src/core/scale.ts
274
+ function niceStep(span, count) {
275
+ if (!(span > 0) || !(count > 0)) return 1;
276
+ const raw = span / count;
277
+ const power = 10 ** Math.floor(Math.log10(raw));
278
+ const fraction = raw / power;
279
+ const nice = fraction <= 1 ? 1 : fraction <= 2 ? 2 : fraction <= 2.5 ? 2.5 : fraction <= 5 ? 5 : 10;
280
+ return nice * power;
281
+ }
282
+ function niceDomain(min, max, count = 5) {
283
+ if (!Number.isFinite(min) || !Number.isFinite(max)) return { domain: [0, 1], ticks: [0, 1] };
284
+ if (min === max) {
285
+ if (min === 0) return { domain: [0, 1], ticks: [0, 0.5, 1] };
286
+ const pad = Math.abs(min) * 0.5;
287
+ [min, max] = min > 0 ? [0, max + pad] : [min - pad, 0];
288
+ }
289
+ const step = niceStep(max - min, count);
290
+ const lo = Math.floor(min / step) * step;
291
+ const hi = Math.ceil(max / step) * step;
292
+ const ticks = [];
293
+ const digits = Math.max(0, -Math.floor(Math.log10(step)) + 2);
294
+ for (let v = lo; v <= hi + step / 2; v += step) ticks.push(Number(v.toFixed(digits)));
295
+ return { domain: [lo, hi], ticks };
296
+ }
297
+ function linearScale(domain, range, ticks = domain) {
298
+ const [d0, d1] = domain;
299
+ const [r0, r1] = range;
300
+ const k = d1 === d0 ? 0 : (r1 - r0) / (d1 - d0);
301
+ const scale = ((value) => r0 + (value - d0) * k);
302
+ return Object.assign(scale, { domain, range, ticks });
303
+ }
304
+ function bandScale(count, range, padding = 0.3) {
305
+ const [r0, r1] = range;
306
+ const step = count > 0 ? (r1 - r0) / count : 0;
307
+ const bandwidth = step * (1 - padding);
308
+ const scale = ((index) => r0 + index * step + (step - bandwidth) / 2);
309
+ return Object.assign(scale, { bandwidth, step, count });
310
+ }
311
+ function pointScale(count, range) {
312
+ const [r0, r1] = range;
313
+ if (count <= 1) return () => (r0 + r1) / 2;
314
+ const step = (r1 - r0) / (count - 1);
315
+ return (index) => r0 + index * step;
316
+ }
317
+ function thinLabels(count, max) {
318
+ if (count <= max) return Array.from({ length: count }, (_, i) => i);
319
+ const every = Math.ceil(count / Math.max(1, max));
320
+ const out = [];
321
+ for (let i = 0; i < count; i += every) out.push(i);
322
+ if (out[out.length - 1] !== count - 1) {
323
+ if (count - 1 - out[out.length - 1] < every) out.pop();
324
+ out.push(count - 1);
325
+ }
326
+ return out;
327
+ }
328
+
329
+ // src/core/shape.ts
330
+ var r = (n) => Math.round(n * 100) / 100;
331
+ function segments(points) {
332
+ const out = [];
333
+ let current = [];
334
+ for (const point of points) {
335
+ if (point) current.push(point);
336
+ else if (current.length) {
337
+ out.push(current);
338
+ current = [];
339
+ }
340
+ }
341
+ if (current.length) out.push(current);
342
+ return out;
343
+ }
344
+ function linePath(points, curve = "monotone") {
345
+ if (points.length === 0) return "";
346
+ const [x0, y0] = points[0];
347
+ if (points.length === 1) return `M${r(x0)},${r(y0)}`;
348
+ if (curve === "step") {
349
+ let d2 = `M${r(x0)},${r(y0)}`;
350
+ for (let i = 1; i < points.length; i += 1) {
351
+ const [px] = points[i - 1];
352
+ const [x, y] = points[i];
353
+ const mid = (px + x) / 2;
354
+ d2 += `H${r(mid)}V${r(y)}H${r(x)}`;
355
+ }
356
+ return d2;
357
+ }
358
+ if (curve === "linear" || points.length === 2) return points.map(([x, y], i) => `${i ? "L" : "M"}${r(x)},${r(y)}`).join("");
359
+ const tangents = monotoneTangents(points);
360
+ let d = `M${r(x0)},${r(y0)}`;
361
+ for (let i = 1; i < points.length; i += 1) {
362
+ const [xa, ya] = points[i - 1];
363
+ const [xb, yb] = points[i];
364
+ const h = (xb - xa) / 3;
365
+ d += `C${r(xa + h)},${r(ya + h * tangents[i - 1])} ${r(xb - h)},${r(yb - h * tangents[i])} ${r(xb)},${r(yb)}`;
366
+ }
367
+ return d;
368
+ }
369
+ function monotoneTangents(points) {
370
+ const n = points.length;
371
+ const slopes = [];
372
+ for (let i = 0; i < n - 1; i += 1) {
373
+ const [xa, ya] = points[i];
374
+ const [xb, yb] = points[i + 1];
375
+ slopes.push(xb === xa ? 0 : (yb - ya) / (xb - xa));
376
+ }
377
+ const tangents = [slopes[0]];
378
+ for (let i = 1; i < n - 1; i += 1) {
379
+ const a = slopes[i - 1];
380
+ const b = slopes[i];
381
+ tangents.push(a * b <= 0 ? 0 : 3 * a * b / (Math.max(a, b) * 2 + Math.min(a, b)) || 0);
382
+ }
383
+ tangents.push(slopes[n - 2]);
384
+ return tangents;
385
+ }
386
+ function areaPath(top, base, curve = "monotone") {
387
+ if (top.length === 0) return "";
388
+ const line = linePath(top, curve);
389
+ const bottom = typeof base === "number" ? [top[top.length - 1], top[0]].map(([x]) => [x, base]) : [...base].reverse();
390
+ if (typeof base === "number") return `${line}L${r(bottom[0][0])},${r(base)}L${r(bottom[1][0])},${r(base)}Z`;
391
+ return `${line}L${linePath(bottom, curve).slice(1)}Z`;
392
+ }
393
+ function barPath(x, y, width, height, radius = 4, horizontal = false, negative = false) {
394
+ if (width <= 0 || height <= 0) return "";
395
+ const rad = Math.min(radius, horizontal ? height / 2 : width / 2, horizontal ? width : height);
396
+ if (!horizontal) {
397
+ if (!negative) {
398
+ 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`;
399
+ }
400
+ 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`;
401
+ }
402
+ if (!negative) {
403
+ 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`;
404
+ }
405
+ 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`;
406
+ }
407
+ function polar(cx, cy, radius, angle) {
408
+ return [cx + radius * Math.sin(angle), cy - radius * Math.cos(angle)];
409
+ }
410
+ function arcPath(cx, cy, inner, outer, start, end) {
411
+ const sweep = end - start;
412
+ if (sweep <= 0 || outer <= 0) return "";
413
+ if (sweep >= Math.PI * 2 - 1e-6) {
414
+ const mid = start + Math.PI;
415
+ return `${arcPath(cx, cy, inner, outer, start, mid)}${arcPath(cx, cy, inner, outer, mid, start + Math.PI * 2)}`;
416
+ }
417
+ const large = sweep > Math.PI ? 1 : 0;
418
+ const [ox0, oy0] = polar(cx, cy, outer, start);
419
+ const [ox1, oy1] = polar(cx, cy, outer, end);
420
+ let d = `M${r(ox0)},${r(oy0)}A${r(outer)},${r(outer)} 0 ${large} 1 ${r(ox1)},${r(oy1)}`;
421
+ if (inner > 0) {
422
+ const [ix1, iy1] = polar(cx, cy, inner, end);
423
+ const [ix0, iy0] = polar(cx, cy, inner, start);
424
+ d += `L${r(ix1)},${r(iy1)}A${r(inner)},${r(inner)} 0 ${large} 0 ${r(ix0)},${r(iy0)}Z`;
425
+ } else d += `L${r(cx)},${r(cy)}Z`;
426
+ return d;
427
+ }
428
+ function strokeArcPath(cx, cy, radius, start, end) {
429
+ if (end - start <= 0) return "";
430
+ const [x0, y0] = polar(cx, cy, radius, start);
431
+ const [x1, y1] = polar(cx, cy, radius, end);
432
+ return `M${r(x0)},${r(y0)}A${r(radius)},${r(radius)} 0 ${end - start > Math.PI ? 1 : 0} 1 ${r(x1)},${r(y1)}`;
433
+ }
434
+
435
+ // ../tokens/dist/native.js
436
+ var themes = /* @__PURE__ */ Object.freeze({ dark: /* @__PURE__ */ Object.freeze({
437
+ "surface0": "#0c0c0e",
438
+ "surface1": "#161618",
439
+ "surface2": "#1f1f23",
440
+ "surface3": "#2a2a2d",
441
+ "media": "#1b1b1d",
442
+ "borderSubtle": "rgba(255,255,255,0.06)",
443
+ "borderDefault": "rgba(255,255,255,0.1)",
444
+ "borderStrong": "rgba(255,255,255,0.16)",
445
+ "textPrimary": "#f5f5f5",
446
+ "textSecondary": "#a0a0a7",
447
+ "textMuted": "#73737d",
448
+ "textOnMedia": "#ffffff",
449
+ "accent": "#196df5",
450
+ "accentHover": "#0e5bd8",
451
+ "accentSoft": "rgba(25,109,245,0.1)",
452
+ "accentText": "#629cf8",
453
+ "accent2": "#196df5",
454
+ "onAccent": "#ffffff",
455
+ "ring": "#196df5",
456
+ "brandGradientFrom": "#0e1525",
457
+ "brandGradientVia": "#0e0f16",
458
+ "brandGradientTo": "#0c0c0e",
459
+ "success": "#10b77f",
460
+ "successText": "#36d399",
461
+ "warning": "#f59f0a",
462
+ "warningText": "#f6a823",
463
+ "danger": "#ef4343",
464
+ "dangerText": "#f87272",
465
+ "info": "#196df5",
466
+ "infoText": "#629cf8",
467
+ "scrim": "rgba(0,0,0,0.6)",
468
+ "scrimStrong": "rgba(0,0,0,0.8)",
469
+ "overlay": "rgba(0,0,0,0.7)"
470
+ }), light: /* @__PURE__ */ Object.freeze({
471
+ "surface0": "#fafafa",
472
+ "surface1": "#ffffff",
473
+ "surface2": "#f1f1f3",
474
+ "surface3": "#e4e4e7",
475
+ "media": "#e9e9ec",
476
+ "borderSubtle": "rgba(0,0,0,0.06)",
477
+ "borderDefault": "rgba(0,0,0,0.1)",
478
+ "borderStrong": "rgba(0,0,0,0.16)",
479
+ "textPrimary": "#18181b",
480
+ "textSecondary": "#64646d",
481
+ "textMuted": "#808089",
482
+ "textOnMedia": "#ffffff",
483
+ "accent": "#0a64f5",
484
+ "accentHover": "#0d55c9",
485
+ "accentSoft": "rgba(10,100,245,0.08)",
486
+ "accentText": "#0954ce",
487
+ "accent2": "#0a64f5",
488
+ "onAccent": "#ffffff",
489
+ "ring": "#0a64f5",
490
+ "brandGradientFrom": "#dcebfe",
491
+ "brandGradientVia": "#f3f6fc",
492
+ "brandGradientTo": "#fafafa",
493
+ "success": "#10b77f",
494
+ "successText": "#0a714e",
495
+ "warning": "#f59f0a",
496
+ "warningText": "#955104",
497
+ "danger": "#ef4343",
498
+ "dangerText": "#af1d1d",
499
+ "info": "#0a64f5",
500
+ "infoText": "#0954ce",
501
+ "scrim": "rgba(0,0,0,0.6)",
502
+ "scrimStrong": "rgba(0,0,0,0.8)",
503
+ "overlay": "rgba(0,0,0,0.7)"
504
+ }) });
505
+
506
+ // src/native/frame.tsx
507
+ import { createContext, useContext, useMemo, useState } from "react";
508
+ import { Pressable, StyleSheet, Text, useColorScheme, View } from "react-native";
509
+
510
+ // src/core/palette.ts
511
+ var HUES = {
512
+ blue: { light: "#2a78d6", dark: "#3987e5" },
513
+ orange: { light: "#eb6834", dark: "#d95926" },
514
+ aqua: { light: "#1baf7a", dark: "#199e70" },
515
+ yellow: { light: "#eda100", dark: "#c98500" },
516
+ magenta: { light: "#e87ba4", dark: "#d55181" },
517
+ green: { light: "#008300", dark: "#008300" },
518
+ violet: { light: "#6250d6", dark: "#9085e9" },
519
+ red: { light: "#e34948", dark: "#e66767" }
520
+ };
521
+ var ORDERS = {
522
+ krizaka: ["blue", "green", "magenta", "yellow", "aqua", "orange", "violet", "red"],
523
+ orazaka: ["orange", "aqua", "blue", "yellow", "magenta", "green", "violet", "red"],
524
+ orochia: ["violet", "magenta", "yellow", "aqua", "orange", "blue", "green", "red"]
525
+ };
526
+ function palette(brand, mode) {
527
+ return ORDERS[brand].map((hue) => HUES[hue][mode]);
528
+ }
529
+ var DIVERGING = {
530
+ light: { low: HUES.blue.light, high: HUES.red.light },
531
+ dark: { low: HUES.blue.dark, high: HUES.red.dark }
532
+ };
533
+
534
+ // src/native/frame.tsx
535
+ import { jsx, jsxs } from "react/jsx-runtime";
536
+ var THEMES = themes;
537
+ var Context = createContext({});
538
+ function ChartsProvider({ children, ...settings }) {
539
+ const parent = useContext(Context);
540
+ const value = useMemo(() => ({ ...parent, ...Object.fromEntries(Object.entries(settings).filter(([, v]) => v !== void 0)) }), [parent, settings]);
541
+ return /* @__PURE__ */ jsx(Context.Provider, { value, children });
542
+ }
543
+ function useNativeSettings(own) {
544
+ const shared = useContext(Context);
545
+ const device = useColorScheme();
546
+ const scheme = own.scheme ?? shared.scheme ?? (device === "light" ? "light" : "dark");
547
+ const brand = own.brand ?? shared.brand ?? "krizaka";
548
+ return useMemo(() => {
549
+ const theme = { ...THEMES[scheme], ...shared.theme, ...own.theme };
550
+ const colors = palette(brand, scheme);
551
+ const tones = { neutral: theme.textSecondary, accent: theme.accent, success: theme.success, warning: theme.warning, danger: theme.danger, info: theme.info };
552
+ return {
553
+ locale: own.locale ?? shared.locale ?? "en-US",
554
+ labels: mergeLabels(shared.labels, own.labels),
555
+ theme,
556
+ palette: colors,
557
+ color: (color, slot) => color === void 0 ? colors[(slot - 1) % 8] : typeof color === "number" ? colors[color - 1] : color in tones ? tones[color] : color
558
+ };
559
+ }, [scheme, brand, shared, own.locale, own.labels, own.theme]);
560
+ }
561
+ function NativeFrame({ frame, defaultHeight, resolved, summary, isEmpty, points, active, onActive, indexAt, legend, children }) {
562
+ const { title, hideTitle, height = defaultHeight, loading, empty, style } = frame;
563
+ const { theme, labels } = resolved;
564
+ const [width, setWidth] = useState(0);
565
+ const onLayout = (event) => setWidth(Math.round(event.nativeEvent.layout.width));
566
+ const readout = active !== null ? points[active] : null;
567
+ const n = points.length;
568
+ let body;
569
+ if (loading) body = /* @__PURE__ */ jsx(View, { style: [styles.state, { backgroundColor: theme.surface2 }], role: "progressbar", "aria-label": labels.loading });
570
+ else if (isEmpty)
571
+ body = empty ?? /* @__PURE__ */ jsx(View, { style: [styles.state, { borderColor: theme.borderDefault, borderWidth: StyleSheet.hairlineWidth, borderStyle: "dashed" }], children: /* @__PURE__ */ jsx(Text, { style: [styles.small, { color: theme.textSecondary }], children: labels.empty }) });
572
+ else body = width > 0 ? children(width, height) : null;
573
+ return /* @__PURE__ */ jsxs(View, { style: [styles.root, style], children: [
574
+ !hideTitle && /* @__PURE__ */ jsx(Text, { style: [styles.title, { color: theme.textPrimary }], role: "heading", children: title }),
575
+ legend,
576
+ /* @__PURE__ */ jsx(
577
+ Pressable,
578
+ {
579
+ onLayout,
580
+ style: { height },
581
+ disabled: isEmpty || loading,
582
+ onPress: (event) => indexAt && onActive(indexAt(event.nativeEvent.locationX, width)),
583
+ accessible: true,
584
+ accessibilityRole: n ? "adjustable" : "image",
585
+ accessibilityLabel: `${title}. ${summary}`,
586
+ accessibilityValue: n ? { min: 0, max: n - 1, now: active ?? 0, ...readout ? { text: readout } : {} } : void 0,
587
+ "aria-valuemin": n ? 0 : void 0,
588
+ "aria-valuemax": n ? n - 1 : void 0,
589
+ "aria-valuenow": n ? active ?? 0 : void 0,
590
+ "aria-valuetext": readout ?? void 0,
591
+ accessibilityActions: n ? [{ name: "increment" }, { name: "decrement" }] : [],
592
+ onAccessibilityAction: (event) => {
593
+ if (!n) return;
594
+ if (event.nativeEvent.actionName === "increment") onActive(Math.min(n - 1, (active ?? -1) + 1));
595
+ if (event.nativeEvent.actionName === "decrement") onActive(Math.max(0, (active ?? n) - 1));
596
+ },
597
+ children: body
598
+ }
599
+ ),
600
+ readout ? /* @__PURE__ */ jsx(Text, { style: [styles.small, { color: theme.textSecondary }], "aria-hidden": true, children: readout }) : null
601
+ ] });
602
+ }
603
+ function NativeLegend({ items, theme }) {
604
+ if (items.length < 2) return null;
605
+ return /* @__PURE__ */ jsx(View, { style: styles.legend, "aria-hidden": true, children: items.map((item) => /* @__PURE__ */ jsxs(View, { style: styles.legendItem, children: [
606
+ /* @__PURE__ */ jsx(View, { style: [styles.key, { backgroundColor: item.color }] }),
607
+ /* @__PURE__ */ jsx(Text, { style: [styles.small, { color: theme.textSecondary }], children: item.label })
608
+ ] }, item.label)) });
609
+ }
610
+ var styles = StyleSheet.create({
611
+ root: { gap: 8 },
612
+ title: { fontSize: 14, fontWeight: "600", lineHeight: 20 },
613
+ small: { fontSize: 12, lineHeight: 16, fontVariant: ["tabular-nums"] },
614
+ state: { flex: 1, borderRadius: 10, alignItems: "center", justifyContent: "center", padding: 16 },
615
+ legend: { flexDirection: "row", flexWrap: "wrap", columnGap: 14, rowGap: 4 },
616
+ legendItem: { flexDirection: "row", alignItems: "center", gap: 6 },
617
+ key: { width: 10, height: 10, borderRadius: 3 }
618
+ });
619
+
620
+ // src/native/cartesian.tsx
621
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
622
+ var textWidth = (text) => Math.ceil(text.length * 6.4);
623
+ function NativeCartesian({ props, mode }) {
624
+ const { data, x, y, yLabel, series: seriesProp, format, xFormat, thresholds = [] } = props;
625
+ const resolved = useNativeSettings(props);
626
+ const { locale, labels, theme, color } = resolved;
627
+ const specs = useMemo2(() => normalizeSeries(seriesProp, y, yLabel), [seriesProp, y, yLabel]);
628
+ const table = useMemo2(() => tabulate(data, x, specs), [data, x, specs]);
629
+ const fmt = useMemo2(
630
+ () => ({ value: valueFormatter(format, locale, labels.noValue), axis: valueFormatter(format, locale, labels.noValue, true), category: categoryFormatter(xFormat, locale), share: shareFormatter(locale) }),
631
+ [format, xFormat, locale, labels.noValue]
632
+ );
633
+ const isEmpty = table.series.length === 0 || table.series.every((s) => s.values.every((v) => v == null));
634
+ const summary = isEmpty ? labels.empty : describeSeries(table, { kind: mode.kind, labels, value: fmt.value, category: fmt.category, share: fmt.share, thresholds });
635
+ const points = table.categories.map((c, i) => `${fmt.category(c)}: ${table.series.map((s) => `${s.label} ${fmt.value(s.values[i])}`).join(", ")}`);
636
+ const [active, setActive] = useState2(null);
637
+ const colors = table.series.map((s) => color(s.color, s.slot));
638
+ const count = table.categories.length;
639
+ const stacked = Boolean(mode.stacked);
640
+ return /* @__PURE__ */ jsx2(
641
+ NativeFrame,
642
+ {
643
+ frame: props,
644
+ defaultHeight: 220,
645
+ resolved,
646
+ summary,
647
+ isEmpty,
648
+ points,
649
+ active,
650
+ onActive: setActive,
651
+ legend: /* @__PURE__ */ jsx2(NativeLegend, { theme, items: table.series.map((s, i) => ({ label: s.label, color: colors[i] })) }),
652
+ indexAt: (px, width) => {
653
+ if (!count) return null;
654
+ const left = 44;
655
+ return Math.max(0, Math.min(count - 1, mode.kind === "bar" ? Math.floor((px - left) / (width - left - 8) * count) : Math.round((px - left) / (width - left - 8) * (count - 1))));
656
+ },
657
+ children: (width, height) => {
658
+ let [lo, hi] = extent(table.series, stacked);
659
+ for (const t of thresholds) {
660
+ lo = Math.min(lo, t.value);
661
+ hi = Math.max(hi, t.value);
662
+ }
663
+ lo = Math.min(0, lo);
664
+ hi = Math.max(0, hi);
665
+ const nice = niceDomain(lo, hi, 4);
666
+ const ticks = nice.ticks.map((t) => fmt.axis(t));
667
+ const x0 = Math.max(...ticks.map(textWidth)) + 8;
668
+ const x1 = width - 8;
669
+ const y0 = 8;
670
+ const y1 = height - 22;
671
+ const value = linearScale(nice.domain, [y1, y0], nice.ticks);
672
+ const band = bandScale(count, [x0, x1], 0.3);
673
+ const at = mode.kind === "bar" ? (i) => band(i) + band.bandwidth / 2 : pointScale(count, [x0, x1]);
674
+ const stacks = stacked ? stack(table.series) : null;
675
+ const widest = Math.max(...table.categories.map((c) => textWidth(fmt.category(c))));
676
+ const labelsAt = thinLabels(count, Math.max(2, Math.floor((x1 - x0) / (widest + 16))));
677
+ const groups = stacked ? 1 : table.series.length;
678
+ const thickness = Math.min(20, Math.max(2, (band.bandwidth - (groups - 1) * 2) / groups));
679
+ return /* @__PURE__ */ jsxs2(Svg, { width, height, children: [
680
+ nice.ticks.map((t, i) => /* @__PURE__ */ jsxs2(G, { children: [
681
+ /* @__PURE__ */ jsx2(Line, { x1: x0, x2: x1, y1: value(t), y2: value(t), stroke: t === 0 ? theme.borderDefault : theme.borderSubtle, strokeWidth: 1 }),
682
+ /* @__PURE__ */ jsx2(SvgText, { x: x0 - 6, y: value(t) + 4, fontSize: 11, fill: theme.textSecondary, textAnchor: "end", children: ticks[i] })
683
+ ] }, t)),
684
+ labelsAt.map((i) => /* @__PURE__ */ jsx2(SvgText, { x: at(i), y: y1 + 16, fontSize: 11, fill: theme.textSecondary, textAnchor: mode.kind !== "bar" && i === 0 ? "start" : mode.kind !== "bar" && i === count - 1 ? "end" : "middle", children: fmt.category(table.categories[i]) }, i)),
685
+ active !== null && /* @__PURE__ */ jsx2(Line, { x1: at(active), x2: at(active), y1: y0, y2: y1, stroke: theme.borderDefault, strokeWidth: 1 }),
686
+ table.series.map((s, k) => {
687
+ if (mode.kind === "bar") {
688
+ return s.values.map((v, i) => {
689
+ const seg = stacks?.[k]?.[i];
690
+ const from = seg ? seg.base : 0;
691
+ const to = seg ? seg.top : v ?? 0;
692
+ if (from === to) return null;
693
+ const isTop = !stacked || k === table.series.length - 1;
694
+ const top = Math.min(value(from), value(to));
695
+ const size = Math.abs(value(to) - value(from)) - (isTop ? 0 : 2);
696
+ const left = band(i) + (band.bandwidth - (thickness * groups + (groups - 1) * 2)) / 2 + (stacked ? 0 : k * (thickness + 2));
697
+ return /* @__PURE__ */ jsx2(Path, { d: barPath(left, isTop ? top : top + 2, thickness, Math.max(0, size), isTop ? 4 : 0, false, to < from), fill: colors[k], opacity: active !== null && active !== i ? 0.4 : 1 }, `${k}-${i}`);
698
+ });
699
+ }
700
+ const pts = s.values.map((v, i) => v == null ? null : [at(i), value(stacks ? stacks[k][i].top : v)]);
701
+ return segments(pts).map((seg) => /* @__PURE__ */ jsxs2(G, { children: [
702
+ mode.kind === "area" && /* @__PURE__ */ jsx2(Path, { d: areaPath(seg, stacks && k > 0 ? seg.map(([px]) => [px, value(stacks[k][Math.round((px - x0) / (x1 - x0) * (count - 1))].base)]) : value(0), mode.curve), fill: colors[k], opacity: stacked ? 0.5 : 0.14 }),
703
+ /* @__PURE__ */ jsx2(Path, { d: linePath(seg, mode.curve), stroke: colors[k], strokeWidth: 2, fill: "none", strokeLinecap: "round", strokeLinejoin: "round", strokeDasharray: s.dashed ? "6 4" : void 0 })
704
+ ] }, `${k}-${seg[0][0]}`));
705
+ }),
706
+ thresholds.map((t, i) => /* @__PURE__ */ jsxs2(G, { children: [
707
+ /* @__PURE__ */ jsx2(Line, { x1: x0, x2: x1, y1: value(t.value), y2: value(t.value), stroke: color(t.tone ?? "neutral", 1), strokeWidth: 1.5, strokeDasharray: "6 4" }),
708
+ /* @__PURE__ */ jsx2(SvgText, { x: x1, y: value(t.value) - 6, fontSize: 11, fontWeight: "600", fill: theme.textPrimary, textAnchor: "end", children: t.label })
709
+ ] }, `t-${i}`)),
710
+ active !== null && mode.kind !== "bar" && table.series.map((s, k) => {
711
+ const v = s.values[active];
712
+ if (v == null) return null;
713
+ return /* @__PURE__ */ jsx2(Circle, { cx: at(active), cy: value(stacks ? stacks[k][active].top : v), r: 5, fill: colors[k], stroke: theme.surface1, strokeWidth: 2 }, k);
714
+ })
715
+ ] });
716
+ }
717
+ }
718
+ );
719
+ }
720
+ function LineChart({ curve = "monotone", ...props }) {
721
+ return /* @__PURE__ */ jsx2(NativeCartesian, { props, mode: { kind: "line", curve } });
722
+ }
723
+ function AreaChart({ curve = "monotone", stacked, ...props }) {
724
+ return /* @__PURE__ */ jsx2(NativeCartesian, { props, mode: { kind: "area", curve, stacked } });
725
+ }
726
+ function BarChart({ stacked, ...props }) {
727
+ return /* @__PURE__ */ jsx2(NativeCartesian, { props, mode: { kind: "bar", stacked } });
728
+ }
729
+
730
+ // src/native/round.tsx
731
+ import { useMemo as useMemo3, useState as useState3 } from "react";
732
+ import Svg2, { Circle as Circle2, Line as Line2, Path as Path2, Text as SvgText2 } from "react-native-svg";
733
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
734
+ function PieChart(props) {
735
+ const { data, label, value, format, donut, centerLabel, maxSlices = 6, otherLabel = "Other" } = props;
736
+ const resolved = useNativeSettings(props);
737
+ const { locale, labels, theme, color } = resolved;
738
+ const fmt = useMemo3(() => ({ value: valueFormatter(format, locale, labels.noValue), share: shareFormatter(locale) }), [format, locale, labels.noValue]);
739
+ const slices = useMemo3(() => {
740
+ const rows = data.map((d, i) => ({ label: read(label, d, i), value: Math.max(0, Number(read(value, d, i)) || 0) })).sort((a, b) => b.value - a.value);
741
+ const kept = rows.length > maxSlices ? rows.slice(0, maxSlices - 1) : rows;
742
+ const out = kept.map((r2, i) => ({ ...r2, color: color(void 0, i + 1) }));
743
+ if (rows.length > maxSlices) out.push({ label: otherLabel, value: rows.slice(maxSlices - 1).reduce((s, r2) => s + r2.value, 0), color: theme.textMuted });
744
+ return out;
745
+ }, [data, label, value, maxSlices, otherLabel, color, theme.textMuted]);
746
+ const total = slices.reduce((s, x) => s + x.value, 0);
747
+ const [active, setActive] = useState3(null);
748
+ const isEmpty = total <= 0;
749
+ const summary = isEmpty ? labels.empty : describeParts(donut ? "donut" : "pie", slices, { labels, value: fmt.value, share: fmt.share });
750
+ return /* @__PURE__ */ jsx3(
751
+ NativeFrame,
752
+ {
753
+ frame: props,
754
+ defaultHeight: 200,
755
+ resolved,
756
+ summary,
757
+ isEmpty,
758
+ points: slices.map((s) => `${s.label}: ${fmt.value(s.value)} (${fmt.share(total ? s.value / total : 0)})`),
759
+ active,
760
+ onActive: setActive,
761
+ legend: /* @__PURE__ */ jsx3(NativeLegend, { theme, items: slices.map((s) => ({ label: `${s.label} \xB7 ${fmt.share(total ? s.value / total : 0)}`, color: s.color })) }),
762
+ children: (width, height) => {
763
+ const radius = Math.max(10, Math.min(width, height) / 2 - 6);
764
+ const inner = donut ? radius * 0.64 : 0;
765
+ let angle = 0;
766
+ return /* @__PURE__ */ jsxs3(Svg2, { width, height, children: [
767
+ slices.map((s, i) => {
768
+ const start = angle;
769
+ angle += total ? s.value / total * Math.PI * 2 : 0;
770
+ return /* @__PURE__ */ jsx3(Path2, { d: arcPath(width / 2, height / 2, inner, radius, start, angle), fill: s.color, stroke: theme.surface1, strokeWidth: slices.length > 1 ? 2 : 0, opacity: active !== null && active !== i ? 0.4 : 1 }, s.label);
771
+ }),
772
+ donut && /* @__PURE__ */ jsx3(SvgText2, { x: width / 2, y: height / 2 + (centerLabel ? 0 : 7), fontSize: Math.max(14, Math.min(24, inner / 3)), fontWeight: "600", fill: theme.textPrimary, textAnchor: "middle", children: fmt.value(total) }),
773
+ donut && centerLabel ? /* @__PURE__ */ jsx3(SvgText2, { x: width / 2, y: height / 2 + 18, fontSize: 11, fill: theme.textSecondary, textAnchor: "middle", children: centerLabel }) : null
774
+ ] });
775
+ }
776
+ }
777
+ );
778
+ }
779
+ function DonutChart(props) {
780
+ return /* @__PURE__ */ jsx3(PieChart, { ...props, donut: true });
781
+ }
782
+ var START = -120 * Math.PI / 180;
783
+ var END = 120 * Math.PI / 180;
784
+ function Gauge(props) {
785
+ const { value, min = 0, max = 100, format, caption, target, zones = [], tone = "accent" } = props;
786
+ const resolved = useNativeSettings(props);
787
+ const { locale, labels, theme, color } = resolved;
788
+ const fmt = valueFormatter(format, locale, labels.noValue);
789
+ const clamped = Math.min(max, Math.max(min, value));
790
+ const zone = zones.find((z) => clamped <= z.to) ?? zones[zones.length - 1];
791
+ const at = (v) => START + (Math.min(max, Math.max(min, v)) - min) / (max - min || 1) * (END - START);
792
+ const text = fmt(value);
793
+ return /* @__PURE__ */ jsx3(
794
+ NativeFrame,
795
+ {
796
+ frame: props,
797
+ defaultHeight: 170,
798
+ resolved,
799
+ summary: `${labels.kinds.gauge}: ${text} / ${fmt(max)}${zone?.label ? `, ${zone.label}` : ""}.`,
800
+ isEmpty: false,
801
+ points: [],
802
+ active: null,
803
+ onActive: () => {
804
+ },
805
+ children: (width, height) => {
806
+ const radius = Math.max(20, Math.min(width / 2 - 12, (height - 16) / 1.58));
807
+ const cx = width / 2;
808
+ const cy = 8 + radius;
809
+ const stroke = Math.max(8, radius * 0.16);
810
+ const [tx0, ty0] = target ? polar(cx, cy, radius - stroke, at(target.value)) : [0, 0];
811
+ const [tx1, ty1] = target ? polar(cx, cy, radius + stroke, at(target.value)) : [0, 0];
812
+ return /* @__PURE__ */ jsxs3(Svg2, { width, height, children: [
813
+ /* @__PURE__ */ jsx3(Path2, { d: strokeArcPath(cx, cy, radius, START, END), stroke: theme.surface3, strokeWidth: stroke, strokeLinecap: "round", fill: "none" }),
814
+ clamped > min && /* @__PURE__ */ jsx3(Path2, { d: strokeArcPath(cx, cy, radius, START, at(clamped)), stroke: color(zone?.tone ?? tone, 1), strokeWidth: stroke, strokeLinecap: "round", fill: "none" }),
815
+ target && /* @__PURE__ */ jsx3(Line2, { x1: tx0, y1: ty0, x2: tx1, y2: ty1, stroke: theme.textPrimary, strokeWidth: 2, strokeLinecap: "round" }),
816
+ /* @__PURE__ */ jsx3(SvgText2, { x: cx, y: cy + 8, fontSize: Math.max(12, Math.min(30, radius / 2.6, radius * 1.45 / (text.length * 0.58))), fontWeight: "600", fill: theme.textPrimary, textAnchor: "middle", children: text }),
817
+ caption ? /* @__PURE__ */ jsx3(SvgText2, { x: cx, y: cy + Math.max(26, radius / 2.4), fontSize: 11, fill: theme.textSecondary, textAnchor: "middle", children: caption }) : null
818
+ ] });
819
+ }
820
+ }
821
+ );
822
+ }
823
+ function Sparkline(props) {
824
+ const { data, categories, variant = "line", color: own, trendTone, format, width: fixed, height = 32 } = props;
825
+ const resolved = useNativeSettings(props);
826
+ const { locale, labels, color } = resolved;
827
+ const fmt = useMemo3(() => ({ value: valueFormatter(format, locale, labels.noValue), category: categoryFormatter(void 0, locale), share: shareFormatter(locale) }), [format, locale, labels.noValue]);
828
+ const values = data.filter((v) => v != null);
829
+ const table = { categories: categories ?? data.map((_, i) => i + 1), series: [{ id: "v", label: props.title, values: data, slot: 1 }] };
830
+ const isEmpty = values.length === 0;
831
+ const up = (values[values.length - 1] ?? 0) >= (values[0] ?? 0);
832
+ const stroke = color(own ?? (trendTone ? (trendTone === "inverse" ? !up : up) ? "success" : "danger" : void 0), 1);
833
+ return /* @__PURE__ */ jsx3(
834
+ NativeFrame,
835
+ {
836
+ frame: { ...props, hideTitle: true, height, style: { ...fixed ? { width: fixed } : {}, ...props.style } },
837
+ defaultHeight: 32,
838
+ resolved,
839
+ summary: isEmpty ? labels.empty : describeSeries(table, { kind: "sparkline", labels, value: fmt.value, category: fmt.category, share: fmt.share }),
840
+ isEmpty,
841
+ points: [],
842
+ active: null,
843
+ onActive: () => {
844
+ },
845
+ children: (width, h) => {
846
+ const lo = variant === "bar" ? Math.min(0, ...values) : Math.min(...values);
847
+ const hi = variant === "bar" ? Math.max(0, ...values) : Math.max(...values);
848
+ const yOf = (v) => 3 + (1 - (v - lo) / (hi - lo || 1)) * (h - 6);
849
+ const n = data.length;
850
+ const xOf = (i) => variant === "bar" ? (i + 0.5) * (width / n) : n > 1 ? 3 + i / (n - 1) * (width - 6) : width / 2;
851
+ const pts = data.map((v, i) => v == null ? null : [xOf(i), yOf(v)]);
852
+ const last = [...pts].reverse().find(Boolean);
853
+ return /* @__PURE__ */ jsxs3(Svg2, { width, height: h, children: [
854
+ variant === "bar" ? data.map((v, i) => v == null || v === 0 ? null : /* @__PURE__ */ jsx3(Path2, { d: barPath(xOf(i) - Math.min(4, width / n / 3), Math.min(yOf(v), yOf(0)), Math.min(8, width / n * 0.7), Math.abs(yOf(v) - yOf(0)), 1.5), fill: stroke }, i)) : segments(pts).map((seg) => [
855
+ variant === "area" ? /* @__PURE__ */ jsx3(Path2, { d: areaPath(seg, h), fill: stroke, opacity: 0.14 }, `a${seg[0][0]}`) : null,
856
+ /* @__PURE__ */ jsx3(Path2, { d: linePath(seg), stroke, strokeWidth: 1.75, fill: "none", strokeLinecap: "round" }, `l${seg[0][0]}`)
857
+ ]),
858
+ variant !== "bar" && last ? /* @__PURE__ */ jsx3(Circle2, { cx: last[0], cy: last[1], r: 2.75, fill: stroke }) : null
859
+ ] });
860
+ }
861
+ }
862
+ );
863
+ }
864
+ export {
865
+ AreaChart,
866
+ BarChart,
867
+ ChartsProvider,
868
+ DEFAULT_LABELS,
869
+ DonutChart,
870
+ Gauge,
871
+ LineChart,
872
+ PieChart,
873
+ Sparkline
874
+ };
875
+ //# sourceMappingURL=native.js.map