@svgrid/grid 2.6.19 → 2.6.21
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/dist/SvGrid.controller.svelte.d.ts +1 -0
- package/dist/SvGrid.controller.svelte.js +64 -2
- package/dist/SvGrid.svelte +2 -1
- package/dist/SvGrid.types.d.ts +150 -0
- package/dist/ai.d.ts +28 -0
- package/dist/ai.js +6 -0
- package/dist/cdn/{GridMenus-B0F9iBrG.js → GridMenus-BfTAKn84.js} +1 -1
- package/dist/cdn/{GridMenus-IHK_l7m6.js → GridMenus-C3bJd7w8.js} +1 -1
- package/dist/cdn/{src-Cd0tearp.js → src-BYq-qyrp.js} +1012 -999
- package/dist/cdn/{src-B1TdiyS8.js → src-DBel9wRZ.js} +1324 -1311
- package/dist/cdn/svgrid.js +1 -1
- package/dist/cdn/svgrid.svelte-external.js +1 -1
- package/dist/cdn/validate-_CDJzgIo.js +75 -0
- package/dist/cell-formatting.d.ts +2 -0
- package/dist/cell-formatting.js +2 -0
- package/dist/chart-export.d.ts +1 -0
- package/dist/chart.d.ts +31 -5
- package/dist/chart.js +9 -3
- package/dist/core.d.ts +197 -0
- package/dist/core.js +72 -0
- package/dist/createTree.svelte.d.ts +3 -0
- package/dist/createTree.svelte.js +1 -0
- package/dist/datetime/date-core.d.ts +2 -0
- package/dist/datetime/date-restrict.d.ts +1 -0
- package/dist/datetime/timezone.d.ts +1 -0
- package/dist/dock-manager-model.d.ts +3 -0
- package/dist/dock-manager-model.js +1 -0
- package/dist/dock-model.d.ts +6 -0
- package/dist/dock-model.js +3 -0
- package/dist/editor-contract.d.ts +1 -0
- package/dist/list-option.d.ts +1 -0
- package/dist/positioning.d.ts +2 -0
- package/dist/scheduler-ical.d.ts +1 -0
- package/dist/scheduler-model.d.ts +1 -0
- package/dist/summaries.js +22 -0
- package/dist/svgrid-wrapper.types.d.ts +5 -0
- package/dist/toast-store.svelte.d.ts +4 -0
- package/dist/validate.d.ts +50 -0
- package/dist/validate.js +187 -0
- package/package.json +4 -1
- package/src/SvGrid.controller.svelte.ts +68 -2
- package/src/SvGrid.svelte +2 -1
- package/src/SvGrid.types.ts +150 -0
- package/src/ai.ts +28 -0
- package/src/cell-formatting.ts +2 -0
- package/src/chart-export.ts +1 -0
- package/src/chart.ts +31 -5
- package/src/core.ts +207 -0
- package/src/createTree.svelte.ts +3 -0
- package/src/datetime/date-core.ts +2 -0
- package/src/datetime/date-restrict.ts +1 -0
- package/src/datetime/timezone.ts +1 -0
- package/src/dock-manager-model.ts +3 -0
- package/src/dock-model.ts +6 -0
- package/src/editor-contract.ts +1 -0
- package/src/list-option.ts +1 -0
- package/src/positioning.ts +2 -0
- package/src/scheduler-ical.ts +1 -0
- package/src/scheduler-model.ts +1 -0
- package/src/summaries.ts +21 -0
- package/src/svgrid-wrapper.types.ts +5 -0
- package/src/svgrid.summaries.test.ts +217 -0
- package/src/toast-store.svelte.ts +4 -0
- package/src/validate.test.ts +207 -0
- package/src/validate.ts +269 -0
package/src/SvGrid.types.ts
CHANGED
|
@@ -1029,7 +1029,21 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1029
1029
|
* work; the shortcut wins only when it is explicitly set.
|
|
1030
1030
|
*/
|
|
1031
1031
|
sortable?: boolean;
|
|
1032
|
+
/**
|
|
1033
|
+
* Click a header to filter that column. Injects `columnFilteringFeature`,
|
|
1034
|
+
* so you do not import it yourself. Which filter surface appears is a
|
|
1035
|
+
* separate question - see `filterMode` (default `'menu'`).
|
|
1036
|
+
*
|
|
1037
|
+
* <SvGrid {data} {columns} filterable />
|
|
1038
|
+
*/
|
|
1032
1039
|
filterable?: boolean;
|
|
1040
|
+
/**
|
|
1041
|
+
* Inline cell editing. Alias of `enableInlineEditing`, and wins over it when
|
|
1042
|
+
* both are set. A column also needs an `editorType` to be editable; without
|
|
1043
|
+
* one it falls back to a text editor.
|
|
1044
|
+
*
|
|
1045
|
+
* <SvGrid {data} {columns} editable />
|
|
1046
|
+
*/
|
|
1033
1047
|
editable?: boolean;
|
|
1034
1048
|
/**
|
|
1035
1049
|
* Cell selection - click a cell to select it, drag or shift-click to extend
|
|
@@ -1081,6 +1095,16 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1081
1095
|
/** Indent per depth level, in px. Default `12`. */
|
|
1082
1096
|
indentPx?: number;
|
|
1083
1097
|
};
|
|
1098
|
+
/**
|
|
1099
|
+
* Show the grouping controls: "Group by this column" in the column menu, and
|
|
1100
|
+
* the group panel when `showGroupPanel` is on. Alias of
|
|
1101
|
+
* `showGroupingControls`, and also injects `columnGroupingFeature`.
|
|
1102
|
+
*
|
|
1103
|
+
* This turns on the UI for grouping. To group without asking the user, set
|
|
1104
|
+
* `groupBy` instead.
|
|
1105
|
+
*
|
|
1106
|
+
* <SvGrid {data} {columns} groupable />
|
|
1107
|
+
*/
|
|
1084
1108
|
groupable?: boolean;
|
|
1085
1109
|
/**
|
|
1086
1110
|
* Group the rows by these column ids, outermost first - `['region',
|
|
@@ -1158,7 +1182,19 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1158
1182
|
autoGroupColumnHeader?: string;
|
|
1159
1183
|
/** Width (px) of each auto-group column. Default `220`. */
|
|
1160
1184
|
autoGroupColumnWidth?: number;
|
|
1185
|
+
/**
|
|
1186
|
+
* Show the pagination footer. Alias of `showPagination`, and wins over it
|
|
1187
|
+
* when both are set. Page size starts at `pageSize` (default 10).
|
|
1188
|
+
*
|
|
1189
|
+
* <SvGrid {data} {columns} pageable pageSize={25} />
|
|
1190
|
+
*/
|
|
1161
1191
|
pageable?: boolean;
|
|
1192
|
+
/**
|
|
1193
|
+
* Show the loading state instead of the rows. By default this replaces the
|
|
1194
|
+
* grid body with "Loading..."; set `loadingOverlay` to keep the current rows
|
|
1195
|
+
* visible under a dimmed overlay instead, which is what you usually want for
|
|
1196
|
+
* a server-paged grid.
|
|
1197
|
+
*/
|
|
1162
1198
|
loading?: boolean;
|
|
1163
1199
|
/**
|
|
1164
1200
|
* Render `loading` as a non-blocking overlay instead of replacing the
|
|
@@ -1170,7 +1206,16 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1170
1206
|
loadingOverlay?: boolean;
|
|
1171
1207
|
/** Skeleton placeholder rows to show on first load. Defaults to 8. */
|
|
1172
1208
|
loadingSkeletonRows?: number;
|
|
1209
|
+
/**
|
|
1210
|
+
* Render an error message in place of the rows. `null` or omitted means no
|
|
1211
|
+
* error. Takes precedence over `loading` and over the empty state.
|
|
1212
|
+
*/
|
|
1173
1213
|
error?: string | null;
|
|
1214
|
+
/**
|
|
1215
|
+
* Text shown when there are no rows to display - either the data is empty or
|
|
1216
|
+
* a filter matched nothing. Defaults to the localized `noRows` string, so
|
|
1217
|
+
* prefer `localization.text.noRows` when you are translating the whole grid.
|
|
1218
|
+
*/
|
|
1174
1219
|
emptyMessage?: string;
|
|
1175
1220
|
/**
|
|
1176
1221
|
* The single place to localize the grid. One object with two fields:
|
|
@@ -1190,7 +1235,21 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1190
1235
|
* Omitting it (or any field) is a no-op. See {@link GridMessages}.
|
|
1191
1236
|
*/
|
|
1192
1237
|
localization?: GridLocalization;
|
|
1238
|
+
/**
|
|
1239
|
+
* Show the single search box that filters across every column. Explicitly
|
|
1240
|
+
* setting this wins over `filterMode`; leaving it unset means it appears only
|
|
1241
|
+
* when `filterMode` is `'global'`.
|
|
1242
|
+
*/
|
|
1193
1243
|
showGlobalFilter?: boolean;
|
|
1244
|
+
/**
|
|
1245
|
+
* Show the filter section inside each column's menu. Explicitly setting this
|
|
1246
|
+
* wins over `filterMode`; unset, it follows `filterMode` (default `'menu'`,
|
|
1247
|
+
* so this is normally on).
|
|
1248
|
+
*
|
|
1249
|
+
* Setting it `true` also adds the inline "floating filter" input under each
|
|
1250
|
+
* header - that surface requires the explicit opt-in, since it otherwise
|
|
1251
|
+
* duplicates the menu's own filter popover.
|
|
1252
|
+
*/
|
|
1194
1253
|
showColumnFilters?: boolean;
|
|
1195
1254
|
/**
|
|
1196
1255
|
* Quick way to pick a single filtering UI. When set it controls which of
|
|
@@ -1199,8 +1258,23 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1199
1258
|
* Defaults to `'menu'` (only the column menu's filter section is shown).
|
|
1200
1259
|
*/
|
|
1201
1260
|
filterMode?: "row" | "menu" | "global" | "none";
|
|
1261
|
+
/**
|
|
1262
|
+
* Show the grouping affordances (the column menu's "Group by this column",
|
|
1263
|
+
* and the group panel). The `groupable` shortcut sets this and registers the
|
|
1264
|
+
* grouping feature in one go; prefer that unless you have already registered
|
|
1265
|
+
* `columnGroupingFeature` yourself.
|
|
1266
|
+
*/
|
|
1202
1267
|
showGroupingControls?: boolean;
|
|
1268
|
+
/**
|
|
1269
|
+
* Show the row-selection checkbox column, including the select-all checkbox
|
|
1270
|
+
* in the header. Unset, it follows `selectionMode` (default `'both'`, so
|
|
1271
|
+
* row selection is on).
|
|
1272
|
+
*/
|
|
1203
1273
|
showRowSelection?: boolean;
|
|
1274
|
+
/**
|
|
1275
|
+
* Show the pagination footer. Off by default. `pageable` is the shortcut
|
|
1276
|
+
* alias and wins when both are set.
|
|
1277
|
+
*/
|
|
1204
1278
|
showPagination?: boolean;
|
|
1205
1279
|
/** Initial page size when pagination is enabled. Defaults to 10. */
|
|
1206
1280
|
pageSize?: number;
|
|
@@ -1230,6 +1304,14 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1230
1304
|
* is on. Fetch that page and update `data` / `rowCount` / `pageIndex`.
|
|
1231
1305
|
*/
|
|
1232
1306
|
onPaginationChange?: (pagination: { pageIndex: number; pageSize: number }) => void;
|
|
1307
|
+
/**
|
|
1308
|
+
* Render only the rows in view instead of all of them. **On by default** -
|
|
1309
|
+
* this is what keeps a 100,000-row grid responsive.
|
|
1310
|
+
*
|
|
1311
|
+
* Turn it off when a row's height cannot be known up front and must not be
|
|
1312
|
+
* clipped, such as a variable-height master-detail panel. Expect the DOM to
|
|
1313
|
+
* hold every row when you do.
|
|
1314
|
+
*/
|
|
1233
1315
|
virtualization?: boolean;
|
|
1234
1316
|
/** Row height in pixels. Pass a function `(rowIndex) => px` for
|
|
1235
1317
|
* per-row variable heights (e.g. an interactive row-resize feature).
|
|
@@ -1254,6 +1336,11 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1254
1336
|
* to their content (the default). Does not affect the filter row.
|
|
1255
1337
|
*/
|
|
1256
1338
|
headerHeight?: number;
|
|
1339
|
+
/**
|
|
1340
|
+
* Extra rows rendered above and below the viewport, so fast scrolling does
|
|
1341
|
+
* not reach empty space before the next batch renders. Defaults to 8.
|
|
1342
|
+
* Raise it for very tall rows, lower it to trim DOM work.
|
|
1343
|
+
*/
|
|
1257
1344
|
overscan?: number;
|
|
1258
1345
|
/**
|
|
1259
1346
|
* Height of the grid's scrollable shell. A number is treated as pixels;
|
|
@@ -1261,8 +1348,24 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1261
1348
|
* make the grid fill its parent. Defaults to 520 px.
|
|
1262
1349
|
*/
|
|
1263
1350
|
containerHeight?: number | string;
|
|
1351
|
+
/**
|
|
1352
|
+
* Render only the columns in view, the horizontal counterpart of
|
|
1353
|
+
* `virtualization`. **On by default**, which is what makes a 100-column grid
|
|
1354
|
+
* scroll smoothly.
|
|
1355
|
+
*
|
|
1356
|
+
* It recycles column DOM nodes, so it cannot coexist with sticky pinned
|
|
1357
|
+
* columns - turn it off if you need pinning to survive horizontal scrolling.
|
|
1358
|
+
*/
|
|
1264
1359
|
columnVirtualization?: boolean;
|
|
1360
|
+
/**
|
|
1361
|
+
* Extra columns rendered either side of the viewport when
|
|
1362
|
+
* `columnVirtualization` is on. Defaults to 3.
|
|
1363
|
+
*/
|
|
1265
1364
|
columnOverscan?: number;
|
|
1365
|
+
/**
|
|
1366
|
+
* Fallback width in pixels for columns whose `ColumnDef` sets no `width`.
|
|
1367
|
+
* Defaults to 140.
|
|
1368
|
+
*/
|
|
1266
1369
|
columnWidth?: number;
|
|
1267
1370
|
/**
|
|
1268
1371
|
* Columns pinned to the left/right edge on mount. Each entry is a
|
|
@@ -1293,8 +1396,24 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1293
1396
|
* breakpoint; pass `{ breakpoint }` to change it. Off by default.
|
|
1294
1397
|
*/
|
|
1295
1398
|
responsive?: boolean | { breakpoint?: number };
|
|
1399
|
+
/**
|
|
1400
|
+
* @deprecated Has no effect - nothing in the grid reads this prop. It is kept
|
|
1401
|
+
* only so existing code keeps compiling. The column menu's filter section is
|
|
1402
|
+
* controlled by `showColumnFilters`, or by `filterMode="menu"` (the default).
|
|
1403
|
+
*/
|
|
1296
1404
|
showFilterMenu?: boolean;
|
|
1405
|
+
/**
|
|
1406
|
+
* Show the always-visible filter row under the header. Explicitly setting
|
|
1407
|
+
* this wins over `filterMode`; unset, it appears only when `filterMode` is
|
|
1408
|
+
* `'row'`.
|
|
1409
|
+
*/
|
|
1297
1410
|
showFilterRow?: boolean;
|
|
1411
|
+
/**
|
|
1412
|
+
* Cell selection - click to select, drag or shift-click to extend to a range,
|
|
1413
|
+
* which is what clipboard copy and the range fill handle operate on. Unset,
|
|
1414
|
+
* it follows `selectionMode` (default `'both'`, so this is on). `selectable`
|
|
1415
|
+
* is the shortcut alias and wins over it.
|
|
1416
|
+
*/
|
|
1298
1417
|
enableCellSelection?: boolean;
|
|
1299
1418
|
/**
|
|
1300
1419
|
* Highlight the row under the pointer. Default **false** - the hover tint can
|
|
@@ -1320,6 +1439,14 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1320
1439
|
rowIndex: number;
|
|
1321
1440
|
columnId: string;
|
|
1322
1441
|
}) => unknown;
|
|
1442
|
+
/**
|
|
1443
|
+
* Inline cell editing: F2 or double-click opens an editor in the active cell,
|
|
1444
|
+
* Enter commits, Esc cancels. Off by default.
|
|
1445
|
+
*
|
|
1446
|
+
* A column still needs an `editorType` to pick its editor (text, number,
|
|
1447
|
+
* date, checkbox, list, ...); without one it gets a plain text editor.
|
|
1448
|
+
* `editable` is the shortcut alias and wins over this.
|
|
1449
|
+
*/
|
|
1323
1450
|
enableInlineEditing?: boolean;
|
|
1324
1451
|
/**
|
|
1325
1452
|
* Full-row editing. When `true`, starting an edit puts the WHOLE row into
|
|
@@ -1329,7 +1456,22 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1329
1456
|
* text / number / date / datetime / checkbox / list-select editor types.
|
|
1330
1457
|
*/
|
|
1331
1458
|
fullRowEditing?: boolean;
|
|
1459
|
+
/**
|
|
1460
|
+
* Append a sticky footer row aggregating every filtered row: the sum of a
|
|
1461
|
+
* numeric column, `Count: N` otherwise. Choose a different aggregate per
|
|
1462
|
+
* column with that column's own `summary` option, or set it to `false` there
|
|
1463
|
+
* to leave the cell blank.
|
|
1464
|
+
*
|
|
1465
|
+
* Off by default. `summary` is the shortcut alias and wins when both are set.
|
|
1466
|
+
*
|
|
1467
|
+
* <SvGrid {data} {columns} summary />
|
|
1468
|
+
*/
|
|
1332
1469
|
enableRowSummaries?: boolean;
|
|
1470
|
+
/**
|
|
1471
|
+
* Shortcut alias for {@link enableRowSummaries}. Wins over it when both are
|
|
1472
|
+
* set, the same precedence `selectable` has over `enableCellSelection`.
|
|
1473
|
+
*/
|
|
1474
|
+
summary?: boolean;
|
|
1333
1475
|
/**
|
|
1334
1476
|
* Excel-style status bar under the grid showing live aggregates of the
|
|
1335
1477
|
* selected cell range (count, numeric count, sum, average, min, max).
|
|
@@ -1544,6 +1686,14 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1544
1686
|
* filter.
|
|
1545
1687
|
*/
|
|
1546
1688
|
conditionalStatScope?: "filtered" | "visible" | "all";
|
|
1689
|
+
/**
|
|
1690
|
+
* Fires after an inline edit commits, with the cell's old and new value and
|
|
1691
|
+
* the row it belongs to. This is where you persist the change.
|
|
1692
|
+
*
|
|
1693
|
+
* The grid has already applied the edit to its own state by the time this
|
|
1694
|
+
* runs, so it is a notification, not a veto - reject a value with the
|
|
1695
|
+
* column's `valueParser` or a validation rule instead.
|
|
1696
|
+
*/
|
|
1547
1697
|
onCellValueChange?: (event: {
|
|
1548
1698
|
rowIndex: number;
|
|
1549
1699
|
columnId: string;
|
package/src/ai.ts
CHANGED
|
@@ -48,6 +48,7 @@ type ExportFormat = 'xlsx' | 'xls' | 'pdf' | 'csv' | 'tsv' | 'html' | 'json' | '
|
|
|
48
48
|
*/
|
|
49
49
|
export type AIProvider = (request: AIRequest) => Promise<string>
|
|
50
50
|
|
|
51
|
+
/** One call out to the model, as the grid builds it. Providers receive this. */
|
|
51
52
|
export type AIRequest = {
|
|
52
53
|
/** Full prompt the grid built for the model. Already includes column
|
|
53
54
|
* schema and any sampled rows where applicable. */
|
|
@@ -66,6 +67,7 @@ export type AIRequest = {
|
|
|
66
67
|
maxOutputTokens?: number
|
|
67
68
|
}
|
|
68
69
|
|
|
70
|
+
/** Which helper produced a request - carried on {@link AIRequest} for routing and telemetry. */
|
|
69
71
|
export type AITask = 'filter' | 'smart-fill' | 'summarize' | 'classify' | 'export' | 'anomaly' | 'chart'
|
|
70
72
|
|
|
71
73
|
let provider: AIProvider | null = null
|
|
@@ -79,10 +81,12 @@ export function setAIProvider(p: AIProvider | null): void {
|
|
|
79
81
|
provider = p
|
|
80
82
|
}
|
|
81
83
|
|
|
84
|
+
/** The provider registered with `setAIProvider`, or null when none is. */
|
|
82
85
|
export function getAIProvider(): AIProvider | null {
|
|
83
86
|
return provider
|
|
84
87
|
}
|
|
85
88
|
|
|
89
|
+
/** Whether an AI provider is registered. Gate AI affordances on this so the UI stays honest. */
|
|
86
90
|
export function hasAIProvider(): boolean {
|
|
87
91
|
return provider != null
|
|
88
92
|
}
|
|
@@ -198,13 +202,16 @@ function schemaToPromptBlock(schema: ColumnSchemaEntry[]): string {
|
|
|
198
202
|
// 1. Natural-language filter / sort
|
|
199
203
|
// ---------------------------------------------------------------------------
|
|
200
204
|
|
|
205
|
+
/** One condition in a filter plan: a column, a comparison, and the value to match. */
|
|
201
206
|
export type AIFilterClause = {
|
|
202
207
|
field: string
|
|
203
208
|
operator: 'contains' | 'equals' | 'startsWith' | 'greaterThan' | 'lessThan' | 'isBlank'
|
|
204
209
|
value?: string
|
|
205
210
|
}
|
|
211
|
+
/** One ordering clause in a filter plan. */
|
|
206
212
|
export type AISortClause = { field: string; desc: boolean }
|
|
207
213
|
|
|
214
|
+
/** A natural-language query turned into filters and sorting, plus the model's reasoning. */
|
|
208
215
|
export type AIFilterResult = {
|
|
209
216
|
filters: AIFilterClause[]
|
|
210
217
|
sort: AISortClause[]
|
|
@@ -213,6 +220,7 @@ export type AIFilterResult = {
|
|
|
213
220
|
rationale: string
|
|
214
221
|
}
|
|
215
222
|
|
|
223
|
+
/** Options for `aiFilter` - preview the plan, or apply it straight to the grid. */
|
|
216
224
|
export type AIFilterOptions = {
|
|
217
225
|
/**
|
|
218
226
|
* When true, the helper not only RETURNS the plan but also applies it
|
|
@@ -284,14 +292,17 @@ export async function aiFilter<
|
|
|
284
292
|
// 2. Smart fill
|
|
285
293
|
// ---------------------------------------------------------------------------
|
|
286
294
|
|
|
295
|
+
/** One worked example teaching smart-fill what to produce for a row. */
|
|
287
296
|
export type AISmartFillExample = { input: Record<string, unknown>; output: unknown }
|
|
288
297
|
|
|
298
|
+
/** Proposed values for the blank cells of one column, each with a confidence score. */
|
|
289
299
|
export type AISmartFillResult<TValue = unknown> = {
|
|
290
300
|
field: string
|
|
291
301
|
predictions: Array<{ rowIndex: number; value: TValue; confidence: number }>
|
|
292
302
|
rationale: string
|
|
293
303
|
}
|
|
294
304
|
|
|
305
|
+
/** Options for `aiSmartFill` - which column to fill, which rows, and the examples to learn from. */
|
|
295
306
|
export type AISmartFillOptions = {
|
|
296
307
|
/** Target column - the one whose values we want filled. */
|
|
297
308
|
field: string
|
|
@@ -379,12 +390,14 @@ export async function aiSmartFill<
|
|
|
379
390
|
// 3. Summarise
|
|
380
391
|
// ---------------------------------------------------------------------------
|
|
381
392
|
|
|
393
|
+
/** What to summarise: one row, the selection, a group, or the whole set. */
|
|
382
394
|
export type AISummarizeTarget =
|
|
383
395
|
| { kind: 'row'; rowIndex: number }
|
|
384
396
|
| { kind: 'all' }
|
|
385
397
|
| { kind: 'selection'; rowIndices: number[] }
|
|
386
398
|
| { kind: 'group'; field: string; value: unknown }
|
|
387
399
|
|
|
400
|
+
/** A generated summary: prose, bullets, and the columns the model leaned on. */
|
|
388
401
|
export type AISummary = {
|
|
389
402
|
text: string
|
|
390
403
|
bullets: string[]
|
|
@@ -393,6 +406,7 @@ export type AISummary = {
|
|
|
393
406
|
highlightedFields: string[]
|
|
394
407
|
}
|
|
395
408
|
|
|
409
|
+
/** Options for `aiSummarize` - the target, and optionally the question to answer. */
|
|
396
410
|
export type AISummarizeOptions = {
|
|
397
411
|
target: AISummarizeTarget
|
|
398
412
|
/** Optional question the user is trying to answer. Helps the model
|
|
@@ -468,6 +482,7 @@ export async function aiSummarize<
|
|
|
468
482
|
// 4. Classify (free-text -> bucketed value)
|
|
469
483
|
// ---------------------------------------------------------------------------
|
|
470
484
|
|
|
485
|
+
/** Options for `aiClassify` - the column to label and the categories to choose from. */
|
|
471
486
|
export type AIClassifyOptions = {
|
|
472
487
|
/** Column whose free-text we're classifying. */
|
|
473
488
|
inputField: string
|
|
@@ -482,6 +497,7 @@ export type AIClassifyOptions = {
|
|
|
482
497
|
signal?: AbortSignal
|
|
483
498
|
}
|
|
484
499
|
|
|
500
|
+
/** Proposed category labels per row, with the model's reasoning. */
|
|
485
501
|
export type AIClassifyResult = {
|
|
486
502
|
inputField: string
|
|
487
503
|
outputField: string
|
|
@@ -545,6 +561,7 @@ export async function aiClassify<
|
|
|
545
561
|
|
|
546
562
|
const EXPORT_FORMATS: ExportFormat[] = ['xlsx', 'xls', 'pdf', 'csv', 'tsv', 'html', 'json', 'xml', 'md']
|
|
547
563
|
|
|
564
|
+
/** An export the model derived from a request: format, columns, and scope. */
|
|
548
565
|
export type AIExportPlan = {
|
|
549
566
|
format: ExportFormat
|
|
550
567
|
filters: AIFilterClause[]
|
|
@@ -554,6 +571,7 @@ export type AIExportPlan = {
|
|
|
554
571
|
rationale: string
|
|
555
572
|
}
|
|
556
573
|
|
|
574
|
+
/** Options for `aiExport` - preview the plan, or run the export it describes. */
|
|
557
575
|
export type AIExportOptions = {
|
|
558
576
|
/**
|
|
559
577
|
* Also apply the filter / sort / grouping to the grid (mutating the view) so
|
|
@@ -719,6 +737,7 @@ function applyPlanToRows<TData extends RowData>(
|
|
|
719
737
|
// 6. Find anomalies
|
|
720
738
|
// ---------------------------------------------------------------------------
|
|
721
739
|
|
|
740
|
+
/** One flagged value, with why it stands out and how strongly. */
|
|
722
741
|
export type AIAnomaly = {
|
|
723
742
|
/** Index into the SCANNED rows (target order), when the model pins one row. */
|
|
724
743
|
rowIndex?: number
|
|
@@ -728,11 +747,13 @@ export type AIAnomaly = {
|
|
|
728
747
|
severity: 'low' | 'medium' | 'high'
|
|
729
748
|
}
|
|
730
749
|
|
|
750
|
+
/** Everything an anomaly scan flagged across the rows it looked at. */
|
|
731
751
|
export type AIAnomalyResult = {
|
|
732
752
|
anomalies: AIAnomaly[]
|
|
733
753
|
summary: string
|
|
734
754
|
}
|
|
735
755
|
|
|
756
|
+
/** Options for `aiFindAnomalies` - which rows and columns to scan. */
|
|
736
757
|
export type AIAnomalyOptions = {
|
|
737
758
|
/** Which rows to scan. Defaults to the whole dataset. */
|
|
738
759
|
target?: AISummarizeTarget
|
|
@@ -814,8 +835,10 @@ export async function aiFindAnomalies<
|
|
|
814
835
|
// 7. Natural-language chart ("chart this")
|
|
815
836
|
// ---------------------------------------------------------------------------
|
|
816
837
|
|
|
838
|
+
/** Chart shapes the model may choose from when planning a visualisation. */
|
|
817
839
|
export type AIChartType = 'bar' | 'line' | 'area' | 'pie'
|
|
818
840
|
|
|
841
|
+
/** A chart the model proposed: its type, and the fields to plot. */
|
|
819
842
|
export type AIChartPlan = {
|
|
820
843
|
type: AIChartType
|
|
821
844
|
/** Group-by (category-axis) column field, or null. */
|
|
@@ -832,6 +855,7 @@ export type AIChartPlan = {
|
|
|
832
855
|
rationale: string
|
|
833
856
|
}
|
|
834
857
|
|
|
858
|
+
/** Options for `aiChart` - preview the plan, or render it into the grid. */
|
|
835
859
|
export type AIChartOptions = {
|
|
836
860
|
/** Apply the plan to the grid's chart panel (open + configure). Default false. */
|
|
837
861
|
apply?: boolean
|
|
@@ -951,6 +975,10 @@ export function enableAiCharting<
|
|
|
951
975
|
})
|
|
952
976
|
}
|
|
953
977
|
|
|
978
|
+
/**
|
|
979
|
+
* Remove the natural-language chart handler, hiding the AI button in the chart
|
|
980
|
+
* panel. The inverse of `enableAiCharting`; safe to call when none was set.
|
|
981
|
+
*/
|
|
954
982
|
export function disableAiCharting<
|
|
955
983
|
TFeatures extends TableFeatures,
|
|
956
984
|
TData extends RowData,
|
package/src/cell-formatting.ts
CHANGED
|
@@ -106,6 +106,8 @@ function getNumberFormatter(
|
|
|
106
106
|
|
|
107
107
|
/** Cache of `Intl.DateTimeFormat` by `(locale, options)` signature. */
|
|
108
108
|
const dateFormatterCache = new Map<string, Intl.DateTimeFormat>()
|
|
109
|
+
/** A cached `Intl.DateTimeFormat` for the locale and options given. Cached because
|
|
110
|
+
* constructing one per cell is the dominant cost when formatting a date column. */
|
|
109
111
|
export function getDateFormatter(
|
|
110
112
|
locales: string | readonly string[] | undefined,
|
|
111
113
|
options: Intl.DateTimeFormatOptions,
|
package/src/chart-export.ts
CHANGED
|
@@ -21,6 +21,7 @@ function cssVar(el: Element, name: string, fallback: string): string {
|
|
|
21
21
|
return v || fallback
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/** Options for exporting a chart: the filename, and the background to paint behind it. */
|
|
24
25
|
export type ChartExportOptions = {
|
|
25
26
|
/** Background color of the exported image. Default: the grid background. */
|
|
26
27
|
background?: string
|
package/src/chart.ts
CHANGED
|
@@ -36,9 +36,8 @@ export type SeriesOverlay = 'linear' | `sma:${number}` | `ema:${number}`
|
|
|
36
36
|
/** A texture fill applied in addition to (and on top of) the series color.
|
|
37
37
|
* Helps colorblind readers distinguish series at a glance. */
|
|
38
38
|
export type SeriesPattern = 'solid' | 'stripe' | 'crosshatch' | 'dots' | 'diagonal'
|
|
39
|
-
/** Cycle used when `ChartSpec.patternFallback` is true and a series has no
|
|
40
|
-
* explicit `pattern` set. Skips `'solid'` so every series gets a texture. */
|
|
41
39
|
|
|
40
|
+
/** One plotted series: its label, its values (one per category), and how to draw it. */
|
|
42
41
|
export type ChartSeries = {
|
|
43
42
|
label: string
|
|
44
43
|
values: number[]
|
|
@@ -95,6 +94,12 @@ export type ChartReferenceLine = {
|
|
|
95
94
|
dashed?: boolean
|
|
96
95
|
}
|
|
97
96
|
|
|
97
|
+
/**
|
|
98
|
+
* What to plot - the input you build and hand to a chart. Categories are the
|
|
99
|
+
* x-axis labels and every series supplies one value per category.
|
|
100
|
+
*
|
|
101
|
+
* {@link buildChart} turns this into a {@link ChartGeometry} for rendering.
|
|
102
|
+
*/
|
|
98
103
|
export type ChartSpec = {
|
|
99
104
|
/** Default type for series that don't set their own `type`. */
|
|
100
105
|
type: ChartType
|
|
@@ -326,6 +331,7 @@ export type ChartHeatmapCell = {
|
|
|
326
331
|
colLabel: string
|
|
327
332
|
}
|
|
328
333
|
|
|
334
|
+
/** A computed bar rectangle in SVG coordinates. Output of {@link buildChart}, not an input. */
|
|
329
335
|
export type ChartBar = {
|
|
330
336
|
x: number
|
|
331
337
|
y: number
|
|
@@ -338,6 +344,7 @@ export type ChartBar = {
|
|
|
338
344
|
series: string
|
|
339
345
|
value: number
|
|
340
346
|
}
|
|
347
|
+
/** One computed point on a line, with whether the series has a value there. */
|
|
341
348
|
export type ChartLinePoint = {
|
|
342
349
|
x: number
|
|
343
350
|
y: number
|
|
@@ -346,6 +353,7 @@ export type ChartLinePoint = {
|
|
|
346
353
|
/** False for null / NaN values - the line breaks (gap), no dot is drawn. */
|
|
347
354
|
defined: boolean
|
|
348
355
|
}
|
|
356
|
+
/** A computed line series: its points and the path drawn through them. */
|
|
349
357
|
export type ChartLine = {
|
|
350
358
|
path: string
|
|
351
359
|
areaPath: string
|
|
@@ -356,6 +364,7 @@ export type ChartLine = {
|
|
|
356
364
|
* series, when both arrays are supplied. Empty otherwise. */
|
|
357
365
|
bandPath?: string
|
|
358
366
|
}
|
|
367
|
+
/** A computed pie slice, as an SVG arc plus its label placement. */
|
|
359
368
|
export type ChartPieSlice = {
|
|
360
369
|
path: string
|
|
361
370
|
color: string
|
|
@@ -366,12 +375,17 @@ export type ChartPieSlice = {
|
|
|
366
375
|
cx: number
|
|
367
376
|
cy: number
|
|
368
377
|
}
|
|
378
|
+
/** A value-axis tick: the number, where it sits vertically, and its label. */
|
|
369
379
|
export type ChartAxisTick = { value: number; y: number; label: string }
|
|
380
|
+
/** A category-axis tick: the label and its horizontal position. */
|
|
370
381
|
export type ChartCategoryTick = { label: string; x: number }
|
|
382
|
+
/** One legend entry, paired with the series colour it stands for. */
|
|
371
383
|
export type ChartLegendItem = { label: string; color: string }
|
|
384
|
+
/** A computed reference line (target, average, threshold) at its plotted height. */
|
|
372
385
|
export type ChartRefLineGeo = { y: number; label: string; color: string; dashed: boolean }
|
|
373
386
|
/** A vertical reference line (horizontal bar charts) positioned by `x`. */
|
|
374
387
|
export type ChartRefLineGeoV = { x: number; label: string; color: string; dashed: boolean }
|
|
388
|
+
/** A computed scatter point in SVG coordinates. */
|
|
375
389
|
export type ChartScatterDot = {
|
|
376
390
|
cx: number
|
|
377
391
|
cy: number
|
|
@@ -383,6 +397,11 @@ export type ChartScatterDot = {
|
|
|
383
397
|
y: number
|
|
384
398
|
}
|
|
385
399
|
|
|
400
|
+
/**
|
|
401
|
+
* Everything needed to render a chart: the plot rectangle plus every mark
|
|
402
|
+
* already positioned in SVG coordinates. Produced by {@link buildChart} from a
|
|
403
|
+
* {@link ChartSpec}, so a renderer does no maths of its own.
|
|
404
|
+
*/
|
|
386
405
|
export type ChartGeometry = {
|
|
387
406
|
type: ChartType
|
|
388
407
|
width: number
|
|
@@ -455,6 +474,7 @@ export type ChartGeometry = {
|
|
|
455
474
|
sankeyLinks: ChartSankeyLink[]
|
|
456
475
|
}
|
|
457
476
|
|
|
477
|
+
/** Series colours used when a {@link ChartSeries} sets none, in order. */
|
|
458
478
|
export const DEFAULT_PALETTE = [
|
|
459
479
|
'#2563eb',
|
|
460
480
|
'#16a34a',
|
|
@@ -480,6 +500,7 @@ function niceNum(range: number, roundIt: boolean): number {
|
|
|
480
500
|
return nf * Math.pow(10, exp)
|
|
481
501
|
}
|
|
482
502
|
|
|
503
|
+
/** An axis range rounded to human-friendly bounds and tick spacing. */
|
|
483
504
|
export type NiceScale = { min: number; max: number; step: number; ticks: number[] }
|
|
484
505
|
|
|
485
506
|
// ---- Color helpers for heatmap / pattern fills ----------------------
|
|
@@ -574,9 +595,6 @@ function project(value: number, min: number, max: number, isLog: boolean): numbe
|
|
|
574
595
|
|
|
575
596
|
// ---- Overlay math: trendline + moving averages -----------------------
|
|
576
597
|
|
|
577
|
-
/** Ordinary least-squares regression on (i, values[i]) pairs (i = x index).
|
|
578
|
-
* Returns the fitted value at each x index, or NaN where the source value
|
|
579
|
-
* was non-finite. */
|
|
580
598
|
/** Build an SVG path from a list of (x,y) pairs, optionally smoothed via
|
|
581
599
|
* monotone cubic interpolation (preserves local extrema - no overshoots).
|
|
582
600
|
* Breaks the path at `defined === false` gaps. */
|
|
@@ -655,6 +673,9 @@ function monotoneCubicPath(pts: Array<{ x: number; y: number }>): string {
|
|
|
655
673
|
return path
|
|
656
674
|
}
|
|
657
675
|
|
|
676
|
+
/** Ordinary least-squares regression on (i, values[i]) pairs (i = x index).
|
|
677
|
+
* Returns the fitted value at each x index, or NaN where the source value
|
|
678
|
+
* was non-finite. */
|
|
658
679
|
export function linearTrend(values: number[]): number[] {
|
|
659
680
|
let n = 0, sumX = 0, sumY = 0, sumXX = 0, sumXY = 0
|
|
660
681
|
for (let i = 0; i < values.length; i += 1) {
|
|
@@ -835,6 +856,11 @@ function axisDomain(
|
|
|
835
856
|
return isLog ? niceLogScale(dMin, dMax) : niceScale(dMin, dMax)
|
|
836
857
|
}
|
|
837
858
|
|
|
859
|
+
/**
|
|
860
|
+
* Lay out a {@link ChartSpec} into renderable {@link ChartGeometry} - scales,
|
|
861
|
+
* ticks, and the position of every bar, line, slice and dot. Pure: no DOM, so
|
|
862
|
+
* it runs during SSR and can be unit-tested directly.
|
|
863
|
+
*/
|
|
838
864
|
export function buildChart(spec: ChartSpec, theme: 'light' | 'dark' = 'light'): ChartGeometry {
|
|
839
865
|
const width = spec.width ?? 520
|
|
840
866
|
const height = spec.height ?? 300
|