@toclocoinc/lattice-grid 1.28.0 → 1.29.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/lattice-grid.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.28.0, type declarations
2
+ * Lattice Grid 1.29.0, type declarations
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -20,7 +20,7 @@ export type TypeName =
20
20
  | 'text' | 'number' | 'boolean' | 'date' | 'dateString' | 'object' | 'lookup'
21
21
  | 'image'
22
22
  // Extended catalogue. Never inferred, a column asks for these by name.
23
- | 'time' | 'datetime' | 'duration'
23
+ | 'time' | 'datetime' | 'duration' | 'timestamp'
24
24
  | 'ipv4' | 'ipv6' | 'cidr'
25
25
  | 'json' | 'secret'
26
26
  | 'hex' | 'hex8' | 'hex16' | 'hex32' | 'binary' | 'binary8' | 'octal'
@@ -551,9 +551,19 @@ export interface ColumnLayoutSpec {
551
551
  }
552
552
 
553
553
  export interface ColumnHeaderSpec {
554
+ /** Not read by the header renderer; use `render` to draw a custom heading. */
554
555
  template?: string;
556
+ /**
557
+ * A custom heading renderer: a function, or a component (a class with a
558
+ * `render` method). A string names a registered renderer. Either form draws
559
+ * the same two ways and they are interchangeable — it may append to the passed
560
+ * label element itself and return nothing, or return an `Element` (attached
561
+ * for you) or a `string` (used as the heading text).
562
+ */
555
563
  render?: string | RendererCtor;
564
+ /** Props passed to `render` as `params.props`. */
556
565
  props?: Record<string, unknown>;
566
+ /** A class, or classes, added to the heading cell. */
557
567
  class?: string | string[];
558
568
  tooltip?: string;
559
569
  align?: Align;
@@ -607,8 +617,17 @@ export interface Column {
607
617
  * Row grouping by this column. `index` fixes its place among several;
608
618
  * `explode` gives a multi-value cell one group per value rather than one
609
619
  * group for the combination.
610
- */
611
- group?: { enabled?: boolean; index?: number; explode?: boolean } | boolean;
620
+ *
621
+ * `granularity` and `weekStart` apply to a `timestamp` column: it buckets by
622
+ * civil `day` (the default), `week` or `month` in the display zone, or
623
+ * `instant` for one group per exact moment. `weekStart` is the first weekday,
624
+ * 1=Monday (default) to 7=Sunday.
625
+ */
626
+ group?: {
627
+ enabled?: boolean; index?: number; explode?: boolean;
628
+ granularity?: 'day' | 'week' | 'month' | 'instant';
629
+ weekStart?: number;
630
+ } | boolean;
612
631
  /** Use this column as a pivot dimension, and where it sits among several. */
613
632
  pivot?: { enabled?: boolean; index?: number } | boolean;
614
633
  /** The reduction shown in the totals row and in group footers. */
@@ -659,6 +678,49 @@ export interface Column {
659
678
  upper?: number;
660
679
  warnLower?: number;
661
680
  warnUpper?: number;
681
+ /**
682
+ * For a rolling time-series kind (`rollingSum`/`rollingAvg`/`rollingMin`/
683
+ * `rollingMax`/`windowCoverage`/`cumulativeToDate`/`periodOverPeriod`,
684
+ * BACKLOG-0000748), the column whose order defines the series — dates,
685
+ * sequence numbers, timestamps. **Required**: the screen sort is never used,
686
+ * because a rolling figure would then change on every header click, so a
687
+ * rolling column with no `orderBy` reports null and warns.
688
+ */
689
+ orderBy?: string;
690
+ /**
691
+ * For the rolling window kinds, the window to aggregate over: the last `span`
692
+ * rows (`count`), the last `span` ms — or `minutes` — of the `orderBy` axis
693
+ * (`time`), or everything so far (`session`). The first rows of a series
694
+ * carry a partial window, stamped by a `windowCoverage` companion rather than
695
+ * dressed as full.
696
+ */
697
+ window?: {
698
+ kind: 'count' | 'time' | 'session';
699
+ span?: number;
700
+ minutes?: number;
701
+ };
702
+ /**
703
+ * For a rolling kind, whether the series is computed per group (`'group'`,
704
+ * the default — partitioned by the grid's active grouping) or across the
705
+ * whole dataset (`'all'`).
706
+ */
707
+ within?: 'group' | 'all';
708
+ /**
709
+ * For `kind: 'rollingQuantile'` (and its `windowApproximate` companion), the
710
+ * quantile in `[0, 1]`, defaulting to the median (`0.5`). Exact while the
711
+ * window is small; past an internal span cap, and for a session window, the
712
+ * value comes from a sketch and is stamped by a `windowApproximate` column.
713
+ */
714
+ q?: number;
715
+ /**
716
+ * For a `fit*` kind (BACKLOG-0000812), the regression model the shadow reads
717
+ * — predictors, response, method and confidence. Its predictors/response may
718
+ * also be given directly on this object.
719
+ */
720
+ model?: RegressionSpec;
721
+ predictors?: string[];
722
+ response?: string;
723
+ method?: 'ols' | 'wls' | 'robust' | 'quantile';
662
724
  };
663
725
  /**
664
726
  * A running total down the grid **as it is currently ordered**.
@@ -719,7 +781,7 @@ export interface ResolvedColumn {
719
781
  edit: ColumnEditSpec;
720
782
  sort: ColumnSortSpec;
721
783
  filter: ColumnFilterSpec;
722
- group: { enabled: boolean; index: number; explode: boolean };
784
+ group: { enabled: boolean; index: number; explode: boolean; granularity?: 'day' | 'week' | 'month' | 'instant'; weekStart?: number };
723
785
  pivot: { enabled: boolean; index: number };
724
786
  total: TotalName | TotalFn | null;
725
787
  /**
@@ -2100,10 +2162,25 @@ export interface ColumnState {
2100
2162
  variant?: VariantSpec | null;
2101
2163
  }
2102
2164
 
2165
+ /**
2166
+ * A persisted banded-header node (§15, BACKLOG-0000739): a band with a `columns`
2167
+ * list whose members are leaf ids or nested bands. This is what round-trips a
2168
+ * drag-created group through a saved view.
2169
+ */
2170
+ export interface ColumnGroupState {
2171
+ id: string;
2172
+ title: string;
2173
+ collapsible: boolean;
2174
+ openByDefault: boolean;
2175
+ columns: Array<string | ColumnGroupState>;
2176
+ }
2177
+
2103
2178
  export interface GridState {
2104
2179
  version: number;
2105
2180
  columns?: ColumnState[];
2106
2181
  columnOrder?: string[];
2182
+ /** The banded-header tree, when the grid has one (BACKLOG-0000739). */
2183
+ columnGroups?: ColumnGroupState[];
2107
2184
  filters?: FilterSet;
2108
2185
  quick?: string;
2109
2186
  sort?: SortEntry[];
@@ -2400,6 +2477,14 @@ export interface StatisticsApi {
2400
2477
  */
2401
2478
  shadow(colId: string, kind: ShadowKind, rowKey: string,
2402
2479
  scope?: 'all' | 'filtered', spec?: object): unknown;
2480
+ /**
2481
+ * One regression shadow value for a row, by key (BACKLOG-0000812): the
2482
+ * predicted value, residual, or Cook's-distance influence flag from the fitted
2483
+ * model, over the filtered rows. Null for a row outside the fit.
2484
+ */
2485
+ fitShadow(kind: 'fitPredicted' | 'fitResidual' | 'fitInfluence'
2486
+ | 'fitStdResidual' | 'fitLeverage' | 'fitCooksD',
2487
+ rowKey: string, spec: RegressionSpec): number | boolean | null;
2403
2488
  /** A running total at one row, down the grid as it is currently ordered. */
2404
2489
  running(colId: string, kind: 'total' | 'percent', rowKey: string): number | null;
2405
2490
  /** Make the current values the new baseline: "mark all". */
@@ -2460,6 +2545,16 @@ export interface StatisticsApi {
2460
2545
  covariance(a: string, b: string, opts?: { population?: boolean }): number | null;
2461
2546
  /** Least-squares fit of `b` on `a`: in finance, beta and alpha. */
2462
2547
  regression(a: string, b: string): RegressionFit | null;
2548
+ /**
2549
+ * Fit a multi-predictor linear model over the filtered rows and return the
2550
+ * full diagnostic set — coefficients with standard errors, t and p; R² and
2551
+ * adjusted R²; per-row fitted values, residuals, leverage and Cook's D; VIF
2552
+ * per predictor; a Breusch–Pagan heteroscedasticity flag; and, for a single
2553
+ * predictor, a pointwise confidence band. `method` is `ols`, `wls` (needs a
2554
+ * `weights` column) or `robust`; `quantile` is reserved and the regularised
2555
+ * families refuse. Null on degenerate input (BACKLOG-0000792).
2556
+ */
2557
+ regressionModel(spec: RegressionSpec): RegressionModel | null;
2463
2558
  /** Spearman's rank correlation, which one outlier cannot drag. */
2464
2559
  spearman(a: string, b: string): number | null;
2465
2560
  /** Kendall's tau-b. Null past 5,000 rows: it is quadratic. */
@@ -2687,7 +2782,47 @@ export type ShadowKind =
2687
2782
  * `{lower, upper}` (and optional inner `{warnLower, warnUpper}`) off the
2688
2783
  * shadow declaration; centred-target ± tolerance is a deliberate follow-up.
2689
2784
  */
2690
- | 'specStatus';
2785
+ | 'specStatus'
2786
+ /**
2787
+ * Rolling time-series aggregates over a stated `orderBy` (BACKLOG-0000748,
2788
+ * Phase 1), computed in one ordered pass the grid caches by row key and never
2789
+ * over the screen sort. `rollingSum`/`rollingAvg`/`rollingMin`/`rollingMax`
2790
+ * reduce the `window`; `windowCoverage` reports how much of the requested
2791
+ * window a row actually covers (so a partial window is never dressed as full);
2792
+ * `cumulativeToDate` is the running total to the row; `periodOverPeriod` is the
2793
+ * change on the previous period (lag-1 in Phase 1). Sortable, filterable,
2794
+ * groupable and exportable like any cell.
2795
+ */
2796
+ | 'rollingSum' | 'rollingAvg' | 'rollingMin' | 'rollingMax'
2797
+ | 'windowCoverage' | 'cumulativeToDate' | 'periodOverPeriod'
2798
+ /**
2799
+ * A rolling quantile over the `orderBy` window (BACKLOG-0000748) — a trailing
2800
+ * median or p95, the quantile set by `q`. Exact while the window is small;
2801
+ * past an internal span cap, and for a session window, it comes from a KLL
2802
+ * sketch and `windowApproximate` reports which rows are approximate, so a
2803
+ * sketched quantile is never presented as exact.
2804
+ */
2805
+ | 'rollingQuantile' | 'windowApproximate'
2806
+ /**
2807
+ * Model-backed regression shadows (BACKLOG-0000812): the predicted value, the
2808
+ * residual, and a Cook's-distance influence flag for the row, read from the
2809
+ * fitted model named on the shadow declaration (`shadow: { kind:
2810
+ * 'fitResidual', model: { predictors, response, method } }`). They follow the
2811
+ * grid's filters — the model refits over the filtered rows — and are
2812
+ * sortable, filterable, groupable and exportable like any cell. Null for a row
2813
+ * outside the fit. `fitInfluence` flags Cook's D > 4/n by default (overridable
2814
+ * via `threshold`); "not influential" (`false`) and "cannot tell" (`null`)
2815
+ * stay distinct.
2816
+ *
2817
+ * `fitStdResidual`, `fitLeverage` and `fitCooksD` (BACKLOG-0000872) surface
2818
+ * the diagnostics the engine already computes — the internally studentised
2819
+ * residual `eᵢ/(s·√(1−hᵢ))`, the hat-matrix leverage `hᵢ`, and Cook's distance
2820
+ * — as their own numeric columns, so the scale-location and
2821
+ * residuals-vs-leverage plots bind to real columns. Null where there is no
2822
+ * spread to standardise against.
2823
+ */
2824
+ | 'fitPredicted' | 'fitResidual' | 'fitInfluence'
2825
+ | 'fitStdResidual' | 'fitLeverage' | 'fitCooksD';
2691
2826
 
2692
2827
  /** The three verdicts a `specStatus` shadow can report. */
2693
2828
  export type SpecStatus = 'PASS' | 'WARN' | 'FAIL';
@@ -2703,6 +2838,83 @@ export interface RegressionFit {
2703
2838
  n: number;
2704
2839
  }
2705
2840
 
2841
+ /** The specification of a multi-predictor model (BACKLOG-0000792). */
2842
+ export interface RegressionSpec {
2843
+ /** The predictor column ids. */
2844
+ predictors: string[];
2845
+ /** The response column id. */
2846
+ response: string;
2847
+ /** `ols` (default), `wls` or `robust`. `quantile` is reserved (coming next). */
2848
+ method?: 'ols' | 'wls' | 'robust' | 'quantile';
2849
+ /** A weights column id, required for `wls`. */
2850
+ weights?: string;
2851
+ /** The confidence level for the band; 0.95 by default. */
2852
+ confidence?: number;
2853
+ }
2854
+
2855
+ /** One fitted coefficient, with the uncertainty around it. */
2856
+ export interface RegressionCoefficient {
2857
+ /** `(intercept)` or the predictor's column id. */
2858
+ name: string;
2859
+ estimate: number;
2860
+ stdError: number;
2861
+ /** estimate ÷ standard error. */
2862
+ t: number;
2863
+ /** Two-sided Student-t p-value; a number with a documented method, not a verdict. */
2864
+ p: number;
2865
+ /**
2866
+ * The Wald confidence interval at the model's confidence level
2867
+ * (BACKLOG-0000872) — the whiskers a coefficient forest plot draws. Null when
2868
+ * there is no residual degree of freedom to form a critical value.
2869
+ */
2870
+ lower: number | null;
2871
+ upper: number | null;
2872
+ }
2873
+
2874
+ /** A pointwise confidence band for the mean response of a single-predictor fit. */
2875
+ export interface RegressionBand {
2876
+ confidence: number;
2877
+ points: { x: number; yhat: number; lower: number; upper: number }[];
2878
+ }
2879
+
2880
+ /** The Breusch–Pagan heteroscedasticity test result. */
2881
+ export interface Heteroscedasticity {
2882
+ statistic: number;
2883
+ df: number;
2884
+ p: number;
2885
+ /** True when the test rejects homoscedasticity at the 0.05 level. */
2886
+ heteroscedastic: boolean;
2887
+ }
2888
+
2889
+ /** A fitted multi-predictor linear model and its diagnostics (BACKLOG-0000792). */
2890
+ export interface RegressionModel {
2891
+ method: string;
2892
+ coefficients: RegressionCoefficient[];
2893
+ r2: number;
2894
+ adjR2: number;
2895
+ n: number;
2896
+ /** Residual degrees of freedom, n − p. */
2897
+ df: number;
2898
+ /** Residual variance, RSS ÷ df. */
2899
+ sigma2: number;
2900
+ fitted: number[];
2901
+ residuals: number[];
2902
+ /** Hat-diagonal leverage per row. */
2903
+ leverage: number[];
2904
+ /** Cook's distance per row; null where it cannot be computed. */
2905
+ cooksD: (number | null)[];
2906
+ /** Variance-inflation factor per predictor; Infinity when exactly collinear. */
2907
+ vif: number[];
2908
+ heteroscedasticity: Heteroscedasticity | null;
2909
+ band: RegressionBand | null;
2910
+ /** Per-row weights actually used (robust/WLS), or null for OLS. */
2911
+ weights: number[] | null;
2912
+ predictors: string[];
2913
+ response: string;
2914
+ /** The physical rows the diagnostics are aligned to, in order. */
2915
+ rows: number[];
2916
+ }
2917
+
2706
2918
  export interface ProcessCapability {
2707
2919
  n: number;
2708
2920
  mean: number;
@@ -3092,7 +3304,7 @@ export type EventName =
3092
3304
  | 'column:moved' | 'column:resized' | 'column:visible' | 'column:pinned'
3093
3305
  | 'column:grouped' | 'column:pivoted' | 'column:filter:open' | 'column:menu:open'
3094
3306
  | 'pivot:drill'
3095
- | 'columns:changed' | 'columns:tagged' | 'header:contextmenu'
3307
+ | 'columns:changed' | 'columns:tagged' | 'columngroup:changed' | 'header:contextmenu'
3096
3308
  /* Selection and view */
3097
3309
  | 'selection:changed' | 'range:changed' | 'clipboard:copy'
3098
3310
  | 'page:changed' | 'scroll' | 'scroll:end' | 'size:changed'
@@ -3322,6 +3534,22 @@ export interface ColumnsApi {
3322
3534
  show(ids: string | string[]): void;
3323
3535
  hide(ids: string | string[]): void;
3324
3536
  move(id: string, to: number): void;
3537
+ /**
3538
+ * Wrap leaf columns in a banded header, or add them to an existing band
3539
+ * (BACKLOG-0000739). Header banding, not row grouping (see {@link group}); the
3540
+ * band is a {@link ColumnGroup} node so a drag-, keyboard- or config-built band
3541
+ * is the same tree, and it round-trips through a saved view. Emits
3542
+ * `columngroup:changed`.
3543
+ */
3544
+ groupColumns(ids: string | string[], opts?: { title?: string; at?: number; groupId?: string }): string | null;
3545
+ /** Take a leaf out of its band; a band emptied by the move is dissolved. */
3546
+ ungroupColumn(id: string): void;
3547
+ /** Rename a banded header. */
3548
+ renameGroup(groupId: string, title: string): void;
3549
+ /** Dissolve a band, returning its columns to the enclosing level in place. */
3550
+ dissolveGroup(groupId: string): void;
3551
+ /** Move a whole band among its siblings, its columns travelling as a block. */
3552
+ moveGroup(groupId: string, to: number): void;
3325
3553
  pin(id: string, side: 'start' | 'end' | null): void;
3326
3554
  resize(id: string, px: number): void;
3327
3555
  /**
@@ -5100,7 +5328,7 @@ export function resolveCatalogue(tag?: string): Record<string, unknown> | null;
5100
5328
  export type ChartType =
5101
5329
  | 'line' | 'step' | 'area' | 'rangeArea'
5102
5330
  | 'bar' | 'horizontalBar' | 'waterfall'
5103
- | 'scatter' | 'bubble'
5331
+ | 'scatter' | 'bubble' | 'forest'
5104
5332
  | 'combo' | 'pareto'
5105
5333
  | 'histogram' | 'boxplot' | 'heatmap'
5106
5334
  | 'qq' | 'ecdf' | 'lorenz' | 'correlogram' | 'control' | 'capability' | 'movingRange'
@@ -5259,6 +5487,29 @@ export interface ChartSpec {
5259
5487
  * through the order they happened to be listed in.
5260
5488
  */
5261
5489
  fit?: boolean | 'line';
5490
+ /**
5491
+ * A pointwise confidence band, drawn as a varying-width ribbon beneath the fit
5492
+ * line (BACKLOG-0000812). Fed by a fitted model's own interval — the `band`
5493
+ * from {@link StatisticsApi.regressionModel}, or as produced by
5494
+ * {@link regressionPlots} — so the ribbon and the diagnostics report the one
5495
+ * computation rather than a slope redrawn here. `line: false` suppresses the
5496
+ * band's own centre line, for a chart that already draws the fit with `fit`.
5497
+ *
5498
+ * Only where the x axis is numeric, for the same reason `fit` is.
5499
+ */
5500
+ band?: (RegressionBand & { line?: boolean }) | null;
5501
+ /**
5502
+ * An explicit point set, bypassing the by-column binder (BACKLOG-0000872): a
5503
+ * cartesian chart whose values are not a grid column — a scale-location plot's
5504
+ * √|standardised residual|, a coefficient forest's per-coefficient estimate —
5505
+ * hands its points in directly. Each is `{x, y}` with an optional `label`,
5506
+ * `size` (a bubble's third channel) and `lower`/`upper` (interval bounds the
5507
+ * error-bar primitive reads). Numeric `x` throughout gives a continuous axis.
5508
+ */
5509
+ points?: {
5510
+ x: number | string; y?: number; label?: string;
5511
+ size?: number; lower?: number; upper?: number; key?: string;
5512
+ }[];
5262
5513
  /**
5263
5514
  * Whiskers showing the uncertainty in each mark. `true` computes a confidence
5264
5515
  * interval from the readings behind the mark; `of` takes a symmetric margin
@@ -5422,6 +5673,43 @@ declare module 'lattice-grid/modules/charts' {
5422
5673
  columns: string[];
5423
5674
  reason: string | null;
5424
5675
  };
5676
+ /**
5677
+ * Turn a fitted regression model into diagnostic chart specs ready for
5678
+ * `createChart` (BACKLOG-0000812). Pass a precomputed `model`, or a `spec` to
5679
+ * fit one over the grid, and the `fitted` and `residual` fit-shadow column ids
5680
+ * the residual and QQ plots draw over.
5681
+ *
5682
+ * The presets that map onto grid columns come back as drawable specs: `fit`
5683
+ * (the fit line with its confidence band), `residualsFitted`, `qq`, and
5684
+ * `multicollinearity` (a correlogram over the predictors, with the model's
5685
+ * `vif` alongside). The three that need a per-row or per-coefficient quantity
5686
+ * the grid has no column for — `scaleLocation`, `residualsLeverage`,
5687
+ * `coefficientForest` — come back with a null `spec` and a stable `reason`,
5688
+ * rather than silently dropped.
5689
+ */
5690
+ export function regressionPlots(
5691
+ grid: Grid,
5692
+ opts?: {
5693
+ model?: RegressionModel;
5694
+ spec?: RegressionSpec;
5695
+ fitted?: string;
5696
+ residual?: string;
5697
+ rows?: object[] | ((grid: Grid) => object[]);
5698
+ confidence?: number;
5699
+ },
5700
+ ): {
5701
+ model: RegressionModel | null;
5702
+ plots: Record<
5703
+ 'fit' | 'residualsFitted' | 'qq' | 'multicollinearity'
5704
+ | 'scaleLocation' | 'residualsLeverage' | 'coefficientForest',
5705
+ {
5706
+ spec: ChartSpec | null;
5707
+ reason: string | null;
5708
+ vif?: number[] | null;
5709
+ coefficients?: RegressionCoefficient[] | null;
5710
+ }
5711
+ >;
5712
+ };
5425
5713
  export function registerScheme(name: string, colours: readonly string[]): void;
5426
5714
  export function resolveScheme(spec?: object): object;
5427
5715
  export function schemeNames(): string[];
@@ -5486,6 +5774,31 @@ declare module 'lattice-grid/modules/svelte' {
5486
5774
  export default createLatticeAction;
5487
5775
  }
5488
5776
 
5777
+ declare module 'lattice-grid/modules/angular' {
5778
+ /**
5779
+ * Build the Angular standalone component and directive from one shared
5780
+ * controller (BACKLOG-0000805).
5781
+ *
5782
+ * The Angular core namespace and `createGrid` are passed in, for the same
5783
+ * reason as every other adapter: the package ships no dependencies and cannot
5784
+ * import `@angular/core` or the grid. Pass `@angular/common`'s
5785
+ * `isPlatformBrowser` too for an explicit SSR guard; without it the adapter
5786
+ * guards on the presence of a `document`.
5787
+ *
5788
+ * The returned `LatticeGridComponent` (`<lattice-grid [config]="…">`) and
5789
+ * `LatticeGridDirective` (`<div [latticeGrid]="…">`) each expose the live grid
5790
+ * through a `grid` getter — the same `Grid` the vanilla `createGrid` returns,
5791
+ * or null before build — at parity with React's `ref.current.grid`. Grid
5792
+ * events are `@Output`s aliased to their dashed names (`(cell-changed)`).
5793
+ */
5794
+ export function createLatticeGrid(
5795
+ deps: { ng: unknown; createGrid: unknown; isPlatformBrowser?: (id: unknown) => boolean },
5796
+ ): { LatticeGridComponent: unknown; LatticeGridDirective: unknown };
5797
+ export const EVENT_NAMES: readonly string[];
5798
+ export function dashedName(event: string): string;
5799
+ export default createLatticeGrid;
5800
+ }
5801
+
5489
5802
  declare module 'lattice-grid/modules/webcomponent' {
5490
5803
  /**
5491
5804
  * Register `<lattice-grid>`.