@oprt/react 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 (266) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +105 -2
  3. package/dist/ActionStatus/ActionStatus.js +104 -0
  4. package/dist/ActionStatus/ActionStatus.manifest.js +64 -0
  5. package/dist/ActionStatus/index.js +7 -0
  6. package/dist/Alert/Alert.js +86 -0
  7. package/dist/Alert/Alert.manifest.js +36 -0
  8. package/dist/Alert/index.js +7 -0
  9. package/dist/AppShell/AppShell.js +103 -0
  10. package/dist/AppShell/AppShell.manifest.js +66 -0
  11. package/dist/AppShell/index.js +9 -0
  12. package/dist/AttachmentPreview/AttachmentPreview.js +145 -0
  13. package/dist/AttachmentPreview/AttachmentPreview.manifest.js +42 -0
  14. package/dist/AttachmentPreview/index.js +9 -0
  15. package/dist/Avatar/Avatar.js +87 -0
  16. package/dist/Avatar/Avatar.manifest.js +25 -0
  17. package/dist/Avatar/index.js +7 -0
  18. package/dist/Badge/Badge.js +124 -0
  19. package/dist/Badge/Badge.manifest.js +41 -0
  20. package/dist/Badge/index.js +7 -0
  21. package/dist/Breadcrumb/Breadcrumb.js +64 -0
  22. package/dist/Breadcrumb/Breadcrumb.manifest.js +28 -0
  23. package/dist/Breadcrumb/index.js +7 -0
  24. package/dist/BulkActionBar/BulkActionBar.js +145 -0
  25. package/dist/BulkActionBar/BulkActionBar.manifest.js +46 -0
  26. package/dist/BulkActionBar/index.js +9 -0
  27. package/dist/BulkActionBar/selection.js +44 -0
  28. package/dist/BulkResults/BulkResults.js +269 -0
  29. package/dist/BulkResults/BulkResults.manifest.js +45 -0
  30. package/dist/BulkResults/index.js +7 -0
  31. package/dist/Button/Button.js +170 -0
  32. package/dist/Button/Button.manifest.js +36 -0
  33. package/dist/Button/index.js +7 -0
  34. package/dist/ButtonGroup/ButtonGroup.js +60 -0
  35. package/dist/ButtonGroup/ButtonGroup.manifest.js +22 -0
  36. package/dist/ButtonGroup/index.js +7 -0
  37. package/dist/Calendar/Calendar.js +106 -0
  38. package/dist/Calendar/Calendar.manifest.js +32 -0
  39. package/dist/Calendar/index.js +7 -0
  40. package/dist/Card/Card.js +70 -0
  41. package/dist/Card/Card.manifest.js +57 -0
  42. package/dist/Card/index.js +16 -0
  43. package/dist/Chart/Chart.js +1200 -0
  44. package/dist/Chart/Chart.manifest.js +110 -0
  45. package/dist/Chart/ChartControls.js +190 -0
  46. package/dist/Chart/geometry.js +217 -0
  47. package/dist/Chart/index.js +9 -0
  48. package/dist/Checkbox/Checkbox.js +166 -0
  49. package/dist/Checkbox/Checkbox.manifest.js +38 -0
  50. package/dist/Checkbox/index.js +7 -0
  51. package/dist/Collapsible/Collapsible.js +177 -0
  52. package/dist/Collapsible/Collapsible.manifest.js +54 -0
  53. package/dist/Collapsible/index.js +12 -0
  54. package/dist/CollectionState/CollectionState.js +68 -0
  55. package/dist/CollectionState/CollectionState.manifest.js +44 -0
  56. package/dist/CollectionState/index.js +7 -0
  57. package/dist/ComboBox/ComboBox.js +221 -0
  58. package/dist/ComboBox/ComboBox.manifest.js +87 -0
  59. package/dist/ComboBox/index.js +7 -0
  60. package/dist/CommandPalette/CommandPalette.js +276 -0
  61. package/dist/CommandPalette/CommandPalette.manifest.js +24 -0
  62. package/dist/CommandPalette/index.js +7 -0
  63. package/dist/ConfirmDialog/ConfirmDialog.js +84 -0
  64. package/dist/ConfirmDialog/ConfirmDialog.manifest.js +32 -0
  65. package/dist/ConfirmDialog/index.js +7 -0
  66. package/dist/ContextMenu/ContextMenu.js +192 -0
  67. package/dist/ContextMenu/ContextMenu.manifest.js +41 -0
  68. package/dist/ContextMenu/index.js +7 -0
  69. package/dist/CoordinateInput/CoordinateInput.js +141 -0
  70. package/dist/CoordinateInput/CoordinateInput.manifest.js +36 -0
  71. package/dist/CoordinateInput/index.js +9 -0
  72. package/dist/CopyButton/CopyButton.js +110 -0
  73. package/dist/CopyButton/CopyButton.manifest.js +35 -0
  74. package/dist/CopyButton/index.js +7 -0
  75. package/dist/DataGrid/DataGrid.js +459 -0
  76. package/dist/DataGrid/DataGrid.manifest.js +135 -0
  77. package/dist/DataGrid/PageControls.js +41 -0
  78. package/dist/DataGrid/index.js +9 -0
  79. package/dist/DataTable/DataTable.js +375 -0
  80. package/dist/DataTable/DataTable.manifest.js +86 -0
  81. package/dist/DataTable/index.js +9 -0
  82. package/dist/DataTable/sort.js +45 -0
  83. package/dist/DataTable/useScrollsSideways.js +61 -0
  84. package/dist/DataTable/useTableWindow.js +185 -0
  85. package/dist/DatePicker/DatePicker.js +187 -0
  86. package/dist/DatePicker/DatePicker.manifest.js +40 -0
  87. package/dist/DatePicker/index.js +7 -0
  88. package/dist/DateRangePicker/DateRangePicker.js +156 -0
  89. package/dist/DateRangePicker/DateRangePicker.manifest.js +41 -0
  90. package/dist/DateRangePicker/index.js +7 -0
  91. package/dist/DateTimePicker/DateTimePicker.js +213 -0
  92. package/dist/DateTimePicker/DateTimePicker.manifest.js +44 -0
  93. package/dist/DateTimePicker/index.js +7 -0
  94. package/dist/DescriptionList/DescriptionList.js +93 -0
  95. package/dist/DescriptionList/DescriptionList.manifest.js +40 -0
  96. package/dist/DescriptionList/index.js +9 -0
  97. package/dist/Dialog/Dialog.js +214 -0
  98. package/dist/Dialog/Dialog.manifest.js +31 -0
  99. package/dist/Dialog/index.js +7 -0
  100. package/dist/Divider/Divider.js +64 -0
  101. package/dist/Divider/Divider.manifest.js +21 -0
  102. package/dist/Divider/index.js +7 -0
  103. package/dist/DropdownMenu/DropdownMenu.js +170 -0
  104. package/dist/DropdownMenu/DropdownMenu.manifest.js +82 -0
  105. package/dist/DropdownMenu/index.js +16 -0
  106. package/dist/EntityPreview/EntityPreview.js +82 -0
  107. package/dist/EntityPreview/EntityPreview.manifest.js +43 -0
  108. package/dist/EntityPreview/index.js +7 -0
  109. package/dist/EventTimeline/EventTimeline.js +249 -0
  110. package/dist/EventTimeline/EventTimeline.manifest.js +57 -0
  111. package/dist/EventTimeline/index.js +7 -0
  112. package/dist/Field/Field.js +81 -0
  113. package/dist/Field/Field.manifest.js +32 -0
  114. package/dist/Field/index.js +9 -0
  115. package/dist/FileUpload/FileUpload.js +215 -0
  116. package/dist/FileUpload/FileUpload.manifest.js +48 -0
  117. package/dist/FileUpload/index.js +7 -0
  118. package/dist/FilterBar/FilterBar.js +173 -0
  119. package/dist/FilterBar/FilterBar.manifest.js +49 -0
  120. package/dist/FilterBar/index.js +7 -0
  121. package/dist/FormErrorSummary/FormErrorSummary.js +70 -0
  122. package/dist/FormErrorSummary/FormErrorSummary.manifest.js +29 -0
  123. package/dist/FormErrorSummary/index.js +9 -0
  124. package/dist/FormSection/FormSection.js +51 -0
  125. package/dist/FormSection/FormSection.manifest.js +30 -0
  126. package/dist/FormSection/index.js +7 -0
  127. package/dist/InlineEdit/InlineEdit.js +261 -0
  128. package/dist/InlineEdit/InlineEdit.manifest.js +40 -0
  129. package/dist/InlineEdit/index.js +7 -0
  130. package/dist/Input/Input.js +126 -0
  131. package/dist/Input/Input.manifest.js +49 -0
  132. package/dist/Input/index.js +7 -0
  133. package/dist/Inspector/Inspector.js +63 -0
  134. package/dist/Inspector/Inspector.manifest.js +35 -0
  135. package/dist/Inspector/index.js +7 -0
  136. package/dist/JobStatus/JobStatus.js +118 -0
  137. package/dist/JobStatus/JobStatus.manifest.js +53 -0
  138. package/dist/JobStatus/index.js +7 -0
  139. package/dist/LayerControl/LayerControl.js +199 -0
  140. package/dist/LayerControl/LayerControl.manifest.js +34 -0
  141. package/dist/LayerControl/index.js +7 -0
  142. package/dist/Link/Link.js +83 -0
  143. package/dist/Link/Link.manifest.js +37 -0
  144. package/dist/Link/index.js +7 -0
  145. package/dist/MapControls/MapControls.js +122 -0
  146. package/dist/MapControls/MapControls.manifest.js +31 -0
  147. package/dist/MapControls/index.js +7 -0
  148. package/dist/MapLegend/MapLegend.js +89 -0
  149. package/dist/MapLegend/MapLegend.manifest.js +29 -0
  150. package/dist/MapLegend/index.js +7 -0
  151. package/dist/MapScale/MapScale.js +96 -0
  152. package/dist/MapScale/MapScale.manifest.js +31 -0
  153. package/dist/MapScale/index.js +7 -0
  154. package/dist/MediaFrame/MediaFrame.js +113 -0
  155. package/dist/MediaFrame/MediaFrame.manifest.js +57 -0
  156. package/dist/MediaFrame/index.js +7 -0
  157. package/dist/MultiSelect/MultiSelect.js +113 -0
  158. package/dist/MultiSelect/MultiSelect.manifest.js +51 -0
  159. package/dist/MultiSelect/index.js +7 -0
  160. package/dist/NumberInput/NumberInput.js +210 -0
  161. package/dist/NumberInput/NumberInput.manifest.js +56 -0
  162. package/dist/NumberInput/index.js +7 -0
  163. package/dist/OperationalStatus/OperationalStatus.js +89 -0
  164. package/dist/OperationalStatus/OperationalStatus.manifest.js +39 -0
  165. package/dist/OperationalStatus/index.js +9 -0
  166. package/dist/PlaybackControls/PlaybackControls.js +289 -0
  167. package/dist/PlaybackControls/PlaybackControls.manifest.js +85 -0
  168. package/dist/PlaybackControls/index.js +7 -0
  169. package/dist/Popover/Popover.js +302 -0
  170. package/dist/Popover/Popover.manifest.js +50 -0
  171. package/dist/Popover/index.js +7 -0
  172. package/dist/Progress/Progress.js +132 -0
  173. package/dist/Progress/Progress.manifest.js +30 -0
  174. package/dist/Progress/index.js +7 -0
  175. package/dist/PropertyFilter/PropertyFilter.js +306 -0
  176. package/dist/PropertyFilter/PropertyFilter.manifest.js +32 -0
  177. package/dist/PropertyFilter/index.js +11 -0
  178. package/dist/PropertyFilter/tokenError.js +17 -0
  179. package/dist/RadioGroup/RadioGroup.js +143 -0
  180. package/dist/RadioGroup/RadioGroup.manifest.js +44 -0
  181. package/dist/RadioGroup/index.js +9 -0
  182. package/dist/Select/Select.js +219 -0
  183. package/dist/Select/Select.manifest.js +77 -0
  184. package/dist/Select/index.js +9 -0
  185. package/dist/Sidebar/Sidebar.js +146 -0
  186. package/dist/Sidebar/Sidebar.manifest.js +72 -0
  187. package/dist/Sidebar/index.js +18 -0
  188. package/dist/Skeleton/Skeleton.js +76 -0
  189. package/dist/Skeleton/Skeleton.manifest.js +30 -0
  190. package/dist/Skeleton/index.js +7 -0
  191. package/dist/Slider/Slider.js +246 -0
  192. package/dist/Slider/Slider.manifest.js +56 -0
  193. package/dist/Slider/index.js +7 -0
  194. package/dist/Sparkline/Sparkline.js +135 -0
  195. package/dist/Sparkline/Sparkline.manifest.js +37 -0
  196. package/dist/Sparkline/index.js +7 -0
  197. package/dist/SplitPane/SplitPane.js +316 -0
  198. package/dist/SplitPane/SplitPane.manifest.js +79 -0
  199. package/dist/SplitPane/index.js +7 -0
  200. package/dist/StatCard/StatCard.js +163 -0
  201. package/dist/StatCard/StatCard.manifest.js +45 -0
  202. package/dist/StatCard/index.js +7 -0
  203. package/dist/Tabs/Tabs.js +181 -0
  204. package/dist/Tabs/Tabs.manifest.js +72 -0
  205. package/dist/Tabs/index.js +16 -0
  206. package/dist/Tabs/useTabsIndicator.js +71 -0
  207. package/dist/Tabs/useTabsScroll.js +123 -0
  208. package/dist/TagGroup/TagGroup.js +142 -0
  209. package/dist/TagGroup/TagGroup.manifest.js +35 -0
  210. package/dist/TagGroup/index.js +7 -0
  211. package/dist/Textarea/Textarea.js +68 -0
  212. package/dist/Textarea/Textarea.manifest.js +25 -0
  213. package/dist/Textarea/index.js +7 -0
  214. package/dist/TimeField/TimeField.js +118 -0
  215. package/dist/TimeField/TimeField.manifest.js +42 -0
  216. package/dist/TimeField/index.js +7 -0
  217. package/dist/TimeRange/TimeRange.js +184 -0
  218. package/dist/TimeRange/TimeRange.manifest.js +48 -0
  219. package/dist/TimeRange/index.js +9 -0
  220. package/dist/Toast/Toast.js +188 -0
  221. package/dist/Toast/Toast.manifest.js +77 -0
  222. package/dist/Toast/index.js +9 -0
  223. package/dist/Toggle/Toggle.js +154 -0
  224. package/dist/Toggle/Toggle.manifest.js +54 -0
  225. package/dist/Toggle/index.js +7 -0
  226. package/dist/Toolbar/Toolbar.js +86 -0
  227. package/dist/Toolbar/Toolbar.manifest.js +70 -0
  228. package/dist/Toolbar/index.js +12 -0
  229. package/dist/Tooltip/Tooltip.js +122 -0
  230. package/dist/Tooltip/Tooltip.manifest.js +27 -0
  231. package/dist/Tooltip/index.js +7 -0
  232. package/dist/TreeView/TreeView.js +129 -0
  233. package/dist/TreeView/TreeView.manifest.js +56 -0
  234. package/dist/TreeView/index.js +7 -0
  235. package/dist/UploadQueue/UploadQueue.js +296 -0
  236. package/dist/UploadQueue/UploadQueue.manifest.js +34 -0
  237. package/dist/UploadQueue/index.js +7 -0
  238. package/dist/_internal/MotionPopover.js +113 -0
  239. package/dist/_internal/aria.js +40 -0
  240. package/dist/_internal/bytes.js +18 -0
  241. package/dist/_internal/controlStyles.js +26 -0
  242. package/dist/_internal/date.js +179 -0
  243. package/dist/_internal/devValidate.js +51 -0
  244. package/dist/_internal/fieldIds.js +50 -0
  245. package/dist/_internal/hydration.js +74 -0
  246. package/dist/_internal/manifest-entry.js +0 -0
  247. package/dist/_internal/mergeRefs.js +68 -0
  248. package/dist/_internal/motion.js +138 -0
  249. package/dist/_internal/navigationLandmark.js +13 -0
  250. package/dist/_internal/numberText.js +176 -0
  251. package/dist/_internal/overlay.js +53 -0
  252. package/dist/_internal/segmentField.js +125 -0
  253. package/dist/_internal/suggestions.js +20 -0
  254. package/dist/_internal/timestamp.js +25 -0
  255. package/dist/_internal/unavailable.js +13 -0
  256. package/dist/_internal/useActionFocus.js +27 -0
  257. package/dist/_internal/useElementWidth.js +37 -0
  258. package/dist/_internal/useIsMounted.js +18 -0
  259. package/dist/_internal/useIsomorphicLayoutEffect.js +8 -0
  260. package/dist/_internal/useRestoreFocusOnRemoval.js +57 -0
  261. package/dist/index.cjs +17811 -0
  262. package/dist/index.d.cts +2330 -0
  263. package/dist/index.d.ts +2330 -0
  264. package/dist/index.js +407 -0
  265. package/dist/version.js +8 -0
  266. package/package.json +80 -3
@@ -0,0 +1,1200 @@
1
+ "use client";
2
+
3
+ // src/Chart/Chart.tsx
4
+ import {
5
+ forwardRef,
6
+ memo,
7
+ useCallback,
8
+ useEffect,
9
+ useMemo,
10
+ useRef,
11
+ useState
12
+ } from "react";
13
+ import { useLocale, useNumberFormatter } from "react-aria";
14
+ import { cva } from "class-variance-authority";
15
+ import clsx from "clsx";
16
+ import { Button } from "../Button/Button.js";
17
+ import { devValidate } from "../_internal/devValidate.js";
18
+ import { usePartIds } from "../_internal/fieldIds.js";
19
+ import { NumberText } from "../_internal/numberText.js";
20
+ import { FocusableWhenUnavailableProvider } from "../_internal/unavailable.js";
21
+ import { useElementWidth } from "../_internal/useElementWidth.js";
22
+ import { ChartManifest } from "./Chart.manifest.js";
23
+ import { ChartInspection, ChartRangeSelector } from "./ChartControls.js";
24
+ import {
25
+ extent,
26
+ fraction,
27
+ indexByX,
28
+ interpolate,
29
+ intervalSeparator,
30
+ isFinitePoint,
31
+ linePath,
32
+ markerPoints,
33
+ nearestIndex,
34
+ niceAxis,
35
+ scale,
36
+ segments,
37
+ sequentialClasses,
38
+ seriesColorClass,
39
+ seriesIdentity,
40
+ tickLabels,
41
+ ticks,
42
+ withoutFloatNoise
43
+ } from "./geometry.js";
44
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
45
+ var chartStyles = cva(
46
+ "min-w-0 w-full border border-oprt-border bg-oprt-surface-1 p-3u font-sans text-oprt-text",
47
+ {
48
+ variants: { variant: { line: "", area: "", bar: "", scatter: "", histogram: "", heatmap: "" } },
49
+ defaultVariants: { variant: "line" }
50
+ }
51
+ );
52
+ var LEFT = 72;
53
+ var Y_LABEL_CHARACTER_WIDTH = (LEFT - 8) / 9;
54
+ var TOP = 16;
55
+ var BOTTOM = 236;
56
+ var HEIGHT = BOTTOM - TOP;
57
+ var SVG_HEIGHT = 270;
58
+ var LABEL_CHARACTER_WIDTH = 8;
59
+ var cellClass = "border-b border-oprt-border px-2u py-1u text-left";
60
+ var dashPatterns = [void 0, "7 3", "2 3", "8 3 2 3", "12 4", "4 2", "1 4", "9 2 1 2"];
61
+ var withUnit = (label, unit) => /* @__PURE__ */ jsxs(Fragment, { children: [
62
+ label,
63
+ unit && /* @__PURE__ */ jsxs("span", { className: "normal-case tracking-normal", children: [
64
+ " (",
65
+ unit,
66
+ ")"
67
+ ] })
68
+ ] });
69
+ var valueWithUnit = (value, unit) => `${value}${unit ? ` ${unit}` : ""}`;
70
+ var EXACT_NUMBER = { maximumSignificantDigits: 21 };
71
+ var CELL_NUMBER = { maximumSignificantDigits: 4 };
72
+ var colorClass = (item) => seriesColorClass(item.id, item.color);
73
+ var KEEP_COLORS = "forced-colors:[forced-color-adjust:none]";
74
+ var shortenLabel = (label, limit) => label.length > limit ? `${label.slice(0, Math.max(1, limit - 1))}\u2026` : label;
75
+ function Marker({
76
+ identity,
77
+ x,
78
+ y,
79
+ size = 3,
80
+ solid = false
81
+ }) {
82
+ const common = {
83
+ fill: solid ? "currentColor" : "var(--oprt-surface-1)",
84
+ stroke: "currentColor",
85
+ strokeWidth: "var(--oprt-chart-stroke-width)",
86
+ vectorEffect: "non-scaling-stroke"
87
+ };
88
+ switch (identity) {
89
+ case 1:
90
+ return /* @__PURE__ */ jsx("rect", { ...common, x: x - size, y: y - size, width: size * 2, height: size * 2 });
91
+ case 2:
92
+ return /* @__PURE__ */ jsx(
93
+ "path",
94
+ {
95
+ ...common,
96
+ d: `M${x},${y - size * 1.4} L${x + size},${y} L${x},${y + size * 1.4} L${x - size},${y} Z`
97
+ }
98
+ );
99
+ case 3:
100
+ return /* @__PURE__ */ jsx(
101
+ "path",
102
+ {
103
+ ...common,
104
+ d: `M${x},${y - size * 1.3} L${x + size * 1.2},${y + size} L${x - size * 1.2},${y + size} Z`
105
+ }
106
+ );
107
+ case 4:
108
+ return /* @__PURE__ */ jsx(
109
+ "path",
110
+ {
111
+ ...common,
112
+ d: `M${x},${y + size * 1.3} L${x + size * 1.2},${y - size} L${x - size * 1.2},${y - size} Z`
113
+ }
114
+ );
115
+ case 5:
116
+ return /* @__PURE__ */ jsx(
117
+ "path",
118
+ {
119
+ ...common,
120
+ d: `M${x - size},${y} H${x + size} M${x},${y - size} V${y + size}`,
121
+ fill: "none"
122
+ }
123
+ );
124
+ case 6:
125
+ return /* @__PURE__ */ jsx(
126
+ "path",
127
+ {
128
+ ...common,
129
+ d: `M${x - size},${y - size} L${x + size},${y + size} M${x + size},${y - size} L${x - size},${y + size}`,
130
+ fill: "none"
131
+ }
132
+ );
133
+ case 7:
134
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
135
+ /* @__PURE__ */ jsx("circle", { ...common, cx: x, cy: y, r: size, fill: "var(--oprt-surface-1)" }),
136
+ solid && /* @__PURE__ */ jsx("circle", { cx: x, cy: y, r: 1, fill: "currentColor" })
137
+ ] });
138
+ default:
139
+ return /* @__PURE__ */ jsx("circle", { ...common, cx: x, cy: y, r: size });
140
+ }
141
+ }
142
+ function histogram(series, bins) {
143
+ const finite = series.flatMap((item) => item.data.filter(isFinitePoint));
144
+ const domain = extent(finite.map((point) => point.y));
145
+ const count = domain.min === domain.max ? 1 : Number.isFinite(bins) ? Math.min(100, Math.max(1, Math.floor(bins))) : 10;
146
+ const edges = Array.from({ length: count + 1 }, (_, index) => interpolate(domain, index / count));
147
+ const counts = /* @__PURE__ */ new Map();
148
+ let missing = 0;
149
+ for (const item of series) {
150
+ const values = Array(count).fill(0);
151
+ for (const point of item.data) {
152
+ if (!isFinitePoint(point)) {
153
+ missing++;
154
+ continue;
155
+ }
156
+ const index = Math.min(count - 1, Math.floor(fraction(point.y, domain) * count));
157
+ values[index] = (values[index] ?? 0) + 1;
158
+ }
159
+ counts.set(item.id, values);
160
+ }
161
+ return { domain, edges, counts, missing };
162
+ }
163
+ function binLabel(data, index, formatNumber, separator) {
164
+ const start = formatNumber(withoutFloatNoise(data.edges[index]));
165
+ const end = formatNumber(withoutFloatNoise(data.edges[index + 1]));
166
+ return start === end ? start : `[${start}${separator}${end}${index === data.edges.length - 2 ? "]" : ")"}`;
167
+ }
168
+ var DataView = memo(function DataView2({
169
+ id,
170
+ label,
171
+ series,
172
+ hidden,
173
+ distribution,
174
+ xHeading,
175
+ yHeading,
176
+ formatX,
177
+ formatNumber,
178
+ separator
179
+ }) {
180
+ return /* @__PURE__ */ jsx(
181
+ "div",
182
+ {
183
+ id,
184
+ className: "max-h-screen overflow-auto border border-oprt-border focus-visible:outline-hidden focus-visible:shadow-oprt-focus",
185
+ tabIndex: 0,
186
+ role: "region",
187
+ "aria-label": `${label} data table`,
188
+ children: /* @__PURE__ */ jsxs("table", { className: "w-full border-collapse text-oprt-base", "aria-label": `${label} data`, children: [
189
+ /* @__PURE__ */ jsxs("caption", { className: "sr-only", children: [
190
+ label,
191
+ " data.",
192
+ " ",
193
+ distribution ? "Bin intervals include their lower boundary; the final bin also includes its upper boundary." : "All supplied samples, including hidden series. Missing means a null or non-finite value."
194
+ ] }),
195
+ /* @__PURE__ */ jsx("thead", { className: "bg-oprt-surface-2 font-semibold uppercase tracking-oprt-caps", children: /* @__PURE__ */ jsxs("tr", { children: [
196
+ /* @__PURE__ */ jsx("th", { scope: "col", className: cellClass, children: "Series" }),
197
+ /* @__PURE__ */ jsx("th", { scope: "col", className: cellClass, children: xHeading }),
198
+ /* @__PURE__ */ jsx("th", { scope: "col", className: cellClass, children: yHeading }),
199
+ /* @__PURE__ */ jsx("th", { scope: "col", className: cellClass, children: "Visibility" })
200
+ ] }) }),
201
+ /* @__PURE__ */ jsx("tbody", { children: series.flatMap(
202
+ (item) => distribution ? (distribution.counts.get(item.id) ?? []).map((count, index) => /* @__PURE__ */ jsxs("tr", { children: [
203
+ /* @__PURE__ */ jsx("th", { scope: "row", className: clsx(cellClass, "font-medium"), children: item.label }),
204
+ /* @__PURE__ */ jsx("td", { className: clsx(cellClass, "font-mono"), children: binLabel(distribution, index, formatNumber, separator) }),
205
+ /* @__PURE__ */ jsx("td", { className: clsx(cellClass, "font-mono"), children: formatNumber(count) }),
206
+ /* @__PURE__ */ jsx("td", { className: cellClass, children: hidden.has(item.id) ? "Hidden" : "Visible" })
207
+ ] }, `${item.id}:${index}`)) : item.data.map((point, index) => /* @__PURE__ */ jsxs("tr", { children: [
208
+ /* @__PURE__ */ jsx("th", { scope: "row", className: clsx(cellClass, "font-medium"), children: item.label }),
209
+ /* @__PURE__ */ jsx("td", { className: clsx(cellClass, "font-mono"), children: Number.isFinite(point.x) ? point.label ?? formatX?.(point.x) ?? formatNumber(point.x) : "Missing" }),
210
+ /* @__PURE__ */ jsx("td", { className: clsx(cellClass, "font-mono"), children: point.y !== null && Number.isFinite(point.y) ? formatNumber(point.y) : "Missing" }),
211
+ /* @__PURE__ */ jsx("td", { className: cellClass, children: hidden.has(item.id) ? "Hidden" : "Visible" })
212
+ ] }, `${item.id}:${index}`))
213
+ ) })
214
+ ] })
215
+ }
216
+ );
217
+ });
218
+ function seriesMarks(item, seriesIndex, samples, context) {
219
+ const {
220
+ variant,
221
+ fill,
222
+ hatchId,
223
+ geometry: { left, x, y, baseline, width, groupWidth },
224
+ visibleCount,
225
+ distribution,
226
+ xValues,
227
+ heatDomain,
228
+ unit,
229
+ formatX,
230
+ formatNumber,
231
+ formatCell,
232
+ separator
233
+ } = context;
234
+ const identity = seriesIdentity(item.id);
235
+ if (variant === "histogram" && distribution) {
236
+ const values = distribution.counts.get(item.id) ?? [];
237
+ const binWidth = width / Math.max(1, values.length);
238
+ const barWidth = binWidth * 0.8 / Math.max(1, visibleCount);
239
+ return values.map((count, index) => /* @__PURE__ */ jsxs("g", { children: [
240
+ /* @__PURE__ */ jsx(
241
+ "rect",
242
+ {
243
+ x: left + index * binWidth + binWidth * 0.1 + seriesIndex * barWidth,
244
+ y: Math.min(y(count), baseline),
245
+ width: barWidth,
246
+ height: Math.abs(y(count) - baseline),
247
+ fill: "currentColor",
248
+ fillOpacity: "var(--oprt-chart-bar-opacity)",
249
+ stroke: "currentColor",
250
+ strokeWidth: "var(--oprt-chart-stroke-width)",
251
+ vectorEffect: "non-scaling-stroke"
252
+ }
253
+ ),
254
+ count > 0 && /* @__PURE__ */ jsx(
255
+ Marker,
256
+ {
257
+ identity,
258
+ x: left + index * binWidth + binWidth * 0.1 + (seriesIndex + 0.5) * barWidth,
259
+ y: y(count),
260
+ size: Math.min(3, barWidth / 3)
261
+ }
262
+ ),
263
+ /* @__PURE__ */ jsx("title", { children: `${item.label}: ${binLabel(distribution, index, formatNumber, separator)}, ${formatNumber(count)} samples` })
264
+ ] }, index));
265
+ }
266
+ if (variant === "bar") {
267
+ const barWidth = groupWidth / Math.max(1, visibleCount);
268
+ return item.data.filter(isFinitePoint).map((point, index) => /* @__PURE__ */ jsxs("g", { "data-chart-point": "", children: [
269
+ /* @__PURE__ */ jsx(
270
+ "rect",
271
+ {
272
+ x: x(point.x) - groupWidth / 2 + barWidth * seriesIndex,
273
+ y: Math.min(y(point.y), baseline),
274
+ width: barWidth * 0.9,
275
+ height: Math.abs(y(point.y) - baseline),
276
+ fill: fill === "hatched" ? `url(#${hatchId})` : "currentColor",
277
+ fillOpacity: fill === "hatched" ? 1 : "var(--oprt-chart-bar-opacity)",
278
+ stroke: "currentColor",
279
+ strokeWidth: "var(--oprt-chart-stroke-width)",
280
+ vectorEffect: "non-scaling-stroke"
281
+ }
282
+ ),
283
+ /* @__PURE__ */ jsx(
284
+ Marker,
285
+ {
286
+ identity,
287
+ x: x(point.x) - groupWidth / 2 + barWidth * (seriesIndex + 0.45),
288
+ y: y(point.y),
289
+ size: Math.min(3, barWidth / 3)
290
+ }
291
+ ),
292
+ /* @__PURE__ */ jsx("title", { children: `${item.label}: ${point.label ?? formatX?.(point.x) ?? formatNumber(point.x)}, ${valueWithUnit(formatNumber(point.y), unit)}` })
293
+ ] }, index));
294
+ }
295
+ if (variant === "heatmap") {
296
+ const cellWidth = width / Math.max(1, xValues.length);
297
+ const cellHeight = HEIGHT / Math.max(1, visibleCount);
298
+ return xValues.map((value, index) => {
299
+ const point = samples?.get(value);
300
+ const valid2 = point && isFinitePoint(point);
301
+ const className = valid2 ? sequentialClasses[Math.min(4, Math.floor(fraction(point.y, heatDomain) * 5))] : "text-oprt-chart-grid";
302
+ const cellX = left + index * cellWidth;
303
+ const cellY = TOP + seriesIndex * cellHeight;
304
+ return /* @__PURE__ */ jsxs("g", { "data-chart-cell": "", "data-chart-missing": valid2 ? void 0 : "", children: [
305
+ /* @__PURE__ */ jsx(
306
+ "rect",
307
+ {
308
+ x: cellX + 1,
309
+ y: cellY + 1,
310
+ width: Math.max(0, cellWidth - 2),
311
+ height: Math.max(0, cellHeight - 2),
312
+ className: clsx(className, valid2 && KEEP_COLORS),
313
+ fill: valid2 ? "currentColor" : "none",
314
+ stroke: valid2 ? "none" : "currentColor"
315
+ }
316
+ ),
317
+ xValues.length <= 12 && visibleCount <= 8 && cellHeight >= 24 && (valid2 ? formatCell(point.y).length : 1) * LABEL_CHARACTER_WIDTH + 8 <= cellWidth && /* @__PURE__ */ jsx(
318
+ "text",
319
+ {
320
+ x: cellX + cellWidth / 2,
321
+ y: cellY + cellHeight / 2,
322
+ dominantBaseline: "middle",
323
+ textAnchor: "middle",
324
+ className: clsx(
325
+ "font-mono text-oprt-base",
326
+ valid2 ? clsx("fill-current text-oprt-bg", KEEP_COLORS) : "fill-current text-oprt-text-dim"
327
+ ),
328
+ children: valid2 ? formatCell(point.y) : "\u2014"
329
+ }
330
+ ),
331
+ /* @__PURE__ */ jsx("title", { children: `${item.label}: ${point?.label ?? formatX?.(value) ?? formatNumber(value)}, ${valid2 ? valueWithUnit(formatNumber(point.y), unit) : "Missing"}` })
332
+ ] }, value);
333
+ });
334
+ }
335
+ const valid = item.data.filter(isFinitePoint);
336
+ if (variant === "scatter") {
337
+ return valid.map((point, index) => /* @__PURE__ */ jsxs("g", { "data-chart-point": "", children: [
338
+ /* @__PURE__ */ jsx("circle", { cx: x(point.x), cy: y(point.y), r: 8, fill: "transparent" }),
339
+ /* @__PURE__ */ jsx("g", { "data-chart-marker": "", children: /* @__PURE__ */ jsx(Marker, { identity, x: x(point.x), y: y(point.y), size: 3.5 }) }),
340
+ /* @__PURE__ */ jsx("title", { children: `${item.label}: ${point.label ?? formatX?.(point.x) ?? formatNumber(point.x)}, ${valueWithUnit(formatNumber(point.y), unit)}` })
341
+ ] }, index));
342
+ }
343
+ const runs = segments(item.data);
344
+ const last = valid[valid.length - 1];
345
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
346
+ runs.map((segment, index) => {
347
+ const path = linePath(segment, x, y);
348
+ return /* @__PURE__ */ jsxs("g", { "data-chart-segment": item.id, children: [
349
+ variant === "area" && /* @__PURE__ */ jsx(
350
+ "path",
351
+ {
352
+ d: `${path} L${x(segment[segment.length - 1].x)},${baseline} L${x(segment[0].x)},${baseline} Z`,
353
+ fill: "currentColor",
354
+ fillOpacity: "var(--oprt-chart-area-opacity)"
355
+ }
356
+ ),
357
+ variant === "area" && fill === "hatched" && /* @__PURE__ */ jsx(
358
+ "path",
359
+ {
360
+ d: `${path} L${x(segment[segment.length - 1].x)},${baseline} L${x(segment[0].x)},${baseline} Z`,
361
+ fill: `url(#${hatchId})`
362
+ }
363
+ ),
364
+ /* @__PURE__ */ jsx(
365
+ "path",
366
+ {
367
+ "data-chart-line": "",
368
+ d: path,
369
+ fill: "none",
370
+ stroke: "currentColor",
371
+ strokeWidth: "var(--oprt-chart-stroke-width)",
372
+ strokeDasharray: dashPatterns[identity],
373
+ strokeLinecap: "butt",
374
+ strokeLinejoin: "miter",
375
+ strokeMiterlimit: 2,
376
+ vectorEffect: "non-scaling-stroke"
377
+ }
378
+ )
379
+ ] }, index);
380
+ }),
381
+ [...markerPoints(runs, x)].map((point, index) => /* @__PURE__ */ jsx("g", { "data-chart-marker": "", children: /* @__PURE__ */ jsx(
382
+ Marker,
383
+ {
384
+ identity,
385
+ x: x(point.x),
386
+ y: y(point.y),
387
+ size: 2.5,
388
+ solid: point === last
389
+ }
390
+ ) }, index))
391
+ ] });
392
+ }
393
+ var Chart = forwardRef((allProps, ref) => {
394
+ const {
395
+ label,
396
+ series,
397
+ variant = "line",
398
+ fill = "solid",
399
+ description,
400
+ xLabel,
401
+ xUnit,
402
+ yLabel,
403
+ unit,
404
+ hiddenSeries,
405
+ onHiddenSeriesChange,
406
+ disabled = false,
407
+ bins = 10,
408
+ formatX,
409
+ threshold,
410
+ rangeSelection = false,
411
+ xDomain: suppliedXDomain,
412
+ range,
413
+ onRangeChange,
414
+ cursor,
415
+ cursorLabel = "Review position",
416
+ className,
417
+ ...props
418
+ } = allProps;
419
+ if (process.env.NODE_ENV !== "production") {
420
+ devValidate("Chart", ChartManifest.Chart.props, { ...allProps });
421
+ }
422
+ const labelRef = useRef(null);
423
+ const { locale } = useLocale();
424
+ const numberFormat = useNumberFormatter(EXACT_NUMBER);
425
+ const separator = useMemo(() => intervalSeparator(locale), [locale]);
426
+ const formatNumber = useCallback(
427
+ (value) => numberFormat.format(value + 0),
428
+ [numberFormat]
429
+ );
430
+ const cellFormat = useNumberFormatter(CELL_NUMBER);
431
+ const formatCell = useCallback((value) => cellFormat.format(value + 0), [cellFormat]);
432
+ const ids = usePartIds(["label", "description", "hatch", "data"], {
433
+ readRendered: () => labelRef.current?.id.replace(/-label$/, "")
434
+ });
435
+ const plotRef = useRef(null);
436
+ const plotWidth = useElementWidth(plotRef, { initial: 640, min: 0 });
437
+ const [localHidden, setLocalHidden] = useState([]);
438
+ const [showData, setShowData] = useState(false);
439
+ const [localRange, setLocalRange] = useState();
440
+ const [inspection, setInspection] = useState(null);
441
+ const [pinned, setPinned] = useState(false);
442
+ const [inspectionFocused, setInspectionFocused] = useState(false);
443
+ const [emphasized, setEmphasized] = useState(null);
444
+ const inspectionRef = useRef(null);
445
+ const hiddenKey = JSON.stringify(hiddenSeries ?? localHidden);
446
+ const hidden = useMemo(() => new Set(JSON.parse(hiddenKey)), [hiddenKey]);
447
+ const inspectable = variant === "line" || variant === "area" || variant === "bar";
448
+ const fullVisible = useMemo(
449
+ () => series.filter((item) => !hidden.has(item.id)),
450
+ [series, hidden]
451
+ );
452
+ const dataDomain = useMemo(
453
+ () => extent(series.flatMap((item) => item.data.map((point) => point.x))),
454
+ [series]
455
+ );
456
+ const suppliedStart = suppliedXDomain?.start;
457
+ const suppliedEnd = suppliedXDomain?.end;
458
+ const fullDomain = useMemo(
459
+ () => inspectable && suppliedStart !== void 0 && suppliedEnd !== void 0 && Number.isFinite(suppliedStart) && Number.isFinite(suppliedEnd) && suppliedStart < suppliedEnd ? { min: suppliedStart, max: suppliedEnd } : dataDomain,
460
+ [inspectable, suppliedStart, suppliedEnd, dataDomain]
461
+ );
462
+ const requested = range ?? localRange;
463
+ const requestedStart = requested?.start;
464
+ const requestedEnd = requested?.end;
465
+ const controlledRange = range !== void 0;
466
+ const view = useMemo(() => {
467
+ const full = { start: fullDomain.min, end: fullDomain.max, valid: false };
468
+ if (!inspectable || requestedStart === void 0 || requestedEnd === void 0) return full;
469
+ if (!Number.isFinite(requestedStart) || !Number.isFinite(requestedEnd) || requestedStart >= requestedEnd)
470
+ return full;
471
+ if (requestedEnd >= fullDomain.min && requestedStart <= fullDomain.max) {
472
+ return {
473
+ start: Math.max(fullDomain.min, requestedStart),
474
+ end: Math.min(fullDomain.max, requestedEnd),
475
+ valid: true
476
+ };
477
+ }
478
+ return controlledRange ? { start: requestedStart, end: requestedEnd, valid: true } : { ...full, valid: true };
479
+ }, [inspectable, requestedStart, requestedEnd, controlledRange, fullDomain]);
480
+ const narrowed = inspectable && (view.start > dataDomain.min || view.end < dataDomain.max);
481
+ const visible = useMemo(
482
+ () => narrowed ? fullVisible.map((item) => ({
483
+ ...item,
484
+ data: item.data.filter(
485
+ (point) => !Number.isFinite(point.x) || point.x >= view.start && point.x <= view.end
486
+ )
487
+ })) : fullVisible,
488
+ [narrowed, fullVisible, view.start, view.end]
489
+ );
490
+ const samplesAt = useMemo(
491
+ () => new Map(visible.map((item) => [item, indexByX(item.data)])),
492
+ [visible]
493
+ );
494
+ const finite = useMemo(
495
+ () => visible.flatMap((item) => item.data.filter(isFinitePoint)),
496
+ [visible]
497
+ );
498
+ const distribution = useMemo(
499
+ () => variant === "histogram" ? histogram(visible, bins) : void 0,
500
+ [variant, visible, bins]
501
+ );
502
+ const thresholdValue = variant !== "heatmap" && threshold && Number.isFinite(threshold.value) ? threshold.value : void 0;
503
+ const yAxis = useMemo(() => {
504
+ const values = distribution ? [...distribution.counts.values()].flat() : finite.map((point) => point.y);
505
+ if (thresholdValue !== void 0) values.push(thresholdValue);
506
+ return niceAxis(
507
+ extent(values, variant === "bar" || variant === "area" || variant === "histogram"),
508
+ variant === "histogram"
509
+ );
510
+ }, [distribution, finite, thresholdValue, variant]);
511
+ const xValues = useMemo(
512
+ () => [
513
+ ...new Set(
514
+ visible.flatMap((item) => item.data.map((point) => point.x)).filter(Number.isFinite)
515
+ )
516
+ ].sort((a, b) => a - b),
517
+ [visible]
518
+ );
519
+ const windowedAxis = inspectable && (rangeSelection || view.valid || suppliedXDomain !== void 0);
520
+ const xDomain = useMemo(
521
+ () => windowedAxis ? { min: view.start, max: view.end } : distribution?.domain ?? (xValues.length > 0 ? { min: xValues[0], max: xValues[xValues.length - 1] } : extent([])),
522
+ [windowedAxis, view.start, view.end, distribution, xValues]
523
+ );
524
+ const heatDomain = useMemo(
525
+ () => variant === "heatmap" ? extent(finite.map((point) => point.y)) : dataDomain,
526
+ [variant, finite, dataDomain]
527
+ );
528
+ const anyFiniteX = useMemo(
529
+ () => series.some((item) => item.data.some((point) => Number.isFinite(point.x))),
530
+ [series]
531
+ );
532
+ const missing = useMemo(
533
+ () => visible.reduce(
534
+ (total, item) => total + item.data.filter((point) => !isFinitePoint(point)).length,
535
+ 0
536
+ ),
537
+ [visible]
538
+ );
539
+ const histogramView = distribution !== void 0;
540
+ const xHeading = useMemo(
541
+ () => histogramView ? withUnit(xLabel ?? "Value", unit) : withUnit(xLabel ?? "Sample", xUnit),
542
+ [histogramView, xLabel, xUnit, unit]
543
+ );
544
+ const yHeading = useMemo(
545
+ () => histogramView ? yLabel ?? "Count" : withUnit(yLabel ?? "Value", unit),
546
+ [histogramView, yLabel, unit]
547
+ );
548
+ const empty = series.length === 0 ? "No data to display." : visible.length === 0 ? "All series are hidden." : narrowed && xValues.length === 0 ? "No samples in this range." : finite.length === 0 ? "No finite data to display." : void 0;
549
+ const yLabels = useMemo(
550
+ () => variant === "heatmap" ? [] : tickLabels(yAxis.ticks, locale),
551
+ [variant, yAxis, locale]
552
+ );
553
+ const longestYLabel = Math.max(9, ...yLabels.map((label2) => label2.length));
554
+ const left = Math.max(LEFT, Math.ceil(8 + longestYLabel * Y_LABEL_CHARACTER_WIDTH));
555
+ const geometry = useMemo(() => {
556
+ const right = Math.max(left + 1, plotWidth - 24);
557
+ const width = right - left;
558
+ const initialX = scale(xDomain, left, right);
559
+ let slotWidth = width;
560
+ for (let index = 1; index < xValues.length; index++)
561
+ slotWidth = Math.min(slotWidth, initialX(xValues[index]) - initialX(xValues[index - 1]));
562
+ const groupWidth = Math.min(48, slotWidth * 0.7);
563
+ const inset = variant === "bar" ? groupWidth / 2 : 0;
564
+ const y2 = scale(yAxis.domain, BOTTOM, TOP);
565
+ return {
566
+ left,
567
+ right,
568
+ width,
569
+ groupWidth,
570
+ x: scale(xDomain, left + inset, right - inset),
571
+ y: y2,
572
+ baseline: y2(0)
573
+ };
574
+ }, [left, plotWidth, xDomain, xValues, variant, yAxis]);
575
+ const xTickLabels = useMemo(() => {
576
+ const { left: left2, width, x: x2 } = geometry;
577
+ const textFor = (value, interpolated) => formatX && !histogramView ? formatX(value) : formatNumber(interpolated ? withoutFloatNoise(value) : value);
578
+ const columnText = variant === "heatmap" && xValues.length <= 6 ? xValues.map((value) => textFor(value, false)) : [];
579
+ const heatmapTicksFit = columnText.length > 0 && columnText.every(
580
+ (text) => text.length * LABEL_CHARACTER_WIDTH + 16 <= width / Math.max(1, xValues.length)
581
+ );
582
+ const xTicks = variant === "heatmap" ? xValues.flatMap(
583
+ (value, index) => heatmapTicksFit || index === 0 || index === xValues.length - 1 ? [
584
+ {
585
+ value,
586
+ position: left2 + (index + 0.5) * width / xValues.length,
587
+ interpolated: false
588
+ }
589
+ ] : []
590
+ ) : ticks(xDomain, width < 384 ? 2 : 3).map((value, index, all) => ({
591
+ value,
592
+ position: x2(value),
593
+ interpolated: index > 0 && index < all.length - 1
594
+ }));
595
+ const texts = xTicks.map((tick) => textFor(tick.value, tick.interpolated));
596
+ return xTicks.map(({ position }, index) => {
597
+ const start = index === 0 ? 0 : Math.min(plotWidth, (xTicks[index - 1].position + position) / 2 + 4);
598
+ const end = index === xTicks.length - 1 ? plotWidth : Math.min(plotWidth, (position + xTicks[index + 1].position) / 2 - 4);
599
+ const text = texts[index];
600
+ const shortText = shortenLabel(
601
+ text,
602
+ Math.max(1, Math.floor((end - start) / LABEL_CHARACTER_WIDTH))
603
+ );
604
+ const halfWidth = shortText.length * LABEL_CHARACTER_WIDTH / 2;
605
+ return {
606
+ text,
607
+ shortText,
608
+ x: Math.max(start + halfWidth, Math.min(end - halfWidth, position))
609
+ };
610
+ });
611
+ }, [geometry, histogramView, formatX, formatNumber, xValues, variant, xDomain, plotWidth]);
612
+ const hatchId = ids.hatch;
613
+ const marksLayer = useMemo(() => {
614
+ const context = {
615
+ variant,
616
+ fill,
617
+ hatchId,
618
+ geometry,
619
+ visibleCount: visible.length,
620
+ distribution,
621
+ xValues,
622
+ heatDomain,
623
+ unit,
624
+ formatX,
625
+ formatNumber,
626
+ formatCell,
627
+ separator
628
+ };
629
+ return visible.map((item, index) => /* @__PURE__ */ jsx("g", { "data-chart-series": item.id, className: colorClass(item), children: seriesMarks(item, index, samplesAt.get(item), context) }));
630
+ }, [
631
+ variant,
632
+ fill,
633
+ hatchId,
634
+ geometry,
635
+ visible,
636
+ distribution,
637
+ xValues,
638
+ heatDomain,
639
+ unit,
640
+ formatX,
641
+ formatNumber,
642
+ formatCell,
643
+ separator,
644
+ samplesAt
645
+ ]);
646
+ const seriesNumber = useMemo(
647
+ () => new Map(series.map((item, index) => [item.id, index + 1])),
648
+ [series]
649
+ );
650
+ const yAxisLayer = useMemo(() => {
651
+ if (variant === "heatmap") {
652
+ return /* @__PURE__ */ jsx("g", { "aria-hidden": "true", children: visible.map((item, index) => /* @__PURE__ */ jsx(
653
+ "text",
654
+ {
655
+ "data-chart-row": "",
656
+ x: geometry.left - 8,
657
+ y: TOP + HEIGHT / visible.length * (index + 0.5),
658
+ textAnchor: "end",
659
+ dominantBaseline: "middle",
660
+ className: "fill-current font-mono text-oprt-base text-oprt-chart-axis",
661
+ children: seriesNumber.get(item.id)
662
+ },
663
+ item.id
664
+ )) });
665
+ }
666
+ return /* @__PURE__ */ jsx("g", { "data-chart-y-axis": "", "aria-hidden": "true", children: yAxis.ticks.map((value, index) => /* @__PURE__ */ jsxs("g", { children: [
667
+ /* @__PURE__ */ jsx(
668
+ "line",
669
+ {
670
+ x1: geometry.left,
671
+ x2: geometry.right,
672
+ y1: Math.round(geometry.y(value)) + 0.5,
673
+ y2: Math.round(geometry.y(value)) + 0.5,
674
+ className: "text-oprt-chart-grid",
675
+ stroke: "currentColor",
676
+ strokeWidth: "var(--oprt-chart-guide-width)",
677
+ strokeDasharray: value === 0 ? void 0 : "2 4",
678
+ strokeOpacity: value === 0 ? 1 : 0.65
679
+ }
680
+ ),
681
+ /* @__PURE__ */ jsx(
682
+ "line",
683
+ {
684
+ x1: geometry.left - 4,
685
+ x2: geometry.left,
686
+ y1: Math.round(geometry.y(value)) + 0.5,
687
+ y2: Math.round(geometry.y(value)) + 0.5,
688
+ className: "text-oprt-chart-axis",
689
+ stroke: "currentColor",
690
+ strokeWidth: "var(--oprt-chart-guide-width)"
691
+ }
692
+ ),
693
+ /* @__PURE__ */ jsxs(
694
+ "text",
695
+ {
696
+ x: geometry.left - 8,
697
+ y: geometry.y(value),
698
+ textAnchor: "end",
699
+ dominantBaseline: "middle",
700
+ className: "fill-current font-mono text-oprt-base text-oprt-chart-axis",
701
+ children: [
702
+ yLabels[index],
703
+ /* @__PURE__ */ jsx("title", { children: formatNumber(value) })
704
+ ]
705
+ }
706
+ )
707
+ ] }, index)) });
708
+ }, [variant, visible, yAxis, yLabels, geometry, seriesNumber, formatNumber]);
709
+ const xAxisLayer = useMemo(
710
+ () => /* @__PURE__ */ jsx("g", { "data-chart-x-axis": "", "aria-hidden": "true", children: xTickLabels.map((tick, index) => /* @__PURE__ */ jsxs(
711
+ "text",
712
+ {
713
+ x: tick.x,
714
+ y: BOTTOM + 22,
715
+ textAnchor: "middle",
716
+ className: "fill-current font-mono text-oprt-base text-oprt-chart-axis",
717
+ children: [
718
+ tick.shortText,
719
+ /* @__PURE__ */ jsx("title", { children: tick.text })
720
+ ]
721
+ },
722
+ index
723
+ )) }),
724
+ [xTickLabels]
725
+ );
726
+ const xIndex = useMemo(
727
+ () => new Map(xValues.map((value, index) => [value, index])),
728
+ [xValues]
729
+ );
730
+ const activeIndex = inspection === null ? void 0 : xIndex.get(inspection);
731
+ const activeX = activeIndex === void 0 ? null : inspection;
732
+ const reviewCursor = inspectable && cursor != null && Number.isFinite(cursor) && cursor >= xDomain.min && cursor <= xDomain.max ? cursor : null;
733
+ useEffect(() => {
734
+ if (activeX === null || !inspectable) {
735
+ setInspection(null);
736
+ setPinned(false);
737
+ }
738
+ if (!inspectable || xValues.length === 0) setInspectionFocused(false);
739
+ }, [activeX, inspectable, xValues.length]);
740
+ const inspectIndex = activeIndex ?? Math.max(0, xValues.length - 1);
741
+ const formatPosition = useCallback(
742
+ (value) => valueWithUnit(formatX?.(value) ?? formatNumber(value), xUnit),
743
+ [formatX, formatNumber, xUnit]
744
+ );
745
+ function authoredLabel(value) {
746
+ let found;
747
+ for (const item of visible) {
748
+ const point = samplesAt.get(item)?.get(value);
749
+ if (!point) continue;
750
+ if (!point.label || found !== void 0 && point.label !== found) return void 0;
751
+ found = point.label;
752
+ }
753
+ return found;
754
+ }
755
+ const renderSamplePosition = (value) => authoredLabel(value) ?? /* @__PURE__ */ jsx(NumberText, { value: formatX?.(value) ?? formatNumber(value), unit: xUnit });
756
+ function describeSample(index) {
757
+ const value = xValues[index];
758
+ if (value === void 0) return "No sample";
759
+ return `${authoredLabel(value) ?? formatPosition(value)}. ${visible.map((item) => {
760
+ const point = samplesAt.get(item)?.get(value);
761
+ return `${item.label}: ${point && isFinitePoint(point) ? valueWithUnit(formatNumber(point.y), unit) : "Missing"}`;
762
+ }).join(". ")}`;
763
+ }
764
+ function inspectPointer(event) {
765
+ if (!inspectable || !xValues.length) return;
766
+ const bounds = event.currentTarget.getBoundingClientRect();
767
+ if (!bounds.width) return;
768
+ const px = (event.clientX - bounds.left) * plotWidth / bounds.width;
769
+ if (px < geometry.left || px > geometry.right) return;
770
+ setInspection(xValues[nearestIndex(xValues, px, geometry.x)] ?? null);
771
+ }
772
+ const changeRange = useCallback(
773
+ (next) => {
774
+ if (disabled) return;
775
+ if (!controlledRange) setLocalRange(next);
776
+ onRangeChange?.(next);
777
+ setInspection(null);
778
+ setPinned(false);
779
+ },
780
+ [disabled, controlledRange, onRangeChange]
781
+ );
782
+ function toggle(item) {
783
+ const next = new Set(hidden);
784
+ if (next.has(item.id)) next.delete(item.id);
785
+ else next.add(item.id);
786
+ const ids2 = [...next];
787
+ if (hiddenSeries === void 0) setLocalHidden(ids2);
788
+ onHiddenSeriesChange?.(ids2);
789
+ }
790
+ const firstX = xValues[0];
791
+ const lastX = xValues[xValues.length - 1];
792
+ const windowEnds = empty ? null : variant === "heatmap" ? firstX === void 0 || lastX === void 0 ? null : [firstX, lastX] : [xDomain.min, xDomain.max];
793
+ const renderPosition = useCallback(
794
+ (value) => histogramView ? /* @__PURE__ */ jsx(NumberText, { value: formatNumber(value), unit }) : /* @__PURE__ */ jsx(NumberText, { value: formatX?.(value) ?? formatNumber(value), unit: xUnit }),
795
+ [histogramView, unit, formatX, formatNumber, xUnit]
796
+ );
797
+ const { x, y } = geometry;
798
+ return /* @__PURE__ */ jsxs(
799
+ "div",
800
+ {
801
+ ...props,
802
+ ref,
803
+ "data-oprt-chart": variant,
804
+ className: clsx(chartStyles({ variant }), className),
805
+ children: [
806
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2u", children: [
807
+ /* @__PURE__ */ jsx(
808
+ "h3",
809
+ {
810
+ ref: labelRef,
811
+ id: ids.label,
812
+ className: "m-0 min-w-0 flex-1 font-semibold text-oprt-base uppercase tracking-oprt-caps oprt-wrap-anywhere",
813
+ children: label
814
+ }
815
+ ),
816
+ /* @__PURE__ */ jsx(
817
+ Button,
818
+ {
819
+ variant: "tertiary",
820
+ size: "sm",
821
+ "aria-expanded": showData,
822
+ "aria-controls": showData ? ids.data : void 0,
823
+ onClick: () => setShowData(!showData),
824
+ children: "View data"
825
+ }
826
+ )
827
+ ] }),
828
+ description && /* @__PURE__ */ jsx("p", { className: "m-0 mt-1u text-oprt-base text-oprt-text-dim oprt-wrap-anywhere", children: description }),
829
+ /* @__PURE__ */ jsxs("p", { id: ids.description, className: "sr-only", children: [
830
+ description ? `${description} ` : "",
831
+ variant,
832
+ " chart. ",
833
+ formatNumber(visible.length),
834
+ " visible series. ",
835
+ formatNumber(missing),
836
+ " ",
837
+ "missing samples. ",
838
+ empty ?? "Use View data to inspect values."
839
+ ] }),
840
+ /* @__PURE__ */ jsxs("div", { className: "mt-2u flex justify-between gap-2u text-oprt-base uppercase tracking-oprt-caps text-oprt-text-dim", children: [
841
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 oprt-wrap-anywhere", children: variant === "heatmap" ? "Series" : yHeading }),
842
+ variant === "heatmap" && /* @__PURE__ */ jsx("span", { className: "min-w-0 oprt-wrap-anywhere", children: yHeading })
843
+ ] }),
844
+ /* @__PURE__ */ jsxs(
845
+ "div",
846
+ {
847
+ ref: plotRef,
848
+ className: "relative min-w-0 w-full border border-transparent focus-within:border-oprt-border-focus focus-within:shadow-oprt-focus",
849
+ onKeyDownCapture: (event) => {
850
+ if (event.key !== "Escape" || activeX === null && !pinned) return;
851
+ event.preventDefault();
852
+ event.stopPropagation();
853
+ setInspection(null);
854
+ setPinned(false);
855
+ },
856
+ children: [
857
+ inspectable && xValues.length > 0 && /* @__PURE__ */ jsx(
858
+ ChartInspection,
859
+ {
860
+ label,
861
+ index: inspectIndex,
862
+ count: xValues.length,
863
+ describe: describeSample,
864
+ inputRef: inspectionRef,
865
+ onChange: (index) => {
866
+ setInspection(xValues[index] ?? null);
867
+ setPinned(true);
868
+ },
869
+ onFocus: () => {
870
+ setInspectionFocused(true);
871
+ setInspection(xValues[inspectIndex] ?? null);
872
+ setPinned(true);
873
+ },
874
+ onBlur: () => setInspectionFocused(false)
875
+ }
876
+ ),
877
+ empty ? /* @__PURE__ */ jsx("p", { className: "m-0 py-6u text-oprt-base text-oprt-text-dim", role: "status", children: empty }) : /* @__PURE__ */ jsxs(
878
+ "svg",
879
+ {
880
+ role: "img",
881
+ "aria-labelledby": ids.label,
882
+ "aria-describedby": ids.description,
883
+ viewBox: `0 0 ${plotWidth} ${SVG_HEIGHT}`,
884
+ height: SVG_HEIGHT,
885
+ preserveAspectRatio: "xMinYMin meet",
886
+ className: "block w-full overflow-hidden",
887
+ onPointerMove: (event) => {
888
+ if (!pinned && !inspectionFocused) inspectPointer(event);
889
+ },
890
+ onPointerLeave: () => {
891
+ if (!pinned && !inspectionFocused) setInspection(null);
892
+ },
893
+ onPointerDown: (event) => {
894
+ if (inspectable && event.button === 0) {
895
+ inspectionRef.current?.focus({ preventScroll: true });
896
+ inspectPointer(event);
897
+ setPinned(true);
898
+ }
899
+ },
900
+ children: [
901
+ fill === "hatched" && (variant === "area" || variant === "bar") && /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("pattern", { id: hatchId, width: 8, height: 8, patternUnits: "userSpaceOnUse", children: /* @__PURE__ */ jsx(
902
+ "path",
903
+ {
904
+ d: "M-2 2 L2 -2 M0 8 L8 0 M6 10 L10 6",
905
+ stroke: "var(--oprt-text-dim)",
906
+ strokeWidth: "var(--oprt-chart-guide-width)",
907
+ strokeOpacity: "var(--oprt-chart-bar-opacity)"
908
+ }
909
+ ) }) }),
910
+ yAxisLayer,
911
+ visible.map((item, index) => /* @__PURE__ */ jsx(
912
+ "g",
913
+ {
914
+ className: "transition-opacity duration-oprt-normal motion-reduce:transition-none",
915
+ opacity: emphasized && emphasized !== item.id ? 0.35 : 1,
916
+ "aria-hidden": "true",
917
+ children: marksLayer[index]
918
+ },
919
+ item.id
920
+ )),
921
+ thresholdValue !== void 0 && /* @__PURE__ */ jsx(
922
+ "line",
923
+ {
924
+ "data-chart-threshold": "",
925
+ x1: geometry.left,
926
+ x2: geometry.right,
927
+ y1: y(thresholdValue),
928
+ y2: y(thresholdValue),
929
+ className: "text-oprt-chart-threshold",
930
+ stroke: "currentColor",
931
+ strokeWidth: "var(--oprt-chart-guide-width)",
932
+ strokeDasharray: "6 4"
933
+ }
934
+ ),
935
+ reviewCursor !== null && /* @__PURE__ */ jsx(
936
+ "line",
937
+ {
938
+ "data-chart-cursor": "",
939
+ "aria-hidden": "true",
940
+ pointerEvents: "none",
941
+ x1: x(reviewCursor),
942
+ x2: x(reviewCursor),
943
+ y1: TOP,
944
+ y2: BOTTOM,
945
+ className: "text-oprt-accent",
946
+ stroke: "currentColor",
947
+ strokeWidth: "var(--oprt-chart-stroke-width)"
948
+ }
949
+ ),
950
+ inspectable && activeX !== null && /* @__PURE__ */ jsxs("g", { "data-chart-crosshair": "", "aria-hidden": "true", pointerEvents: "none", children: [
951
+ /* @__PURE__ */ jsx(
952
+ "line",
953
+ {
954
+ x1: x(activeX),
955
+ x2: x(activeX),
956
+ y1: TOP,
957
+ y2: BOTTOM,
958
+ stroke: "var(--oprt-text-dim)",
959
+ strokeWidth: "var(--oprt-chart-guide-width)",
960
+ strokeDasharray: "3 3"
961
+ }
962
+ ),
963
+ visible.map((item, index) => {
964
+ const point = samplesAt.get(item)?.get(activeX);
965
+ if (!point || !isFinitePoint(point)) return null;
966
+ const pointX = variant === "bar" ? x(activeX) - geometry.groupWidth / 2 + geometry.groupWidth / visible.length * (index + 0.45) : x(activeX);
967
+ return /* @__PURE__ */ jsx("g", { className: colorClass(item), children: /* @__PURE__ */ jsx(
968
+ Marker,
969
+ {
970
+ identity: seriesIdentity(item.id),
971
+ x: pointX,
972
+ y: y(point.y),
973
+ size: 4,
974
+ solid: true
975
+ }
976
+ ) }, item.id);
977
+ })
978
+ ] }),
979
+ xAxisLayer
980
+ ]
981
+ }
982
+ )
983
+ ]
984
+ }
985
+ ),
986
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-baseline justify-between gap-x-2u", children: [
987
+ windowEnds && /* @__PURE__ */ jsxs(
988
+ "p",
989
+ {
990
+ "data-chart-window": "",
991
+ className: "m-0 min-w-0 font-mono text-oprt-base text-oprt-text-dim oprt-wrap-anywhere",
992
+ children: [
993
+ /* @__PURE__ */ jsx("span", { className: "inline-block max-w-full", children: renderPosition(windowEnds[0]) }),
994
+ " to ",
995
+ /* @__PURE__ */ jsx("span", { className: "inline-block max-w-full", children: renderPosition(windowEnds[1]) })
996
+ ]
997
+ }
998
+ ),
999
+ /* @__PURE__ */ jsx("p", { className: "m-0 ml-auto min-w-0 text-right text-oprt-base uppercase tracking-oprt-caps text-oprt-text-dim oprt-wrap-anywhere", children: xHeading })
1000
+ ] }),
1001
+ reviewCursor !== null && /* @__PURE__ */ jsxs("p", { className: "m-0 text-oprt-base text-oprt-text-dim oprt-wrap-anywhere", children: [
1002
+ cursorLabel,
1003
+ ": ",
1004
+ renderSamplePosition(reviewCursor)
1005
+ ] }),
1006
+ inspectable && /* @__PURE__ */ jsxs(
1007
+ "div",
1008
+ {
1009
+ role: "region",
1010
+ "aria-label": `${label} readout`,
1011
+ className: "mt-2u border-y border-oprt-border bg-oprt-surface-2 px-2u py-1u",
1012
+ children: [
1013
+ /* @__PURE__ */ jsxs("div", { className: "flex min-h-3u flex-wrap items-center justify-between gap-1u", children: [
1014
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 font-mono text-oprt-base oprt-wrap-anywhere", children: activeX !== null ? renderSamplePosition(activeX) : "Hover or focus the plot to inspect" }),
1015
+ /* @__PURE__ */ jsx(FocusableWhenUnavailableProvider, { value: true, children: /* @__PURE__ */ jsx(
1016
+ Button,
1017
+ {
1018
+ variant: "ghost",
1019
+ size: "sm",
1020
+ disabled: activeX === null,
1021
+ onClick: () => {
1022
+ setInspection(null);
1023
+ setPinned(false);
1024
+ },
1025
+ children: "Clear inspection"
1026
+ }
1027
+ ) })
1028
+ ] }),
1029
+ /* @__PURE__ */ jsx("dl", { className: "m-0 flex flex-wrap gap-x-3u gap-y-1u pb-1u", children: visible.map((item) => {
1030
+ const point = activeX === null ? void 0 : samplesAt.get(item)?.get(activeX);
1031
+ return /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-1u", children: [
1032
+ /* @__PURE__ */ jsx(
1033
+ "svg",
1034
+ {
1035
+ width: "16",
1036
+ height: "16",
1037
+ viewBox: "0 0 16 16",
1038
+ "aria-hidden": "true",
1039
+ className: clsx("shrink-0", colorClass(item)),
1040
+ children: /* @__PURE__ */ jsx(Marker, { identity: seriesIdentity(item.id), x: 8, y: 8, size: 3 })
1041
+ }
1042
+ ),
1043
+ /* @__PURE__ */ jsx("dt", { className: "min-w-0 text-oprt-base text-oprt-text-dim oprt-wrap-anywhere", children: item.label }),
1044
+ /* @__PURE__ */ jsx("dd", { className: "m-0 font-mono text-oprt-base", children: activeX === null ? "\u2014" : point && isFinitePoint(point) ? /* @__PURE__ */ jsx(NumberText, { value: formatNumber(point.y), unit }) : "Missing" })
1045
+ ] }, item.id);
1046
+ }) })
1047
+ ]
1048
+ }
1049
+ ),
1050
+ thresholdValue !== void 0 && threshold && /* @__PURE__ */ jsxs("p", { className: "m-0 mt-1u font-mono text-oprt-base text-oprt-chart-threshold oprt-wrap-anywhere", children: [
1051
+ threshold.label,
1052
+ ":",
1053
+ " ",
1054
+ /* @__PURE__ */ jsx(NumberText, { value: formatNumber(thresholdValue), unit: distribution ? void 0 : unit })
1055
+ ] }),
1056
+ missing > 0 && /* @__PURE__ */ jsx("p", { className: "m-0 mt-1u text-oprt-base text-oprt-text-dim", children: distribution ? `${formatNumber(missing)} missing samples excluded from bins.` : `${formatNumber(missing)} missing samples shown as gaps.` }),
1057
+ variant === "heatmap" && finite.length > 0 && /* @__PURE__ */ jsxs(
1058
+ "div",
1059
+ {
1060
+ className: "mt-2u flex flex-wrap items-center gap-1u text-oprt-base",
1061
+ "aria-label": "Value scale",
1062
+ children: [
1063
+ /* @__PURE__ */ jsx(
1064
+ NumberText,
1065
+ {
1066
+ value: formatNumber(heatDomain.min),
1067
+ unit,
1068
+ className: "min-w-0 font-mono"
1069
+ }
1070
+ ),
1071
+ /* @__PURE__ */ jsx("span", { className: "flex shrink-0 gap-1u", "aria-hidden": "true", children: sequentialClasses.map((color) => /* @__PURE__ */ jsx("span", { className: clsx("h-1u w-3u bg-current", color, KEEP_COLORS) }, color)) }),
1072
+ /* @__PURE__ */ jsx(
1073
+ NumberText,
1074
+ {
1075
+ value: formatNumber(heatDomain.max),
1076
+ unit,
1077
+ className: "min-w-0 font-mono"
1078
+ }
1079
+ )
1080
+ ]
1081
+ }
1082
+ ),
1083
+ series.length > 0 && /* @__PURE__ */ jsx(
1084
+ "div",
1085
+ {
1086
+ className: "mt-2u flex flex-wrap gap-1u",
1087
+ role: "group",
1088
+ "aria-label": `${label} series visibility`,
1089
+ children: series.map((item) => /* @__PURE__ */ jsxs(
1090
+ Button,
1091
+ {
1092
+ variant: "ghost",
1093
+ size: "sm",
1094
+ className: "min-w-0 max-w-full oprt-wrap-anywhere",
1095
+ "aria-label": variant === "heatmap" ? `${seriesNumber.get(item.id)} ${item.label}` : item.label,
1096
+ "aria-pressed": !hidden.has(item.id),
1097
+ disabled,
1098
+ onClick: () => {
1099
+ toggle(item);
1100
+ setEmphasized(null);
1101
+ },
1102
+ onPointerEnter: () => {
1103
+ if (!hidden.has(item.id)) setEmphasized(item.id);
1104
+ },
1105
+ onPointerLeave: () => setEmphasized(null),
1106
+ onFocus: () => {
1107
+ if (!hidden.has(item.id)) setEmphasized(item.id);
1108
+ },
1109
+ onBlur: () => setEmphasized(null),
1110
+ children: [
1111
+ variant !== "heatmap" && /* @__PURE__ */ jsxs(
1112
+ "svg",
1113
+ {
1114
+ "aria-hidden": "true",
1115
+ width: "28",
1116
+ height: "16",
1117
+ viewBox: "0 0 28 16",
1118
+ className: clsx("mr-1u shrink-0", colorClass(item)),
1119
+ children: [
1120
+ (variant === "line" || variant === "area") && /* @__PURE__ */ jsx(
1121
+ "path",
1122
+ {
1123
+ d: "M1 8 H27",
1124
+ fill: "none",
1125
+ stroke: "currentColor",
1126
+ strokeWidth: "var(--oprt-chart-stroke-width)",
1127
+ strokeDasharray: dashPatterns[seriesIdentity(item.id)]
1128
+ }
1129
+ ),
1130
+ (variant === "bar" || variant === "histogram") && /* @__PURE__ */ jsx(
1131
+ "rect",
1132
+ {
1133
+ x: 8,
1134
+ y: 5,
1135
+ width: 12,
1136
+ height: 9,
1137
+ fill: "currentColor",
1138
+ fillOpacity: "var(--oprt-chart-bar-opacity)",
1139
+ stroke: "currentColor",
1140
+ strokeWidth: "var(--oprt-chart-stroke-width)"
1141
+ }
1142
+ ),
1143
+ /* @__PURE__ */ jsx(
1144
+ Marker,
1145
+ {
1146
+ identity: seriesIdentity(item.id),
1147
+ x: 14,
1148
+ y: variant === "bar" || variant === "histogram" ? 5 : 8,
1149
+ size: 2.5,
1150
+ solid: variant === "line" || variant === "area"
1151
+ }
1152
+ )
1153
+ ]
1154
+ }
1155
+ ),
1156
+ variant === "heatmap" && /* @__PURE__ */ jsx("span", { className: "mr-1u font-mono", children: seriesNumber.get(item.id) }),
1157
+ item.label,
1158
+ hidden.has(item.id) && /* @__PURE__ */ jsx("span", { className: "ml-1u text-oprt-text-dim", children: "Hidden" })
1159
+ ]
1160
+ },
1161
+ item.id
1162
+ ))
1163
+ }
1164
+ ),
1165
+ rangeSelection && inspectable && fullDomain.min < fullDomain.max && anyFiniteX && /* @__PURE__ */ jsx(
1166
+ ChartRangeSelector,
1167
+ {
1168
+ label,
1169
+ series: fullVisible,
1170
+ domain: fullDomain,
1171
+ range: view,
1172
+ format: formatPosition,
1173
+ renderPosition,
1174
+ disabled,
1175
+ onChange: changeRange
1176
+ }
1177
+ ),
1178
+ showData && /* @__PURE__ */ jsx("div", { className: "mt-2u", children: /* @__PURE__ */ jsx(
1179
+ DataView,
1180
+ {
1181
+ id: ids.data,
1182
+ label,
1183
+ series: distribution ? visible : series,
1184
+ hidden,
1185
+ distribution,
1186
+ xHeading,
1187
+ yHeading,
1188
+ formatX,
1189
+ formatNumber,
1190
+ separator
1191
+ }
1192
+ ) })
1193
+ ]
1194
+ }
1195
+ );
1196
+ });
1197
+ Chart.displayName = "Chart";
1198
+ export {
1199
+ Chart
1200
+ };