@matthieumordrel/chart-studio 0.2.0 → 0.2.2

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 (175) hide show
  1. package/README.md +1 -1
  2. package/dist/core/chart-capabilities.d.mts +48 -0
  3. package/dist/core/chart-capabilities.mjs +55 -0
  4. package/dist/core/{colors.d.ts → colors.d.mts} +5 -3
  5. package/dist/core/colors.mjs +55 -0
  6. package/dist/core/config-utils.mjs +79 -0
  7. package/dist/core/date-utils.mjs +49 -0
  8. package/dist/core/define-chart-schema.d.mts +106 -0
  9. package/dist/core/define-chart-schema.mjs +47 -0
  10. package/dist/core/formatting.mjs +349 -0
  11. package/dist/core/infer-columns.d.mts +9 -0
  12. package/dist/core/infer-columns.mjs +481 -0
  13. package/dist/core/metric-utils.d.mts +13 -0
  14. package/dist/core/metric-utils.mjs +121 -0
  15. package/dist/core/pipeline-data-points.mjs +212 -0
  16. package/dist/core/pipeline-helpers.mjs +85 -0
  17. package/dist/core/{pipeline.d.ts → pipeline.d.mts} +21 -24
  18. package/dist/core/pipeline.mjs +153 -0
  19. package/dist/core/types.d.mts +957 -0
  20. package/dist/core/use-chart-options.d.mts +64 -0
  21. package/dist/core/use-chart-options.mjs +7 -0
  22. package/dist/core/use-chart-resolvers.mjs +34 -0
  23. package/dist/core/{use-chart.d.ts → use-chart.d.mts} +12 -9
  24. package/dist/core/use-chart.mjs +299 -0
  25. package/dist/index.d.mts +10 -0
  26. package/dist/index.mjs +8 -0
  27. package/dist/ui/chart-axis-ticks.mjs +65 -0
  28. package/dist/ui/{chart-canvas.d.ts → chart-canvas.d.mts} +13 -6
  29. package/dist/ui/chart-canvas.mjs +461 -0
  30. package/dist/ui/chart-context.d.mts +92 -0
  31. package/dist/ui/chart-context.mjs +112 -0
  32. package/dist/ui/{chart-date-range-badge.d.ts → chart-date-range-badge.d.mts} +10 -4
  33. package/dist/ui/chart-date-range-badge.mjs +49 -0
  34. package/dist/ui/chart-date-range-panel.d.mts +18 -0
  35. package/dist/ui/chart-date-range-panel.mjs +208 -0
  36. package/dist/ui/{chart-date-range.d.ts → chart-date-range.d.mts} +10 -4
  37. package/dist/ui/chart-date-range.mjs +67 -0
  38. package/dist/ui/chart-debug.d.mts +17 -0
  39. package/dist/ui/chart-debug.mjs +169 -0
  40. package/dist/ui/chart-dropdown.mjs +92 -0
  41. package/dist/ui/{chart-filters-panel.d.ts → chart-filters-panel.d.mts} +12 -5
  42. package/dist/ui/chart-filters-panel.mjs +132 -0
  43. package/dist/ui/{chart-filters.d.ts → chart-filters.d.mts} +10 -4
  44. package/dist/ui/chart-filters.mjs +48 -0
  45. package/dist/ui/chart-group-by-selector.d.mts +14 -0
  46. package/dist/ui/chart-group-by-selector.mjs +29 -0
  47. package/dist/ui/{chart-metric-panel.d.ts → chart-metric-panel.d.mts} +12 -5
  48. package/dist/ui/chart-metric-panel.mjs +172 -0
  49. package/dist/ui/chart-metric-selector.d.mts +16 -0
  50. package/dist/ui/chart-metric-selector.mjs +50 -0
  51. package/dist/ui/chart-select.mjs +62 -0
  52. package/dist/ui/{chart-source-switcher.d.ts → chart-source-switcher.d.mts} +10 -4
  53. package/dist/ui/chart-source-switcher.mjs +54 -0
  54. package/dist/ui/chart-time-bucket-selector.d.mts +15 -0
  55. package/dist/ui/chart-time-bucket-selector.mjs +34 -0
  56. package/dist/ui/chart-toolbar-overflow.d.mts +28 -0
  57. package/dist/ui/chart-toolbar-overflow.mjs +209 -0
  58. package/dist/ui/chart-toolbar.d.mts +29 -0
  59. package/dist/ui/chart-toolbar.mjs +56 -0
  60. package/dist/ui/chart-type-selector.d.mts +14 -0
  61. package/dist/ui/chart-type-selector.mjs +33 -0
  62. package/dist/ui/chart-x-axis-selector.d.mts +14 -0
  63. package/dist/ui/chart-x-axis-selector.mjs +25 -0
  64. package/dist/ui/index.d.mts +19 -0
  65. package/dist/ui/index.mjs +18 -0
  66. package/dist/ui/toolbar-types.d.mts +7 -0
  67. package/dist/ui/toolbar-types.mjs +83 -0
  68. package/package.json +11 -10
  69. package/dist/core/chart-capabilities.d.ts +0 -60
  70. package/dist/core/chart-capabilities.d.ts.map +0 -1
  71. package/dist/core/chart-capabilities.js +0 -54
  72. package/dist/core/colors.d.ts.map +0 -1
  73. package/dist/core/colors.js +0 -54
  74. package/dist/core/config-utils.d.ts +0 -43
  75. package/dist/core/config-utils.d.ts.map +0 -1
  76. package/dist/core/config-utils.js +0 -80
  77. package/dist/core/date-utils.d.ts +0 -29
  78. package/dist/core/date-utils.d.ts.map +0 -1
  79. package/dist/core/date-utils.js +0 -58
  80. package/dist/core/define-chart-schema.d.ts +0 -105
  81. package/dist/core/define-chart-schema.d.ts.map +0 -1
  82. package/dist/core/define-chart-schema.js +0 -44
  83. package/dist/core/formatting.d.ts +0 -47
  84. package/dist/core/formatting.d.ts.map +0 -1
  85. package/dist/core/formatting.js +0 -396
  86. package/dist/core/index.d.ts +0 -17
  87. package/dist/core/index.d.ts.map +0 -1
  88. package/dist/core/index.js +0 -12
  89. package/dist/core/infer-columns.d.ts +0 -6
  90. package/dist/core/infer-columns.d.ts.map +0 -1
  91. package/dist/core/infer-columns.js +0 -512
  92. package/dist/core/metric-utils.d.ts +0 -43
  93. package/dist/core/metric-utils.d.ts.map +0 -1
  94. package/dist/core/metric-utils.js +0 -141
  95. package/dist/core/pipeline-data-points.d.ts +0 -23
  96. package/dist/core/pipeline-data-points.d.ts.map +0 -1
  97. package/dist/core/pipeline-data-points.js +0 -235
  98. package/dist/core/pipeline-helpers.d.ts +0 -38
  99. package/dist/core/pipeline-helpers.d.ts.map +0 -1
  100. package/dist/core/pipeline-helpers.js +0 -97
  101. package/dist/core/pipeline.d.ts.map +0 -1
  102. package/dist/core/pipeline.js +0 -156
  103. package/dist/core/types.d.ts +0 -1109
  104. package/dist/core/types.d.ts.map +0 -1
  105. package/dist/core/types.js +0 -14
  106. package/dist/core/use-chart-options.d.ts +0 -66
  107. package/dist/core/use-chart-options.d.ts.map +0 -1
  108. package/dist/core/use-chart-options.js +0 -4
  109. package/dist/core/use-chart-resolvers.d.ts +0 -14
  110. package/dist/core/use-chart-resolvers.d.ts.map +0 -1
  111. package/dist/core/use-chart-resolvers.js +0 -41
  112. package/dist/core/use-chart.d.ts.map +0 -1
  113. package/dist/core/use-chart.js +0 -265
  114. package/dist/index.d.ts +0 -36
  115. package/dist/index.d.ts.map +0 -1
  116. package/dist/index.js +0 -35
  117. package/dist/ui/chart-axis-ticks.d.ts +0 -35
  118. package/dist/ui/chart-axis-ticks.d.ts.map +0 -1
  119. package/dist/ui/chart-axis-ticks.js +0 -79
  120. package/dist/ui/chart-canvas.d.ts.map +0 -1
  121. package/dist/ui/chart-canvas.js +0 -337
  122. package/dist/ui/chart-context.d.ts +0 -89
  123. package/dist/ui/chart-context.d.ts.map +0 -1
  124. package/dist/ui/chart-context.js +0 -128
  125. package/dist/ui/chart-date-range-badge.d.ts.map +0 -1
  126. package/dist/ui/chart-date-range-badge.js +0 -30
  127. package/dist/ui/chart-date-range-panel.d.ts +0 -25
  128. package/dist/ui/chart-date-range-panel.d.ts.map +0 -1
  129. package/dist/ui/chart-date-range-panel.js +0 -125
  130. package/dist/ui/chart-date-range.d.ts.map +0 -1
  131. package/dist/ui/chart-date-range.js +0 -37
  132. package/dist/ui/chart-debug.d.ts +0 -10
  133. package/dist/ui/chart-debug.d.ts.map +0 -1
  134. package/dist/ui/chart-debug.js +0 -126
  135. package/dist/ui/chart-dropdown.d.ts +0 -35
  136. package/dist/ui/chart-dropdown.d.ts.map +0 -1
  137. package/dist/ui/chart-dropdown.js +0 -76
  138. package/dist/ui/chart-filters-panel.d.ts.map +0 -1
  139. package/dist/ui/chart-filters-panel.js +0 -46
  140. package/dist/ui/chart-filters.d.ts.map +0 -1
  141. package/dist/ui/chart-filters.js +0 -26
  142. package/dist/ui/chart-group-by-selector.d.ts +0 -8
  143. package/dist/ui/chart-group-by-selector.d.ts.map +0 -1
  144. package/dist/ui/chart-group-by-selector.js +0 -19
  145. package/dist/ui/chart-metric-panel.d.ts.map +0 -1
  146. package/dist/ui/chart-metric-panel.js +0 -118
  147. package/dist/ui/chart-metric-selector.d.ts +0 -10
  148. package/dist/ui/chart-metric-selector.d.ts.map +0 -1
  149. package/dist/ui/chart-metric-selector.js +0 -27
  150. package/dist/ui/chart-select.d.ts +0 -25
  151. package/dist/ui/chart-select.d.ts.map +0 -1
  152. package/dist/ui/chart-select.js +0 -35
  153. package/dist/ui/chart-source-switcher.d.ts.map +0 -1
  154. package/dist/ui/chart-source-switcher.js +0 -31
  155. package/dist/ui/chart-time-bucket-selector.d.ts +0 -9
  156. package/dist/ui/chart-time-bucket-selector.d.ts.map +0 -1
  157. package/dist/ui/chart-time-bucket-selector.js +0 -25
  158. package/dist/ui/chart-toolbar-overflow.d.ts +0 -29
  159. package/dist/ui/chart-toolbar-overflow.d.ts.map +0 -1
  160. package/dist/ui/chart-toolbar-overflow.js +0 -109
  161. package/dist/ui/chart-toolbar.d.ts +0 -45
  162. package/dist/ui/chart-toolbar.d.ts.map +0 -1
  163. package/dist/ui/chart-toolbar.js +0 -44
  164. package/dist/ui/chart-type-selector.d.ts +0 -8
  165. package/dist/ui/chart-type-selector.d.ts.map +0 -1
  166. package/dist/ui/chart-type-selector.js +0 -22
  167. package/dist/ui/chart-x-axis-selector.d.ts +0 -8
  168. package/dist/ui/chart-x-axis-selector.d.ts.map +0 -1
  169. package/dist/ui/chart-x-axis-selector.js +0 -14
  170. package/dist/ui/index.d.ts +0 -25
  171. package/dist/ui/index.d.ts.map +0 -1
  172. package/dist/ui/index.js +0 -23
  173. package/dist/ui/toolbar-types.d.ts +0 -43
  174. package/dist/ui/toolbar-types.d.ts.map +0 -1
  175. package/dist/ui/toolbar-types.js +0 -50
@@ -0,0 +1,349 @@
1
+ //#region src/core/formatting.ts
2
+ const DURATION_UNIT_TO_SECONDS = {
3
+ seconds: 1,
4
+ minutes: 60,
5
+ hours: 3600,
6
+ days: 1440 * 60
7
+ };
8
+ /**
9
+ * Build a numeric range from chart values.
10
+ */
11
+ function createNumericRange(values) {
12
+ const finiteValues = values.filter((value) => Number.isFinite(value));
13
+ if (finiteValues.length === 0) return null;
14
+ let min = finiteValues[0];
15
+ let max = finiteValues[0];
16
+ for (const value of finiteValues) {
17
+ if (value < min) min = value;
18
+ if (value > max) max = value;
19
+ }
20
+ return {
21
+ min,
22
+ max
23
+ };
24
+ }
25
+ /**
26
+ * Decide whether an axis should keep decimal ticks for the current visible
27
+ * numeric values.
28
+ */
29
+ function shouldAllowDecimalTicks(values) {
30
+ const finiteValues = values.filter((value) => Number.isFinite(value));
31
+ if (finiteValues.length === 0) return false;
32
+ if (shouldUsePercentByDefault(createNumericRange(finiteValues))) return true;
33
+ return finiteValues.some((value) => !isEffectivelyInteger(value));
34
+ }
35
+ /**
36
+ * Format one chart value for a specific UI surface.
37
+ */
38
+ function formatChartValue(value, options) {
39
+ const { column, surface, timeBucket, numericRange, locale = "en-US", item } = options;
40
+ if (column.formatter) return column.formatter(value, item);
41
+ if (value == null) return "Unknown";
42
+ switch (column.type) {
43
+ case "boolean": return formatBooleanValue(value, column);
44
+ case "category": return String(value);
45
+ case "date": return value instanceof Date || typeof value === "string" || typeof value === "number" ? formatDateValue(value, column.format, surface, timeBucket, locale) : String(value);
46
+ case "number": return typeof value === "number" ? formatNumberValue(value, column.format, surface, numericRange, locale) : String(value);
47
+ }
48
+ }
49
+ /**
50
+ * Format a date bucket label from the machine-friendly pipeline key.
51
+ */
52
+ function formatTimeBucketLabel(key, bucket, surface, locale = "en-US") {
53
+ switch (bucket) {
54
+ case "day": return formatDateWithOptions(parseBucketDate(key), locale, getBucketDayOptions(surface));
55
+ case "week": {
56
+ const date = parseBucketDate(key);
57
+ return `${surface === "tooltip" ? "Week of " : "Wk of "}${formatDateWithOptions(date, locale, getBucketWeekOptions(surface))}`;
58
+ }
59
+ case "month": return formatDateWithOptions(parseBucketMonth(key), locale, {
60
+ month: "short",
61
+ year: "2-digit"
62
+ });
63
+ case "quarter": {
64
+ const { year, quarter } = parseQuarterKey(key);
65
+ return `Q${quarter} ${year.slice(-2)}`;
66
+ }
67
+ case "year": return key;
68
+ }
69
+ }
70
+ /**
71
+ * Resolve the boolean labels while keeping null handling in the shared entry
72
+ * point above.
73
+ */
74
+ function formatBooleanValue(value, column) {
75
+ if (value === true) return column.trueLabel ?? "True";
76
+ if (value === false) return column.falseLabel ?? "False";
77
+ return String(value);
78
+ }
79
+ /**
80
+ * Format numeric values with surface-aware defaults and optional overrides.
81
+ */
82
+ function formatNumberValue(value, format, surface, numericRange, locale) {
83
+ if (!Number.isFinite(value)) return String(value);
84
+ if (typeof format === "object" && format.kind === "duration") return formatDurationValue(value, format);
85
+ if (typeof format === "object" && format.kind === "number") return new Intl.NumberFormat(format.locale ?? locale, format.options).format(value);
86
+ const mode = resolveNumberFormatMode(format, surface, numericRange, value);
87
+ return new Intl.NumberFormat(locale, getNumberFormatOptions(mode, surface, numericRange, value)).format(value);
88
+ }
89
+ /**
90
+ * Format one numeric duration into a compact, surface-agnostic label such as
91
+ * `36s`, `1h36m`, or `1d5h`.
92
+ */
93
+ function formatDurationValue(value, format) {
94
+ const sign = value < 0 ? "-" : "";
95
+ const totalSeconds = Math.round(Math.abs(value) * DURATION_UNIT_TO_SECONDS[format.unit]);
96
+ if (totalSeconds === 0) return `${sign}0${getDurationZeroSuffix(format.unit)}`;
97
+ return `${sign}${buildDurationParts(totalSeconds).slice(0, 2).map((part) => `${part.value}${part.suffix}`).join("")}`;
98
+ }
99
+ /**
100
+ * Build the ordered duration parts used by the compact formatter.
101
+ */
102
+ function buildDurationParts(totalSeconds) {
103
+ const parts = [];
104
+ let remainingSeconds = totalSeconds;
105
+ const units = [
106
+ {
107
+ seconds: DURATION_UNIT_TO_SECONDS.days,
108
+ suffix: "d"
109
+ },
110
+ {
111
+ seconds: DURATION_UNIT_TO_SECONDS.hours,
112
+ suffix: "h"
113
+ },
114
+ {
115
+ seconds: DURATION_UNIT_TO_SECONDS.minutes,
116
+ suffix: "m"
117
+ },
118
+ {
119
+ seconds: DURATION_UNIT_TO_SECONDS.seconds,
120
+ suffix: "s"
121
+ }
122
+ ];
123
+ for (const unit of units) {
124
+ if (remainingSeconds < unit.seconds) continue;
125
+ const unitValue = Math.floor(remainingSeconds / unit.seconds);
126
+ remainingSeconds -= unitValue * unit.seconds;
127
+ parts.push({
128
+ value: unitValue,
129
+ suffix: unit.suffix
130
+ });
131
+ }
132
+ return parts.length > 0 ? parts : [{
133
+ value: 0,
134
+ suffix: "s"
135
+ }];
136
+ }
137
+ /**
138
+ * Keep zero durations aligned with the unit declared by the schema author.
139
+ */
140
+ function getDurationZeroSuffix(unit) {
141
+ switch (unit) {
142
+ case "seconds": return "s";
143
+ case "minutes": return "m";
144
+ case "hours": return "h";
145
+ case "days": return "d";
146
+ }
147
+ }
148
+ /**
149
+ * Format date values with either a caller-specified `Intl` config or the shared
150
+ * time-bucket-aware defaults.
151
+ */
152
+ function formatDateValue(value, format, surface, timeBucket, locale) {
153
+ if (typeof format === "object" && format.kind === "date") return formatDateWithOptions(value, format.locale ?? locale, format.options ?? {});
154
+ if (timeBucket) {
155
+ const date = toDate(value);
156
+ if (date) return formatDateWithOptions(date, locale, getBucketDateOptions(timeBucket, surface));
157
+ }
158
+ return formatDateWithOptions(value, locale, getDateValueOptions(resolveDateFormatMode(format), surface));
159
+ }
160
+ /**
161
+ * Convert a broad value into a valid Date when possible.
162
+ */
163
+ function toDate(value) {
164
+ const date = value instanceof Date ? new Date(value) : new Date(value);
165
+ return Number.isNaN(date.getTime()) ? null : date;
166
+ }
167
+ /**
168
+ * Safely format a parsed date, falling back to the raw string when parsing
169
+ * fails.
170
+ */
171
+ function formatDateWithOptions(value, locale, options) {
172
+ const date = value == null ? null : toDate(value);
173
+ if (!date) return value == null ? "Unknown" : String(value);
174
+ return new Intl.DateTimeFormat(locale, options).format(date);
175
+ }
176
+ /**
177
+ * Decide which number family should power the current surface.
178
+ */
179
+ function resolveNumberFormatMode(format, surface, numericRange, value) {
180
+ if (typeof format === "string") switch (format) {
181
+ case "currency": return surface === "tooltip" ? "currency" : "compact-currency";
182
+ case "compact-number": return "compact-number";
183
+ case "percent": return "percent";
184
+ case "number":
185
+ case "date":
186
+ case "datetime": return surface === "tooltip" ? "number" : shouldUseCompactNumber(numericRange, value) ? "compact-number" : "number";
187
+ }
188
+ if (shouldUsePercentByDefault(numericRange)) return "percent";
189
+ if (surface !== "tooltip" && shouldUseCompactNumber(numericRange, value)) return "compact-number";
190
+ return "number";
191
+ }
192
+ /**
193
+ * Decide which date family should power the current surface.
194
+ */
195
+ function resolveDateFormatMode(format) {
196
+ return format === "datetime" ? "datetime" : "date";
197
+ }
198
+ /**
199
+ * Use percentage defaults only when the visible values all live in the
200
+ * percentage-like range.
201
+ */
202
+ function shouldUsePercentByDefault(numericRange) {
203
+ if (!numericRange) return false;
204
+ const maxAbs = Math.max(Math.abs(numericRange.min), Math.abs(numericRange.max));
205
+ return maxAbs > 0 && maxAbs <= 1;
206
+ }
207
+ /**
208
+ * Compact large values on short surfaces while leaving small ranges readable.
209
+ */
210
+ function shouldUseCompactNumber(numericRange, value) {
211
+ return (numericRange ? Math.max(Math.abs(numericRange.min), Math.abs(numericRange.max)) : Math.abs(value)) >= 1e3;
212
+ }
213
+ /**
214
+ * Treat floating-point noise around whole numbers as integers so axis policy
215
+ * follows the actual metric shape rather than binary rounding artifacts.
216
+ */
217
+ function isEffectivelyInteger(value) {
218
+ return Math.abs(value - Math.round(value)) < 1e-9;
219
+ }
220
+ /**
221
+ * Produce the final `Intl.NumberFormat` options for one numeric mode.
222
+ */
223
+ function getNumberFormatOptions(mode, surface, numericRange, value) {
224
+ switch (mode) {
225
+ case "compact-currency": return {
226
+ style: "currency",
227
+ currency: "USD",
228
+ notation: "compact",
229
+ maximumFractionDigits: 1
230
+ };
231
+ case "currency": return {
232
+ style: "currency",
233
+ currency: "USD",
234
+ maximumFractionDigits: getStandardFractionDigits(surface, numericRange, value)
235
+ };
236
+ case "compact-number": return {
237
+ notation: "compact",
238
+ maximumFractionDigits: 1
239
+ };
240
+ case "percent": return {
241
+ style: "percent",
242
+ maximumFractionDigits: surface === "tooltip" ? 2 : 1
243
+ };
244
+ case "number": return { maximumFractionDigits: getStandardFractionDigits(surface, numericRange, value) };
245
+ }
246
+ }
247
+ /**
248
+ * Keep tooltip values more precise than axis and data-label surfaces.
249
+ */
250
+ function getStandardFractionDigits(surface, numericRange, value) {
251
+ const span = numericRange ? Math.abs(numericRange.max - numericRange.min) : Math.abs(value);
252
+ if (surface === "tooltip") {
253
+ if (span < 1) return 3;
254
+ if (span < 10) return 2;
255
+ if (span < 100) return 1;
256
+ return 0;
257
+ }
258
+ if (span < 1) return 2;
259
+ if (span < 10) return 1;
260
+ return 0;
261
+ }
262
+ /**
263
+ * Match raw date values to a clear default display.
264
+ */
265
+ function getDateValueOptions(mode, surface) {
266
+ if (mode === "datetime") return surface === "tooltip" ? {
267
+ dateStyle: "medium",
268
+ timeStyle: "short"
269
+ } : {
270
+ month: "short",
271
+ day: "numeric",
272
+ hour: "numeric",
273
+ minute: "2-digit"
274
+ };
275
+ return {
276
+ month: "short",
277
+ day: "numeric",
278
+ year: "2-digit"
279
+ };
280
+ }
281
+ /**
282
+ * Match bucketed dates to the active time bucket.
283
+ */
284
+ function getBucketDateOptions(bucket, surface) {
285
+ switch (bucket) {
286
+ case "day": return getBucketDayOptions(surface);
287
+ case "week": return getBucketWeekOptions(surface);
288
+ case "month": return {
289
+ month: "short",
290
+ year: "2-digit"
291
+ };
292
+ case "quarter": return {
293
+ month: "short",
294
+ year: "2-digit"
295
+ };
296
+ case "year": return { year: "numeric" };
297
+ }
298
+ }
299
+ /**
300
+ * Keep day buckets short on axes and clearer in tooltips.
301
+ */
302
+ function getBucketDayOptions(surface) {
303
+ return surface === "tooltip" ? {
304
+ month: "short",
305
+ day: "numeric",
306
+ year: "2-digit"
307
+ } : {
308
+ month: "short",
309
+ day: "numeric"
310
+ };
311
+ }
312
+ /**
313
+ * Keep week buckets short on axes and clearer in tooltips.
314
+ */
315
+ function getBucketWeekOptions(surface) {
316
+ return surface === "tooltip" ? {
317
+ month: "short",
318
+ day: "numeric",
319
+ year: "2-digit"
320
+ } : {
321
+ month: "short",
322
+ day: "numeric"
323
+ };
324
+ }
325
+ /**
326
+ * Parse a `YYYY-MM-DD` bucket key.
327
+ */
328
+ function parseBucketDate(key) {
329
+ return /* @__PURE__ */ new Date(`${key}T00:00:00`);
330
+ }
331
+ /**
332
+ * Parse a `YYYY-MM` bucket key.
333
+ */
334
+ function parseBucketMonth(key) {
335
+ const [year, month] = key.split("-");
336
+ return new Date(Number(year), Number(month) - 1, 1);
337
+ }
338
+ /**
339
+ * Parse a `YYYY-QN` quarter key.
340
+ */
341
+ function parseQuarterKey(key) {
342
+ const [year, quarter] = key.split("-Q");
343
+ return {
344
+ year: year ?? key,
345
+ quarter: quarter ?? "1"
346
+ };
347
+ }
348
+ //#endregion
349
+ export { createNumericRange, formatChartValue, formatTimeBucketLabel, shouldAllowDecimalTicks };
@@ -0,0 +1,9 @@
1
+ import { ChartColumn, ChartSchema, ResolvedColumnIdFromSchema } from "./types.mjs";
2
+
3
+ //#region src/core/infer-columns.d.ts
4
+ /**
5
+ * Resolve chart columns directly from raw data and an optional explicit schema.
6
+ */
7
+ declare function inferColumnsFromData<T, const TSchema extends ChartSchema<T, any> | undefined = undefined>(data: readonly T[], schema?: TSchema): readonly ChartColumn<T, ResolvedColumnIdFromSchema<T, TSchema>>[];
8
+ //#endregion
9
+ export { inferColumnsFromData };