@toclocoinc/lattice-grid 1.20.0 → 1.22.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 +1 -1
- package/docs/API.html +33 -1
- package/docs/api-detail.html +24 -1
- package/lattice-grid.d.ts +93 -4
- package/lattice-grid.esm.min.js +804 -172
- package/lattice-grid.min.cjs +803 -172
- package/lattice-grid.min.css +1 -1
- package/lattice-grid.min.js +803 -172
- package/modules/charts.esm.min.js +2 -2
- package/modules/devtools.esm.min.js +2 -2
- package/modules/dhtmlx-compat.esm.min.js +21 -9
- package/modules/htmx.esm.min.js +802 -172
- package/modules/htmx.min.cjs +802 -172
- package/modules/htmx.min.js +802 -172
- package/modules/react.esm.min.js +2 -2
- package/modules/svelte.esm.min.js +2 -2
- package/modules/vue.esm.min.js +2 -2
- package/modules/webcomponent.esm.min.js +803 -172
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
dependencies, no build step required. Optional adapters for React, Vue, Svelte
|
|
5
5
|
and Web Components ship alongside it.
|
|
6
6
|
|
|
7
|
-
Version 1.
|
|
7
|
+
Version 1.22.0 · [latticegrid.dev](https://www.latticegrid.dev) · TOCLOCO Inc
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
package/docs/API.html
CHANGED
|
@@ -4811,6 +4811,7 @@ grid.destroy();
|
|
|
4811
4811
|
<tbody>
|
|
4812
4812
|
<tr><td class="name">headers</td><td class="type">boolean</td><td class="desc"><small>(optional)</small></td></tr>
|
|
4813
4813
|
<tr><td class="name">rows</td><td class="type">'visible' | 'all' | 'selected' | 'range'</td><td class="desc"><small>(optional)</small></td></tr>
|
|
4814
|
+
<tr><td class="name">sanitise</td><td class="type">boolean</td><td class="desc">Apply the CSV/Excel formula-injection guard to copied cells: prefix a field beginning with `=`, `+`, `-`, `@`, a tab or a CR with an apostrophe so a spreadsheet treats it as text. **Off by default** (unlike CSV/Excel export, which default it on), because the clipboard most often round-trips back into a grid or cell range where the apostrophe would corrupt the value. Turn it on when your users paste the clipboard into Excel or Google Sheets. <small>(optional)</small></td></tr>
|
|
4814
4815
|
</tbody>
|
|
4815
4816
|
</table>
|
|
4816
4817
|
</div>
|
|
@@ -5288,6 +5289,36 @@ grid.destroy();
|
|
|
5288
5289
|
</tbody>
|
|
5289
5290
|
</table>
|
|
5290
5291
|
</div>
|
|
5292
|
+
<h3 id="type-DatasetColumnDifference">DatasetColumnDifference</h3>
|
|
5293
|
+
<div class="table-wrap">
|
|
5294
|
+
<table>
|
|
5295
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
5296
|
+
<tbody>
|
|
5297
|
+
<tr><td class="name">column</td><td class="type">string</td><td class="desc">The column id, present on both grids.</td></tr>
|
|
5298
|
+
<tr><td class="name">name</td><td class="type">string</td><td class="desc">The column's display name, or its id.</td></tr>
|
|
5299
|
+
<tr><td class="name">measure</td><td class="type">'pooledStandardMeanDifference' | 'categoricalTotalVariation'</td><td class="desc">The effect size reported for this column's family: the pooled standardised mean difference (Cohen's d) for a numeric column, the total variation of the category mix for a categorical one. Never a p-value.</td></tr>
|
|
5300
|
+
<tr><td class="name">magnitude</td><td class="type">number | null</td><td class="desc">The effect size in its own terms, or null when it has no scale here.</td></tr>
|
|
5301
|
+
<tr><td class="name">distance</td><td class="type">number</td><td class="desc">The total variation distance between the two datasets, 0 to 1 — the common scale both families reduce to, and what the ranking sorts by.</td></tr>
|
|
5302
|
+
<tr><td class="name">direction</td><td class="type">number</td><td class="desc">+1 when dataset A sits above dataset B, −1 below, 0 for a mix.</td></tr>
|
|
5303
|
+
<tr><td class="name">nA</td><td class="type">number</td><td class="desc">How many rows the first grid's side stood on.</td></tr>
|
|
5304
|
+
<tr><td class="name">nB</td><td class="type">number</td><td class="desc">How many rows the second grid's side stood on.</td></tr>
|
|
5305
|
+
<tr><td class="name">reliable</td><td class="type">boolean</td><td class="desc">False when either side is too small to read the difference from.</td></tr>
|
|
5306
|
+
</tbody>
|
|
5307
|
+
</table>
|
|
5308
|
+
</div>
|
|
5309
|
+
<h3 id="type-DatasetComparison">DatasetComparison</h3>
|
|
5310
|
+
<div class="table-wrap">
|
|
5311
|
+
<table>
|
|
5312
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
5313
|
+
<tbody>
|
|
5314
|
+
<tr><td class="name">ranked</td><td class="type">DatasetColumnDifference[]</td><td class="desc">Every shared column, largest difference first.</td></tr>
|
|
5315
|
+
<tr><td class="name">nA</td><td class="type">number</td><td class="desc">How many rows the first grid contributed (its filtered set).</td></tr>
|
|
5316
|
+
<tr><td class="name">nB</td><td class="type">number</td><td class="desc">How many rows the second grid contributed (its filtered set).</td></tr>
|
|
5317
|
+
<tr><td class="name">unmatched</td><td class="type">{ onlyA: string[]; onlyB: string[] }</td><td class="desc">Columns present on only one side, which cannot be compared.</td></tr>
|
|
5318
|
+
<tr><td class="name">measures</td><td class="type">{ numeric: string; categorical: string; common: string }</td><td class="desc">The measure each family reports, and the common scale, named for a legend.</td></tr>
|
|
5319
|
+
</tbody>
|
|
5320
|
+
</table>
|
|
5321
|
+
</div>
|
|
5291
5322
|
<h3 id="type-DataType">DataType</h3>
|
|
5292
5323
|
<div class="table-wrap">
|
|
5293
5324
|
<table>
|
|
@@ -7047,13 +7078,14 @@ grid.destroy();
|
|
|
7047
7078
|
<table>
|
|
7048
7079
|
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
7049
7080
|
<tbody>
|
|
7050
|
-
<tr><td class="name">shadow</td><td class="type">(colId: string, kind: ShadowKind, rowKey: string
|
|
7081
|
+
<tr><td class="name">shadow</td><td class="type">(colId: string, kind: ShadowKind, rowKey: string,</td><td class="desc">One shadow value for one row, by the column it shadows and the kind. For `kind: 'specStatus'`, `spec` carries the `{lower, upper, warnLower, warnUpper}` limits to judge the row's value against; other kinds ignore it.</td></tr>
|
|
7051
7082
|
<tr><td class="name">running</td><td class="type">(colId: string, kind: 'total' | 'percent', rowKey: string): number | null</td><td class="desc">A running total at one row, down the grid as it is currently ordered.</td></tr>
|
|
7052
7083
|
<tr><td class="name">rebase</td><td class="type">(colId?: string): void</td><td class="desc">Make the current values the new baseline: "mark all".</td></tr>
|
|
7053
7084
|
<tr><td class="name">tracking</td><td class="type">(): { columns: string[]; rows: number; forgotten: number }</td><td class="desc">What the shadow histories are costing.</td></tr>
|
|
7054
7085
|
<tr><td class="name">reduce</td><td class="type">(colId: string, fn: string): unknown</td><td class="desc">Reduce a column by a named kernel over the filtered rows.</td></tr>
|
|
7055
7086
|
<tr><td class="name">profile</td><td class="type">(colId: string): ColumnProfile | null</td><td class="desc">Everything worth knowing about one column, in one pass each.</td></tr>
|
|
7056
7087
|
<tr><td class="name">subsetVsPopulation</td><td class="type">(opts?: { columns?: string[] }): SubsetComparison</td><td class="desc">Which columns differ most between the filtered subset and the whole population it was drawn from, ranked by effect size — never by a p-value. The measure is stated per column; a numeric and a categorical column are put on one bounded scale so they rank against each other.</td></tr>
|
|
7088
|
+
<tr><td class="name">datasetVsDataset</td><td class="type">(other: Grid, opts?: { columns?: string[] }): DatasetComparison</td><td class="desc">Which columns differ most between this grid and another, ranked by effect size — never by a p-value (BACKLOG-0000735). The generalisation of {@link subsetVsPopulation} from subset-vs-population to dataset-vs-dataset: two independent grids, yoked by passing one in, no shared store. A numeric column reports a pooled standardised mean difference (Cohen's d, symmetric in the two peers where Glass's delta is not); a categorical column the total variation of its category mix; both land on one bounded scale. Both sides are read over their filtered rows. Only shared columns are ranked; a column on one side alone is returned under `unmatched`.</td></tr>
|
|
7057
7089
|
<tr><td class="name">correlation</td><td class="type">(a: string, b: string): number | null</td><td class="desc">Pearson's correlation between two columns.</td></tr>
|
|
7058
7090
|
<tr><td class="name">covariance</td><td class="type">(a: string, b: string, opts?: { population?: boolean }): number | null</td><td class="desc">Covariance, a correlation before the scales are divided out.</td></tr>
|
|
7059
7091
|
<tr><td class="name">regression</td><td class="type">(a: string, b: string): RegressionFit | null</td><td class="desc">Least-squares fit of `b` on `a`: in finance, beta and alpha.</td></tr>
|
package/docs/api-detail.html
CHANGED
|
@@ -437,7 +437,7 @@
|
|
|
437
437
|
<div class="shell">
|
|
438
438
|
<aside class="rail">
|
|
439
439
|
<p class="rail__brand">Lattice Grid</p>
|
|
440
|
-
<p class="rail__sub">Developer guide · v1.
|
|
440
|
+
<p class="rail__sub">Developer guide · v1.22.0</p>
|
|
441
441
|
<nav>
|
|
442
442
|
<div class="rail__group">
|
|
443
443
|
<span class="rail__label">Start here</span>
|
|
@@ -4864,6 +4864,29 @@ grid.export.clipboard({ rows: 'range' }); <span class="cmt">// copy the
|
|
|
4864
4864
|
grid.export.clipboard({ headers: true, rows: 'selected' });
|
|
4865
4865
|
|
|
4866
4866
|
grid.edit.pasteInto(text); <span class="cmt">// Excel's tiling rules</span></code></pre>
|
|
4867
|
+
</div>
|
|
4868
|
+
<h3 id="clipboard-formula-guard">Guarding against formula injection on paste</h3>
|
|
4869
|
+
<p class="lead-in">
|
|
4870
|
+
By default a copied range round-trips verbatim, so a value beginning <code>=</code>,
|
|
4871
|
+
<code>+</code>, <code>-</code> or <code>@</code> is carried unchanged — the right thing
|
|
4872
|
+
when the paste target is another grid or cell range. When the paste target is a spreadsheet,
|
|
4873
|
+
pass <code>sanitise: true</code> and a leading formula character is neutralised with an
|
|
4874
|
+
apostrophe, so the value cannot be executed as a formula in Excel or Sheets.
|
|
4875
|
+
</p>
|
|
4876
|
+
<div class="example">
|
|
4877
|
+
<p class="example__label">Opt in per copy</p>
|
|
4878
|
+
<pre data-run="js" data-expect="default:=1+1 guarded:'=1+1" data-covers="config:sanitise"><code><span class="kw">const</span> { buildClipboardText } = <span class="kw">await</span> import('../packages/core/src/export/index.js');
|
|
4879
|
+
|
|
4880
|
+
<span class="cmt">// An explicit cell matrix; the formula guard applies to data fields.</span>
|
|
4881
|
+
<span class="kw">const</span> cells = [['=1+1']];
|
|
4882
|
+
|
|
4883
|
+
<span class="cmt">// Off by default: the value round-trips exactly as copied.</span>
|
|
4884
|
+
<span class="kw">const</span> plain = buildClipboardText({}, { rows: 'range', cells });
|
|
4885
|
+
|
|
4886
|
+
<span class="cmt">// sanitise:true prefixes an apostrophe so a spreadsheet stores it as text.</span>
|
|
4887
|
+
<span class="kw">const</span> guarded = buildClipboardText({}, { rows: 'range', cells, sanitise: <span class="kw">true</span> });
|
|
4888
|
+
|
|
4889
|
+
<span class="kw">return</span> `default:${plain} guarded:${guarded}`;</code></pre>
|
|
4867
4890
|
</div>
|
|
4868
4891
|
<div class="why">
|
|
4869
4892
|
<p>Pasting follows the spreadsheet convention: one cell into a range fills the range, one row
|
package/lattice-grid.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.
|
|
2
|
+
* Lattice Grid 1.22.0, type declarations
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
@@ -639,6 +639,17 @@ export interface Column {
|
|
|
639
639
|
* `'filtered'` ranks within what the filters left.
|
|
640
640
|
*/
|
|
641
641
|
scope?: 'all' | 'filtered';
|
|
642
|
+
/**
|
|
643
|
+
* For `kind: 'specStatus'`, the hard specification the row is judged
|
|
644
|
+
* against. `lower`/`upper` are the pass limits (a value beyond either
|
|
645
|
+
* fails); the optional `warnLower`/`warnUpper` are inner thresholds that
|
|
646
|
+
* mark a still-in-spec reading `'WARN'`. Centred-target ± tolerance is a
|
|
647
|
+
* deliberate follow-up and is not read here.
|
|
648
|
+
*/
|
|
649
|
+
lower?: number;
|
|
650
|
+
upper?: number;
|
|
651
|
+
warnLower?: number;
|
|
652
|
+
warnUpper?: number;
|
|
642
653
|
};
|
|
643
654
|
/**
|
|
644
655
|
* A running total down the grid **as it is currently ordered**.
|
|
@@ -2210,8 +2221,13 @@ export interface PushdownSourceConfig {
|
|
|
2210
2221
|
}
|
|
2211
2222
|
|
|
2212
2223
|
export interface StatisticsApi {
|
|
2213
|
-
/**
|
|
2214
|
-
|
|
2224
|
+
/**
|
|
2225
|
+
* One shadow value for one row, by the column it shadows and the kind. For
|
|
2226
|
+
* `kind: 'specStatus'`, `spec` carries the `{lower, upper, warnLower,
|
|
2227
|
+
* warnUpper}` limits to judge the row's value against; other kinds ignore it.
|
|
2228
|
+
*/
|
|
2229
|
+
shadow(colId: string, kind: ShadowKind, rowKey: string,
|
|
2230
|
+
scope?: 'all' | 'filtered', spec?: object): unknown;
|
|
2215
2231
|
/** A running total at one row, down the grid as it is currently ordered. */
|
|
2216
2232
|
running(colId: string, kind: 'total' | 'percent', rowKey: string): number | null;
|
|
2217
2233
|
/** Make the current values the new baseline: "mark all". */
|
|
@@ -2229,6 +2245,18 @@ export interface StatisticsApi {
|
|
|
2229
2245
|
* on one bounded scale so they rank against each other.
|
|
2230
2246
|
*/
|
|
2231
2247
|
subsetVsPopulation(opts?: { columns?: string[] }): SubsetComparison;
|
|
2248
|
+
/**
|
|
2249
|
+
* Which columns differ most between this grid and another, ranked by effect
|
|
2250
|
+
* size — never by a p-value (BACKLOG-0000735). The generalisation of
|
|
2251
|
+
* {@link subsetVsPopulation} from subset-vs-population to dataset-vs-dataset:
|
|
2252
|
+
* two independent grids, yoked by passing one in, no shared store. A numeric
|
|
2253
|
+
* column reports a pooled standardised mean difference (Cohen's d, symmetric
|
|
2254
|
+
* in the two peers where Glass's delta is not); a categorical column the total
|
|
2255
|
+
* variation of its category mix; both land on one bounded scale. Both sides
|
|
2256
|
+
* are read over their filtered rows. Only shared columns are ranked; a column
|
|
2257
|
+
* on one side alone is returned under `unmatched`.
|
|
2258
|
+
*/
|
|
2259
|
+
datasetVsDataset(other: Grid, opts?: { columns?: string[] }): DatasetComparison;
|
|
2232
2260
|
/** Pearson's correlation between two columns. */
|
|
2233
2261
|
correlation(a: string, b: string): number | null;
|
|
2234
2262
|
/** Covariance, a correlation before the scales are divided out. */
|
|
@@ -2336,7 +2364,18 @@ export type ShadowKind =
|
|
|
2336
2364
|
| 'rate' | 'history' | 'firstValue' | 'streak'
|
|
2337
2365
|
/** Where the row sits among the others, over every tracked row. */
|
|
2338
2366
|
| 'rank' | 'rankAsc' | 'rankChange' | 'percentile' | 'quartile'
|
|
2339
|
-
| 'zScore' | 'shareOfTotal'
|
|
2367
|
+
| 'zScore' | 'shareOfTotal'
|
|
2368
|
+
/**
|
|
2369
|
+
* The row's pass/fail verdict against a hard-limit spec, as a value:
|
|
2370
|
+
* `'PASS'`, `'WARN'` or `'FAIL'`. Sortable, filterable, groupable and
|
|
2371
|
+
* exportable, and rolled up by the `passRate`/`failureCount` totals. Reads
|
|
2372
|
+
* `{lower, upper}` (and optional inner `{warnLower, warnUpper}`) off the
|
|
2373
|
+
* shadow declaration; centred-target ± tolerance is a deliberate follow-up.
|
|
2374
|
+
*/
|
|
2375
|
+
| 'specStatus';
|
|
2376
|
+
|
|
2377
|
+
/** The three verdicts a `specStatus` shadow can report. */
|
|
2378
|
+
export type SpecStatus = 'PASS' | 'WARN' | 'FAIL';
|
|
2340
2379
|
|
|
2341
2380
|
export interface RegressionFit {
|
|
2342
2381
|
slope: number;
|
|
@@ -2474,6 +2513,47 @@ export interface SubsetComparison {
|
|
|
2474
2513
|
measures: { numeric: string; categorical: string; common: string };
|
|
2475
2514
|
}
|
|
2476
2515
|
|
|
2516
|
+
export interface DatasetColumnDifference {
|
|
2517
|
+
/** The column id, present on both grids. */
|
|
2518
|
+
column: string;
|
|
2519
|
+
/** The column's display name, or its id. */
|
|
2520
|
+
name: string;
|
|
2521
|
+
/**
|
|
2522
|
+
* The effect size reported for this column's family: the pooled standardised
|
|
2523
|
+
* mean difference (Cohen's d) for a numeric column, the total variation of the
|
|
2524
|
+
* category mix for a categorical one. Never a p-value.
|
|
2525
|
+
*/
|
|
2526
|
+
measure: 'pooledStandardMeanDifference' | 'categoricalTotalVariation';
|
|
2527
|
+
/** The effect size in its own terms, or null when it has no scale here. */
|
|
2528
|
+
magnitude: number | null;
|
|
2529
|
+
/**
|
|
2530
|
+
* The total variation distance between the two datasets, 0 to 1 — the common
|
|
2531
|
+
* scale both families reduce to, and what the ranking sorts by.
|
|
2532
|
+
*/
|
|
2533
|
+
distance: number;
|
|
2534
|
+
/** +1 when dataset A sits above dataset B, −1 below, 0 for a mix. */
|
|
2535
|
+
direction: number;
|
|
2536
|
+
/** How many rows the first grid's side stood on. */
|
|
2537
|
+
nA: number;
|
|
2538
|
+
/** How many rows the second grid's side stood on. */
|
|
2539
|
+
nB: number;
|
|
2540
|
+
/** False when either side is too small to read the difference from. */
|
|
2541
|
+
reliable: boolean;
|
|
2542
|
+
}
|
|
2543
|
+
|
|
2544
|
+
export interface DatasetComparison {
|
|
2545
|
+
/** Every shared column, largest difference first. */
|
|
2546
|
+
ranked: DatasetColumnDifference[];
|
|
2547
|
+
/** How many rows the first grid contributed (its filtered set). */
|
|
2548
|
+
nA: number;
|
|
2549
|
+
/** How many rows the second grid contributed (its filtered set). */
|
|
2550
|
+
nB: number;
|
|
2551
|
+
/** Columns present on only one side, which cannot be compared. */
|
|
2552
|
+
unmatched: { onlyA: string[]; onlyB: string[] };
|
|
2553
|
+
/** The measure each family reports, and the common scale, named for a legend. */
|
|
2554
|
+
measures: { numeric: string; categorical: string; common: string };
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2477
2557
|
export interface FormattingApi {
|
|
2478
2558
|
list(scope?: FormattingScope): FormattingRule[];
|
|
2479
2559
|
all(): Record<FormattingScope, FormattingRule[]>;
|
|
@@ -2679,6 +2759,15 @@ export interface ExcelExportOptions extends Omit<CsvExportOptions, 'delimiter' |
|
|
|
2679
2759
|
export interface ClipboardOptions {
|
|
2680
2760
|
headers?: boolean;
|
|
2681
2761
|
rows?: 'visible' | 'all' | 'selected' | 'range';
|
|
2762
|
+
/**
|
|
2763
|
+
* Apply the CSV/Excel formula-injection guard to copied cells: prefix a field
|
|
2764
|
+
* beginning with `=`, `+`, `-`, `@`, a tab or a CR with an apostrophe so a
|
|
2765
|
+
* spreadsheet treats it as text. **Off by default** (unlike CSV/Excel export,
|
|
2766
|
+
* which default it on), because the clipboard most often round-trips back into
|
|
2767
|
+
* a grid or cell range where the apostrophe would corrupt the value. Turn it
|
|
2768
|
+
* on when your users paste the clipboard into Excel or Google Sheets.
|
|
2769
|
+
*/
|
|
2770
|
+
sanitise?: boolean;
|
|
2682
2771
|
}
|
|
2683
2772
|
|
|
2684
2773
|
// ---------------------------------------------------------------------------
|