@matthieumordrel/chart-studio 0.2.5 → 0.4.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.
- package/README.md +402 -12
- package/dist/core/chart-builder-controls.mjs +141 -0
- package/dist/core/dashboard.types.d.mts +220 -0
- package/dist/core/data-label-defaults.mjs +74 -0
- package/dist/core/data-model.types.d.mts +196 -0
- package/dist/core/dataset-builder.types.d.mts +51 -0
- package/dist/core/dataset-chart-metadata.d.mts +8 -0
- package/dist/core/dataset-chart-metadata.mjs +4 -0
- package/dist/core/date-range-presets.mjs +1 -1
- package/dist/core/define-dashboard.d.mts +8 -0
- package/dist/core/define-dashboard.mjs +156 -0
- package/dist/core/define-data-model.d.mts +11 -0
- package/dist/core/define-data-model.mjs +327 -0
- package/dist/core/define-dataset.d.mts +13 -0
- package/dist/core/define-dataset.mjs +111 -0
- package/dist/core/index.d.mts +17 -0
- package/dist/core/infer-columns.mjs +28 -2
- package/dist/core/materialized-view.mjs +580 -0
- package/dist/core/materialized-view.types.d.mts +223 -0
- package/dist/core/model-chart.mjs +242 -0
- package/dist/core/model-chart.types.d.mts +199 -0
- package/dist/core/model-inference.mjs +169 -0
- package/dist/core/model-inference.types.d.mts +71 -0
- package/dist/core/pipeline.mjs +32 -1
- package/dist/core/schema-builder.mjs +28 -158
- package/dist/core/schema-builder.types.d.mts +2 -49
- package/dist/core/types.d.mts +59 -8
- package/dist/core/use-chart-options.d.mts +35 -8
- package/dist/core/use-chart-resolvers.mjs +13 -3
- package/dist/core/use-chart.d.mts +16 -12
- package/dist/core/use-chart.mjs +136 -34
- package/dist/core/use-dashboard.d.mts +190 -0
- package/dist/core/use-dashboard.mjs +551 -0
- package/dist/index.d.mts +10 -3
- package/dist/index.mjs +5 -2
- package/dist/ui/chart-canvas.d.mts +11 -4
- package/dist/ui/chart-canvas.mjs +45 -34
- package/dist/ui/chart-context.d.mts +2 -0
- package/dist/ui/chart-context.mjs +2 -0
- package/dist/ui/chart-filters-panel.d.mts +1 -1
- package/dist/ui/chart-filters-panel.mjs +163 -37
- package/dist/ui/chart-group-by-selector.mjs +4 -4
- package/dist/ui/chart-time-bucket-selector.mjs +1 -1
- package/dist/ui/chart-toolbar-overflow.mjs +5 -13
- package/dist/ui/chart-toolbar.mjs +1 -1
- package/package.json +1 -1
- package/dist/core/define-chart-schema.d.mts +0 -38
- package/dist/core/define-chart-schema.mjs +0 -39
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createMetricBuilder, createSelectableControlBuilder, getMetricBuilderConfig, getSelectableControlConfig } from "./chart-builder-controls.mjs";
|
|
2
|
+
import { DATASET_CHART_METADATA } from "./dataset-chart-metadata.mjs";
|
|
2
3
|
//#region src/core/schema-builder.ts
|
|
3
|
-
const SELECTABLE_CONTROL_CONFIG = Symbol("chart-schema-selectable-control-config");
|
|
4
|
-
const METRIC_CONTROL_CONFIG = Symbol("chart-schema-metric-config");
|
|
5
4
|
const COLUMN_HELPER = {
|
|
6
5
|
field(id, options = {}) {
|
|
7
6
|
return {
|
|
@@ -104,141 +103,6 @@ const COLUMN_HELPER = {
|
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
105
|
};
|
|
107
|
-
function uniqueValues(values) {
|
|
108
|
-
if (!values || values.length === 0) return;
|
|
109
|
-
return [...new Set(values)];
|
|
110
|
-
}
|
|
111
|
-
function sanitizeSelectableControlConfig(config, supportsDefault) {
|
|
112
|
-
const allowed = uniqueValues(config.allowed);
|
|
113
|
-
let hidden = uniqueValues(config.hidden);
|
|
114
|
-
if (allowed && hidden) {
|
|
115
|
-
const allowedSet = new Set(allowed);
|
|
116
|
-
hidden = hidden.filter((option) => allowedSet.has(option));
|
|
117
|
-
}
|
|
118
|
-
let nextDefault = supportsDefault ? config.default : void 0;
|
|
119
|
-
if (nextDefault !== void 0) {
|
|
120
|
-
if (allowed && !allowed.includes(nextDefault)) nextDefault = void 0;
|
|
121
|
-
if (nextDefault !== void 0 && hidden?.includes(nextDefault)) nextDefault = void 0;
|
|
122
|
-
}
|
|
123
|
-
const nextConfig = {};
|
|
124
|
-
if (allowed && allowed.length > 0) nextConfig.allowed = allowed;
|
|
125
|
-
if (hidden && hidden.length > 0) nextConfig.hidden = hidden;
|
|
126
|
-
if (nextDefault !== void 0) nextConfig.default = nextDefault;
|
|
127
|
-
return nextConfig;
|
|
128
|
-
}
|
|
129
|
-
function createSelectableControlBuilder(config = {}, supportsDefault) {
|
|
130
|
-
const nextConfig = sanitizeSelectableControlConfig(config, supportsDefault);
|
|
131
|
-
return {
|
|
132
|
-
allowed(...options) {
|
|
133
|
-
return createSelectableControlBuilder({
|
|
134
|
-
...nextConfig,
|
|
135
|
-
allowed: options
|
|
136
|
-
}, supportsDefault);
|
|
137
|
-
},
|
|
138
|
-
hidden(...options) {
|
|
139
|
-
return createSelectableControlBuilder({
|
|
140
|
-
...nextConfig,
|
|
141
|
-
hidden: [...nextConfig.hidden ?? [], ...options]
|
|
142
|
-
}, supportsDefault);
|
|
143
|
-
},
|
|
144
|
-
default(option) {
|
|
145
|
-
return createSelectableControlBuilder({
|
|
146
|
-
...nextConfig,
|
|
147
|
-
default: option
|
|
148
|
-
}, supportsDefault);
|
|
149
|
-
},
|
|
150
|
-
[SELECTABLE_CONTROL_CONFIG]: nextConfig
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
function uniqueMetrics(metrics) {
|
|
154
|
-
if (!metrics || metrics.length === 0) return;
|
|
155
|
-
const unique = [];
|
|
156
|
-
for (const metric of metrics) if (!unique.some((candidate) => isSameMetric(candidate, metric))) unique.push(metric);
|
|
157
|
-
return unique;
|
|
158
|
-
}
|
|
159
|
-
function sanitizeMetricConfig(config) {
|
|
160
|
-
const allowed = config.allowed && config.allowed.length > 0 ? [...config.allowed] : void 0;
|
|
161
|
-
let hidden = uniqueMetrics(config.hidden);
|
|
162
|
-
const expandedAllowed = normalizeMetricAllowances(allowed);
|
|
163
|
-
if (expandedAllowed && hidden) hidden = hidden.filter((metric) => expandedAllowed.some((allowedMetric) => isSameMetric(allowedMetric, metric)));
|
|
164
|
-
let nextDefault = config.default;
|
|
165
|
-
if (nextDefault) {
|
|
166
|
-
const defaultMetric = nextDefault;
|
|
167
|
-
if (expandedAllowed && !expandedAllowed.some((metric) => isSameMetric(metric, defaultMetric))) nextDefault = void 0;
|
|
168
|
-
if (nextDefault) {
|
|
169
|
-
const visibleDefault = nextDefault;
|
|
170
|
-
if (hidden?.some((metric) => isSameMetric(metric, visibleDefault))) nextDefault = void 0;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
const nextConfig = {};
|
|
174
|
-
if (allowed && allowed.length > 0) nextConfig.allowed = allowed;
|
|
175
|
-
if (hidden && hidden.length > 0) nextConfig.hidden = hidden;
|
|
176
|
-
if (nextDefault) nextConfig.default = nextDefault;
|
|
177
|
-
return nextConfig;
|
|
178
|
-
}
|
|
179
|
-
function createMetricBuilder(config = {}) {
|
|
180
|
-
const nextConfig = sanitizeMetricConfig(config);
|
|
181
|
-
return {
|
|
182
|
-
count() {
|
|
183
|
-
return createMetricBuilder({
|
|
184
|
-
...nextConfig,
|
|
185
|
-
allowed: [...nextConfig.allowed ?? [], { kind: "count" }]
|
|
186
|
-
});
|
|
187
|
-
},
|
|
188
|
-
aggregate(columnId, firstAggregate, ...restAggregates) {
|
|
189
|
-
const aggregates = [firstAggregate, ...restAggregates];
|
|
190
|
-
const selection = restAggregates.length === 0 ? firstAggregate : aggregates;
|
|
191
|
-
return createMetricBuilder({
|
|
192
|
-
...nextConfig,
|
|
193
|
-
allowed: [...nextConfig.allowed ?? [], {
|
|
194
|
-
kind: "aggregate",
|
|
195
|
-
columnId,
|
|
196
|
-
aggregate: selection
|
|
197
|
-
}]
|
|
198
|
-
});
|
|
199
|
-
},
|
|
200
|
-
hideCount() {
|
|
201
|
-
return createMetricBuilder({
|
|
202
|
-
...nextConfig,
|
|
203
|
-
hidden: [...nextConfig.hidden ?? [], { kind: "count" }]
|
|
204
|
-
});
|
|
205
|
-
},
|
|
206
|
-
hideAggregate(columnId, firstAggregate, ...restAggregates) {
|
|
207
|
-
const aggregates = [firstAggregate, ...restAggregates];
|
|
208
|
-
return createMetricBuilder({
|
|
209
|
-
...nextConfig,
|
|
210
|
-
hidden: [...nextConfig.hidden ?? [], ...aggregates.map((aggregate) => ({
|
|
211
|
-
kind: "aggregate",
|
|
212
|
-
columnId,
|
|
213
|
-
aggregate
|
|
214
|
-
}))]
|
|
215
|
-
});
|
|
216
|
-
},
|
|
217
|
-
defaultCount() {
|
|
218
|
-
return createMetricBuilder({
|
|
219
|
-
...nextConfig,
|
|
220
|
-
default: { kind: "count" }
|
|
221
|
-
});
|
|
222
|
-
},
|
|
223
|
-
defaultAggregate(columnId, aggregate) {
|
|
224
|
-
return createMetricBuilder({
|
|
225
|
-
...nextConfig,
|
|
226
|
-
default: {
|
|
227
|
-
kind: "aggregate",
|
|
228
|
-
columnId,
|
|
229
|
-
aggregate
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
},
|
|
233
|
-
[METRIC_CONTROL_CONFIG]: nextConfig
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
function getSelectableControlConfig(builder) {
|
|
237
|
-
return builder[SELECTABLE_CONTROL_CONFIG];
|
|
238
|
-
}
|
|
239
|
-
function getMetricBuilderConfig(builder) {
|
|
240
|
-
return builder[METRIC_CONTROL_CONFIG];
|
|
241
|
-
}
|
|
242
106
|
function buildColumnsMap(entries) {
|
|
243
107
|
const columns = {};
|
|
244
108
|
for (const entry of entries) {
|
|
@@ -247,69 +111,62 @@ function buildColumnsMap(entries) {
|
|
|
247
111
|
}
|
|
248
112
|
return columns;
|
|
249
113
|
}
|
|
250
|
-
function assertColumnEntries(entries) {
|
|
251
|
-
if (!Array.isArray(entries)) throw new TypeError(
|
|
114
|
+
function assertColumnEntries(entries, owner = "defineDataset") {
|
|
115
|
+
if (!Array.isArray(entries)) throw new TypeError(`${owner}().columns(...) must return an array of column entries.`);
|
|
252
116
|
}
|
|
253
117
|
function resolveChartSchemaDefinition(schema) {
|
|
254
118
|
if (!schema) return;
|
|
255
119
|
if (typeof schema === "object" && "build" in schema && typeof schema.build === "function") return schema.build();
|
|
256
120
|
return schema;
|
|
257
121
|
}
|
|
258
|
-
function
|
|
122
|
+
function createDatasetChartBuilder(state = {}, metadata) {
|
|
259
123
|
let cachedSchema;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
const entries = defineColumns(COLUMN_HELPER);
|
|
263
|
-
assertColumnEntries(entries);
|
|
264
|
-
return createChartSchemaBuilder({
|
|
265
|
-
...state,
|
|
266
|
-
columns: buildColumnsMap(entries)
|
|
267
|
-
});
|
|
268
|
-
},
|
|
124
|
+
const createNext = (nextState) => createDatasetChartBuilder(nextState, metadata);
|
|
125
|
+
const builder = {
|
|
269
126
|
xAxis(defineXAxis) {
|
|
270
127
|
const builder = defineXAxis(createSelectableControlBuilder({}, true));
|
|
271
|
-
return
|
|
128
|
+
return createNext({
|
|
272
129
|
...state,
|
|
273
130
|
xAxis: getSelectableControlConfig(builder)
|
|
274
131
|
});
|
|
275
132
|
},
|
|
276
133
|
groupBy(defineGroupBy) {
|
|
277
134
|
const builder = defineGroupBy(createSelectableControlBuilder({}, true));
|
|
278
|
-
return
|
|
135
|
+
return createNext({
|
|
279
136
|
...state,
|
|
280
137
|
groupBy: getSelectableControlConfig(builder)
|
|
281
138
|
});
|
|
282
139
|
},
|
|
283
140
|
filters(defineFilters) {
|
|
284
141
|
const builder = defineFilters(createSelectableControlBuilder({}, false));
|
|
285
|
-
return
|
|
142
|
+
return createNext({
|
|
286
143
|
...state,
|
|
287
144
|
filters: getSelectableControlConfig(builder)
|
|
288
145
|
});
|
|
289
146
|
},
|
|
290
147
|
metric(defineMetric) {
|
|
291
148
|
const builder = defineMetric(createMetricBuilder());
|
|
292
|
-
return
|
|
149
|
+
return createNext({
|
|
293
150
|
...state,
|
|
294
151
|
metric: getMetricBuilderConfig(builder)
|
|
295
152
|
});
|
|
296
153
|
},
|
|
297
154
|
chartType(defineChartType) {
|
|
298
155
|
const builder = defineChartType(createSelectableControlBuilder({}, true));
|
|
299
|
-
return
|
|
156
|
+
return createNext({
|
|
300
157
|
...state,
|
|
301
158
|
chartType: getSelectableControlConfig(builder)
|
|
302
159
|
});
|
|
303
160
|
},
|
|
304
161
|
timeBucket(defineTimeBucket) {
|
|
305
162
|
const builder = defineTimeBucket(createSelectableControlBuilder({}, true));
|
|
306
|
-
return
|
|
163
|
+
return createNext({
|
|
307
164
|
...state,
|
|
308
165
|
timeBucket: getSelectableControlConfig(builder)
|
|
309
166
|
});
|
|
310
167
|
},
|
|
311
168
|
connectNulls(value) {
|
|
312
|
-
return
|
|
169
|
+
return createNext({
|
|
313
170
|
...state,
|
|
314
171
|
connectNulls: value
|
|
315
172
|
});
|
|
@@ -327,9 +184,22 @@ function createChartSchemaBuilder(state = {}) {
|
|
|
327
184
|
...state.connectNulls !== void 0 ? { connectNulls: state.connectNulls } : {},
|
|
328
185
|
__chartSchemaBrand: "chart-schema-definition"
|
|
329
186
|
};
|
|
187
|
+
if (metadata) Object.defineProperty(cachedSchema, DATASET_CHART_METADATA, {
|
|
188
|
+
value: metadata,
|
|
189
|
+
enumerable: false,
|
|
190
|
+
configurable: false,
|
|
191
|
+
writable: false
|
|
192
|
+
});
|
|
330
193
|
return cachedSchema;
|
|
331
194
|
}
|
|
332
195
|
};
|
|
196
|
+
if (metadata) Object.defineProperty(builder, DATASET_CHART_METADATA, {
|
|
197
|
+
value: metadata,
|
|
198
|
+
enumerable: false,
|
|
199
|
+
configurable: false,
|
|
200
|
+
writable: false
|
|
201
|
+
});
|
|
202
|
+
return builder;
|
|
333
203
|
}
|
|
334
204
|
//#endregion
|
|
335
|
-
export {
|
|
205
|
+
export { COLUMN_HELPER, assertColumnEntries, buildColumnsMap, createDatasetChartBuilder, resolveChartSchemaDefinition };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseColumnHint,
|
|
1
|
+
import { BaseColumnHint, ChartTypeConfig, CountMetric, DerivedBooleanColumnSchema, DerivedCategoryColumnSchema, DerivedDateColumnSchema, DerivedNumberColumnSchema, FiltersConfig, GroupByConfig, InferableFieldKey, Metric, MetricConfig, NumericAggregateFunction, RawColumnSchemaFor, TimeBucketConfig, XAxisConfig } from "./types.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/core/schema-builder.types.d.ts
|
|
4
4
|
type Nullish = null | undefined;
|
|
@@ -7,9 +7,6 @@ type Simplify<T> = { [TKey in keyof T]: T[TKey] } & {};
|
|
|
7
7
|
type NonEmptyReadonlyArray<TValue> = readonly [TValue, ...TValue[]];
|
|
8
8
|
type FieldKeyMatchingValue<T, TValue> = Extract<{ [TKey in InferableFieldKey<T>]-?: [NonNullish<T[TKey]>] extends [TValue] ? TKey : never }[InferableFieldKey<T>], string>;
|
|
9
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
10
|
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
11
|
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
12
|
type AggregateSelectionFromList<TAggregates extends readonly NumericAggregateFunction[]> = TAggregates extends readonly [infer TOnlyAggregate extends NumericAggregateFunction] ? TOnlyAggregate : TAggregates;
|
|
@@ -231,49 +228,5 @@ type SchemaFromBuilder<TColumns extends Record<string, unknown> | undefined, TXA
|
|
|
231
228
|
timeBucket?: Extract<TTimeBucket, TimeBucketConfig | undefined>;
|
|
232
229
|
connectNulls?: Extract<TConnectNulls, boolean | undefined>;
|
|
233
230
|
};
|
|
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
231
|
//#endregion
|
|
279
|
-
export {
|
|
232
|
+
export { ColumnHelper, ColumnsFromEntries, MetricBuilder, MetricBuilderConfig, SchemaColumnEntry, SchemaFromBuilder, SelectableControlBuilder, SelectableControlBuilderConfig, ValidateColumnEntries };
|
package/dist/core/types.d.mts
CHANGED
|
@@ -497,15 +497,21 @@ type ChartSchemaValidationTarget<T, TSchema extends ChartSchema<T, any>> = {
|
|
|
497
497
|
chartType?: ChartTypeConfig;
|
|
498
498
|
timeBucket?: TimeBucketConfig;
|
|
499
499
|
};
|
|
500
|
-
/** Strict schema object returned by
|
|
500
|
+
/** Strict schema object returned by a chart schema builder. */
|
|
501
501
|
type ValidatedChartSchema<T, TSchema> = TSchema extends ChartSchema<T, any> ? TSchema & ExactShape<ChartSchemaValidationTarget<T, TSchema>, TSchema> & ValidateChartSchemaLiterals<T, TSchema> : TSchema;
|
|
502
|
-
/** Strict schema object returned by
|
|
502
|
+
/** Strict schema object returned by a chart schema builder. */
|
|
503
503
|
type DefinedChartSchema<T, TSchema extends ChartSchema<T, any> = ChartSchema<T, any>> = TSchema & ChartSchemaDefinitionBrand;
|
|
504
504
|
/**
|
|
505
505
|
* Public schema definition input accepted by chart-studio APIs.
|
|
506
506
|
*
|
|
507
|
-
*
|
|
508
|
-
*
|
|
507
|
+
* In the simple single-chart case this is the contract for
|
|
508
|
+
* `useChart({data, schema})`.
|
|
509
|
+
*
|
|
510
|
+
* Most callers use the dataset-backed chart builder from
|
|
511
|
+
* `defineDataset<Row>().chart(...)`.
|
|
512
|
+
*
|
|
513
|
+
* Builders can be passed directly. Plain schema objects are also accepted at
|
|
514
|
+
* the runtime boundary.
|
|
509
515
|
*/
|
|
510
516
|
type ChartSchemaDefinition<T, TSchema extends ChartSchema<T, any> = ChartSchema<T, any>> = TSchema | {
|
|
511
517
|
build: () => DefinedChartSchema<T, TSchema>;
|
|
@@ -741,6 +747,8 @@ type ChartSchemaDefinitionBrand = {
|
|
|
741
747
|
* - For boolean columns: true/false/null (null = no filter)
|
|
742
748
|
*/
|
|
743
749
|
type FilterState<TColumnId extends string = string> = Map<TColumnId, Set<string>>;
|
|
750
|
+
/** Whether one chart input slice is owned externally or by the hook itself. */
|
|
751
|
+
type ChartControlMode = 'controlled' | 'uncontrolled';
|
|
744
752
|
/** Sort direction. */
|
|
745
753
|
type SortDirection = 'asc' | 'desc';
|
|
746
754
|
/**
|
|
@@ -836,6 +844,37 @@ type DateRangeFilter = {
|
|
|
836
844
|
from: Date | null;
|
|
837
845
|
to: Date | null;
|
|
838
846
|
};
|
|
847
|
+
/**
|
|
848
|
+
* Requested date-range selection for externally driven chart inputs.
|
|
849
|
+
*
|
|
850
|
+
* When `preset` is non-null, the effective `dateRangeFilter` is derived from
|
|
851
|
+
* that preset and `customFilter` is simply preserved for later custom mode.
|
|
852
|
+
*/
|
|
853
|
+
type ChartDateRangeSelection = {
|
|
854
|
+
preset: DateRangePresetId | null;
|
|
855
|
+
customFilter: DateRangeFilter | null;
|
|
856
|
+
};
|
|
857
|
+
/**
|
|
858
|
+
* Optional externally driven inputs for the chart's data scope.
|
|
859
|
+
*
|
|
860
|
+
* Provide a value to control that slice. Omit it to let `useChart(...)` own
|
|
861
|
+
* the state internally. Callbacks fire for both controlled and uncontrolled
|
|
862
|
+
* usage; in controlled mode they are the only way setters can request changes.
|
|
863
|
+
*/
|
|
864
|
+
type ChartDataScopeInputs<TFilterColumnId extends string = string, TDateColumnId extends string = string> = {
|
|
865
|
+
filters?: FilterState<TFilterColumnId>;
|
|
866
|
+
onFiltersChange?: (filters: FilterState<TFilterColumnId>) => void;
|
|
867
|
+
referenceDateId?: TDateColumnId | null;
|
|
868
|
+
onReferenceDateIdChange?: (columnId: TDateColumnId | null) => void;
|
|
869
|
+
dateRange?: ChartDateRangeSelection;
|
|
870
|
+
onDateRangeChange?: (selection: ChartDateRangeSelection) => void;
|
|
871
|
+
};
|
|
872
|
+
/** Controlled/uncontrolled status for each data-scope slice. */
|
|
873
|
+
type ChartDataScopeControlState = {
|
|
874
|
+
filters: ChartControlMode;
|
|
875
|
+
referenceDateId: ChartControlMode;
|
|
876
|
+
dateRange: ChartControlMode;
|
|
877
|
+
};
|
|
839
878
|
/**
|
|
840
879
|
* Full chart state returned by the useChart hook.
|
|
841
880
|
* Contains both controlled state and derived computations.
|
|
@@ -879,7 +918,12 @@ type ChartInstance<T, TColumnId extends string = string, TChartType extends Char
|
|
|
879
918
|
availableGroupBys: Array<{
|
|
880
919
|
id: TGroupById;
|
|
881
920
|
label: string;
|
|
882
|
-
}>;
|
|
921
|
+
}>;
|
|
922
|
+
/**
|
|
923
|
+
* Whether groupBy can be set to `null` (no grouping).
|
|
924
|
+
* False when the schema forces a default that always resolves to a column.
|
|
925
|
+
*/
|
|
926
|
+
isGroupByOptional: boolean; /** Current metric (what the Y-axis measures). */
|
|
883
927
|
metric: TMetric;
|
|
884
928
|
/**
|
|
885
929
|
* Change the metric.
|
|
@@ -899,7 +943,8 @@ type ChartInstance<T, TColumnId extends string = string, TChartType extends Char
|
|
|
899
943
|
* Whether line and area charts connect across null data points.
|
|
900
944
|
* Derived from the schema's `connectNulls` option.
|
|
901
945
|
*/
|
|
902
|
-
connectNulls: boolean; /**
|
|
946
|
+
connectNulls: boolean; /** Which data-scope slices are externally controlled vs chart-owned. */
|
|
947
|
+
dataScopeControl: ChartDataScopeControlState; /** Active filter values per column after runtime sanitization for the active source. */
|
|
903
948
|
filters: FilterState<TFilterColumnId>;
|
|
904
949
|
/**
|
|
905
950
|
* Toggle a specific filter value on/off for a column.
|
|
@@ -911,7 +956,7 @@ type ChartInstance<T, TColumnId extends string = string, TChartType extends Char
|
|
|
911
956
|
availableFilters: AvailableFilter<TFilterColumnId>[]; /** Current sort configuration (null = default order). */
|
|
912
957
|
sorting: SortConfig | null; /** Change sorting. */
|
|
913
958
|
setSorting: (sorting: SortConfig | null) => void; /** Date range for the active reference date column (computed from filtered data). */
|
|
914
|
-
dateRange: DateRange<TDateColumnId> | null; /** Which date column provides the visible date range context. */
|
|
959
|
+
dateRange: DateRange<TDateColumnId> | null; /** Which date column provides the visible date range context after source-local fallback. */
|
|
915
960
|
referenceDateId: TDateColumnId | null;
|
|
916
961
|
/**
|
|
917
962
|
* Change the reference date column.
|
|
@@ -946,6 +991,8 @@ type ChartInstance<T, TColumnId extends string = string, TChartType extends Char
|
|
|
946
991
|
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
992
|
/** Single-source chart instance narrowed by any supported schema input. */
|
|
948
993
|
type ChartInstanceFromSchemaDefinition<T, TSchema extends ChartSchemaDefinition<T, any> | undefined = undefined> = ChartInstanceFromSchema<T, ResolvedChartSchemaFromDefinition<TSchema>>;
|
|
994
|
+
/** Data-scope input typing for one single-source chart definition. */
|
|
995
|
+
type ChartDataScopeInputsFromSchemaDefinition<T, TSchema extends ChartSchemaDefinition<T, any> | undefined = undefined> = ChartDataScopeInputs<RestrictedFilterColumnIdFromSchema<T, ResolvedChartSchemaFromDefinition<TSchema>>, ResolvedDateColumnIdFromSchema<T, ResolvedChartSchemaFromDefinition<TSchema>>>;
|
|
949
996
|
type SourceIdFromSource<TSource extends AnyChartSourceOptions> = TSource['id'];
|
|
950
997
|
type SourceRowFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, any> ? TRow : never;
|
|
951
998
|
type SourceColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? ResolvedColumnIdFromSchema<TRow, ResolvedChartSchemaFromDefinition<TSchema>> : never;
|
|
@@ -956,6 +1003,8 @@ type SourceFilterColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSo
|
|
|
956
1003
|
type SourceDateColumnIdFromSource<TSource extends AnyChartSourceOptions> = TSource extends ChartSourceOptions<string, infer TRow, infer TSchema> ? ResolvedDateColumnIdFromSchema<TRow, ResolvedChartSchemaFromDefinition<TSchema>> : never;
|
|
957
1004
|
type SourceIdFromSources<TSources extends NonEmptyChartSourceOptions> = Extract<TSources[number]['id'], string>;
|
|
958
1005
|
type SourceColumnIdFromSources<TSources extends NonEmptyChartSourceOptions> = TSources[number] extends infer TSource ? TSource extends AnyChartSourceOptions ? SourceColumnIdFromSource<TSource> : never : never;
|
|
1006
|
+
type SourceFilterColumnIdFromSources<TSources extends NonEmptyChartSourceOptions> = TSources[number] extends infer TSource ? TSource extends AnyChartSourceOptions ? SourceFilterColumnIdFromSource<TSource> : never : never;
|
|
1007
|
+
type SourceDateColumnIdFromSources<TSources extends NonEmptyChartSourceOptions> = TSources[number] extends infer TSource ? TSource extends AnyChartSourceOptions ? SourceDateColumnIdFromSource<TSource> : never : never;
|
|
959
1008
|
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'> & {
|
|
960
1009
|
activeSourceId: SourceIdFromSource<TSource>;
|
|
961
1010
|
setActiveSource: (sourceId: SourceIdFromSources<TSources>) => void;
|
|
@@ -997,5 +1046,7 @@ type MultiSourceChartBranch<TSources extends NonEmptyChartSourceOptions, TSource
|
|
|
997
1046
|
* Narrow on `activeSourceId` to recover the source-specific row and column IDs.
|
|
998
1047
|
*/
|
|
999
1048
|
type MultiSourceChartInstance<TSources extends NonEmptyChartSourceOptions> = TSources[number] extends infer TSource ? TSource extends AnyChartSourceOptions ? MultiSourceChartBranch<TSources, TSource> : never : never;
|
|
1049
|
+
/** Data-scope input typing for one multi-source source-switching chart. */
|
|
1050
|
+
type MultiSourceChartDataScopeInputs<TSources extends NonEmptyChartSourceOptions> = ChartDataScopeInputs<SourceFilterColumnIdFromSources<TSources>, SourceDateColumnIdFromSources<TSources>>;
|
|
1000
1051
|
//#endregion
|
|
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 };
|
|
1052
|
+
export { AggregateFunction, AggregateMetric, AggregateMetricAllowance, AvailableFilter, BaseColumnHint, BooleanColumn, CategoricalChartType, CategoryColumn, ChartColumn, ChartColumnType, ChartControlMode, ChartDataScopeControlState, ChartDataScopeInputs, ChartDataScopeInputsFromSchemaDefinition, ChartDateRangeSelection, ChartInstance, ChartInstanceFromSchema, ChartInstanceFromSchemaDefinition, ChartSchema, ChartSchemaDefinition, ChartSeries, ChartSourceOptions, ChartType, ChartTypeConfig, ColumnFormat, ColumnFormatPreset, ColumnHintFor, CountMetric, DateColumn, DateColumnFormat, DateRange, DateRangeFilter, DefinedChartSchema, DerivedBooleanColumnSchema, DerivedCategoryColumnSchema, DerivedColumnSchema, DerivedDateColumnSchema, DerivedNumberColumnSchema, DurationColumnFormat, DurationInputUnit, FilterState, FiltersConfig, GroupByConfig, InferableFieldKey, Metric, MetricAllowance, MetricConfig, MultiSourceChartDataScopeInputs, MultiSourceChartInstance, NonEmptyChartSourceOptions, NumberColumn, NumberColumnFormat, NumericAggregateFunction, NumericAggregateSelection, RawColumnSchemaFor, RawColumnSchemaMap, ResolvedChartSchemaFromDefinition, ResolvedColumnIdFromSchema, ResolvedDateColumnIdFromSchema, ResolvedFilterColumnIdFromSchema, ResolvedGroupByColumnIdFromSchema, ResolvedMetricColumnIdFromSchema, ResolvedXAxisColumnIdFromSchema, RestrictedChartTypeFromSchema, RestrictedFilterColumnIdFromSchema, RestrictedGroupByColumnIdFromSchema, RestrictedMetricFromSchema, RestrictedTimeBucketFromSchema, RestrictedXAxisColumnIdFromSchema, SelectableControlConfig, SortConfig, SortDirection, TimeBucket, TimeBucketConfig, TimeSeriesChartType, TransformedDataPoint, ValidatedChartSchema, XAxisConfig };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { ChartSchemaDefinition, ChartSourceOptions, NonEmptyChartSourceOptions } from "./types.mjs";
|
|
1
|
+
import { ChartDataScopeInputsFromSchemaDefinition, ChartSchemaDefinition, ChartSourceOptions, MultiSourceChartDataScopeInputs, NonEmptyChartSourceOptions } from "./types.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/core/use-chart-options.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Single-source options for `useChart(...)`.
|
|
6
6
|
*
|
|
7
|
-
* This is the
|
|
8
|
-
*
|
|
7
|
+
* This is the stable chart-first path:
|
|
8
|
+
* one dataset, one optional schema, one chart.
|
|
9
9
|
*/
|
|
10
10
|
interface SingleSourceOptions<T, TSchema extends ChartSchemaDefinition<T, any> | undefined = undefined> {
|
|
11
11
|
/**
|
|
@@ -18,8 +18,11 @@ interface SingleSourceOptions<T, TSchema extends ChartSchemaDefinition<T, any> |
|
|
|
18
18
|
/**
|
|
19
19
|
* Optional explicit schema layered on top of inference.
|
|
20
20
|
*
|
|
21
|
-
* Usually this is the
|
|
22
|
-
*
|
|
21
|
+
* Usually this is the dataset-backed chart builder from
|
|
22
|
+
* `defineDataset<Row>().chart(...)`.
|
|
23
|
+
*
|
|
24
|
+
* Builders can be passed directly without calling `.build()`. Plain schema
|
|
25
|
+
* objects are also accepted.
|
|
23
26
|
*
|
|
24
27
|
* Use this when you want to:
|
|
25
28
|
* - rename fields with `label`
|
|
@@ -28,6 +31,9 @@ interface SingleSourceOptions<T, TSchema extends ChartSchemaDefinition<T, any> |
|
|
|
28
31
|
* - exclude fields
|
|
29
32
|
* - create derived columns
|
|
30
33
|
* - restrict what users can select in the chart UI
|
|
34
|
+
*
|
|
35
|
+
* Unspecified raw fields still participate through inference unless you
|
|
36
|
+
* explicitly exclude them.
|
|
31
37
|
*/
|
|
32
38
|
schema?: TSchema;
|
|
33
39
|
/**
|
|
@@ -36,18 +42,39 @@ interface SingleSourceOptions<T, TSchema extends ChartSchemaDefinition<T, any> |
|
|
|
36
42
|
* Example: `'Jobs'`, `'Quarterly Financials'`, or `'Pipeline Health'`.
|
|
37
43
|
*/
|
|
38
44
|
sourceLabel?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Optional externally driven data-scope inputs for this one chart.
|
|
47
|
+
*
|
|
48
|
+
* This is additive:
|
|
49
|
+
* `useChart({data})` and `useChart({data, schema})` stay the simple chart-first paths.
|
|
50
|
+
*
|
|
51
|
+
* Only data-scope state belongs here:
|
|
52
|
+
* filters, reference-date selection, and date-range selection.
|
|
53
|
+
*
|
|
54
|
+
* Presentation controls such as `xAxis`, `groupBy`, `metric`, and
|
|
55
|
+
* `chartType` remain chart-local.
|
|
56
|
+
*/
|
|
57
|
+
inputs?: ChartDataScopeInputsFromSchemaDefinition<T, TSchema>;
|
|
39
58
|
sources?: never;
|
|
40
59
|
}
|
|
41
60
|
/**
|
|
42
61
|
* Multi-source options for `useChart(...)`.
|
|
43
62
|
*
|
|
44
|
-
* Use this
|
|
45
|
-
*
|
|
63
|
+
* Use this for source-switching within one chart. It is separate from the
|
|
64
|
+
* single-source `useChart({data, schema})` contract and is not dashboard
|
|
65
|
+
* composition.
|
|
46
66
|
*/
|
|
47
67
|
interface MultiSourceOptions<TSources extends NonEmptyChartSourceOptions = NonEmptyChartSourceOptions> {
|
|
48
68
|
data?: never;
|
|
49
69
|
schema?: never;
|
|
50
70
|
sourceLabel?: never;
|
|
71
|
+
/**
|
|
72
|
+
* Optional externally driven data-scope inputs for one source-switching chart.
|
|
73
|
+
*
|
|
74
|
+
* These inputs are chart-level and sanitize against the active source at
|
|
75
|
+
* runtime. They do not turn `sources` into dashboard composition.
|
|
76
|
+
*/
|
|
77
|
+
inputs?: MultiSourceChartDataScopeInputs<TSources>;
|
|
51
78
|
/**
|
|
52
79
|
* Named list of chart sources.
|
|
53
80
|
*
|
|
@@ -64,4 +91,4 @@ interface MultiSourceOptions<TSources extends NonEmptyChartSourceOptions = NonEm
|
|
|
64
91
|
*/
|
|
65
92
|
type UseChartOptions<T, TSchema extends ChartSchemaDefinition<T, any> | undefined = undefined> = SingleSourceOptions<T, TSchema> | MultiSourceOptions;
|
|
66
93
|
//#endregion
|
|
67
|
-
export { SingleSourceOptions, UseChartOptions };
|
|
94
|
+
export { MultiSourceOptions, SingleSourceOptions, UseChartOptions };
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
//#region src/core/use-chart-resolvers.ts
|
|
2
2
|
/**
|
|
3
|
+
* Clone filter state so callers can safely derive the next map without sharing
|
|
4
|
+
* mutable `Set` instances.
|
|
5
|
+
*/
|
|
6
|
+
function cloneFilterState(filters) {
|
|
7
|
+
return new Map([...filters].map(([columnId, values]) => [columnId, new Set(values)]));
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
3
10
|
* Resolve the active X-axis, preferring date columns first.
|
|
4
11
|
*/
|
|
5
12
|
function resolveXAxisId(xAxisId, activeColumns) {
|
|
@@ -21,14 +28,17 @@ function resolveReferenceDateId(referenceDateIdRaw, dateColumns, resolvedXAxisId
|
|
|
21
28
|
/**
|
|
22
29
|
* Remove filters that target columns not present in the active source.
|
|
23
30
|
*/
|
|
24
|
-
function sanitizeFilters(filters, activeColumns) {
|
|
31
|
+
function sanitizeFilters(filters, activeColumns, availableValues) {
|
|
25
32
|
const validColumnIds = new Set(activeColumns.map((column) => column.id));
|
|
26
33
|
const next = /* @__PURE__ */ new Map();
|
|
27
34
|
for (const [columnId, values] of filters) {
|
|
28
35
|
if (!validColumnIds.has(columnId)) continue;
|
|
29
|
-
|
|
36
|
+
const allowedValues = availableValues?.get(columnId);
|
|
37
|
+
const sanitizedValues = allowedValues ? new Set([...values].filter((value) => allowedValues.has(value))) : new Set(values);
|
|
38
|
+
if (sanitizedValues.size === 0) continue;
|
|
39
|
+
next.set(columnId, sanitizedValues);
|
|
30
40
|
}
|
|
31
41
|
return next;
|
|
32
42
|
}
|
|
33
43
|
//#endregion
|
|
34
|
-
export { resolveReferenceDateId, resolveXAxisId, sanitizeFilters };
|
|
44
|
+
export { cloneFilterState, resolveReferenceDateId, resolveXAxisId, sanitizeFilters };
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { ChartInstanceFromSchemaDefinition, ChartSchemaDefinition, MultiSourceChartInstance, NonEmptyChartSourceOptions } from "./types.mjs";
|
|
2
|
-
import { SingleSourceOptions } from "./use-chart-options.mjs";
|
|
2
|
+
import { MultiSourceOptions, SingleSourceOptions } from "./use-chart-options.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/core/use-chart.d.ts
|
|
5
5
|
/**
|
|
6
|
-
* Headless React hook that manages
|
|
6
|
+
* Headless React hook that manages one chart's configuration, state, and
|
|
7
|
+
* derived/transformed data for rendering.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
* -
|
|
10
|
-
* -
|
|
9
|
+
* The stable primary path is single-source:
|
|
10
|
+
* - `useChart({data})` for zero-config inference
|
|
11
|
+
* - `useChart({data, schema})` when one chart needs an explicit contract
|
|
12
|
+
*
|
|
13
|
+
* Multi-source `sources` support exists for source-switching between
|
|
14
|
+
* interchangeable datasets, but it is intentionally separate from the
|
|
15
|
+
* single-chart schema contract and is not dashboard composition.
|
|
11
16
|
*
|
|
12
17
|
* @template T - The type of each data record in the dataset.
|
|
13
18
|
* @template TSchema - Optional explicit schema for inferred single-source columns.
|
|
@@ -15,8 +20,11 @@ import { SingleSourceOptions } from "./use-chart-options.mjs";
|
|
|
15
20
|
* Chart configuration options. Should provide either:
|
|
16
21
|
* - `data`, optional `schema`, and (optionally) `sourceLabel` for a single source
|
|
17
22
|
* - or `sources` array for multiple sources
|
|
23
|
+
* - and optional `inputs` when filters/reference-date/date-range state is
|
|
24
|
+
* driven externally
|
|
18
25
|
* Any explicit single-source or per-source schema is usually authored with
|
|
19
|
-
* `
|
|
26
|
+
* `defineDataset<Row>().chart(...)`.
|
|
27
|
+
* Builders can be passed directly; plain schema objects are also accepted.
|
|
20
28
|
*
|
|
21
29
|
* @returns {ChartInstance}
|
|
22
30
|
* An object representing chart configuration, state, and all derived data/operations:
|
|
@@ -30,6 +38,7 @@ import { SingleSourceOptions } from "./use-chart-options.mjs";
|
|
|
30
38
|
* - `metric`, `setMetric`, `availableMetrics`: Current aggregation metric, setter, and options
|
|
31
39
|
* - `timeBucket`, `setTimeBucket`, `availableTimeBuckets`: Date/time bucketing state, setter, and options
|
|
32
40
|
* - `isTimeSeries`: Whether the chart is a time series (based on axis)
|
|
41
|
+
* - `dataScopeControl`: Which data-scope slices are controlled externally
|
|
33
42
|
* - `filters`, `toggleFilter`, `clearFilter`, `clearAllFilters`, `availableFilters`: Current filters and their controls
|
|
34
43
|
* - `sorting`, `setSorting`: Current sorting config and setter
|
|
35
44
|
* - `dateRange`, `referenceDateId`, `setReferenceDateId`, `availableDateColumns`, `dateRangeFilter`, `setDateRangeFilter`: Date filtering state and controls
|
|
@@ -39,12 +48,7 @@ import { SingleSourceOptions } from "./use-chart-options.mjs";
|
|
|
39
48
|
* - `rawData`: The raw input data for the active data source
|
|
40
49
|
* - `recordCount`: Number of records present in the current data source
|
|
41
50
|
*/
|
|
42
|
-
declare function useChart<const TSources extends NonEmptyChartSourceOptions>(options:
|
|
43
|
-
data?: never;
|
|
44
|
-
schema?: never;
|
|
45
|
-
sourceLabel?: never;
|
|
46
|
-
sources: TSources;
|
|
47
|
-
}): MultiSourceChartInstance<TSources>;
|
|
51
|
+
declare function useChart<const TSources extends NonEmptyChartSourceOptions>(options: MultiSourceOptions<TSources>): MultiSourceChartInstance<TSources>;
|
|
48
52
|
declare function useChart<T, const TSchema extends ChartSchemaDefinition<T, any> | undefined = undefined>(options: SingleSourceOptions<T, TSchema>): ChartInstanceFromSchemaDefinition<T, TSchema>;
|
|
49
53
|
//#endregion
|
|
50
54
|
export { useChart };
|