@matthieumordrel/chart-studio 0.2.3 → 0.2.5

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 (48) hide show
  1. package/README.md +42 -42
  2. package/dist/core/chart-capabilities.d.mts +15 -0
  3. package/dist/core/chart-capabilities.mjs +23 -0
  4. package/dist/core/colors.mjs +5 -5
  5. package/dist/core/config-utils.mjs +6 -2
  6. package/dist/core/date-range-presets.d.mts +12 -0
  7. package/dist/core/date-range-presets.mjs +152 -0
  8. package/dist/core/define-chart-schema.d.mts +26 -94
  9. package/dist/core/define-chart-schema.mjs +26 -34
  10. package/dist/core/infer-columns.d.mts +2 -2
  11. package/dist/core/infer-columns.mjs +4 -2
  12. package/dist/core/metric-utils.mjs +13 -5
  13. package/dist/core/pipeline-data-points.mjs +4 -1
  14. package/dist/core/schema-builder.mjs +335 -0
  15. package/dist/core/schema-builder.types.d.mts +279 -0
  16. package/dist/core/types.d.mts +61 -17
  17. package/dist/core/use-chart-options.d.mts +7 -4
  18. package/dist/core/use-chart.d.mts +4 -4
  19. package/dist/core/use-chart.mjs +70 -40
  20. package/dist/index.d.mts +2 -2
  21. package/dist/index.mjs +1 -1
  22. package/dist/ui/chart-canvas.d.mts +8 -4
  23. package/dist/ui/chart-canvas.mjs +347 -29
  24. package/dist/ui/chart-context.d.mts +11 -4
  25. package/dist/ui/chart-context.mjs +3 -0
  26. package/dist/ui/chart-date-range-badge.mjs +2 -2
  27. package/dist/ui/chart-date-range-panel.mjs +19 -101
  28. package/dist/ui/chart-date-range.mjs +3 -3
  29. package/dist/ui/chart-debug.d.mts +6 -2
  30. package/dist/ui/chart-debug.mjs +5 -1
  31. package/dist/ui/chart-group-by-selector.d.mts +3 -1
  32. package/dist/ui/chart-group-by-selector.mjs +4 -1
  33. package/dist/ui/chart-metric-selector.mjs +2 -2
  34. package/dist/ui/chart-select.mjs +9 -10
  35. package/dist/ui/chart-source-switcher.d.mts +3 -1
  36. package/dist/ui/chart-source-switcher.mjs +4 -2
  37. package/dist/ui/chart-time-bucket-selector.d.mts +3 -1
  38. package/dist/ui/chart-time-bucket-selector.mjs +4 -1
  39. package/dist/ui/chart-toolbar-overflow.mjs +48 -26
  40. package/dist/ui/chart-toolbar.d.mts +6 -2
  41. package/dist/ui/chart-toolbar.mjs +4 -0
  42. package/dist/ui/chart-type-selector.d.mts +7 -2
  43. package/dist/ui/chart-type-selector.mjs +155 -20
  44. package/dist/ui/chart-x-axis-selector.d.mts +3 -1
  45. package/dist/ui/chart-x-axis-selector.mjs +4 -1
  46. package/dist/ui/percent-stacked.mjs +36 -0
  47. package/dist/ui/theme.css +54 -49
  48. package/package.json +7 -6
@@ -0,0 +1,279 @@
1
+ import { BaseColumnHint, ChartType, ChartTypeConfig, CountMetric, DefinedChartSchema, DerivedBooleanColumnSchema, DerivedCategoryColumnSchema, DerivedDateColumnSchema, DerivedNumberColumnSchema, FiltersConfig, GroupByConfig, InferableFieldKey, Metric, MetricConfig, NumericAggregateFunction, RawColumnSchemaFor, ResolvedFilterColumnIdFromSchema, ResolvedGroupByColumnIdFromSchema, ResolvedMetricColumnIdFromSchema, ResolvedXAxisColumnIdFromSchema, TimeBucket, TimeBucketConfig, XAxisConfig } from "./types.mjs";
2
+
3
+ //#region src/core/schema-builder.types.d.ts
4
+ type Nullish = null | undefined;
5
+ type NonNullish<T> = Exclude<T, Nullish>;
6
+ type Simplify<T> = { [TKey in keyof T]: T[TKey] } & {};
7
+ type NonEmptyReadonlyArray<TValue> = readonly [TValue, ...TValue[]];
8
+ type FieldKeyMatchingValue<T, TValue> = Extract<{ [TKey in InferableFieldKey<T>]-?: [NonNullish<T[TKey]>] extends [TValue] ? TKey : never }[InferableFieldKey<T>], string>;
9
+ type ReplaceConfigValue<TConfig, TKey extends PropertyKey, TValue> = Simplify<Omit<TConfig, TKey> & { [TProperty in TKey]: TValue }>;
10
+ type SchemaColumnsContext<TColumns extends Record<string, unknown> | undefined> = [TColumns] extends [undefined] ? undefined : {
11
+ columns?: TColumns;
12
+ };
13
+ type AppendConfigValue<TConfig, TKey extends PropertyKey, TValue> = Simplify<Omit<TConfig, TKey> & { [TProperty in TKey]: TConfig extends Record<TKey, infer TExisting extends readonly unknown[]> ? readonly [...TExisting, TValue] : readonly [TValue] }>;
14
+ type AppendManyConfigValues<TConfig, TKey extends PropertyKey, TValues extends readonly unknown[]> = Simplify<Omit<TConfig, TKey> & { [TProperty in TKey]: TConfig extends Record<TKey, infer TExisting extends readonly unknown[]> ? readonly [...TExisting, ...TValues] : TValues }>;
15
+ type AggregateSelectionFromList<TAggregates extends readonly NumericAggregateFunction[]> = TAggregates extends readonly [infer TOnlyAggregate extends NumericAggregateFunction] ? TOnlyAggregate : TAggregates;
16
+ type MetricColumnIdFromMetric<TMetric> = Extract<TMetric extends {
17
+ kind: 'aggregate';
18
+ columnId: infer TColumnId extends string;
19
+ } ? TColumnId : never, string>;
20
+ type MetricAggregateFromMetric<TMetric, TColumnId extends string> = Extract<Extract<TMetric, {
21
+ kind: 'aggregate';
22
+ columnId: TColumnId;
23
+ }> extends {
24
+ aggregate: infer TAggregate extends NumericAggregateFunction;
25
+ } ? TAggregate : never, NumericAggregateFunction>;
26
+ type AggregateMetricUnionFromSelection<TColumnId extends string, TAggregates extends readonly NumericAggregateFunction[]> = { [TIndex in keyof TAggregates]: TAggregates[TIndex] extends NumericAggregateFunction ? {
27
+ kind: 'aggregate';
28
+ columnId: TColumnId;
29
+ aggregate: TAggregates[TIndex];
30
+ } : never }[number];
31
+ type AggregateMetricTupleFromSelection<TColumnId extends string, TAggregates extends readonly NumericAggregateFunction[]> = TAggregates extends readonly [infer THead extends NumericAggregateFunction, ...infer TTail extends NumericAggregateFunction[]] ? readonly [{
32
+ kind: 'aggregate';
33
+ columnId: TColumnId;
34
+ aggregate: THead;
35
+ }, ...AggregateMetricTupleFromSelection<TColumnId, TTail>] : readonly [];
36
+ type SelectableMetricUnion<TMetricColumnId extends string, TAllowedMetric> = [TAllowedMetric] extends [never] ? Metric<TMetricColumnId> : TAllowedMetric;
37
+ type VisibleMetricUnion<TMetricColumnId extends string, TAllowedMetric, THiddenMetric> = Exclude<SelectableMetricUnion<TMetricColumnId, TAllowedMetric>, THiddenMetric>;
38
+ type DerivedColumnId<TRow, TColumnId extends string> = TColumnId extends InferableFieldKey<TRow> ? never : TColumnId;
39
+ type ColumnEntryId<TEntry> = TEntry extends {
40
+ id: infer TId extends string;
41
+ } ? TId : never;
42
+ type DuplicateColumnIds<TEntries extends readonly unknown[], TSeen extends string = never> = TEntries extends readonly [infer THead, ...infer TTail] ? ColumnEntryId<THead> extends TSeen ? ColumnEntryId<THead> | DuplicateColumnIds<TTail, TSeen> : DuplicateColumnIds<TTail, TSeen | ColumnEntryId<THead>> : never;
43
+ type DuplicateColumnIdError<TColumnId extends string> = {
44
+ __columnBuilderError__: `Duplicate column id "${TColumnId}"`;
45
+ };
46
+ type StringFieldKey<T> = FieldKeyMatchingValue<T, string>;
47
+ type NumberFieldKey<T> = FieldKeyMatchingValue<T, number>;
48
+ type BooleanFieldKey<T> = FieldKeyMatchingValue<T, boolean>;
49
+ type DateLikeFieldKey<T> = Extract<{ [TKey in InferableFieldKey<T>]-?: [NonNullish<T[TKey]>] extends [string | number | Date] ? TKey : never }[InferableFieldKey<T>], string>;
50
+ type SharedColumnOptions<TRow, TValue> = BaseColumnHint<TRow, TValue>;
51
+ type FieldColumnOptions<TRow, TFieldId extends InferableFieldKey<TRow>> = RawColumnSchemaFor<TRow[TFieldId], TRow>;
52
+ type DateColumnOptions<TRow> = SharedColumnOptions<TRow, string | number | Date>;
53
+ type CategoryColumnOptions<TRow> = SharedColumnOptions<TRow, string>;
54
+ type NumberColumnOptions<TRow> = SharedColumnOptions<TRow, number>;
55
+ type BooleanColumnOptions<TRow> = SharedColumnOptions<TRow, boolean> & {
56
+ trueLabel?: string;
57
+ falseLabel?: string;
58
+ };
59
+ type DerivedDateColumnOptions<TRow> = Omit<DerivedDateColumnSchema<TRow>, 'kind' | 'type'>;
60
+ type DerivedCategoryColumnOptions<TRow> = Omit<DerivedCategoryColumnSchema<TRow>, 'kind' | 'type'>;
61
+ type DerivedBooleanColumnOptions<TRow> = Omit<DerivedBooleanColumnSchema<TRow>, 'kind' | 'type'>;
62
+ type DerivedNumberColumnOptions<TRow> = Omit<DerivedNumberColumnSchema<TRow>, 'kind' | 'type'>;
63
+ type RawFieldColumnEntry<TRow, TFieldId extends InferableFieldKey<TRow>, TColumn> = {
64
+ readonly kind: 'raw';
65
+ readonly id: TFieldId;
66
+ readonly column: TColumn;
67
+ };
68
+ type ExcludedFieldColumnEntry<TRow, TFieldId extends InferableFieldKey<TRow>> = {
69
+ readonly kind: 'exclude';
70
+ readonly id: TFieldId;
71
+ readonly column: false;
72
+ };
73
+ type DerivedColumnEntry<TRow, TColumnId extends string, TColumn extends DerivedDateColumnSchema<TRow> | DerivedCategoryColumnSchema<TRow> | DerivedBooleanColumnSchema<TRow> | DerivedNumberColumnSchema<TRow>> = {
74
+ readonly kind: 'derived';
75
+ readonly id: TColumnId;
76
+ readonly column: TColumn;
77
+ };
78
+ type SchemaColumnEntry<TRow> = RawFieldColumnEntry<TRow, InferableFieldKey<TRow>, unknown> | ExcludedFieldColumnEntry<TRow, InferableFieldKey<TRow>> | DerivedColumnEntry<TRow, string, DerivedDateColumnSchema<TRow> | DerivedCategoryColumnSchema<TRow> | DerivedBooleanColumnSchema<TRow> | DerivedNumberColumnSchema<TRow>>;
79
+ type ValidateColumnEntries<TEntries extends readonly unknown[]> = [DuplicateColumnIds<TEntries>] extends [never] ? unknown : DuplicateColumnIdError<Extract<DuplicateColumnIds<TEntries>, string>>;
80
+ type ColumnsFromEntries<TRow, TEntries extends readonly SchemaColumnEntry<TRow>[]> = Simplify<{ [TEntry in TEntries[number] as TEntry['id']]: TEntry['column'] }>;
81
+ interface ColumnHelper<TRow> {
82
+ /**
83
+ * Override one existing raw field using the raw-field schema surface.
84
+ *
85
+ * Use this when you want the full hint surface for a field, including type
86
+ * overrides on string/number columns.
87
+ */
88
+ field<const TFieldId extends InferableFieldKey<TRow>>(id: TFieldId, options?: FieldColumnOptions<TRow, TFieldId>): RawFieldColumnEntry<TRow, TFieldId, FieldColumnOptions<TRow, TFieldId>>;
89
+ /**
90
+ * Treat one raw field as a date column.
91
+ *
92
+ * Supports raw `string`, `number`, and `Date` fields that should behave as a
93
+ * time-series axis.
94
+ */
95
+ date<const TFieldId extends DateLikeFieldKey<TRow>>(id: TFieldId, options?: DateColumnOptions<TRow>): RawFieldColumnEntry<TRow, TFieldId, {
96
+ type: 'date';
97
+ } & DateColumnOptions<TRow>>;
98
+ /**
99
+ * Treat one raw string field as a category column.
100
+ *
101
+ * Category columns are eligible for the X-axis, grouping, and filters.
102
+ */
103
+ category<const TFieldId extends StringFieldKey<TRow>>(id: TFieldId, options?: CategoryColumnOptions<TRow>): RawFieldColumnEntry<TRow, TFieldId, {
104
+ type: 'category';
105
+ } & CategoryColumnOptions<TRow>>;
106
+ /**
107
+ * Treat one raw numeric field as a number column.
108
+ *
109
+ * Number columns participate in metric aggregation.
110
+ */
111
+ number<const TFieldId extends NumberFieldKey<TRow>>(id: TFieldId, options?: NumberColumnOptions<TRow>): RawFieldColumnEntry<TRow, TFieldId, {
112
+ type: 'number';
113
+ } & NumberColumnOptions<TRow>>;
114
+ /**
115
+ * Treat one raw boolean field as a boolean column.
116
+ *
117
+ * Boolean columns are useful for grouping and filters.
118
+ */
119
+ boolean<const TFieldId extends BooleanFieldKey<TRow>>(id: TFieldId, options?: BooleanColumnOptions<TRow>): RawFieldColumnEntry<TRow, TFieldId, {
120
+ type: 'boolean';
121
+ } & BooleanColumnOptions<TRow>>;
122
+ /**
123
+ * Remove one raw field from the chart schema entirely.
124
+ */
125
+ exclude<const TFieldId extends InferableFieldKey<TRow>>(id: TFieldId): ExcludedFieldColumnEntry<TRow, TFieldId>;
126
+ /** Helper group for declaring new derived columns. */
127
+ readonly derived: {
128
+ /**
129
+ * Add one derived date column.
130
+ *
131
+ * The accessor receives the original row type.
132
+ */
133
+ date<const TColumnId extends string>(id: DerivedColumnId<TRow, TColumnId>, options: DerivedDateColumnOptions<TRow>): DerivedColumnEntry<TRow, TColumnId, {
134
+ kind: 'derived';
135
+ type: 'date';
136
+ } & DerivedDateColumnOptions<TRow>>;
137
+ /**
138
+ * Add one derived category column.
139
+ *
140
+ * The accessor receives the original row type.
141
+ */
142
+ category<const TColumnId extends string>(id: DerivedColumnId<TRow, TColumnId>, options: DerivedCategoryColumnOptions<TRow>): DerivedColumnEntry<TRow, TColumnId, {
143
+ kind: 'derived';
144
+ type: 'category';
145
+ } & DerivedCategoryColumnOptions<TRow>>;
146
+ /**
147
+ * Add one derived boolean column.
148
+ *
149
+ * The accessor receives the original row type.
150
+ */
151
+ boolean<const TColumnId extends string>(id: DerivedColumnId<TRow, TColumnId>, options: DerivedBooleanColumnOptions<TRow>): DerivedColumnEntry<TRow, TColumnId, {
152
+ kind: 'derived';
153
+ type: 'boolean';
154
+ } & DerivedBooleanColumnOptions<TRow>>;
155
+ /**
156
+ * Add one derived numeric column.
157
+ *
158
+ * The accessor receives the original row type.
159
+ */
160
+ number<const TColumnId extends string>(id: DerivedColumnId<TRow, TColumnId>, options: DerivedNumberColumnOptions<TRow>): DerivedColumnEntry<TRow, TColumnId, {
161
+ kind: 'derived';
162
+ type: 'number';
163
+ } & DerivedNumberColumnOptions<TRow>>;
164
+ };
165
+ }
166
+ type SelectableControlBuilderConfig<TBuilder> = TBuilder extends SelectableControlBuilder<any, any, any, any, infer TConfig> ? TConfig : never;
167
+ interface SelectableControlBuilder<TOption extends string, TSupportsDefault extends boolean, TAllowedOption extends TOption = TOption, THiddenOption extends TOption = never, TConfig extends object = {}> {
168
+ /**
169
+ * Keep only the listed options visible and selectable.
170
+ *
171
+ * Calling `allowed(...)` again replaces the previous allowed list.
172
+ */
173
+ allowed<const TOptions extends NonEmptyReadonlyArray<TOption>>(...options: TOptions): SelectableControlBuilder<TOption, TSupportsDefault, Extract<TOptions[number], TOption>, Extract<THiddenOption, Extract<TOptions[number], TOption>>, ReplaceConfigValue<TConfig, 'allowed', TOptions>>;
174
+ /**
175
+ * Hide one or more options after the allowed set is resolved.
176
+ *
177
+ * Hidden options can still exist in the broader schema; they simply stop
178
+ * appearing in the public control surface.
179
+ */
180
+ hidden<const TOptions extends NonEmptyReadonlyArray<Exclude<TAllowedOption, THiddenOption>>>(...options: TOptions): SelectableControlBuilder<TOption, TSupportsDefault, TAllowedOption, THiddenOption | Extract<TOptions[number], TOption>, AppendConfigValue<TConfig, 'hidden', TOptions[number]>>;
181
+ /**
182
+ * Set the preferred fallback option when the current selection is missing or
183
+ * invalid for the current schema.
184
+ */
185
+ default: TSupportsDefault extends true ? <const TDefaultOption extends Exclude<TAllowedOption, THiddenOption>>(option: TDefaultOption) => SelectableControlBuilder<TOption, TSupportsDefault, TAllowedOption, THiddenOption, ReplaceConfigValue<TConfig, 'default', TDefaultOption>> : never;
186
+ }
187
+ type MetricBuilderConfig<TBuilder> = TBuilder extends MetricBuilder<any, any, any, infer TConfig> ? TConfig : never;
188
+ interface MetricBuilder<TMetricColumnId extends string, TAllowedMetric = never, THiddenMetric = never, TConfig extends object = {}> {
189
+ /**
190
+ * Allow the built-in row count metric.
191
+ */
192
+ count(): MetricBuilder<TMetricColumnId, TAllowedMetric | CountMetric, THiddenMetric, AppendConfigValue<TConfig, 'allowed', CountMetric>>;
193
+ /**
194
+ * Allow one or more numeric aggregates for the given column.
195
+ *
196
+ * Example: `aggregate('salary', 'sum', 'avg')`
197
+ */
198
+ aggregate<const TColumnId extends TMetricColumnId, const TAggregates extends NonEmptyReadonlyArray<NumericAggregateFunction>>(columnId: TColumnId, ...aggregates: TAggregates): MetricBuilder<TMetricColumnId, TAllowedMetric | AggregateMetricUnionFromSelection<TColumnId, TAggregates>, THiddenMetric, AppendConfigValue<TConfig, 'allowed', {
199
+ kind: 'aggregate';
200
+ columnId: TColumnId;
201
+ aggregate: AggregateSelectionFromList<TAggregates>;
202
+ }>>;
203
+ /**
204
+ * Hide the row count metric from the public metric picker.
205
+ */
206
+ hideCount(...args: CountMetric extends VisibleMetricUnion<TMetricColumnId, TAllowedMetric, THiddenMetric> ? [] : [never]): MetricBuilder<TMetricColumnId, TAllowedMetric, THiddenMetric | CountMetric, AppendConfigValue<TConfig, 'hidden', CountMetric>>;
207
+ /**
208
+ * Hide one or more aggregate metrics for a numeric column.
209
+ */
210
+ hideAggregate<const TColumnId extends MetricColumnIdFromMetric<VisibleMetricUnion<TMetricColumnId, TAllowedMetric, THiddenMetric>>, const TAggregates extends NonEmptyReadonlyArray<MetricAggregateFromMetric<VisibleMetricUnion<TMetricColumnId, TAllowedMetric, THiddenMetric>, TColumnId>>>(columnId: TColumnId, ...aggregates: TAggregates): MetricBuilder<TMetricColumnId, TAllowedMetric, THiddenMetric | AggregateMetricUnionFromSelection<TColumnId, TAggregates>, AppendManyConfigValues<TConfig, 'hidden', AggregateMetricTupleFromSelection<TColumnId, TAggregates>>>;
211
+ /**
212
+ * Prefer the row count metric when the current metric becomes invalid.
213
+ */
214
+ defaultCount(...args: CountMetric extends VisibleMetricUnion<TMetricColumnId, TAllowedMetric, THiddenMetric> ? [] : [never]): MetricBuilder<TMetricColumnId, TAllowedMetric, THiddenMetric, ReplaceConfigValue<TConfig, 'default', CountMetric>>;
215
+ /**
216
+ * Prefer one aggregate metric when the current metric becomes invalid.
217
+ */
218
+ defaultAggregate<const TColumnId extends MetricColumnIdFromMetric<VisibleMetricUnion<TMetricColumnId, TAllowedMetric, THiddenMetric>>, const TAggregate extends MetricAggregateFromMetric<VisibleMetricUnion<TMetricColumnId, TAllowedMetric, THiddenMetric>, TColumnId>>(columnId: TColumnId, aggregate: TAggregate): MetricBuilder<TMetricColumnId, TAllowedMetric, THiddenMetric, ReplaceConfigValue<TConfig, 'default', {
219
+ kind: 'aggregate';
220
+ columnId: TColumnId;
221
+ aggregate: TAggregate;
222
+ }>>;
223
+ }
224
+ type SchemaFromBuilder<TColumns extends Record<string, unknown> | undefined, TXAxis extends XAxisConfig<any> | undefined, TGroupBy extends GroupByConfig<any> | undefined, TFilters extends FiltersConfig<any> | undefined, TMetric extends MetricConfig<any> | undefined, TChartType extends ChartTypeConfig | undefined, TTimeBucket extends TimeBucketConfig | undefined, TConnectNulls extends boolean | undefined> = {
225
+ columns?: Extract<TColumns, Record<string, unknown> | undefined>;
226
+ xAxis?: Extract<TXAxis, XAxisConfig<any> | undefined>;
227
+ groupBy?: Extract<TGroupBy, GroupByConfig<any> | undefined>;
228
+ filters?: Extract<TFilters, FiltersConfig<any> | undefined>;
229
+ metric?: Extract<TMetric, MetricConfig<any> | undefined>;
230
+ chartType?: Extract<TChartType, ChartTypeConfig | undefined>;
231
+ timeBucket?: Extract<TTimeBucket, TimeBucketConfig | undefined>;
232
+ connectNulls?: Extract<TConnectNulls, boolean | undefined>;
233
+ };
234
+ type ChartSchemaBuilder<TRow, TColumns extends Record<string, unknown> | undefined = undefined, TXAxis extends XAxisConfig<any> | undefined = undefined, TGroupBy extends GroupByConfig<any> | undefined = undefined, TFilters extends FiltersConfig<any> | undefined = undefined, TMetric extends MetricConfig<any> | undefined = undefined, TChartType extends ChartTypeConfig | undefined = undefined, TTimeBucket extends TimeBucketConfig | undefined = undefined, TConnectNulls extends boolean | undefined = undefined> = {
235
+ /**
236
+ * Declare explicit raw and derived columns for this schema.
237
+ *
238
+ * Place this early in the chain so later sections can narrow against the
239
+ * final column ids and roles.
240
+ */
241
+ columns: TColumns extends undefined ? <const TEntries extends readonly SchemaColumnEntry<TRow>[]>(defineColumns: (columns: ColumnHelper<TRow>) => TEntries & ValidateColumnEntries<TEntries>) => ChartSchemaBuilder<TRow, ColumnsFromEntries<TRow, TEntries>, TXAxis, TGroupBy, TFilters, TMetric, TChartType, TTimeBucket, TConnectNulls> : never;
242
+ /**
243
+ * Configure which columns may appear on the X-axis.
244
+ */
245
+ xAxis<const TBuilder extends SelectableControlBuilder<ResolvedXAxisColumnIdFromSchema<TRow, SchemaColumnsContext<TColumns>>, true>>(defineXAxis: (xAxis: SelectableControlBuilder<ResolvedXAxisColumnIdFromSchema<TRow, SchemaColumnsContext<TColumns>>, true>) => TBuilder): ChartSchemaBuilder<TRow, TColumns, SelectableControlBuilderConfig<TBuilder>, TGroupBy, TFilters, TMetric, TChartType, TTimeBucket, TConnectNulls>;
246
+ /**
247
+ * Configure which columns may split the chart into series.
248
+ */
249
+ groupBy<const TBuilder extends SelectableControlBuilder<ResolvedGroupByColumnIdFromSchema<TRow, SchemaColumnsContext<TColumns>>, true>>(defineGroupBy: (groupBy: SelectableControlBuilder<ResolvedGroupByColumnIdFromSchema<TRow, SchemaColumnsContext<TColumns>>, true>) => TBuilder): ChartSchemaBuilder<TRow, TColumns, TXAxis, SelectableControlBuilderConfig<TBuilder>, TFilters, TMetric, TChartType, TTimeBucket, TConnectNulls>;
250
+ /**
251
+ * Configure which columns may appear in the filters UI.
252
+ */
253
+ filters<const TBuilder extends SelectableControlBuilder<ResolvedFilterColumnIdFromSchema<TRow, SchemaColumnsContext<TColumns>>, false>>(defineFilters: (filters: SelectableControlBuilder<ResolvedFilterColumnIdFromSchema<TRow, SchemaColumnsContext<TColumns>>, false>) => TBuilder): ChartSchemaBuilder<TRow, TColumns, TXAxis, TGroupBy, SelectableControlBuilderConfig<TBuilder>, TMetric, TChartType, TTimeBucket, TConnectNulls>;
254
+ /**
255
+ * Configure the public metric surface.
256
+ */
257
+ metric<const TBuilder extends MetricBuilder<ResolvedMetricColumnIdFromSchema<TRow, SchemaColumnsContext<TColumns>>, any, any, any>>(defineMetric: (metric: MetricBuilder<ResolvedMetricColumnIdFromSchema<TRow, SchemaColumnsContext<TColumns>>>) => TBuilder): ChartSchemaBuilder<TRow, TColumns, TXAxis, TGroupBy, TFilters, MetricBuilderConfig<TBuilder>, TChartType, TTimeBucket, TConnectNulls>;
258
+ /**
259
+ * Restrict which chart renderers are exposed to users.
260
+ */
261
+ chartType<const TBuilder extends SelectableControlBuilder<ChartType, true>>(defineChartType: (chartType: SelectableControlBuilder<ChartType, true>) => TBuilder): ChartSchemaBuilder<TRow, TColumns, TXAxis, TGroupBy, TFilters, TMetric, SelectableControlBuilderConfig<TBuilder>, TTimeBucket, TConnectNulls>;
262
+ /**
263
+ * Restrict which time buckets are exposed for date X-axes.
264
+ */
265
+ timeBucket<const TBuilder extends SelectableControlBuilder<TimeBucket, true>>(defineTimeBucket: (timeBucket: SelectableControlBuilder<TimeBucket, true>) => TBuilder): ChartSchemaBuilder<TRow, TColumns, TXAxis, TGroupBy, TFilters, TMetric, TChartType, SelectableControlBuilderConfig<TBuilder>, TConnectNulls>;
266
+ /**
267
+ * Control whether line and area charts visually bridge null gaps.
268
+ *
269
+ * `true` keeps the line connected across missing buckets. `false` shows a
270
+ * visible gap.
271
+ */
272
+ connectNulls<const TValue extends boolean>(value: TValue): ChartSchemaBuilder<TRow, TColumns, TXAxis, TGroupBy, TFilters, TMetric, TChartType, TTimeBucket, TValue>;
273
+ /**
274
+ * Finalize the schema into the runtime object consumed by `useChart(...)`.
275
+ */
276
+ build(): DefinedChartSchema<TRow, SchemaFromBuilder<TColumns, TXAxis, TGroupBy, TFilters, TMetric, TChartType, TTimeBucket, TConnectNulls>>;
277
+ };
278
+ //#endregion
279
+ export { ChartSchemaBuilder };
@@ -1,3 +1,5 @@
1
+ import { DateRangePresetId } from "./date-range-presets.mjs";
2
+
1
3
  //#region src/core/types.d.ts
2
4
  /**
3
5
  * Core types for chart-studio.
@@ -499,7 +501,18 @@ type ChartSchemaValidationTarget<T, TSchema extends ChartSchema<T, any>> = {
499
501
  type ValidatedChartSchema<T, TSchema> = TSchema extends ChartSchema<T, any> ? TSchema & ExactShape<ChartSchemaValidationTarget<T, TSchema>, TSchema> & ValidateChartSchemaLiterals<T, TSchema> : TSchema;
500
502
  /** Strict schema object returned by `defineChartSchema(...)`. */
501
503
  type DefinedChartSchema<T, TSchema extends ChartSchema<T, any> = ChartSchema<T, any>> = TSchema & ChartSchemaDefinitionBrand;
502
- type ResolvedChartSchemaFromDefinition<TSchema> = TSchema extends DefinedChartSchema<any, infer TResolvedSchema> ? TResolvedSchema : undefined;
504
+ /**
505
+ * Public schema definition input accepted by chart-studio APIs.
506
+ *
507
+ * Most callers use the fluent builder returned by `defineChartSchema<Row>()`.
508
+ * Plain schema objects are also accepted at the runtime boundary.
509
+ */
510
+ type ChartSchemaDefinition<T, TSchema extends ChartSchema<T, any> = ChartSchema<T, any>> = TSchema | {
511
+ build: () => DefinedChartSchema<T, TSchema>;
512
+ };
513
+ type ResolvedChartSchemaFromDefinition<TSchema> = TSchema extends DefinedChartSchema<any, infer TResolvedSchema> ? TResolvedSchema : TSchema extends {
514
+ build: () => DefinedChartSchema<any, infer TResolvedSchema>;
515
+ } ? TResolvedSchema : TSchema extends ChartSchema<any, any> ? TSchema : undefined;
503
516
  /** GroupBy IDs narrowed by explicit schema restrictions when present. */
504
517
  type RestrictedGroupByColumnIdFromSchema<T, TSchema extends ChartSchema<T, any> | undefined = undefined> = RestrictOptionsFromControlConfig<ResolvedGroupByColumnIdFromSchema<T, TSchema>, ConfigSection<TSchema, 'groupBy'>>;
505
518
  /** X-axis IDs narrowed by explicit schema restrictions when present. */
@@ -570,9 +583,9 @@ type NumberColumn<T, TId extends string = string> = ColumnBase<T, TId> & {
570
583
  /** Union of all column types. */
571
584
  type ChartColumn<T, TId extends string = string> = DateColumn<T, TId> | CategoryColumn<T, TId> | BooleanColumn<T, TId> | NumberColumn<T, TId>;
572
585
  /** Chart types available for time-series (date X-axis). */
573
- type TimeSeriesChartType = 'bar' | 'line' | 'area';
586
+ type TimeSeriesChartType = 'bar' | 'grouped-bar' | 'percent-bar' | 'line' | 'area' | 'percent-area';
574
587
  /** Chart types available for categorical (category/boolean X-axis). */
575
- type CategoricalChartType = 'bar' | 'pie' | 'donut';
588
+ type CategoricalChartType = 'bar' | 'grouped-bar' | 'percent-bar' | 'pie' | 'donut';
576
589
  /** All supported chart types. */
577
590
  type ChartType = TimeSeriesChartType | CategoricalChartType;
578
591
  /** Time bucket sizes for date X-axis. */
@@ -655,7 +668,7 @@ type ChartTypeConfig = SelectableControlConfig<ChartType>;
655
668
  type TimeBucketConfig = SelectableControlConfig<TimeBucket>;
656
669
  type ExtractSchemaColumns<TSchema> = TSchema extends {
657
670
  columns?: infer TColumns;
658
- } ? Extract<TColumns, Record<string, unknown>> : undefined;
671
+ } ? [Extract<TColumns, Record<string, unknown>>] extends [never] ? undefined : Extract<TColumns, Record<string, unknown>> : undefined;
659
672
  type RawSchemaColumnsFromColumns<T, TColumns extends Record<string, unknown> | undefined> = TColumns extends Record<string, unknown> ? { [TKey in keyof TColumns as TKey extends InferableFieldKey<T> ? TKey : never]: TColumns[TKey] } : undefined;
660
673
  type RawSchemaColumns<T, TSchema> = RawSchemaColumnsFromColumns<T, ExtractSchemaColumns<TSchema>>;
661
674
  type DerivedColumnIdsFromColumns<TColumns extends Record<string, unknown> | undefined> = Extract<TColumns extends Record<string, unknown> ? { [TKey in keyof TColumns]-?: TColumns[TKey] extends DerivedColumnSchema<any> ? TKey : never }[keyof TColumns] : never, string>;
@@ -706,6 +719,18 @@ type ChartSchema<T, TColumns extends Record<string, unknown> | undefined = Recor
706
719
  metric?: MetricConfig<string>; /** Restrict which chart types are available to the user. */
707
720
  chartType?: ChartTypeConfig; /** Restrict which time buckets are available for date X-axes. */
708
721
  timeBucket?: TimeBucketConfig;
722
+ /**
723
+ * Whether line and area charts should connect across null (empty bucket)
724
+ * data points instead of showing a gap.
725
+ *
726
+ * When `true` (default), the line bridges across empty buckets.
727
+ * When `false`, empty time buckets produce a visible gap in the line/area.
728
+ *
729
+ * This is useful for sparse datasets (e.g. quarterly data displayed in a
730
+ * monthly time bucket) where connecting across gaps produces a cleaner
731
+ * visual than showing drops to zero.
732
+ */
733
+ connectNulls?: boolean;
709
734
  };
710
735
  type ChartSchemaDefinitionBrand = {
711
736
  readonly __chartSchemaBrand: 'chart-schema-definition';
@@ -736,11 +761,11 @@ type SortConfig = {
736
761
  * @property data - Array of raw data items
737
762
  * @property schema - Optional explicit schema layered on top of inference
738
763
  */
739
- type ChartSourceOptions<TId extends string = string, T = unknown, TSchema extends ChartSchema<T, any> | undefined = undefined> = {
764
+ type ChartSourceOptions<TId extends string = string, T = unknown, TSchema extends ChartSchemaDefinition<T, any> | undefined = undefined> = {
740
765
  id: TId;
741
766
  label: string;
742
767
  data: readonly T[];
743
- schema?: DefinedChartSchema<T, Exclude<TSchema, undefined>>;
768
+ schema?: TSchema;
744
769
  };
745
770
  /** Convenience alias for any multi-source input definition. */
746
771
  type AnyChartSourceOptions = {
@@ -767,7 +792,7 @@ type ChartSeries = {
767
792
  * A single data point in the transformed output.
768
793
  * Keys are dynamic based on groupBy values.
769
794
  */
770
- type TransformedDataPoint = Record<string, string | number>;
795
+ type TransformedDataPoint = Record<string, string | number | null>;
771
796
  /**
772
797
  * Available filter options extracted from the data for a column.
773
798
  *
@@ -869,7 +894,12 @@ type ChartInstance<T, TColumnId extends string = string, TChartType extends Char
869
894
  timeBucket: TTimeBucket; /** Change the time bucket. Runtime accepts only values in `availableTimeBuckets`. */
870
895
  setTimeBucket: (bucket: TTimeBucket) => void; /** Time buckets currently available for the active chart state and config. */
871
896
  availableTimeBuckets: TTimeBucket[]; /** Whether time bucketing controls should be shown. */
872
- isTimeSeries: boolean; /** Active filter values per column. */
897
+ isTimeSeries: boolean;
898
+ /**
899
+ * Whether line and area charts connect across null data points.
900
+ * Derived from the schema's `connectNulls` option.
901
+ */
902
+ connectNulls: boolean; /** Active filter values per column. */
873
903
  filters: FilterState<TFilterColumnId>;
874
904
  /**
875
905
  * Toggle a specific filter value on/off for a column.
@@ -891,8 +921,20 @@ type ChartInstance<T, TColumnId extends string = string, TChartType extends Char
891
921
  availableDateColumns: Array<{
892
922
  id: TDateColumnId;
893
923
  label: string;
894
- }>; /** Active date range filter (null = all time). */
895
- dateRangeFilter: DateRangeFilter | null; /** Set the date range filter. Pass null to clear (show all time). */
924
+ }>; /** Active date range preset (null = custom range via `dateRangeFilter`). */
925
+ dateRangePreset: DateRangePresetId | null;
926
+ /**
927
+ * Select a named date range preset.
928
+ * The `dateRangeFilter` is derived automatically from the preset.
929
+ * For `'auto'`, the filter adjusts reactively when the time bucket changes.
930
+ */
931
+ setDateRangePreset: (preset: DateRangePresetId) => void; /** Active date range filter (null = all time). Derived from the preset when one is active. */
932
+ dateRangeFilter: DateRangeFilter | null;
933
+ /**
934
+ * Set the date range filter directly (custom range).
935
+ * Clears any active preset — the range becomes "Custom".
936
+ * Pass null to clear (show all time, equivalent to selecting 'all-time' preset).
937
+ */
896
938
  setDateRangeFilter: (filter: DateRangeFilter | null) => void; /** Transformed data points ready for recharts. */
897
939
  transformedData: TransformedDataPoint[]; /** Auto-generated series definitions for recharts. */
898
940
  series: ChartSeries[]; /** Active columns for the current source. */
@@ -902,14 +944,16 @@ type ChartInstance<T, TColumnId extends string = string, TChartType extends Char
902
944
  };
903
945
  /** Single-source chart instance narrowed by one explicit schema. */
904
946
  type ChartInstanceFromSchema<T, TSchema extends ChartSchema<T, any> | undefined = undefined> = ChartInstance<T, ResolvedColumnIdFromSchema<T, TSchema>, RestrictedChartTypeFromSchema<TSchema>, RestrictedXAxisColumnIdFromSchema<T, TSchema>, RestrictedGroupByColumnIdFromSchema<T, TSchema>, Extract<MetricColumnIdFromMetric<RestrictedMetricFromSchema<T, TSchema>>, ResolvedMetricColumnIdFromSchema<T, TSchema>>, RestrictedMetricFromSchema<T, TSchema>, RestrictedFilterColumnIdFromSchema<T, TSchema>, ResolvedDateColumnIdFromSchema<T, TSchema>, RestrictedTimeBucketFromSchema<TSchema>>;
947
+ /** Single-source chart instance narrowed by any supported schema input. */
948
+ type ChartInstanceFromSchemaDefinition<T, TSchema extends ChartSchemaDefinition<T, any> | undefined = undefined> = ChartInstanceFromSchema<T, ResolvedChartSchemaFromDefinition<TSchema>>;
905
949
  type SourceIdFromSource<TSource extends AnyChartSourceOptions> = TSource['id'];
906
950
  type SourceRowFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, any> ? TRow : never;
907
- type SourceColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? ResolvedColumnIdFromSchema<TRow, Extract<TSchema, ChartSchema<TRow> | undefined>> : never;
908
- type SourceXAxisColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? RestrictedXAxisColumnIdFromSchema<TRow, Extract<TSchema, ChartSchema<TRow> | undefined>> : never;
909
- type SourceGroupByColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? RestrictedGroupByColumnIdFromSchema<TRow, Extract<TSchema, ChartSchema<TRow> | undefined>> : never;
910
- type SourceMetricColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? Extract<MetricColumnIdFromMetric<RestrictedMetricFromSchema<TRow, Extract<TSchema, ChartSchema<TRow> | undefined>>>, ResolvedMetricColumnIdFromSchema<TRow, Extract<TSchema, ChartSchema<TRow> | undefined>>> : never;
911
- type SourceFilterColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? RestrictedFilterColumnIdFromSchema<TRow, Extract<TSchema, ChartSchema<TRow> | undefined>> : never;
912
- type SourceDateColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? ResolvedDateColumnIdFromSchema<TRow, Extract<TSchema, ChartSchema<TRow> | undefined>> : never;
951
+ type SourceColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? ResolvedColumnIdFromSchema<TRow, ResolvedChartSchemaFromDefinition<TSchema>> : never;
952
+ type SourceXAxisColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? RestrictedXAxisColumnIdFromSchema<TRow, ResolvedChartSchemaFromDefinition<TSchema>> : never;
953
+ type SourceGroupByColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? RestrictedGroupByColumnIdFromSchema<TRow, ResolvedChartSchemaFromDefinition<TSchema>> : never;
954
+ type SourceMetricColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? Extract<MetricColumnIdFromMetric<RestrictedMetricFromSchema<TRow, ResolvedChartSchemaFromDefinition<TSchema>>>, ResolvedMetricColumnIdFromSchema<TRow, ResolvedChartSchemaFromDefinition<TSchema>>> : never;
955
+ type SourceFilterColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? RestrictedFilterColumnIdFromSchema<TRow, ResolvedChartSchemaFromDefinition<TSchema>> : never;
956
+ type SourceDateColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? ResolvedDateColumnIdFromSchema<TRow, ResolvedChartSchemaFromDefinition<TSchema>> : never;
913
957
  type SourceIdFromSources<TSources extends NonEmptyChartSourceOptions> = Extract<TSources[number]['id'], string>;
914
958
  type SourceColumnIdFromSources<TSources extends NonEmptyChartSourceOptions> = TSources[number] extends infer TSource ? TSource extends AnyChartSourceOptions ? SourceColumnIdFromSource<TSource> : never : never;
915
959
  type MultiSourceChartBranch<TSources extends NonEmptyChartSourceOptions, TSource extends AnyChartSourceOptions> = Omit<ChartInstance<SourceRowFromSource<TSource>, SourceColumnIdFromSources<TSources>>, 'activeSourceId' | 'setActiveSource' | 'sources' | 'xAxisId' | 'setXAxis' | 'availableXAxes' | 'groupById' | 'setGroupBy' | 'availableGroupBys' | 'metric' | 'setMetric' | 'availableMetrics' | 'filters' | 'toggleFilter' | 'clearFilter' | 'availableFilters' | 'dateRange' | 'referenceDateId' | 'setReferenceDateId' | 'availableDateColumns' | 'columns'> & {
@@ -954,4 +998,4 @@ type MultiSourceChartBranch<TSources extends NonEmptyChartSourceOptions, TSource
954
998
  */
955
999
  type MultiSourceChartInstance<TSources extends NonEmptyChartSourceOptions> = TSources[number] extends infer TSource ? TSource extends AnyChartSourceOptions ? MultiSourceChartBranch<TSources, TSource> : never : never;
956
1000
  //#endregion
957
- export { AggregateFunction, AggregateMetric, AvailableFilter, BooleanColumn, CategoricalChartType, CategoryColumn, ChartColumn, ChartColumnType, ChartInstance, ChartInstanceFromSchema, ChartSchema, ChartSeries, ChartSourceOptions, ChartType, ChartTypeConfig, ColumnFormat, ColumnFormatPreset, CountMetric, DateColumn, DateColumnFormat, DefinedChartSchema, DerivedBooleanColumnSchema, DerivedCategoryColumnSchema, DerivedColumnSchema, DerivedDateColumnSchema, DerivedNumberColumnSchema, ExactShape, FilterState, FiltersConfig, GroupByConfig, InferableFieldKey, Metric, MetricConfig, MultiSourceChartInstance, NonEmptyChartSourceOptions, NumberColumn, NumberColumnFormat, NumericAggregateFunction, RawColumnSchemaFor, RawColumnSchemaMap, ResolvedChartSchemaFromDefinition, ResolvedColumnIdFromSchema, ResolvedFilterColumnIdFromSchema, ResolvedGroupByColumnIdFromSchema, ResolvedMetricColumnIdFromSchema, ResolvedXAxisColumnIdFromSchema, RestrictedChartTypeFromSchema, RestrictedFilterColumnIdFromSchema, RestrictedGroupByColumnIdFromSchema, RestrictedMetricFromSchema, RestrictedTimeBucketFromSchema, RestrictedXAxisColumnIdFromSchema, SchemaColumnsValidationShape, SelectableControlConfig, SortConfig, SortDirection, TimeBucket, TimeBucketConfig, TimeSeriesChartType, TransformedDataPoint, ValidatedChartSchema, XAxisConfig };
1001
+ export { AggregateFunction, AggregateMetric, AvailableFilter, BaseColumnHint, BooleanColumn, CategoricalChartType, CategoryColumn, ChartColumn, ChartColumnType, ChartInstance, ChartInstanceFromSchema, ChartInstanceFromSchemaDefinition, ChartSchema, ChartSchemaDefinition, ChartSeries, ChartSourceOptions, ChartType, ChartTypeConfig, ColumnFormat, ColumnFormatPreset, CountMetric, DateColumn, DateColumnFormat, DefinedChartSchema, DerivedBooleanColumnSchema, DerivedCategoryColumnSchema, DerivedColumnSchema, DerivedDateColumnSchema, DerivedNumberColumnSchema, FilterState, FiltersConfig, GroupByConfig, InferableFieldKey, Metric, MetricConfig, MultiSourceChartInstance, NonEmptyChartSourceOptions, NumberColumn, NumberColumnFormat, NumericAggregateFunction, RawColumnSchemaFor, RawColumnSchemaMap, ResolvedChartSchemaFromDefinition, ResolvedColumnIdFromSchema, ResolvedFilterColumnIdFromSchema, ResolvedGroupByColumnIdFromSchema, ResolvedMetricColumnIdFromSchema, ResolvedXAxisColumnIdFromSchema, RestrictedChartTypeFromSchema, RestrictedFilterColumnIdFromSchema, RestrictedGroupByColumnIdFromSchema, RestrictedMetricFromSchema, RestrictedTimeBucketFromSchema, RestrictedXAxisColumnIdFromSchema, SelectableControlConfig, SortConfig, SortDirection, TimeBucket, TimeBucketConfig, TimeSeriesChartType, TransformedDataPoint, ValidatedChartSchema, XAxisConfig };
@@ -1,4 +1,4 @@
1
- import { ChartSchema, ChartSourceOptions, DefinedChartSchema, NonEmptyChartSourceOptions } from "./types.mjs";
1
+ import { ChartSchemaDefinition, ChartSourceOptions, NonEmptyChartSourceOptions } from "./types.mjs";
2
2
 
3
3
  //#region src/core/use-chart-options.d.ts
4
4
  /**
@@ -7,7 +7,7 @@ import { ChartSchema, ChartSourceOptions, DefinedChartSchema, NonEmptyChartSourc
7
7
  * This is the common case: one dataset, one optional schema, one optional
8
8
  * human-readable source label.
9
9
  */
10
- interface SingleSourceOptions<T, TSchema extends ChartSchema<T, any> | undefined = undefined> {
10
+ interface SingleSourceOptions<T, TSchema extends ChartSchemaDefinition<T, any> | undefined = undefined> {
11
11
  /**
12
12
  * Raw rows that chart-studio should inspect and transform.
13
13
  *
@@ -18,6 +18,9 @@ interface SingleSourceOptions<T, TSchema extends ChartSchema<T, any> | undefined
18
18
  /**
19
19
  * Optional explicit schema layered on top of inference.
20
20
  *
21
+ * Usually this is the fluent builder returned by `defineChartSchema<Row>()`.
22
+ * Plain schema objects are also accepted.
23
+ *
21
24
  * Use this when you want to:
22
25
  * - rename fields with `label`
23
26
  * - force or refine column `type`
@@ -26,7 +29,7 @@ interface SingleSourceOptions<T, TSchema extends ChartSchema<T, any> | undefined
26
29
  * - create derived columns
27
30
  * - restrict what users can select in the chart UI
28
31
  */
29
- schema?: DefinedChartSchema<T, Exclude<TSchema, undefined>>;
32
+ schema?: TSchema;
30
33
  /**
31
34
  * Human-readable source name shown by the built-in UI when relevant.
32
35
  *
@@ -59,6 +62,6 @@ interface MultiSourceOptions<TSources extends NonEmptyChartSourceOptions = NonEm
59
62
  /**
60
63
  * Options for the useChart hook.
61
64
  */
62
- type UseChartOptions<T, TSchema extends ChartSchema<T, any> | undefined = undefined> = SingleSourceOptions<T, TSchema> | MultiSourceOptions;
65
+ type UseChartOptions<T, TSchema extends ChartSchemaDefinition<T, any> | undefined = undefined> = SingleSourceOptions<T, TSchema> | MultiSourceOptions;
63
66
  //#endregion
64
67
  export { SingleSourceOptions, UseChartOptions };
@@ -1,4 +1,4 @@
1
- import { ChartInstanceFromSchema, ChartSchema, MultiSourceChartInstance, NonEmptyChartSourceOptions } from "./types.mjs";
1
+ import { ChartInstanceFromSchemaDefinition, ChartSchemaDefinition, MultiSourceChartInstance, NonEmptyChartSourceOptions } from "./types.mjs";
2
2
  import { SingleSourceOptions } from "./use-chart-options.mjs";
3
3
 
4
4
  //#region src/core/use-chart.d.ts
@@ -15,8 +15,8 @@ import { SingleSourceOptions } from "./use-chart-options.mjs";
15
15
  * Chart configuration options. Should provide either:
16
16
  * - `data`, optional `schema`, and (optionally) `sourceLabel` for a single source
17
17
  * - or `sources` array for multiple sources
18
- * Any explicit single-source or per-source schema should be created with
19
- * `defineChartSchema<Row>()(...)` so the schema shape stays exact and strongly typed.
18
+ * Any explicit single-source or per-source schema is usually authored with
19
+ * `defineChartSchema<Row>()...`. Plain schema objects are also accepted.
20
20
  *
21
21
  * @returns {ChartInstance}
22
22
  * An object representing chart configuration, state, and all derived data/operations:
@@ -45,6 +45,6 @@ declare function useChart<const TSources extends NonEmptyChartSourceOptions>(opt
45
45
  sourceLabel?: never;
46
46
  sources: TSources;
47
47
  }): MultiSourceChartInstance<TSources>;
48
- declare function useChart<T, const TSchema extends ChartSchema<T, any> | undefined = undefined>(options: SingleSourceOptions<T, TSchema>): ChartInstanceFromSchema<T, TSchema>;
48
+ declare function useChart<T, const TSchema extends ChartSchemaDefinition<T, any> | undefined = undefined>(options: SingleSourceOptions<T, TSchema>): ChartInstanceFromSchemaDefinition<T, TSchema>;
49
49
  //#endregion
50
50
  export { useChart };