@toclocoinc/lattice-grid 1.27.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/LICENSE +13 -13
- package/README.md +1 -1
- package/docs/API.html +234 -16
- package/docs/api-detail.html +61 -4
- package/lattice-grid.d.ts +357 -11
- package/lattice-grid.esm.min.js +2153 -540
- package/lattice-grid.min.cjs +2153 -540
- package/lattice-grid.min.css +1 -1
- package/lattice-grid.min.js +2153 -540
- package/modules/angular.esm.min.js +264 -0
- package/modules/angular.min.cjs +265 -0
- package/modules/angular.min.js +265 -0
- package/modules/charts.esm.min.js +366 -4
- package/modules/charts.min.cjs +365 -4
- package/modules/charts.min.js +365 -4
- package/modules/devtools.esm.min.js +2 -2
- package/modules/devtools.min.cjs +2 -2
- package/modules/devtools.min.js +2 -2
- package/modules/dhtmlx-compat.esm.min.js +4 -4
- package/modules/dhtmlx-compat.min.cjs +4 -4
- package/modules/dhtmlx-compat.min.js +4 -4
- package/modules/htmx.esm.min.js +2153 -540
- package/modules/htmx.min.cjs +2153 -540
- package/modules/htmx.min.js +2153 -540
- package/modules/react.esm.min.js +4 -3
- package/modules/react.min.cjs +4 -3
- package/modules/react.min.js +4 -3
- package/modules/svelte.esm.min.js +4 -3
- package/modules/svelte.min.cjs +4 -3
- package/modules/svelte.min.js +4 -3
- package/modules/vue.esm.min.js +4 -3
- package/modules/vue.min.cjs +4 -3
- package/modules/vue.min.js +4 -3
- package/modules/webcomponent.esm.min.js +2159 -540
- package/modules/webcomponent.min.cjs +2156 -540
- package/modules/webcomponent.min.js +2156 -540
- package/package.json +18 -1
package/LICENSE
CHANGED
|
@@ -27,25 +27,25 @@ and ::1 -- no watermark is shown and no key is required. Development needs no
|
|
|
27
27
|
paperwork.
|
|
28
28
|
|
|
29
29
|
--------------------------------------------------------------------------
|
|
30
|
-
3. WHAT
|
|
30
|
+
3. SERVING ON OTHER HOSTS, AND WHAT A KEY REMOVES
|
|
31
31
|
--------------------------------------------------------------------------
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
You may serve Lattice Grid from any host -- including production, staging,
|
|
34
|
+
internal tools, intranets and private networks -- without a licence key and
|
|
35
|
+
without charge. On any host other than a loopback host (section 2), the grid
|
|
36
|
+
renders in full and displays a trial watermark. Nothing is disabled, degraded
|
|
37
|
+
or withheld: every capability works, watermarked, for as long as you like.
|
|
38
|
+
|
|
39
|
+
A valid licence key issued by TOCLOCO Inc removes that watermark. Removing the
|
|
40
|
+
watermark is the only thing a key does (section 1), so you need one when, and
|
|
41
|
+
only when, you want the watermark gone -- typically for a production or
|
|
42
|
+
customer-facing deployment. Serving watermarked, without a key, is permitted
|
|
43
|
+
rather than a breach.
|
|
37
44
|
|
|
38
45
|
Keys are issued per deployment rather than per developer or per seat. A key
|
|
39
|
-
names the domains it covers and one key covers every developer, every build and
|
|
46
|
+
names the domains it covers, and one key covers every developer, every build and
|
|
40
47
|
every user on them.
|
|
41
48
|
|
|
42
|
-
Without a valid key, the grid renders in full and displays a trial watermark.
|
|
43
|
-
Nothing is disabled, degraded or withheld. That behaviour exists to protect
|
|
44
|
-
your production screens from a licence lapsing at an inconvenient moment; it is
|
|
45
|
-
a courtesy, not a grant of licence. Deploying to a non-loopback host without a
|
|
46
|
-
valid key is a breach of these terms whether or not the software continues to
|
|
47
|
-
work.
|
|
48
|
-
|
|
49
49
|
--------------------------------------------------------------------------
|
|
50
50
|
4. GRANT
|
|
51
51
|
--------------------------------------------------------------------------
|
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.29.0 · [latticegrid.dev](https://www.latticegrid.dev) · TOCLOCO Inc
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
package/docs/API.html
CHANGED
|
@@ -848,7 +848,7 @@ autoInit(document); <span class="cmt">// builds every [data-lattice-grid] under
|
|
|
848
848
|
<tbody>
|
|
849
849
|
<tr><td class="name">statusBar</td><td class="type">boolean | { panels }</td><td class="desc">Composable panels along the bottom. Default set: <code>rowCount</code>, <code>selectedCount</code>, <code>aggregation</code>, <code>comments</code>, <code>updates</code>, <code>progress</code>. Each is silent when it has nothing to report.</td></tr>
|
|
850
850
|
<tr><td class="name">maximise</td><td class="type">boolean</td><td class="dflt">true</td><td class="desc"><code>false</code> removes the rail button and <code>grid.maximise</code>, for an application with its own full-screen mode.</td></tr>
|
|
851
|
-
<tr><td class="name">toolPanel</td><td class="type">boolean | object</td><td class="desc">Side dock. <code>panels</code>: <code>columns</code>, <code>filters</code>, <code>views</code>, <code>quick</code>, <code>formatting</code>, <code>statistics</code>. <code>side: 'left'</code> makes it the icon rail, which also turns on <code>actions</code> (<code>undo</code>, <code>redo</code>, <code>pause</code>, <code>restore</code>, <code>maximise</code>, then the export group: <code>export</code>, <code>excel</code>, <code>clipboard</code>, <code>print</code>: nine in all, and an array takes these names rather than the button labels) and <code>icons</code>. An explicit array <em>replaces</em> that list rather than extending it; a bare <code>'-'</code> in it renders a divider between groups. <code>exportName</code> names the CSV.</td></tr>
|
|
851
|
+
<tr><td class="name">toolPanel</td><td class="type">boolean | object</td><td class="desc">Side dock. <code>panels</code>: <code>columns</code>, <code>filters</code>, <code>views</code>, <code>quick</code>, <code>formatting</code>, <code>statistics</code>, <code>regression</code>. <code>side: 'left'</code> makes it the icon rail, which also turns on <code>actions</code> (<code>undo</code>, <code>redo</code>, <code>pause</code>, <code>restore</code>, <code>maximise</code>, then the export group: <code>export</code>, <code>excel</code>, <code>clipboard</code>, <code>print</code>: nine in all, and an array takes these names rather than the button labels) and <code>icons</code>. An explicit array <em>replaces</em> that list rather than extending it; a bare <code>'-'</code> in it renders a divider between groups. <code>exportName</code> names the CSV. <code>annotate: true</code> adds the native annotation tools — <code>pen</code>, <code>arrow</code>, <code>rect</code>, <code>highlight</code> — to the rail as toggle buttons (pressed while in use, pressed again to exit); they also appear automatically for the duration of a presentation.</td></tr>
|
|
852
852
|
<tr><td class="name">groupPanel</td><td class="type">boolean | object</td><td class="desc">A drag-and-drop group-by strip above the column header — the row-group panel. Drag a heading into it to group by that column; the active groups show as removable, reorderable chips, and reordering the chips changes the nesting order. It is keyboard-operable — arrows move between chips, <code>Shift</code> with an arrow reorders, <code>Delete</code> ungroups, and an add control groups any column — and every change is announced through the live region. Off by default and non-breaking; it drives the same model as <code>grid.columns.group()</code> and reimplements nothing. The object form takes <code>hint</code>, the placeholder shown while nothing is grouped.</td></tr>
|
|
853
853
|
<tr><td class="name">kpis</td><td class="type">StatConfig[]</td><td class="desc">A built-in KPI/stat strip: a labelled band of stat tiles the grid places for you above the column header. Each entry is a <code>createStat</code> spec — <code>of</code>, <code>fn</code>, <code>title</code>, <code>interval</code>, <code>footer</code>, <code>format</code> and the rest, minus <code>grid</code> and <code>container</code>, which the grid supplies — so a strip tile and a hand-placed one are the same object. The tiles follow the grid's filters, recomputing on every change like a stand-alone stat does. Off by default and non-breaking; it reuses <code>createStat</code> and reimplements no compute.</td></tr>
|
|
854
854
|
<tr><td class="name">timeZone</td><td class="type">string</td><td class="desc">An IANA zone every date column formats and parses in, so a grid shows one zone whatever the viewer's machine says. Individual columns may override it.</td></tr>
|
|
@@ -990,7 +990,7 @@ autoInit(document); <span class="cmt">// builds every [data-lattice-grid] under
|
|
|
990
990
|
<tr><td class="name">sort</td><td class="desc"><code>enabled</code>, <code>direction</code>, <code>order</code>, <code>nullsFirst</code></td></tr>
|
|
991
991
|
<tr><td class="name">filter</td><td class="desc"><code>enabled</code>, <code>type</code>, <code>props</code></td></tr>
|
|
992
992
|
<tr><td class="name">layout</td><td class="desc"><code>width</code>, <code>min</code>, <code>max</code>, <code>flex</code>, <code>pin</code>, <code>hidden</code>, <code>resizable</code>, <code>movable</code>, <code>lockVisible</code>, <code>lockPosition</code>. A <code>pin</code> of <code>'start'</code> or <code>'end'</code> holds the viewport edge while there is something to scroll; where the columns do not fill the grid, spare width falls beyond the last column rather than in front of it.</td></tr>
|
|
993
|
-
<tr><td class="name">header</td><td class="desc"><code>template</code>, <code>render</code>, <code>props</code>, <code>class</code>, <code>tooltip</code>, <code>align</code
|
|
993
|
+
<tr><td class="name">header</td><td class="desc"><code>template</code>, <code>render</code>, <code>props</code>, <code>class</code>, <code>tooltip</code>, <code>align</code>. <code>render</code> draws a custom heading and may be a <strong>function</strong> or a <strong>component</strong> (a class with a <code>render</code> method); the two forms are interchangeable and each may either append to the passed heading element itself (returning nothing) or <em>return</em> an <code>Element</code> (attached for you) or a <code>string</code> (used as the heading text). <code>class</code> adds a class to the heading cell; <code>template</code> is not read.</td></tr>
|
|
994
994
|
</tbody>
|
|
995
995
|
</table>
|
|
996
996
|
</div>
|
|
@@ -1819,6 +1819,8 @@ grid.statistics.shadow('price', 'delta', 'R42'); // one row's shadow value
|
|
|
1819
1819
|
grid.statistics.rebase('price'); // "mark all": today's values become the baseline
|
|
1820
1820
|
grid.statistics.tracking(); // { columns, rows, forgotten }</code></pre>
|
|
1821
1821
|
<p>The <code>statistics</code> tool panel is the end-user half of <code>profile()</code>: a column picker, the twelve figures and a histogram of the column's shape, all following the filters. Add it with <code>toolPanel: { panels: ['columns', 'statistics'] }</code>.</p>
|
|
1822
|
+
<p>The <code>regression</code> tool panel is its multi-column sibling (BACKLOG-0000812): it fits the model you name and shows the coefficient table — each term's estimate ± standard error with its t and p — alongside R² and adjusted R², the variance-inflation factor per predictor, and the Breusch–Pagan heteroscedasticity flag, all over the filtered rows and computed by the one core engine (<code>grid.statistics.regressionModel</code>). Name the model on the panel: <code>toolPanel: { panels: ['columns', { name: 'regression', props: { predictors: ['x1', 'x2'], response: 'y' } }] }</code>. p-values are reported as numbers with a documented method, never a significance verdict.</p>
|
|
1823
|
+
<p>The same fitted model can live in the data as shadow columns (BACKLOG-0000812): <code>shadow: { kind: 'fitPredicted', model: { predictors: ['x'], response: 'y' } }</code>, and likewise <code>fitResidual</code> and <code>fitInfluence</code> — plus <code>fitStdResidual</code>, <code>fitLeverage</code> and <code>fitCooksD</code> (BACKLOG-0000872), which surface the internally studentised residual, the hat-matrix leverage and Cook's distance the engine already computes. They are ordinary numeric/boolean cells — sortable, filterable, groupable, exportable — that read the fit by row key and follow the grid's filters (the model refits over the filtered rows); a row outside the fit reads <code>null</code>. <code>fitInfluence</code> flags Cook's D > 4/n by default (overridable with <code>threshold</code>), keeping "not influential" (<code>false</code>) and "cannot tell" (<code>null</code>) distinct.</p>
|
|
1822
1824
|
<p>It shows the twelve one-pass figures, then <strong>Shape</strong> (skewness, kurtosis, Jarque–Bera), <strong>Robust</strong> (trimmed and winsorized means, MAD, robust outliers), <strong>Concentration</strong> (Gini, HHI, entropy, evenness, top-3 share) and <strong>Capability</strong> where the column declares a <code>spec</code>. A section whose reductions all return null is left out rather than shown as a column of dashes.</p>
|
|
1823
1825
|
<p>Or put it in your own page. <code>mountPanel</code> takes no dock and does not create one: <code>toolPanel</code> may be off entirely, so a statistics readout can sit beside a chart, in your own sidebar, or in a settings dialog, at whatever size you give it. It repaints on the same events the rail does, so it stays in step with filters, edits and saved views without you subscribing to anything.</p>
|
|
1824
1826
|
<pre><code>import { mountPanel } from '@toclocoinc/lattice-grid';
|
|
@@ -1826,7 +1828,7 @@ grid.statistics.tracking(); // { columns, rows, forgotten
|
|
|
1826
1828
|
const stats = mountPanel({ grid, panel: 'statistics', container: sidebar });
|
|
1827
1829
|
stats.refresh(); // for a change the grid does not announce
|
|
1828
1830
|
stats.destroy(); // yours to call: the element belongs to your page</code></pre>
|
|
1829
|
-
<p>Any built-in panel works: <code>columns</code>, <code>filters</code>, <code>views</code>, <code>quick</code>, <code>formatting</code>, <code>statistics</code>, <code>compare</code>, <code>insights</code>, as does a constructor of your own.</p>
|
|
1831
|
+
<p>Any built-in panel works: <code>columns</code>, <code>filters</code>, <code>views</code>, <code>quick</code>, <code>formatting</code>, <code>statistics</code>, <code>regression</code>, <code>compare</code>, <code>insights</code>, as does a constructor of your own.</p>
|
|
1830
1832
|
|
|
1831
1833
|
<h3>The insights panel</h3>
|
|
1832
1834
|
<p>The <code>insights</code> tool panel is the on-screen half of the comparison analytics (§9.9): the API-only <code>subsetVsPopulation()</code>, <code>datasetVsDataset()</code>, <code>capability()</code> and <code>compareGroups()</code> rendered without you building any UI. It is opt-in — off unless you name it. Add it with <code>toolPanel: { panels: ['columns', 'insights'] }</code>.</p>
|
|
@@ -1994,6 +1996,53 @@ createGrid(el, {
|
|
|
1994
1996
|
<div class="note"><p>Positional kinds rank over every <em>tracked</em> row, not over the filtered set: a rank that changed as you filtered would make "the top ten movers" depend on what happened to be on screen, and the column would disagree with itself between two views of the same data. Pass <code>scope: 'filtered'</code> on the shadow spec to rank within what the filters left instead: both answers are legitimate, which is why it is a choice rather than a default.</p></div>
|
|
1995
1997
|
<div class="note"><p>Shadow state is keyed by row key, never by index: after any sort an index-keyed history would report one row's past against another row's present, and the wrong number would be <em>sortable</em>. Memory is capped at 200,000 tracked rows per column; past that the oldest are dropped and <code>tracking().forgotten</code> says how many, rather than a smaller number being reported as though it were the truth.</p></div>
|
|
1996
1998
|
|
|
1999
|
+
<h3 id="rolling-shadows">Rolling time-series columns</h3>
|
|
2000
|
+
<p>A total answers "how much"; a <em>rolling</em> total answers "how much lately, as the series ran" — the seven-day average that smooths a daily figure, the trailing sum, the change on the period before. These are rolling shadow kinds (BACKLOG-0000748): real columns, sortable and filterable and exportable like any other, computed in one ordered pass and cached by row key. They <strong>compose the windowed-aggregate model</strong> the grid already uses for "the average lately" over a live stream, asked instead over a column arranged in a stated order.</p>
|
|
2001
|
+
<p>The order is explicit and required — an <code>orderBy</code> column, never the screen sort, because a rolling figure defined by the current sort would change on every header click and a column sorted on its own rolling value would define itself. The window is the last <code>span</code> rows (<code>count</code>), the last span of the order axis (<code>time</code>), or the whole series so far (<code>session</code>). The first rows carry a <em>partial</em> window; that figure is still emitted, but a <code>windowCoverage</code> companion stamps how much of the window it actually covers, so a two-day average is never shown as a seven-day one. <code>within</code> chooses per-group (the default, partitioned by the grid's grouping) or across the whole dataset.</p>
|
|
2002
|
+
<p>A <code>rollingQuantile</code> (a trailing median, a p95, set by <code>q</code>) is exact while the window is small and comes from a KLL sketch past an internal span cap and for a session window — where a <code>windowApproximate</code> companion reports which rows are approximate, so a sketched quantile is never presented as exact. At a million rows the single ordered pass stays well within the suite's budget (≈380ms for the window aggregates, ≈490ms for the exact rolling median, ≈420ms for the session sketch on the reference bench).</p>
|
|
2003
|
+
<pre><code>columns: [
|
|
2004
|
+
{ field: 'day', type: 'date' },
|
|
2005
|
+
{ field: 'sales', type: 'number' },
|
|
2006
|
+
{ id: 'ma7', title: '7-day avg', shadow: { kind: 'rollingAvg', of: 'sales', orderBy: 'day', window: { kind: 'count', span: 7 } } },
|
|
2007
|
+
{ id: 'cover', title: 'Coverage', shadow: { kind: 'windowCoverage', of: 'sales', orderBy: 'day', window: { kind: 'count', span: 7 } } },
|
|
2008
|
+
{ id: 'p50', title: '30-day median', shadow: { kind: 'rollingQuantile', of: 'sales', orderBy: 'day', window: { kind: 'count', span: 30 }, q: 0.5 } },
|
|
2009
|
+
{ id: 'ytd', title: 'Cumulative', shadow: { kind: 'cumulativeToDate', of: 'sales', orderBy: 'day' } },
|
|
2010
|
+
{ id: 'delta', title: 'vs prev', shadow: { kind: 'periodOverPeriod', of: 'sales', orderBy: 'day' } },
|
|
2011
|
+
]</code></pre>
|
|
2012
|
+
<p>A rolling window is a property of the series, so it is computed over every row before any filter: hiding rows with a filter narrows what you see, never what "the last seven" means. A missing reading is a gap, skipped rather than treated as a zero that would report a plunge and a rebound the series never made.</p>
|
|
2013
|
+
<pre data-run="js" data-expect="11|3.6667|4.6667|0.33|20|2|4" data-covers="export:createHeadlessGrid"><code><span class="kw">const</span> { createHeadlessGrid } = <span class="kw">await</span> import('../packages/core/src/index.js');
|
|
2014
|
+
<span class="cmt">// A short series, ordered by t: values 2,4,5,4,5.</span>
|
|
2015
|
+
<span class="kw">const</span> base = { of: 'v', orderBy: 't', within: 'all' };
|
|
2016
|
+
<span class="kw">const</span> win = { kind: 'count', span: 3 };
|
|
2017
|
+
<span class="kw">const</span> grid = createHeadlessGrid({
|
|
2018
|
+
columns: [
|
|
2019
|
+
{ field: 't', type: 'number' },
|
|
2020
|
+
{ field: 'v', type: 'number' },
|
|
2021
|
+
{ id: 'sum', shadow: { kind: 'rollingSum', window: win, ...base } },
|
|
2022
|
+
{ id: 'avg', shadow: { kind: 'rollingAvg', window: win, ...base } },
|
|
2023
|
+
{ id: 'cov', shadow: { kind: 'windowCoverage', window: win, ...base } },
|
|
2024
|
+
{ id: 'med', shadow: { kind: 'rollingQuantile', window: win, q: 0.5, ...base } },
|
|
2025
|
+
{ id: 'cum', shadow: { kind: 'cumulativeToDate', ...base } },
|
|
2026
|
+
{ id: 'pop', shadow: { kind: 'periodOverPeriod', ...base } },
|
|
2027
|
+
],
|
|
2028
|
+
rows: [
|
|
2029
|
+
{ id: 'r1', t: 1, v: 2 }, { id: 'r2', t: 2, v: 4 }, { id: 'r3', t: 3, v: 5 },
|
|
2030
|
+
{ id: 'r4', t: 4, v: 4 }, { id: 'r5', t: 5, v: 5 },
|
|
2031
|
+
],
|
|
2032
|
+
rowKey: 'id',
|
|
2033
|
+
});
|
|
2034
|
+
<span class="kw">const</span> round4 = (x) => Math.round(x * 10000) / 10000;
|
|
2035
|
+
<span class="kw">const</span> round2 = (x) => Math.round(x * 100) / 100;
|
|
2036
|
+
<span class="kw">return</span> [
|
|
2037
|
+
grid.rows.value('r3', 'sum'), <span class="cmt">// 2+4+5 = 11</span>
|
|
2038
|
+
round4(grid.rows.value('r3', 'avg')), <span class="cmt">// 11/3</span>
|
|
2039
|
+
round4(grid.rows.value('r5', 'avg')), <span class="cmt">// (5+4+5)/3</span>
|
|
2040
|
+
round2(grid.rows.value('r1', 'cov')), <span class="cmt">// 1/3 of the window filled</span>
|
|
2041
|
+
grid.rows.value('r5', 'cum'), <span class="cmt">// running total to the end</span>
|
|
2042
|
+
grid.rows.value('r2', 'pop'), <span class="cmt">// 4 - 2</span>
|
|
2043
|
+
grid.rows.value('r3', 'med'), <span class="cmt">// median of 2,4,5 = 4</span>
|
|
2044
|
+
].join('|');</code></pre>
|
|
2045
|
+
|
|
1997
2046
|
<h2 id="highlight">grid.highlight</h2>
|
|
1998
2047
|
<p>One mechanism for two jobs: the flash a changed cell makes, and a marker you paint deliberately. A target is a cell (<code>{key, colId}</code>), a row (<code>{key}</code>, or a bare row key) or a column (<code>{colId}</code>). Cell beats row beats column, so a specific highlight is never hidden by a broad one laid over it.</p>
|
|
1999
2048
|
<pre><code>createGrid(el, {
|
|
@@ -3404,6 +3453,7 @@ off(); <span class="cmt">// on() returns i
|
|
|
3404
3453
|
<tr><td class="name">licence:changed</td><td class="type">{ info, state }</td><td class="desc">A key was installed, and again when verification settles.</td></tr>
|
|
3405
3454
|
<tr><td class="name">columns:changed</td><td class="desc">The column set was replaced or reordered wholesale.</td></tr>
|
|
3406
3455
|
<tr><td class="name">columns:tagged</td><td class="desc">A column's tags changed.</td></tr>
|
|
3456
|
+
<tr><td class="name">columngroup:changed</td><td class="desc">A banded header was formed, renamed, dissolved, moved, or a column joined or left one — by drag, keyboard or API.</td></tr>
|
|
3407
3457
|
<tr><td class="name">detail:toggled</td><td class="desc">A master-detail row opened or closed.</td></tr>
|
|
3408
3458
|
<tr><td class="name">formatting:changed</td><td class="desc">A conditional formatting rule was added, edited, reordered or restated.</td></tr>
|
|
3409
3459
|
<tr><td class="name">redaction:changed</td><td class="desc">A redaction rule changed.</td></tr>
|
|
@@ -3755,10 +3805,11 @@ const chart = createChart({
|
|
|
3755
3805
|
</div>
|
|
3756
3806
|
|
|
3757
3807
|
<h3>Clicking a chart</h3>
|
|
3758
|
-
<p>A chart emits <code>point:click</code>, <code>point:hover</code>
|
|
3759
|
-
<pre><code>chart.on('
|
|
3760
|
-
grid.filters.set({ col:
|
|
3808
|
+
<p>A chart emits <code>click</code>, <code>hover</code>, <code>leave</code>, <code>focus</code>, <code>draw</code>, <code>drill</code>, <code>brush</code> and <code>legend</code> — there is no <code>point:click</code>, <code>point:hover</code> or <code>series:toggle</code>. The common use is filtering the grid from a mark, which makes the pair two views of one selection rather than a chart beside a table. The <code>click</code> and <code>hover</code> payload is <strong>flat</strong> — <code>{ label, category, column, value, series, rowKeys, native, preventDefault }</code>, with no <code>point</code> wrapper — where <code>column</code> is the grid column the mark filters on and <code>category</code> the value to filter it to.</p>
|
|
3809
|
+
<pre><code>chart.on('click', ({ column, category }) => {
|
|
3810
|
+
grid.filters.set({ col: column, op: 'eq', value: category });
|
|
3761
3811
|
});</code></pre>
|
|
3812
|
+
<p>Simplest of all, set <code>filterOnClick: true</code> in the spec and the chart applies exactly that filter itself on the clicked mark. The <code>click</code> event still fires first, so a handler that calls <code>preventDefault()</code> on the payload takes the click over instead.</p>
|
|
3762
3813
|
|
|
3763
3814
|
<h3 id="chart-a-range">Chart a selected range</h3>
|
|
3764
3815
|
<p>A user who drags out a block of cells — a text column and the numbers beside it — is asking a question a spreadsheet answers with one gesture: chart this. <code>chartRange</code> is that gesture. It reads the selected range, derives the chart from its shape, and returns the same live <code>Chart</code> <code>createChart</code> does, so nothing about it is a second kind of chart.</p>
|
|
@@ -3817,6 +3868,65 @@ createGrid(el, {
|
|
|
3817
3868
|
},
|
|
3818
3869
|
});</code></pre>
|
|
3819
3870
|
|
|
3871
|
+
<h3 id="regression-diagnostics">Regression diagnostics</h3>
|
|
3872
|
+
<p>A regression is not finished when it has coefficients; it is finished when the residuals
|
|
3873
|
+
have been looked at. <code>regressionPlots</code> turns a fitted model — the one
|
|
3874
|
+
<code>grid.statistics.regressionModel</code> returns — into ready chart specs, so the
|
|
3875
|
+
diagnostic pictures are one call rather than a hand-assembled spec each. It reimplements no
|
|
3876
|
+
charting and no statistics: the fit line’s confidence band is the module’s own ribbon
|
|
3877
|
+
primitive fed by the model’s own interval, and the multicollinearity plot is the existing
|
|
3878
|
+
correlogram paired with the model’s VIF.</p>
|
|
3879
|
+
<p>The presets that map onto grid columns are returned as drawable specs: the fit with its
|
|
3880
|
+
band, residuals-vs-fitted (over the <code>fitPredicted</code> and <code>fitResidual</code>
|
|
3881
|
+
shadow columns), a QQ plot of the residuals, the multicollinearity correlogram, and — over the
|
|
3882
|
+
<code>fitStdResidual</code>, <code>fitLeverage</code> and <code>fitCooksD</code> columns
|
|
3883
|
+
(BACKLOG-0000872) — residuals-vs-leverage, a bubble sized by Cook's distance. Scale-location
|
|
3884
|
+
(√|standardised residual| vs fitted) is drawn from explicit points computed off the model,
|
|
3885
|
+
since its y is a transform no column holds; the coefficient <code>forest</code> plot draws one
|
|
3886
|
+
row per coefficient — its estimate with a confidence whisker and a line at zero — through the
|
|
3887
|
+
explicit-bound error-bar primitive. A preset a given model cannot support (no multicollinearity
|
|
3888
|
+
for one predictor, no band for several) is returned as a null spec carrying a machine-readable
|
|
3889
|
+
reason rather than silently dropped.</p>
|
|
3890
|
+
<pre data-run="js" data-expect="scatter|5|scatter|qq|bubble|cook|scatter|forest" data-covers="export:regressionPlots"><code><span class="kw">const</span> { createHeadlessGrid } = <span class="kw">await</span> import('../packages/core/src/index.js');
|
|
3891
|
+
<span class="kw">const</span> { regressionPlots } = <span class="kw">await</span> import('../packages/modules/charts/index.js');
|
|
3892
|
+
|
|
3893
|
+
<span class="cmt">// x=1..5, y=2,4,5,4,5. Shadow columns carry the model's per-row diagnostics —</span>
|
|
3894
|
+
<span class="cmt">// fitted value, residual, standardised residual, leverage and Cook's D — so a</span>
|
|
3895
|
+
<span class="cmt">// diagnostic chart is a plain chart over columns.</span>
|
|
3896
|
+
<span class="kw">const</span> model = { predictors: ['x'], response: 'y' };
|
|
3897
|
+
<span class="kw">const</span> grid = createHeadlessGrid({
|
|
3898
|
+
columns: [
|
|
3899
|
+
{ field: 'x', type: 'number' },
|
|
3900
|
+
{ field: 'y', type: 'number' },
|
|
3901
|
+
{ id: 'yhat', title: 'Fitted', shadow: { kind: 'fitPredicted', model } },
|
|
3902
|
+
{ id: 'resid', title: 'Residual', shadow: { kind: 'fitResidual', model } },
|
|
3903
|
+
{ id: 'sresid', title: 'Std residual', shadow: { kind: 'fitStdResidual', model } },
|
|
3904
|
+
{ id: 'lev', title: 'Leverage', shadow: { kind: 'fitLeverage', model } },
|
|
3905
|
+
{ id: 'cook', title: "Cook's D", shadow: { kind: 'fitCooksD', model } },
|
|
3906
|
+
],
|
|
3907
|
+
rows: [
|
|
3908
|
+
{ id: 'r1', x: 1, y: 2 }, { id: 'r2', x: 2, y: 4 }, { id: 'r3', x: 3, y: 5 },
|
|
3909
|
+
{ id: 'r4', x: 4, y: 4 }, { id: 'r5', x: 5, y: 5 },
|
|
3910
|
+
],
|
|
3911
|
+
rowKey: 'id',
|
|
3912
|
+
source: { mode: 'memory', columnarBelow: 0 },
|
|
3913
|
+
});
|
|
3914
|
+
|
|
3915
|
+
<span class="kw">const</span> { plots } = regressionPlots(grid, {
|
|
3916
|
+
spec: model, fitted: 'yhat', residual: 'resid', stdResidual: 'sresid', leverage: 'lev', cooksD: 'cook',
|
|
3917
|
+
});
|
|
3918
|
+
|
|
3919
|
+
<span class="kw">return</span> [
|
|
3920
|
+
plots.fit.spec.type, <span class="cmt">// scatter, with fit:true and band</span>
|
|
3921
|
+
plots.fit.spec.band.points.length, <span class="cmt">// a band point per row</span>
|
|
3922
|
+
plots.residualsFitted.spec.type, <span class="cmt">// residual vs fitted, a scatter</span>
|
|
3923
|
+
plots.qq.spec.type, <span class="cmt">// a QQ plot of the residuals</span>
|
|
3924
|
+
plots.residualsLeverage.spec.type, <span class="cmt">// bubble, over the diagnostic columns</span>
|
|
3925
|
+
plots.residualsLeverage.spec.size, <span class="cmt">// sized by Cook's D</span>
|
|
3926
|
+
plots.scaleLocation.spec.type, <span class="cmt">// scatter, from explicit points off the model</span>
|
|
3927
|
+
plots.coefficientForest.spec.type, <span class="cmt">// forest, estimate + whisker per coefficient</span>
|
|
3928
|
+
].join('|');</code></pre>
|
|
3929
|
+
|
|
3820
3930
|
<h3>Maps</h3>
|
|
3821
3931
|
<p>A <code>geomap</code> takes an ISO code from one column and a value from another. Alpha-2, alpha-3 and numeric codes are all accepted, and continent codes draw a continent map without any outline data. Country outlines are yours to supply through <code>shapes</code>, because a world atlas is larger than the whole library and this package fetches nothing at runtime.</p>
|
|
3822
3932
|
<p>Codes that match nothing are counted and reported on the chart rather than dropped, a map missing half its data looks exactly like a map of a world where half the data is zero. The full code tables are in <a href="CHART-CODES.md">CHART-CODES.md</a>.</p>
|
|
@@ -4024,7 +4134,7 @@ createGrid(el, {
|
|
|
4024
4134
|
<span class="chip">text</span><span class="chip">number</span><span class="chip">boolean</span><span class="chip">date</span><span class="chip">dateString</span><span class="chip">lookup</span><span class="chip">object</span>
|
|
4025
4135
|
</div>
|
|
4026
4136
|
<div class="chips">
|
|
4027
|
-
<span class="chip chip--new">time</span><span class="chip chip--new">datetime</span><span class="chip chip--new">duration</span>
|
|
4137
|
+
<span class="chip chip--new">time</span><span class="chip chip--new">datetime</span><span class="chip chip--new">timestamp</span><span class="chip chip--new">duration</span>
|
|
4028
4138
|
<span class="chip chip--new">ipv4</span><span class="chip chip--new">cidr</span><span class="chip chip--new">ipv6</span>
|
|
4029
4139
|
<span class="chip chip--new">json</span><span class="chip chip--new">secret</span>
|
|
4030
4140
|
<span class="chip chip--new">hex</span><span class="chip chip--new">hex8</span><span class="chip chip--new">hex16</span><span class="chip chip--new">hex32</span>
|
|
@@ -4212,7 +4322,7 @@ grid.destroy();
|
|
|
4212
4322
|
<h3 id="events-example">Events, executed</h3>
|
|
4213
4323
|
<p class="section-note">Fourteen events raised by ordinary calls, asserted on every build. An event that
|
|
4214
4324
|
stopped firing, or changed name, fails here rather than in a consumer.</p>
|
|
4215
|
-
<pre data-run="js" data-expect="
|
|
4325
|
+
<pre data-run="js" data-expect="15" data-covers="event:sort:changed event:filter:changed event:column:visible event:column:moved event:column:pinned event:columngroup:changed event:config:changed event:rows:changed event:model:changed event:state:reset event:state:changed method:on method:destroy"><code><span class="kw">const</span> { createHeadlessGrid } = <span class="kw">await</span> import('../packages/core/src/index.js');
|
|
4216
4326
|
|
|
4217
4327
|
<span class="kw">const</span> grid = createHeadlessGrid({
|
|
4218
4328
|
rowKey: 'id',
|
|
@@ -4229,6 +4339,7 @@ grid.filters.set({ col: 's', op: 'gt', value: 0 }); <span class="cmt">// filter:
|
|
|
4229
4339
|
grid.columns.hide('n'); <span class="cmt">// column:visible</span>
|
|
4230
4340
|
grid.columns.move('n', 1); <span class="cmt">// column:moved</span>
|
|
4231
4341
|
grid.columns.pin('n', 'left'); <span class="cmt">// column:pinned</span>
|
|
4342
|
+
grid.columns.groupColumns(['n', 's'], { title: 'Both' }); <span class="cmt">// columngroup:changed</span>
|
|
4232
4343
|
grid.set('rowHeight', 30); <span class="cmt">// config:changed</span>
|
|
4233
4344
|
grid.rows.apply({ update: [{ id: '1', s: 9 }] }); <span class="cmt">// rows:changed, model:changed</span>
|
|
4234
4345
|
grid.state.reset(); <span class="cmt">// state:reset, state:changed</span>
|
|
@@ -4371,7 +4482,7 @@ spans.addSpan('R0', 'name', 3, 2); <span class="cmt">// rowspan 3, colspan 2</sp
|
|
|
4371
4482
|
|
|
4372
4483
|
<h3 id="module-exports-example">Every module export, executed</h3>
|
|
4373
4484
|
<p class="section-note">Nine shipped modules, each export resolved against its own barrel on every build.</p>
|
|
4374
|
-
<pre data-run="js" data-expect="
|
|
4485
|
+
<pre data-run="js" data-expect="61" data-covers="export:ContextMenu export:Messages export:Registry export:autoInit export:createGrid export:createLocalViewStorage export:createMessages export:createStat export:deltaOf export:gridElementsWithin export:hydrateTable export:mountPanel export:readTable export:toneOf export:Chart export:PALETTE export:SCHEMES export:TYPES export:createChart export:chartRange export:canChartRange export:deriveRangeSpec export:regressionPlots export:registerScheme export:resolveScheme export:schemeNames export:setDefaultScheme export:HTML_ROW_WARNING_THRESHOLD export:QUERY_CHANGED_EVENT export:SCROLL_NEAR_END_EVENT export:attach export:destroyWithin export:driveInfiniteScroll export:driveOobUpdates export:driveServerMode export:ingestResponse export:initWithin export:queryParams export:restoreStateWithin export:rowsFromFragment export:rowsFromJson export:saveStateWithin export:ATTRIBUTE_CONFIG export:EVENT_PREFIX export:GridElementController export:LatticeGrid export:TAG_NAME export:createLatticeGridElement export:defineLatticeGrid export:domEventName export:observedAttributeNames export:CONSOLE_ACTIVATION export:createDevtools export:expose export:EVENT_NAMES export:handlerName export:createLatticeGrid export:dashedName export:createLatticeAction export:Grid export:warnIfLargeHtmlPayload"><code><span class="cmt">// Every declared export of every shipped module, resolved against its own</span>
|
|
4375
4486
|
<span class="cmt">// barrel. A module that stopped exporting something fails here.</span>
|
|
4376
4487
|
<span class="kw">const</span> modules = [
|
|
4377
4488
|
[<span class="kw">await</span> import('../packages/dom/src/index.js'), [
|
|
@@ -4382,7 +4493,7 @@ spans.addSpan('R0', 'name', 3, 2); <span class="cmt">// rowspan 3, colspan 2</sp
|
|
|
4382
4493
|
]],
|
|
4383
4494
|
[<span class="kw">await</span> import('../packages/modules/charts/index.js'), [
|
|
4384
4495
|
'Chart', 'PALETTE', 'SCHEMES', 'TYPES',
|
|
4385
|
-
'createChart', 'chartRange', 'canChartRange', 'deriveRangeSpec',
|
|
4496
|
+
'createChart', 'chartRange', 'canChartRange', 'deriveRangeSpec', 'regressionPlots',
|
|
4386
4497
|
'registerScheme', 'resolveScheme', 'schemeNames',
|
|
4387
4498
|
'setDefaultScheme',
|
|
4388
4499
|
]],
|
|
@@ -5116,6 +5227,8 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
5116
5227
|
<tr><td class="name">font</td><td class="type">object</td><td class="desc"><small>(optional)</small></td></tr>
|
|
5117
5228
|
<tr><td class="name">margin</td><td class="type">number | { top?: number; right?: number; bottom?: number; left?: number }</td><td class="desc"><small>(optional)</small></td></tr>
|
|
5118
5229
|
<tr><td class="name">fit</td><td class="type">boolean | 'line'</td><td class="desc">A least-squares line through a scatter or bubble chart, one per series. `true` draws the line and its R²; `'line'` draws the line alone. Only where the x axis is numeric: on a band scale the positions are categories in an arbitrary order, and a slope through them would be a slope through the order they happened to be listed in. <small>(optional)</small></td></tr>
|
|
5230
|
+
<tr><td class="name">band</td><td class="type">(RegressionBand & { line?: boolean }) | null</td><td class="desc">A pointwise confidence band, drawn as a varying-width ribbon beneath the fit line (BACKLOG-0000812). Fed by a fitted model's own interval — the `band` from {@link StatisticsApi.regressionModel}, or as produced by {@link regressionPlots} — so the ribbon and the diagnostics report the one computation rather than a slope redrawn here. `line: false` suppresses the band's own centre line, for a chart that already draws the fit with `fit`. Only where the x axis is numeric, for the same reason `fit` is. <small>(optional)</small></td></tr>
|
|
5231
|
+
<tr><td class="name">points</td><td class="type">{</td><td class="desc">An explicit point set, bypassing the by-column binder (BACKLOG-0000872): a cartesian chart whose values are not a grid column — a scale-location plot's √|standardised residual|, a coefficient forest's per-coefficient estimate — hands its points in directly. Each is `{x, y}` with an optional `label`, `size` (a bubble's third channel) and `lower`/`upper` (interval bounds the error-bar primitive reads). Numeric `x` throughout gives a continuous axis. <small>(optional)</small></td></tr>
|
|
5119
5232
|
<tr><td class="name">error</td><td class="type">boolean | { of?: string; confidence?: number }</td><td class="desc">Whiskers showing the uncertainty in each mark. `true` computes a confidence interval from the readings behind the mark; `of` takes a symmetric margin from another column instead. <small>(optional)</small></td></tr>
|
|
5120
5233
|
<tr><td class="name">reference</td><td class="type">{ value: number; label?: string; axis?: 'left' | 'right' }[]</td><td class="desc">Horizontal reference lines. On a dual-axis bar or line chart (see {@link ChartMeasure.axis}) a line naming `axis: 'right'` is placed on the right-hand scale, so it means what the right axis says rather than landing at the same number on the scale it does not belong to. <small>(optional)</small></td></tr>
|
|
5121
5234
|
<tr><td class="name">annotations</td><td class="type">ChartAnnotation[]</td><td class="desc">The declarative annotation layer: reference and target lines, shaded bands and callouts, each naming the axis it reads and each described into the accessible table as a sentence. A value may be a constant or `compute`d from the data it annotates, so it follows the chart as the grid is filtered. <small>(optional)</small></td></tr>
|
|
@@ -5192,7 +5305,7 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
5192
5305
|
<tr><td class="name">edit</td><td class="type">ColumnEditSpec | boolean | string</td><td class="desc">Whether and how the cell can be edited. A string names an editor. <small>(optional)</small></td></tr>
|
|
5193
5306
|
<tr><td class="name">sort</td><td class="type">ColumnSortSpec | boolean</td><td class="desc">Whether the column sorts, and by what comparison. `false` refuses it. <small>(optional)</small></td></tr>
|
|
5194
5307
|
<tr><td class="name">filter</td><td class="type">ColumnFilterSpec | boolean | FilterName</td><td class="desc">Whether the column filters, and with which filter. A string names one. <small>(optional)</small></td></tr>
|
|
5195
|
-
<tr><td class="name">group</td><td class="type">{
|
|
5308
|
+
<tr><td class="name">group</td><td class="type">{</td><td class="desc">Row grouping by this column. `index` fixes its place among several; `explode` gives a multi-value cell one group per value rather than one group for the combination. `granularity` and `weekStart` apply to a `timestamp` column: it buckets by civil `day` (the default), `week` or `month` in the display zone, or `instant` for one group per exact moment. `weekStart` is the first weekday, 1=Monday (default) to 7=Sunday. <small>(optional)</small></td></tr>
|
|
5196
5309
|
<tr><td class="name">pivot</td><td class="type">{ enabled?: boolean; index?: number } | boolean</td><td class="desc">Use this column as a pivot dimension, and where it sits among several. <small>(optional)</small></td></tr>
|
|
5197
5310
|
<tr><td class="name">total</td><td class="type">TotalName | TotalFn</td><td class="desc">The reduction shown in the totals row and in group footers. <small>(optional)</small></td></tr>
|
|
5198
5311
|
<tr><td class="name">groupTotal</td><td class="type">TotalName | TotalFn</td><td class="desc">The reduction for group subtotals — group footers, tree-node rollups and pivot cells — where it should differ from the grand total. Overrides `total` for those scopes only; when omitted the column's `total` applies to both. Lets a column average within each group while the grand total sums, for example (BACKLOG-0000726). <small>(optional)</small></td></tr>
|
|
@@ -5340,15 +5453,29 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
5340
5453
|
</tbody>
|
|
5341
5454
|
</table>
|
|
5342
5455
|
</div>
|
|
5456
|
+
<h3 id="type-ColumnGroupState">ColumnGroupState</h3>
|
|
5457
|
+
<p class="section-note">A persisted banded-header node (§15, BACKLOG-0000739): a band with a `columns` list whose members are leaf ids or nested bands. This is what round-trips a drag-created group through a saved view.</p>
|
|
5458
|
+
<div class="table-wrap">
|
|
5459
|
+
<table>
|
|
5460
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
5461
|
+
<tbody>
|
|
5462
|
+
<tr><td class="name">id</td><td class="type">string</td><td class="desc"></td></tr>
|
|
5463
|
+
<tr><td class="name">title</td><td class="type">string</td><td class="desc"></td></tr>
|
|
5464
|
+
<tr><td class="name">collapsible</td><td class="type">boolean</td><td class="desc"></td></tr>
|
|
5465
|
+
<tr><td class="name">openByDefault</td><td class="type">boolean</td><td class="desc"></td></tr>
|
|
5466
|
+
<tr><td class="name">columns</td><td class="type">Array<string | ColumnGroupState></td><td class="desc"></td></tr>
|
|
5467
|
+
</tbody>
|
|
5468
|
+
</table>
|
|
5469
|
+
</div>
|
|
5343
5470
|
<h3 id="type-ColumnHeaderSpec">ColumnHeaderSpec</h3>
|
|
5344
5471
|
<div class="table-wrap">
|
|
5345
5472
|
<table>
|
|
5346
5473
|
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
5347
5474
|
<tbody>
|
|
5348
|
-
<tr><td class="name">template</td><td class="type">string</td><td class="desc"
|
|
5349
|
-
<tr><td class="name">render</td><td class="type">string | RendererCtor</td><td class="desc"
|
|
5350
|
-
<tr><td class="name">props</td><td class="type">Record<string, unknown></td><td class="desc"
|
|
5351
|
-
<tr><td class="name">class</td><td class="type">string | string[]</td><td class="desc"
|
|
5475
|
+
<tr><td class="name">template</td><td class="type">string</td><td class="desc">Not read by the header renderer; use `render` to draw a custom heading. <small>(optional)</small></td></tr>
|
|
5476
|
+
<tr><td class="name">render</td><td class="type">string | RendererCtor</td><td class="desc">A custom heading renderer: a function, or a component (a class with a `render` method). A string names a registered renderer. Either form draws the same two ways and they are interchangeable — it may append to the passed label element itself and return nothing, or return an `Element` (attached for you) or a `string` (used as the heading text). <small>(optional)</small></td></tr>
|
|
5477
|
+
<tr><td class="name">props</td><td class="type">Record<string, unknown></td><td class="desc">Props passed to `render` as `params.props`. <small>(optional)</small></td></tr>
|
|
5478
|
+
<tr><td class="name">class</td><td class="type">string | string[]</td><td class="desc">A class, or classes, added to the heading cell. <small>(optional)</small></td></tr>
|
|
5352
5479
|
<tr><td class="name">tooltip</td><td class="type">string</td><td class="desc"><small>(optional)</small></td></tr>
|
|
5353
5480
|
<tr><td class="name">align</td><td class="type">Align</td><td class="desc"><small>(optional)</small></td></tr>
|
|
5354
5481
|
</tbody>
|
|
@@ -5426,6 +5553,11 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
5426
5553
|
<tr><td class="name">show</td><td class="type">(ids: string | string[]): void</td><td class="desc"></td></tr>
|
|
5427
5554
|
<tr><td class="name">hide</td><td class="type">(ids: string | string[]): void</td><td class="desc"></td></tr>
|
|
5428
5555
|
<tr><td class="name">move</td><td class="type">(id: string, to: number): void</td><td class="desc"></td></tr>
|
|
5556
|
+
<tr><td class="name">groupColumns</td><td class="type">(ids: string | string[], opts?: { title?: string; at?: number; groupId?: string }): string | null</td><td class="desc">Wrap leaf columns in a banded header, or add them to an existing band (BACKLOG-0000739). Header banding, not row grouping (see {@link group}); the band is a {@link ColumnGroup} node so a drag-, keyboard- or config-built band is the same tree, and it round-trips through a saved view. Emits `columngroup:changed`.</td></tr>
|
|
5557
|
+
<tr><td class="name">ungroupColumn</td><td class="type">(id: string): void</td><td class="desc">Take a leaf out of its band; a band emptied by the move is dissolved.</td></tr>
|
|
5558
|
+
<tr><td class="name">renameGroup</td><td class="type">(groupId: string, title: string): void</td><td class="desc">Rename a banded header.</td></tr>
|
|
5559
|
+
<tr><td class="name">dissolveGroup</td><td class="type">(groupId: string): void</td><td class="desc">Dissolve a band, returning its columns to the enclosing level in place.</td></tr>
|
|
5560
|
+
<tr><td class="name">moveGroup</td><td class="type">(groupId: string, to: number): void</td><td class="desc">Move a whole band among its siblings, its columns travelling as a block.</td></tr>
|
|
5429
5561
|
<tr><td class="name">pin</td><td class="type">(id: string, side: 'start' | 'end' | null): void</td><td class="desc"></td></tr>
|
|
5430
5562
|
<tr><td class="name">resize</td><td class="type">(id: string, px: number): void</td><td class="desc"></td></tr>
|
|
5431
5563
|
<tr><td class="name">decorate</td><td class="type">(id: string, decoration: DecorationName | DecorationSpec | null, opts?: { variant?: VariantSpec }): void</td><td class="desc">Set, change or clear a column's decoration at runtime (§8.7). Pass `null` to clear it back to plain text. Presentation config: it is not on the undo timeline and is not carried in a saved view — use `grid.formatting` for durable, view-persisted conditional styling.</td></tr>
|
|
@@ -6448,6 +6580,7 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
6448
6580
|
<tr><td class="name">version</td><td class="type">number</td><td class="desc"></td></tr>
|
|
6449
6581
|
<tr><td class="name">columns</td><td class="type">ColumnState[]</td><td class="desc"><small>(optional)</small></td></tr>
|
|
6450
6582
|
<tr><td class="name">columnOrder</td><td class="type">string[]</td><td class="desc"><small>(optional)</small></td></tr>
|
|
6583
|
+
<tr><td class="name">columnGroups</td><td class="type">ColumnGroupState[]</td><td class="desc">The banded-header tree, when the grid has one (BACKLOG-0000739). <small>(optional)</small></td></tr>
|
|
6451
6584
|
<tr><td class="name">filters</td><td class="type">FilterSet</td><td class="desc"><small>(optional)</small></td></tr>
|
|
6452
6585
|
<tr><td class="name">quick</td><td class="type">string</td><td class="desc"><small>(optional)</small></td></tr>
|
|
6453
6586
|
<tr><td class="name">sort</td><td class="type">SortEntry[]</td><td class="desc"><small>(optional)</small></td></tr>
|
|
@@ -6511,6 +6644,19 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
6511
6644
|
</tbody>
|
|
6512
6645
|
</table>
|
|
6513
6646
|
</div>
|
|
6647
|
+
<h3 id="type-Heteroscedasticity">Heteroscedasticity</h3>
|
|
6648
|
+
<p class="section-note">The Breusch–Pagan heteroscedasticity test result.</p>
|
|
6649
|
+
<div class="table-wrap">
|
|
6650
|
+
<table>
|
|
6651
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
6652
|
+
<tbody>
|
|
6653
|
+
<tr><td class="name">statistic</td><td class="type">number</td><td class="desc"></td></tr>
|
|
6654
|
+
<tr><td class="name">df</td><td class="type">number</td><td class="desc"></td></tr>
|
|
6655
|
+
<tr><td class="name">p</td><td class="type">number</td><td class="desc"></td></tr>
|
|
6656
|
+
<tr><td class="name">heteroscedastic</td><td class="type">boolean</td><td class="desc">True when the test rejects homoscedasticity at the 0.05 level.</td></tr>
|
|
6657
|
+
</tbody>
|
|
6658
|
+
</table>
|
|
6659
|
+
</div>
|
|
6514
6660
|
<h3 id="type-HighlightApi">HighlightApi</h3>
|
|
6515
6661
|
<div class="table-wrap">
|
|
6516
6662
|
<table>
|
|
@@ -7138,6 +7284,7 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
7138
7284
|
<tr><td class="name">icon</td><td class="type">string | (() => string)</td><td class="desc"><small>(optional)</small></td></tr>
|
|
7139
7285
|
<tr><td class="name">run</td><td class="type">(params: RailActionParams): void</td><td class="desc"></td></tr>
|
|
7140
7286
|
<tr><td class="name">enabled</td><td class="type">(): boolean</td><td class="desc"><small>(optional)</small></td></tr>
|
|
7287
|
+
<tr><td class="name">active</td><td class="type">(): boolean</td><td class="desc">Marks the action as a toggle and reports whether it is currently on. When present the rail renders `aria-pressed` and a pressed style, re-read on every repaint; a one-shot action omits it and is unchanged. This is the hook the native annotation tools use, and it is available to a host button that is itself a toggle. <small>(optional)</small></td></tr>
|
|
7141
7288
|
</tbody>
|
|
7142
7289
|
</table>
|
|
7143
7290
|
</div>
|
|
@@ -7187,6 +7334,33 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
7187
7334
|
</tbody>
|
|
7188
7335
|
</table>
|
|
7189
7336
|
</div>
|
|
7337
|
+
<h3 id="type-RegressionBand">RegressionBand</h3>
|
|
7338
|
+
<p class="section-note">A pointwise confidence band for the mean response of a single-predictor fit.</p>
|
|
7339
|
+
<div class="table-wrap">
|
|
7340
|
+
<table>
|
|
7341
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
7342
|
+
<tbody>
|
|
7343
|
+
<tr><td class="name">confidence</td><td class="type">number</td><td class="desc"></td></tr>
|
|
7344
|
+
<tr><td class="name">points</td><td class="type">{ x: number; yhat: number; lower: number; upper: number }[]</td><td class="desc"></td></tr>
|
|
7345
|
+
</tbody>
|
|
7346
|
+
</table>
|
|
7347
|
+
</div>
|
|
7348
|
+
<h3 id="type-RegressionCoefficient">RegressionCoefficient</h3>
|
|
7349
|
+
<p class="section-note">One fitted coefficient, with the uncertainty around it.</p>
|
|
7350
|
+
<div class="table-wrap">
|
|
7351
|
+
<table>
|
|
7352
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
7353
|
+
<tbody>
|
|
7354
|
+
<tr><td class="name">name</td><td class="type">string</td><td class="desc">`(intercept)` or the predictor's column id.</td></tr>
|
|
7355
|
+
<tr><td class="name">estimate</td><td class="type">number</td><td class="desc"></td></tr>
|
|
7356
|
+
<tr><td class="name">stdError</td><td class="type">number</td><td class="desc"></td></tr>
|
|
7357
|
+
<tr><td class="name">t</td><td class="type">number</td><td class="desc">estimate ÷ standard error.</td></tr>
|
|
7358
|
+
<tr><td class="name">p</td><td class="type">number</td><td class="desc">Two-sided Student-t p-value; a number with a documented method, not a verdict.</td></tr>
|
|
7359
|
+
<tr><td class="name">lower</td><td class="type">number | null</td><td class="desc">The Wald confidence interval at the model's confidence level (BACKLOG-0000872) — the whiskers a coefficient forest plot draws. Null when there is no residual degree of freedom to form a critical value.</td></tr>
|
|
7360
|
+
<tr><td class="name">upper</td><td class="type">number | null</td><td class="desc"></td></tr>
|
|
7361
|
+
</tbody>
|
|
7362
|
+
</table>
|
|
7363
|
+
</div>
|
|
7190
7364
|
<h3 id="type-RegressionFit">RegressionFit</h3>
|
|
7191
7365
|
<div class="table-wrap">
|
|
7192
7366
|
<table>
|
|
@@ -7200,6 +7374,47 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
7200
7374
|
</tbody>
|
|
7201
7375
|
</table>
|
|
7202
7376
|
</div>
|
|
7377
|
+
<h3 id="type-RegressionModel">RegressionModel</h3>
|
|
7378
|
+
<p class="section-note">A fitted multi-predictor linear model and its diagnostics (BACKLOG-0000792).</p>
|
|
7379
|
+
<div class="table-wrap">
|
|
7380
|
+
<table>
|
|
7381
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
7382
|
+
<tbody>
|
|
7383
|
+
<tr><td class="name">method</td><td class="type">string</td><td class="desc"></td></tr>
|
|
7384
|
+
<tr><td class="name">coefficients</td><td class="type">RegressionCoefficient[]</td><td class="desc"></td></tr>
|
|
7385
|
+
<tr><td class="name">r2</td><td class="type">number</td><td class="desc"></td></tr>
|
|
7386
|
+
<tr><td class="name">adjR2</td><td class="type">number</td><td class="desc"></td></tr>
|
|
7387
|
+
<tr><td class="name">n</td><td class="type">number</td><td class="desc"></td></tr>
|
|
7388
|
+
<tr><td class="name">df</td><td class="type">number</td><td class="desc">Residual degrees of freedom, n − p.</td></tr>
|
|
7389
|
+
<tr><td class="name">sigma2</td><td class="type">number</td><td class="desc">Residual variance, RSS ÷ df.</td></tr>
|
|
7390
|
+
<tr><td class="name">fitted</td><td class="type">number[]</td><td class="desc"></td></tr>
|
|
7391
|
+
<tr><td class="name">residuals</td><td class="type">number[]</td><td class="desc"></td></tr>
|
|
7392
|
+
<tr><td class="name">leverage</td><td class="type">number[]</td><td class="desc">Hat-diagonal leverage per row.</td></tr>
|
|
7393
|
+
<tr><td class="name">cooksD</td><td class="type">(number | null)[]</td><td class="desc">Cook's distance per row; null where it cannot be computed.</td></tr>
|
|
7394
|
+
<tr><td class="name">vif</td><td class="type">number[]</td><td class="desc">Variance-inflation factor per predictor; Infinity when exactly collinear.</td></tr>
|
|
7395
|
+
<tr><td class="name">heteroscedasticity</td><td class="type">Heteroscedasticity | null</td><td class="desc"></td></tr>
|
|
7396
|
+
<tr><td class="name">band</td><td class="type">RegressionBand | null</td><td class="desc"></td></tr>
|
|
7397
|
+
<tr><td class="name">weights</td><td class="type">number[] | null</td><td class="desc">Per-row weights actually used (robust/WLS), or null for OLS.</td></tr>
|
|
7398
|
+
<tr><td class="name">predictors</td><td class="type">string[]</td><td class="desc"></td></tr>
|
|
7399
|
+
<tr><td class="name">response</td><td class="type">string</td><td class="desc"></td></tr>
|
|
7400
|
+
<tr><td class="name">rows</td><td class="type">number[]</td><td class="desc">The physical rows the diagnostics are aligned to, in order.</td></tr>
|
|
7401
|
+
</tbody>
|
|
7402
|
+
</table>
|
|
7403
|
+
</div>
|
|
7404
|
+
<h3 id="type-RegressionSpec">RegressionSpec</h3>
|
|
7405
|
+
<p class="section-note">The specification of a multi-predictor model (BACKLOG-0000792).</p>
|
|
7406
|
+
<div class="table-wrap">
|
|
7407
|
+
<table>
|
|
7408
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
7409
|
+
<tbody>
|
|
7410
|
+
<tr><td class="name">predictors</td><td class="type">string[]</td><td class="desc">The predictor column ids.</td></tr>
|
|
7411
|
+
<tr><td class="name">response</td><td class="type">string</td><td class="desc">The response column id.</td></tr>
|
|
7412
|
+
<tr><td class="name">method</td><td class="type">'ols' | 'wls' | 'robust' | 'quantile'</td><td class="desc">`ols` (default), `wls` or `robust`. `quantile` is reserved (coming next). <small>(optional)</small></td></tr>
|
|
7413
|
+
<tr><td class="name">weights</td><td class="type">string</td><td class="desc">A weights column id, required for `wls`. <small>(optional)</small></td></tr>
|
|
7414
|
+
<tr><td class="name">confidence</td><td class="type">number</td><td class="desc">The confidence level for the band; 0.95 by default. <small>(optional)</small></td></tr>
|
|
7415
|
+
</tbody>
|
|
7416
|
+
</table>
|
|
7417
|
+
</div>
|
|
7203
7418
|
<h3 id="type-RejectedRow">RejectedRow</h3>
|
|
7204
7419
|
<p class="section-note">A row a change could not apply, and why. Reported, never thrown.</p>
|
|
7205
7420
|
<div class="table-wrap">
|
|
@@ -7286,7 +7501,7 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
7286
7501
|
<tr><td class="name">edit</td><td class="type">ColumnEditSpec</td><td class="desc"></td></tr>
|
|
7287
7502
|
<tr><td class="name">sort</td><td class="type">ColumnSortSpec</td><td class="desc"></td></tr>
|
|
7288
7503
|
<tr><td class="name">filter</td><td class="type">ColumnFilterSpec</td><td class="desc"></td></tr>
|
|
7289
|
-
<tr><td class="name">group</td><td class="type">{ enabled: boolean; index: number; explode: boolean }</td><td class="desc"></td></tr>
|
|
7504
|
+
<tr><td class="name">group</td><td class="type">{ enabled: boolean; index: number; explode: boolean; granularity?: 'day' | 'week' | 'month' | 'instant'; weekStart?: number }</td><td class="desc"></td></tr>
|
|
7290
7505
|
<tr><td class="name">pivot</td><td class="type">{ enabled: boolean; index: number }</td><td class="desc"></td></tr>
|
|
7291
7506
|
<tr><td class="name">total</td><td class="type">TotalName | TotalFn | null</td><td class="desc"></td></tr>
|
|
7292
7507
|
<tr><td class="name">groupTotal</td><td class="type">TotalName | TotalFn | null</td><td class="desc">The group-subtotal override, or null when group subtotals follow `total` (BACKLOG-0000726).</td></tr>
|
|
@@ -7600,6 +7815,8 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
7600
7815
|
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
7601
7816
|
<tbody>
|
|
7602
7817
|
<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>
|
|
7818
|
+
<tr><td class="name">fitShadow</td><td class="type">(kind: 'fitPredicted' | 'fitResidual' | 'fitInfluence'</td><td class="desc">One regression shadow value for a row, by key (BACKLOG-0000812): the predicted value, residual, or Cook's-distance influence flag from the fitted model, over the filtered rows. Null for a row outside the fit.</td></tr>
|
|
7819
|
+
<tr><td class="name">rowKey</td><td class="type">string, spec: RegressionSpec): number | boolean | null</td><td class="desc"></td></tr>
|
|
7603
7820
|
<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>
|
|
7604
7821
|
<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>
|
|
7605
7822
|
<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>
|
|
@@ -7612,6 +7829,7 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
7612
7829
|
<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>
|
|
7613
7830
|
<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>
|
|
7614
7831
|
<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>
|
|
7832
|
+
<tr><td class="name">regressionModel</td><td class="type">(spec: RegressionSpec): RegressionModel | null</td><td class="desc">Fit a multi-predictor linear model over the filtered rows and return the full diagnostic set — coefficients with standard errors, t and p; R² and adjusted R²; per-row fitted values, residuals, leverage and Cook's D; VIF per predictor; a Breusch–Pagan heteroscedasticity flag; and, for a single predictor, a pointwise confidence band. `method` is `ols`, `wls` (needs a `weights` column) or `robust`; `quantile` is reserved and the regularised families refuse. Null on degenerate input (BACKLOG-0000792).</td></tr>
|
|
7615
7833
|
<tr><td class="name">spearman</td><td class="type">(a: string, b: string): number | null</td><td class="desc">Spearman's rank correlation, which one outlier cannot drag.</td></tr>
|
|
7616
7834
|
<tr><td class="name">kendall</td><td class="type">(a: string, b: string): number | null</td><td class="desc">Kendall's tau-b. Null past 5,000 rows: it is quadratic.</td></tr>
|
|
7617
7835
|
<tr><td class="name">weightedQuantile</td><td class="type">(colId: string, weightId: string, p?: number): number | null</td><td class="desc">A quantile of one column weighted by another; the median by default.</td></tr>
|