@toclocoinc/lattice-grid 1.37.0 → 1.38.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 +182 -6
- package/docs/api-detail.html +44 -1
- package/lattice-grid.d.ts +350 -10
- package/lattice-grid.esm.min.js +693 -40
- package/lattice-grid.min.cjs +690 -40
- package/lattice-grid.min.css +1 -1
- package/lattice-grid.min.js +690 -40
- package/modules/angular.esm.min.js +2 -2
- package/modules/angular.min.cjs +2 -2
- package/modules/angular.min.js +2 -2
- package/modules/chart-alluvial.esm.min.js +1 -1
- package/modules/chart-arc.esm.min.js +1 -1
- package/modules/chart-bubblemap.esm.min.js +1 -1
- package/modules/chart-bump.esm.min.js +1 -1
- package/modules/chart-calendar.esm.min.js +1 -1
- package/modules/chart-decomposition.esm.min.js +1 -1
- package/modules/chart-diverging.esm.min.js +1 -1
- package/modules/chart-dumbbell.esm.min.js +1 -1
- package/modules/chart-fan.esm.min.js +1 -1
- package/modules/chart-hexbin.esm.min.js +1 -1
- package/modules/chart-hexmap.esm.min.js +1 -1
- package/modules/chart-icicle.esm.min.js +1 -1
- package/modules/chart-parallel.esm.min.js +1 -1
- package/modules/chart-ridgeline.esm.min.js +1 -1
- package/modules/chart-roc.esm.min.js +1 -1
- package/modules/chart-slope.esm.min.js +1 -1
- package/modules/chart-splom.esm.min.js +1 -1
- package/modules/chart-waffle.esm.min.js +1 -1
- package/modules/charts.esm.min.js +450 -7
- package/modules/charts.min.cjs +450 -7
- package/modules/charts.min.js +450 -7
- package/modules/data-router.esm.min.js +4 -4
- package/modules/data-router.min.cjs +4 -4
- package/modules/data-router.min.js +4 -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/gantt.esm.min.js +714 -16
- package/modules/gantt.min.cjs +712 -16
- package/modules/gantt.min.js +712 -16
- package/modules/htmx.esm.min.js +687 -40
- package/modules/htmx.min.cjs +687 -40
- package/modules/htmx.min.js +687 -40
- package/modules/kanban.esm.min.js +379 -5
- package/modules/kanban.min.cjs +379 -5
- package/modules/kanban.min.js +379 -5
- package/modules/kpi.esm.min.js +4 -4
- package/modules/kpi.min.cjs +4 -4
- package/modules/kpi.min.js +4 -4
- package/modules/mock-socket.esm.min.js +2 -2
- package/modules/mock-socket.min.cjs +2 -2
- package/modules/mock-socket.min.js +2 -2
- package/modules/react.esm.min.js +2 -2
- package/modules/react.min.cjs +2 -2
- package/modules/react.min.js +2 -2
- package/modules/svelte.esm.min.js +2 -2
- package/modules/svelte.min.cjs +2 -2
- package/modules/svelte.min.js +2 -2
- package/modules/vue.esm.min.js +2 -2
- package/modules/vue.min.cjs +2 -2
- package/modules/vue.min.js +2 -2
- package/modules/webcomponent.esm.min.js +690 -40
- package/modules/webcomponent.min.cjs +690 -40
- package/modules/webcomponent.min.js +690 -40
- 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.38.0 · [latticegrid.dev](https://www.latticegrid.dev) · TOCLOCO Inc
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
package/docs/API.html
CHANGED
|
@@ -386,6 +386,7 @@
|
|
|
386
386
|
<a href="#pagination">grid.pagination</a>
|
|
387
387
|
<a href="#scroll">grid.scroll</a>
|
|
388
388
|
<a href="#export">grid.export</a>
|
|
389
|
+
<a href="#import">grid.import</a>
|
|
389
390
|
<a href="#state">grid.state</a>
|
|
390
391
|
<a href="#history">grid.history</a>
|
|
391
392
|
<a href="#diagnostics">grid.diagnostics</a>
|
|
@@ -1155,6 +1156,7 @@ grid.overlay.hide();</code></pre>
|
|
|
1155
1156
|
<tr><td class="sig">status(key, colId)</td><td class="type">'pending' | null</td><td class="desc">Whether a cell has a write in flight.</td></tr>
|
|
1156
1157
|
<tr><td class="sig">addRow(row)</td><td class="type">string | null</td><td class="desc">Append a row optimistically and persist it (over a source declaring <code>mutate.append</code>). Returns the client temp key; on the server key it fires <code>row:confirmed</code> after rekeying selection, expansion, focus and in-flight cell edits. <code>null</code> when append is unavailable.</td></tr>
|
|
1157
1158
|
<tr><td class="sig">deleteRow(key)</td><td class="type">string | null</td><td class="desc">Delete a row optimistically and persist it (over a source declaring <code>mutate.delete</code>). Tombstones then confirms, or restores on refusal. <code>null</code> when delete is unavailable.</td></tr>
|
|
1159
|
+
<tr><td class="sig">deleteRows(keys?, opts?)</td><td class="type">string[] | Promise</td><td class="desc">The user-gesture delete (what the Delete key and the "Delete row" menu item call), through the cancellable <code>beforeDelete</code> event — on a <strong>memory</strong> grid as well as a remote one. Off until <code>config.rowDelete</code>. Keys default to the selection; returns the keys removed (empty on a veto or when disabled), or a Promise when a handler deferred.</td></tr>
|
|
1158
1160
|
<tr><td class="sig">settleRow(id, ok, reason?, reconcile?)</td><td class="type">boolean</td><td class="desc">Report the outcome of a structural op. Only needed with <code>edit.confirm: 'manual'</code>; the id arrives on <code>row:pending</code>.</td></tr>
|
|
1159
1161
|
<tr><td class="sig">rowStatus(key)</td><td class="type">'pending' | null</td><td class="desc">Whether a row has an append/delete in flight.</td></tr>
|
|
1160
1162
|
<tr><td class="sig">pendingRows()</td><td class="type">OpenRowOp[]</td><td class="desc">Structural ops still awaiting an outcome. Empty unless the source can append or delete.</td></tr>
|
|
@@ -1217,6 +1219,35 @@ grid.destroy();
|
|
|
1217
1219
|
<span class="cmt">// fired: pending:append, confirmed:append, pending:delete, confirmed:delete</span>
|
|
1218
1220
|
<span class="kw">return</span> `${movedTo} selected; ${gone ? 'deleted' : 'still-there'}`;</code></pre>
|
|
1219
1221
|
|
|
1222
|
+
<p class="section-note">
|
|
1223
|
+
<strong>The built-in delete gesture.</strong> <code>deleteRow</code> above only fires
|
|
1224
|
+
<code>beforeDelete</code> on a remote source. For the common case — letting a user delete
|
|
1225
|
+
rows of a <em>memory</em> grid with the Delete key or a "Delete row" menu item, confirmed
|
|
1226
|
+
through the same <code>beforeDelete</code> hook — set <code>config.rowDelete: true</code>.
|
|
1227
|
+
It is off by default because deleting data on a keystroke is destructive; every deletion still
|
|
1228
|
+
flows through <code>beforeDelete</code>, so a handler can confirm or veto it with
|
|
1229
|
+
<code>preventDefault(reason)</code>. <code>grid.edit.deleteRows</code> is the programmatic entry.
|
|
1230
|
+
</p>
|
|
1231
|
+
<pre data-run="js" data-expect="2 rows" data-covers="config:rowDelete"><code><span class="kw">const</span> { createHeadlessGrid } = <span class="kw">await</span> import('../packages/core/src/index.js');
|
|
1232
|
+
|
|
1233
|
+
<span class="kw">const</span> grid = createHeadlessGrid({
|
|
1234
|
+
columns: [{ field: 'id' }],
|
|
1235
|
+
rows: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
|
|
1236
|
+
rowKey: 'id',
|
|
1237
|
+
selection: 'multiple',
|
|
1238
|
+
rowDelete: <span class="kw">true</span>, <span class="cmt">// opt in to the Delete-key / menu gesture and the API</span>
|
|
1239
|
+
});
|
|
1240
|
+
|
|
1241
|
+
<span class="cmt">// A confirm hook that vetoes deleting row 'b' but allows the rest.</span>
|
|
1242
|
+
grid.on('beforeDelete', (e) => { <span class="kw">if</span> (e.rows.includes('b')) e.preventDefault('kept'); });
|
|
1243
|
+
|
|
1244
|
+
grid.edit.deleteRows(['a']); <span class="cmt">// allowed — 'a' is removed</span>
|
|
1245
|
+
grid.edit.deleteRows(['b']); <span class="cmt">// vetoed — 'b' stays, delete:cancelled fires</span>
|
|
1246
|
+
|
|
1247
|
+
<span class="kw">const</span> count = grid.rows.count();
|
|
1248
|
+
grid.destroy();
|
|
1249
|
+
<span class="kw">return</span> `${count} rows`; <span class="cmt">// 2 rows: 'b' and 'c'</span></code></pre>
|
|
1250
|
+
|
|
1220
1251
|
<p class="section-note">
|
|
1221
1252
|
<strong>Previewing a bulk paste.</strong> A paste can rewrite dozens of cells at once, and one
|
|
1222
1253
|
that lands somewhere unexpected looks exactly like one that worked. Set
|
|
@@ -1317,6 +1348,37 @@ grid.edit.setCells(preview.changes.map((c) => ({ key: c.key, colId: c.colId,
|
|
|
1317
1348
|
<p>IP columns are stored as packed integers so they sort as addresses, and declare <code>excelKind: 'string'</code> so the dotted form is what reaches the file. Radix columns export decimal: OOXML cannot express base 16, and staying numeric was judged worth more than display fidelity.</p>
|
|
1318
1349
|
</div>
|
|
1319
1350
|
|
|
1351
|
+
<h2 id="import">grid.import</h2>
|
|
1352
|
+
<p>The mirror of <a href="#export">grid.export</a>: rows coming <em>in</em> from delimited text — a CSV or TSV file, or the tab-separated block a spreadsheet puts on the clipboard. The pipeline is parse, infer each column's type, map the columns onto the grid's own fields, then preview and confirm. The API is always present; set <code>config.import</code> to add the DOM affordances (a "Import rows from CSV…" cell-menu item, a file drop target, and paste).</p>
|
|
1353
|
+
<div class="table-wrap">
|
|
1354
|
+
<table>
|
|
1355
|
+
<thead><tr><th>Method</th><th>Returns</th><th>Description</th></tr></thead>
|
|
1356
|
+
<tbody>
|
|
1357
|
+
<tr><td class="sig">preview(text, opts?)</td><td class="type">ImportPreview</td><td class="desc">Parse, infer and map without changing the grid — the columns, the coerced records, a sample and any warnings a confirm dialog needs.</td></tr>
|
|
1358
|
+
<tr><td class="sig">csv(text, opts?)</td><td class="type">object[]</td><td class="desc">Parse delimited text into coerced record objects, the inverse of <code>export.csv</code>.</td></tr>
|
|
1359
|
+
<tr><td class="sig">apply(input, opts?)</td><td class="type">ChangeResult | null</td><td class="desc">Add (<code>mode: 'append'</code>, the default) or replace (<code>mode: 'replace'</code>) the grid's rows from text, a preview or a record array. A client-side operation, so it applies to a memory-source grid; on any other source it declines rather than show rows that cannot persist.</td></tr>
|
|
1360
|
+
</tbody>
|
|
1361
|
+
</table>
|
|
1362
|
+
</div>
|
|
1363
|
+
<div class="note"><p><strong>Excel.</strong> <code>.xlsx</code> is not read: it needs an inflate and XML reader the zero-dependency envelope does not carry. Save the sheet as CSV — every spreadsheet does — and import that.</p></div>
|
|
1364
|
+
<pre data-run="js" data-expect="2 previewed, 3 rows" data-covers="method:import config:import"><code><span class="kw">const</span> { createHeadlessGrid } = <span class="kw">await</span> import('../packages/core/src/index.js');
|
|
1365
|
+
|
|
1366
|
+
<span class="kw">const</span> grid = createHeadlessGrid({
|
|
1367
|
+
columns: [{ field: 'id' }, { field: 'age', type: 'integer' }],
|
|
1368
|
+
rows: [{ id: 'seed', age: 1 }],
|
|
1369
|
+
rowKey: 'id',
|
|
1370
|
+
<span class="cmt">// Opt in to the DOM affordances; the grid.import API is present either way.</span>
|
|
1371
|
+
import: <span class="kw">true</span>,
|
|
1372
|
+
});
|
|
1373
|
+
|
|
1374
|
+
<span class="cmt">// Preview changes nothing — it is what a confirm dialog shows.</span>
|
|
1375
|
+
<span class="kw">const</span> preview = grid.import.preview('id,age\nx,20\ny,30');
|
|
1376
|
+
|
|
1377
|
+
<span class="cmt">// Confirming appends the previewed rows; `age` arrives coerced to a number.</span>
|
|
1378
|
+
grid.import.apply(preview);
|
|
1379
|
+
|
|
1380
|
+
<span class="kw">return</span> `${preview.rowCount} previewed, ${grid.rows.count()} rows`; <span class="cmt">// 2 previewed, 3 rows</span></code></pre>
|
|
1381
|
+
|
|
1320
1382
|
<h2 id="state">grid.state</h2>
|
|
1321
1383
|
<div class="table-wrap">
|
|
1322
1384
|
<table>
|
|
@@ -4060,6 +4122,7 @@ const chart = createChart({
|
|
|
4060
4122
|
<tr><td class="name">footnote</td><td class="type">string</td><td class="desc">A note under the plot, a source, a caveat, a unit.</td></tr>
|
|
4061
4123
|
<tr><td class="name">emptyText</td><td class="type">string</td><td class="desc">What to show when the binding produces nothing. Said rather than left blank, because an empty plot and a broken one look identical.</td></tr>
|
|
4062
4124
|
<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. <code>true</code> draws it with its R²; <code>'line'</code> draws the line alone. Only where the x axis is numeric: on a band scale a slope would be a slope through the order the categories happened to be listed in.</td></tr>
|
|
4125
|
+
<tr><td class="name">trend</td><td class="type">boolean | string | ChartTrend | array</td><td class="desc">Trend and forecast overlays (BACKLOG-0000952): a <code>linear</code> least-squares line, a <code>movingAverage</code>, or <code>exponential</code> smoothing, one per series. <code>true</code> draws a single linear trend; a method name or a <code>{ method, forecast, window, kind, alpha, beta }</code> object configures one; an array draws several. The maths matches the core stats engine to the last digit (a parity test asserts it) but is computed locally to keep the charts bundle lean. For the linear method, <code>forecast: n</code> projects the line <code>n</code> steps past the data as a dashed forecast; a moving average and a smoothed level have no slope to project, so <code>forecast</code> is ignored for them and the fact is said in the accessible description.</td></tr>
|
|
4063
4126
|
<tr><td class="name">error</td><td class="type">boolean | object</td><td class="desc">Whiskers showing the uncertainty in each mark, computed from the readings the chart can see behind it. <code>{ of }</code> takes a symmetric margin from a column instead; <code>{ confidence }</code> sets the level. A mark the chart sees only one value for gets none, and the chart says so.</td></tr>
|
|
4064
4127
|
<tr><td class="name">stack</td><td class="type">boolean</td><td class="desc">Stack the series rather than drawing them side by side.</td></tr>
|
|
4065
4128
|
<tr><td class="name">curve</td><td class="type">boolean</td><td class="desc">Overlay a kernel density curve on a histogram, which shows which features are in the data and which are in the binning.</td></tr>
|
|
@@ -4700,6 +4763,8 @@ plan.applyEdit({ id: 'design', duration: 7 }); // recomputes; the critical path
|
|
|
4700
4763
|
<tr><td class="sig">toISODate(day)</td><td class="desc">Format an engine day-number as an ISO calendar date (<code>YYYY-MM-DD</code>, UTC).</td></tr>
|
|
4701
4764
|
<tr><td class="sig">LINK_TYPES</td><td class="desc">The four dependency link types, in order: <code>['FS','SS','FF','SF']</code>.</td></tr>
|
|
4702
4765
|
<tr><td class="sig">SCHEDULE_ERROR</td><td class="desc">The error codes the engine reports rather than throwing (<code>cycle</code>, <code>duplicate-id</code>, <code>unknown-task</code>, <code>bad-duration</code>, <code>bad-link-type</code>, <code>unknown-parent</code>, <code>parent-cycle</code>, …).</td></tr>
|
|
4766
|
+
<tr><td class="sig">importMSPDI(xml, { hoursPerDay? })</td><td class="desc">Import a Microsoft Project (MSPDI) <code>.xml</code> document into a <code>{ tasks, dependencies, resources, projectStart, calendar }</code> model ready for <code>createGantt</code>: the task tree, typed dependencies with lag, constraints, baseline, %complete, resources with capacity and the resource assignments.</td></tr>
|
|
4767
|
+
<tr><td class="sig">exportMSPDI(model, { hoursPerDay?, projectName? })</td><td class="desc">Serialise a Gantt model (optionally a scheduled one) back to Microsoft Project (MSPDI) XML — the same fields, round-tripping with <code>importMSPDI</code>. The controller offers <code>gantt.toMSPDI()</code> as a shortcut over the current plan.</td></tr>
|
|
4703
4768
|
</tbody>
|
|
4704
4769
|
</table>
|
|
4705
4770
|
</div>
|
|
@@ -4730,6 +4795,21 @@ const tasks = [
|
|
|
4730
4795
|
const s = computeSchedule(tasks, [{ from: 'a', to: 'b' }, { from: 'phase', to: 'ship' }]);
|
|
4731
4796
|
const phase = s.tasks.get('phase');
|
|
4732
4797
|
return [phase.es, phase.ef, phase.percentComplete, phase.isSummary, s.tasks.get('ship').es].join(' | ');</code></pre>
|
|
4798
|
+
<p><strong>Resource management.</strong> Assign people (or machines) to tasks with <code>assignee</code>/<code>assignees</code> or explicit <code>assignments: [{ resource, units }]</code>, and give each resource a capacity through the <code>resources</code> option. The controller then reports <code>overAllocations</code> — where one resource is booked beyond its capacity across concurrent tasks — and the full <code>resourceLoad</code>; the split view rings the over-booked avatars and outlines the clashing bars. <code>gantt.level()</code> auto-shifts the lower-priority tasks later to clear the over-allocation, honouring the critical path and the working-time calendar (pass <code>{ dryRun: true }</code> to preview the moves).</p>
|
|
4799
|
+
<p><strong>Microsoft Project.</strong> <code>importMSPDI</code> reads a Project <code>.xml</code> (MSPDI) document into a model for <code>createGantt</code>, and <code>exportMSPDI</code> (or <code>gantt.toMSPDI()</code>) writes one back — tasks, typed dependencies with lag, constraints, baseline, %complete, resources and assignments all round-trip.</p>
|
|
4800
|
+
<pre data-run="js" data-expect="1 | 0 | true | 2 | true" data-covers="export:importMSPDI export:exportMSPDI"><code>const { createGantt, exportMSPDI, importMSPDI } = await import('../packages/modules/gantt/index.js');
|
|
4801
|
+
const plan = createGantt({
|
|
4802
|
+
tasks: [
|
|
4803
|
+
{ id: '1', name: 'Design', duration: 5, assignee: 'Ada' },
|
|
4804
|
+
{ id: '2', name: 'Build', duration: 3, assignee: 'Ada' },
|
|
4805
|
+
],
|
|
4806
|
+
});
|
|
4807
|
+
const overBefore = plan.overAllocations.length; // Ada is double-booked
|
|
4808
|
+
plan.level(); // shift one task later
|
|
4809
|
+
const overAfter = plan.overAllocations.length; // now clear
|
|
4810
|
+
const xml = exportMSPDI({ tasks: plan.tasks, dependencies: plan.dependencies, schedule: plan.schedule });
|
|
4811
|
+
const back = importMSPDI(xml);
|
|
4812
|
+
return [overBefore, overAfter, back.ok, back.tasks.length, xml.startsWith('<?xml')].join(' | ');</code></pre>
|
|
4733
4813
|
<p>Render the plan as an SVG timeline with <code>mount(container, options)</code> — bars on a time scale, dependency arrows with a per-link-type anchor and a lag/lead label, the critical path highlighted, a today line, optional non-working-day shading, milestones as diamonds, a progress bar-fill and configurable labels. The view redraws itself whenever the schedule recomputes; <code>unmount()</code> detaches it. All geometry is computed from the schedule, so it draws identically headless or in a browser.</p>
|
|
4734
4814
|
<pre><code>import { createGantt } from '@toclocoinc/lattice-grid/modules/gantt';
|
|
4735
4815
|
|
|
@@ -6047,6 +6127,9 @@ return `avg ${avg.value} over ${avg.over.size}; kinds ${WINDOW_KINDS.join('/')};
|
|
|
6047
6127
|
<tr><td class="name">modifiedZScores</td><td class="type">(values, opts?) => { median, mad, threshold, scores, flags, flagged }</td><td class="desc">Per-row robust outlier score, <code>0.6745·(x − median)/MAD</code>, flagged past <code>threshold</code> (default 3.5). Built on the median and MAD, so one wild reading cannot inflate the spread and hide — the masking effect that fools an ordinary z-score. A non-finite reading and a zero-MAD column yield a null score, not an invented one.</td></tr>
|
|
6048
6128
|
<tr><td class="name">iqrFences</td><td class="type">(values, opts?) => { q1, q3, iqr, lower, upper, k } | null</td><td class="desc">Tukey's fences, <code>[Q1 − k·IQR, Q3 + k·IQR]</code> (default <code>k = 1.5</code>), the same fence the box plot draws, on R type 7 quartiles.</td></tr>
|
|
6049
6129
|
<tr><td class="name">mahalanobis</td><td class="type">(matrix, opts?) => { center, df, cutoff, singular, used, distances, squared, flags, flagged } | null</td><td class="desc">Distance of every row from the joint centre in the metric of the data's own covariance, cut at a χ² quantile (default the 0.975 point). Catches a row impossible only in combination — heavy <em>and</em> short — that a per-column scan misses. A row with any missing coordinate is left unplaced; a singular covariance is ridge-regularised and reported as <code>singular</code> rather than throwing.</td></tr>
|
|
6130
|
+
<tr><td class="name">ROLLING_ANOMALY_METHODS</td><td class="type">readonly ('rollingModifiedZScore' | 'rollingIqr')[]</td><td class="desc">The rolling (windowed) methods, named alongside <code>ANOMALY_METHODS</code> so a caller can enumerate every detector. Also accepted by <code>grid.statistics.anomalies({ method, windowLen })</code>.</td></tr>
|
|
6131
|
+
<tr><td class="name">rollingAnomalies</td><td class="type">(values, opts?) => { method, windowLen, minPeriods, threshold, k, scores, flags, flagged }</td><td class="desc">Rolling (windowed) detection (BACKLOG-0000954): judge every reading against a causal trailing window of <code>windowLen</code> ending at it, so a spike is caught against its recent neighbours and a drift never poisons a global baseline. <code>rollingModifiedZScore</code> (median + MAD) or <code>rollingIqr</code> (Tukey fences). With a window as long as the series the last point's score equals the static <code>modifiedZScores</code> one.</td></tr>
|
|
6132
|
+
<tr><td class="name">anomalyCondition</td><td class="type">(opts) => (rows) => false | { method, field, flagged }</td><td class="desc">Build a Data Router alert condition from a detector: a <code>(rows) => signal</code> the router's existing <code>router.alert(value, condition, handler)</code> drives, so live anomaly monitoring reuses the router's partitioning, debounce and rising-edge re-arm rather than duplicating an alert engine. Reads one numeric <code>field</code> per row; <code>latest: true</code> signals only when the newest reading is the anomaly.</td></tr>
|
|
6050
6133
|
</tbody>
|
|
6051
6134
|
</table>
|
|
6052
6135
|
</div>
|
|
@@ -6065,6 +6148,21 @@ hw.push([182, 45]);
|
|
|
6065
6148
|
const m = mahalanobis(hw); // the χ² cut flags the off-line row
|
|
6066
6149
|
return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.upper}; joint ${m.flags[12]}`;</code></pre>
|
|
6067
6150
|
|
|
6151
|
+
<p class="section-note">Rolling (windowed) detection and the Data Router bridge (BACKLOG-0000954): judge each reading against its trailing window for live monitoring, and turn any detector into a <code>router.alert(...)</code> condition without a second alert engine.</p>
|
|
6152
|
+
<pre data-run="js" data-expect="methods 2; spike true; alert 1" data-covers="export:ROLLING_ANOMALY_METHODS export:rollingAnomalies export:anomalyCondition"><code>const { rollingAnomalies, anomalyCondition, ROLLING_ANOMALY_METHODS } = await import('../packages/core/src/index.js');
|
|
6153
|
+
// A steady stream that suddenly spikes. The trailing window catches the spike
|
|
6154
|
+
// against its recent neighbours, where scoring against the whole run could let a
|
|
6155
|
+
// long earlier drift hide it.
|
|
6156
|
+
const stream = [10, 11, 9, 10, 11, 9, 10, 11, 9, 10, 40];
|
|
6157
|
+
const roll = rollingAnomalies(stream, { windowLen: 6, minPeriods: 4 });
|
|
6158
|
+
// The SAME detector, wired as a Data Router alert condition: (rows) => signal,
|
|
6159
|
+
// exactly the predicate router.alert(value, condition, handler) already drives —
|
|
6160
|
+
// no second alert engine. `latest` fires only when the newest tick is the one out.
|
|
6161
|
+
const condition = anomalyCondition({ field: 'temp', method: 'rollingModifiedZScore', orderBy: 't', windowLen: 6, minPeriods: 4, latest: true });
|
|
6162
|
+
const rows = stream.map((temp, t) => ({ t, temp }));
|
|
6163
|
+
const signal = condition(rows);
|
|
6164
|
+
return `methods ${ROLLING_ANOMALY_METHODS.length}; spike ${roll.flags[10]}; alert ${signal ? signal.flagged.length : 0}`;</code></pre>
|
|
6165
|
+
|
|
6068
6166
|
|
|
6069
6167
|
<!-- BEGIN GENERATED TYPE REFERENCE -->
|
|
6070
6168
|
<h2 id="type-reference">Type reference</h2>
|
|
@@ -6365,21 +6463,21 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
6365
6463
|
</table>
|
|
6366
6464
|
</div>
|
|
6367
6465
|
<h3 id="type-ChartAnnotation">ChartAnnotation</h3>
|
|
6368
|
-
<p class="section-note">One declarative annotation (BACKLOG-0000744). A reference or target line, a shaded band, or
|
|
6466
|
+
<p class="section-note">One declarative annotation (BACKLOG-0000744, extended by BACKLOG-0000953). A reference or target line, a shaded band, a callout, or an `event` marker. Its value is a constant `value` (or `from`/`to` for a band), or a `compute` reduction of the data it annotates — `mean`, `median`, `min`, `max`, or `p95` for a percentile — so it follows the data as the grid is filtered. A band with `orient: 'vertical'` shades an x-range instead — an event window, a maintenance period — and an `event` marker is a labelled vertical rule with a flag at a position on the x axis. Every annotation names the axis it reads, which on a dual-axis chart is what stops it being placed against the wrong scale, and is written into the accessible table as a sentence — a vertical marker and an event stating the position they sit at, because a screen-reader user needs where and when, not only that a marker exists.</p>
|
|
6369
6467
|
<div class="table-wrap">
|
|
6370
6468
|
<table>
|
|
6371
6469
|
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
6372
6470
|
<tbody>
|
|
6373
|
-
<tr><td class="name">kind</td><td class="type">'line' | 'target' | 'band' | 'callout'</td><td class="desc">The default is a reference line. <small>(optional)</small></td></tr>
|
|
6471
|
+
<tr><td class="name">kind</td><td class="type">'line' | 'target' | 'band' | 'callout' | 'event'</td><td class="desc">The default is a reference line. `event` is a labelled vertical marker with a flag at a position on the x axis, described into the accessible table with that position stated (BACKLOG-0000953). <small>(optional)</small></td></tr>
|
|
6374
6472
|
<tr><td class="name">value</td><td class="type">number</td><td class="desc">A constant value, for a line, target or callout's measure position. <small>(optional)</small></td></tr>
|
|
6375
6473
|
<tr><td class="name">compute</td><td class="type">'mean' | 'avg' | 'median' | 'min' | 'max' | string</td><td class="desc">A reduction of the annotated data instead of a constant. <small>(optional)</small></td></tr>
|
|
6376
|
-
<tr><td class="name">from</td><td class="type">number</td><td class="desc">A band's two edges
|
|
6377
|
-
<tr><td class="name">to</td><td class="type">number</td><td class="desc"><small>(optional)</small></td></tr>
|
|
6474
|
+
<tr><td class="name">from</td><td class="type">number | string</td><td class="desc">A band's two edges. On a horizontal band each is a measure value, a constant or (with `fromCompute`/`toCompute`) computed. On a vertical band (`orient: 'vertical'`, BACKLOG-0000953) each is an x position — a category or a number — and the band shades the x-range between them: an event window, a maintenance period, a recession. <small>(optional)</small></td></tr>
|
|
6475
|
+
<tr><td class="name">to</td><td class="type">number | string</td><td class="desc"><small>(optional)</small></td></tr>
|
|
6378
6476
|
<tr><td class="name">fromCompute</td><td class="type">string</td><td class="desc"><small>(optional)</small></td></tr>
|
|
6379
6477
|
<tr><td class="name">toCompute</td><td class="type">string</td><td class="desc"><small>(optional)</small></td></tr>
|
|
6380
|
-
<tr><td class="name">x</td><td class="type">unknown</td><td class="desc">A vertical line's or callout's x position: a category or a number. <small>(optional)</small></td></tr>
|
|
6478
|
+
<tr><td class="name">x</td><td class="type">unknown</td><td class="desc">A vertical line's, event marker's or callout's x position: a category or a number. <small>(optional)</small></td></tr>
|
|
6381
6479
|
<tr><td class="name">at</td><td class="type">unknown</td><td class="desc"><small>(optional)</small></td></tr>
|
|
6382
|
-
<tr><td class="name">orient</td><td class="type">'horizontal' | 'vertical'</td><td class="desc">Force a line vertical rather than horizontal. <small>(optional)</small></td></tr>
|
|
6480
|
+
<tr><td class="name">orient</td><td class="type">'horizontal' | 'vertical'</td><td class="desc">Force a line vertical rather than horizontal, or shade a `band` across an x-range rather than a measure range (BACKLOG-0000953). <small>(optional)</small></td></tr>
|
|
6383
6481
|
<tr><td class="name">axis</td><td class="type">'left' | 'right' | 'y2'</td><td class="desc">Which measure axis the annotation reads. <small>(optional)</small></td></tr>
|
|
6384
6482
|
<tr><td class="name">series</td><td class="type">string</td><td class="desc">Restrict a `compute` to one series, by its key. <small>(optional)</small></td></tr>
|
|
6385
6483
|
<tr><td class="name">label</td><td class="type">string</td><td class="desc"><small>(optional)</small></td></tr>
|
|
@@ -6461,6 +6559,7 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
6461
6559
|
<tr><td class="name">font</td><td class="type">object</td><td class="desc"><small>(optional)</small></td></tr>
|
|
6462
6560
|
<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>
|
|
6463
6561
|
<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>
|
|
6562
|
+
<tr><td class="name">trend</td><td class="type">boolean | ChartTrendMethod | ChartTrend | Array<ChartTrendMethod | ChartTrend></td><td class="desc">Trend and forecast overlays (BACKLOG-0000952): a least-squares line, a trailing moving average, or exponential smoothing, drawn over a line, area or scatter chart. `true` draws a single linear trend; a method name or a {@link ChartTrend} object configures one; an array draws several. The maths matches the core stats engine to the last digit — the same least-squares fit, rolling window and exponential recursions — but is computed locally in the charts module rather than imported, because the in-tree bundler does not tree-shake and the import would inline the whole statistics closure; a test asserts the parity. A `forecast` count projects the linear line that many steps past the data, drawn dashed so it never reads as a reading; a moving average and a smoothed level have no slope to project, so `forecast` is ignored for them and the fact is stated in the accessible description rather than faked. <small>(optional)</small></td></tr>
|
|
6464
6563
|
<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>
|
|
6465
6564
|
<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>
|
|
6466
6565
|
<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>
|
|
@@ -6499,6 +6598,23 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
6499
6598
|
</tbody>
|
|
6500
6599
|
</table>
|
|
6501
6600
|
</div>
|
|
6601
|
+
<h3 id="type-ChartTrend">ChartTrend</h3>
|
|
6602
|
+
<p class="section-note">One trend or forecast overlay (BACKLOG-0000952).</p>
|
|
6603
|
+
<div class="table-wrap">
|
|
6604
|
+
<table>
|
|
6605
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
6606
|
+
<tbody>
|
|
6607
|
+
<tr><td class="name">method</td><td class="type">ChartTrendMethod</td><td class="desc">The overlay method; `linear` by default. <small>(optional)</small></td></tr>
|
|
6608
|
+
<tr><td class="name">forecast</td><td class="type">number</td><td class="desc">For the linear method, how many steps to project the line past the data as a dashed forecast. Ignored by the moving-average and exponential methods, which have no slope to extrapolate. <small>(optional)</small></td></tr>
|
|
6609
|
+
<tr><td class="name">window</td><td class="type">number</td><td class="desc">For the moving-average method, the trailing window in points; 3 by default. <small>(optional)</small></td></tr>
|
|
6610
|
+
<tr><td class="name">period</td><td class="type">number</td><td class="desc">An alias for `window`. <small>(optional)</small></td></tr>
|
|
6611
|
+
<tr><td class="name">kind</td><td class="type">'ses' | 'holt'</td><td class="desc">For the exponential method, single smoothing (`ses`) or Holt's level+trend (`holt`). <small>(optional)</small></td></tr>
|
|
6612
|
+
<tr><td class="name">alpha</td><td class="type">number</td><td class="desc">For the exponential method, the level factor in `[0, 1]`; omit to fit it. <small>(optional)</small></td></tr>
|
|
6613
|
+
<tr><td class="name">beta</td><td class="type">number</td><td class="desc">For Holt's exponential smoothing, the trend factor in `[0, 1]`; omit to fit it. <small>(optional)</small></td></tr>
|
|
6614
|
+
<tr><td class="name">label</td><td class="type">boolean</td><td class="desc">`false` suppresses the R² label on a linear trend. <small>(optional)</small></td></tr>
|
|
6615
|
+
</tbody>
|
|
6616
|
+
</table>
|
|
6617
|
+
</div>
|
|
6502
6618
|
<h3 id="type-Chunk">Chunk</h3>
|
|
6503
6619
|
<div class="table-wrap">
|
|
6504
6620
|
<table>
|
|
@@ -7295,6 +7411,7 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
7295
7411
|
<tr><td class="name">status</td><td class="type">(key: string, colId: string): 'pending' | null</td><td class="desc"></td></tr>
|
|
7296
7412
|
<tr><td class="name">addRow</td><td class="type">(row: object): string | null</td><td class="desc">Append a row to a remote source optimistically and persist it (§5.3), the structural analog of the cell edit path. The row shows immediately under a client temp key, and `adapter.mutate({ kind: 'append', rows: [row] })` is asked to persist it; when the server returns the real key the row is rekeyed everywhere the grid tracks it and `row:confirmed` fires, while a refused append is removed and fires `row:reverted`. Only wired when the source declares `mutate.append`; otherwise it warns once and returns null.</td></tr>
|
|
7297
7413
|
<tr><td class="name">deleteRow</td><td class="type">(key: string): string | null</td><td class="desc">Delete a row from a remote source optimistically and persist it (§5.3). The row is tombstoned immediately and `adapter.mutate({ kind: 'delete', keys: [key] })` is asked to remove it; on confirmation the row is purged and `row:confirmed` fires, on refusal it is restored and `row:reverted` fires. Only wired when the source declares `mutate.delete`; otherwise it warns once and returns null.</td></tr>
|
|
7414
|
+
<tr><td class="name">deleteRows</td><td class="type">(keys?: string | string[], opts?: { origin?: string }): string[] | Promise<string[]></td><td class="desc">Delete rows on a user gesture, through the cancellable `beforeDelete` event (§18.4, BACKLOG-0000968) — what the built-in Delete-key and "Delete row" gestures call. Unlike {@link deleteRow}, `beforeDelete` fires on a memory-source grid too, so the row can be confirmed or vetoed there. Off until `config.rowDelete` opts in; the keys default to the row selection. Returns the keys removed (empty on a veto or when disabled), or a Promise of them when a `beforeDelete` handler deferred.</td></tr>
|
|
7298
7415
|
<tr><td class="name">settleRow</td><td class="type">(id: string, ok: boolean, reason?: string, reconcile?: { key?: string; row?: unknown; conflict?: { serverRow?: unknown } }): boolean</td><td class="desc">Report the outcome of an optimistic structural write (§5.3), the counterpart to {@link settle} for `edit.confirm: 'manual'` over a backend that acknowledges an append/delete on a separate channel. The id arrives on `row:pending`.</td></tr>
|
|
7299
7416
|
<tr><td class="name">rowStatus</td><td class="type">(key: string): 'pending' | null</td><td class="desc">Whether a row has a structural op in flight (§5.3).</td></tr>
|
|
7300
7417
|
<tr><td class="name">pendingRows</td><td class="type">(): OpenRowOp[]</td><td class="desc">Every structural op still awaiting an outcome (§5.3), oldest first; always empty when the source cannot append or delete.</td></tr>
|
|
@@ -7638,6 +7755,7 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
7638
7755
|
<tr><td class="name">edit</td><td class="type">EditApi</td><td class="desc">Editing sessions: starting, committing and cancelling them. <small>(read-only)</small></td></tr>
|
|
7639
7756
|
<tr><td class="name">scroll</td><td class="type">ScrollApi</td><td class="desc">Where the viewport is, and moving it. <small>(read-only)</small></td></tr>
|
|
7640
7757
|
<tr><td class="name">export</td><td class="type">ExportApi</td><td class="desc">CSV, Excel and clipboard. <small>(read-only)</small></td></tr>
|
|
7758
|
+
<tr><td class="name">import</td><td class="type">ImportApi</td><td class="desc">Bringing rows in from CSV/TSV text, a file, the clipboard or a drop. <small>(read-only)</small></td></tr>
|
|
7641
7759
|
<tr><td class="name">state</td><td class="type">StateApi</td><td class="desc">Everything the user arranged, as a serialisable object. <small>(read-only)</small></td></tr>
|
|
7642
7760
|
<tr><td class="name">overlay</td><td class="type">OverlayApi</td><td class="desc">The loading, empty and error surfaces drawn over the grid. <small>(read-only)</small></td></tr>
|
|
7643
7761
|
<tr><td class="name">history</td><td class="type">HistoryApi</td><td class="desc">Undo and redo over edits and structural changes. <small>(read-only)</small></td></tr>
|
|
@@ -7759,6 +7877,8 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
7759
7877
|
<tr><td class="name">columnVirtualisationAbove</td><td class="type">number</td><td class="desc">Render only the visible columns once there are more than this many. <small>(optional)</small></td></tr>
|
|
7760
7878
|
<tr><td class="name">statusBar</td><td class="type">boolean | { panels?: string[] }</td><td class="desc">The bar beneath the grid, and which panels it carries. <small>(optional)</small></td></tr>
|
|
7761
7879
|
<tr><td class="name">contextMenu</td><td class="type">boolean | ((p: CellMenuParams, defaults: MenuItem[]) => MenuItem[] | void)</td><td class="desc">The cell right-click menu. A function supplies custom items; `false` suppresses it entirely, which is what a read-only grid wants, the default menu offers Paste, Clear and Fill down. <small>(optional)</small></td></tr>
|
|
7880
|
+
<tr><td class="name">import</td><td class="type">boolean | ImportSettings</td><td class="desc">Bringing rows in from a file, the clipboard or a drop (§14, the mirror of export). `true` adds a "Import rows from CSV…" item to the cell menu, makes the grid a drop target for `.csv`/`.tsv` files, and reads a pasted spreadsheet block, each opening a preview the user confirms. An object tunes the affordances. Off by default; the `grid.import` API is always present. Import is a client-side data operation, so it applies to a memory grid. <small>(optional)</small></td></tr>
|
|
7881
|
+
<tr><td class="name">rowDelete</td><td class="type">boolean</td><td class="desc">Enable the built-in row-delete gesture (§18.4, BACKLOG-0000968) — the Delete/Backspace key on selected rows and a "Delete row" cell-menu item — and the `grid.edit.deleteRows` API. Off by default, because deleting data on a keystroke is destructive and opt-in. Every deletion flows through the cancellable `beforeDelete` event, so a handler can confirm or veto it, on a memory-source grid as well as a remote one. <small>(optional)</small></td></tr>
|
|
7762
7882
|
<tr><td class="name">columnMenu</td><td class="type">boolean | ((p: ColumnMenuParams, defaults: MenuItem[]) => MenuItem[] | void)</td><td class="desc">The header's 3-dot menu, and the right-click menu on a column heading. `false` suppresses both. A function supplies custom items, receiving the grid's own so it can add to them rather than reproduce them. Default true. <small>(optional)</small></td></tr>
|
|
7763
7883
|
<tr><td class="name">rangeChart</td><td class="type"></td><td class="desc">Chart a selected cell range — the spreadsheet "chart this selection" gesture. Off by default, so a grid opts in. The DOM layer draws no charts itself — the charts module is optional and loaded by the host — so this is where the host wires the two together: a function, or an object carrying `onChart`, is called with the grid and the selected range when the reader chooses "Chart selection" from the cell menu. The handler typically calls `chartRange` from `lattice-grid/modules/charts`. `true` offers the item and emits nothing extra; supply a handler to have it actually draw. <small>(optional)</small></td></tr>
|
|
7764
7884
|
<tr><td class="name">shortcuts</td><td class="type">boolean</td><td class="desc">The `?` keyboard shortcut overlay. `false` suppresses it, for a host that wants `?` for itself. Default true. <small>(optional)</small></td></tr>
|
|
@@ -7958,6 +8078,62 @@ return `methods ${ANOMALY_METHODS.length}; flagged ${z.flagged}; upper ${fence.u
|
|
|
7958
8078
|
</tbody>
|
|
7959
8079
|
</table>
|
|
7960
8080
|
</div>
|
|
8081
|
+
<h3 id="type-ImportApi">ImportApi</h3>
|
|
8082
|
+
<p class="section-note">Bringing rows in — the mirror of {@link ExportApi} (§14, BACKLOG-0000949).</p>
|
|
8083
|
+
<div class="table-wrap">
|
|
8084
|
+
<table>
|
|
8085
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
8086
|
+
<tbody>
|
|
8087
|
+
<tr><td class="name">preview</td><td class="type">(text: string, opts?: object): ImportPreview</td><td class="desc">Parse delimited text into a preview, changing nothing.</td></tr>
|
|
8088
|
+
<tr><td class="name">csv</td><td class="type">(text: string, opts?: object): Record<string, unknown>[]</td><td class="desc">Parse delimited text into coerced records — the inverse of `export.csv`.</td></tr>
|
|
8089
|
+
<tr><td class="name">apply</td><td class="type">(</td><td class="desc">Add or replace the grid's rows from text, a preview or records.</td></tr>
|
|
8090
|
+
</tbody>
|
|
8091
|
+
</table>
|
|
8092
|
+
</div>
|
|
8093
|
+
<h3 id="type-ImportColumn">ImportColumn</h3>
|
|
8094
|
+
<p class="section-note">One source column as understood by the importer, after type inference (§14).</p>
|
|
8095
|
+
<div class="table-wrap">
|
|
8096
|
+
<table>
|
|
8097
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
8098
|
+
<tbody>
|
|
8099
|
+
<tr><td class="name">source</td><td class="type">string</td><td class="desc">The heading as written in the file.</td></tr>
|
|
8100
|
+
<tr><td class="name">index</td><td class="type">number</td><td class="desc">The column's position in each row.</td></tr>
|
|
8101
|
+
<tr><td class="name">field</td><td class="type">string</td><td class="desc">The grid field this column maps onto; empty to exclude it from the import.</td></tr>
|
|
8102
|
+
<tr><td class="name">type</td><td class="type">string</td><td class="desc">The inferred (or grid-dictated) type used to coerce the column's values.</td></tr>
|
|
8103
|
+
<tr><td class="name">samples</td><td class="type">string[]</td><td class="desc">A few non-blank sample values, for the preview.</td></tr>
|
|
8104
|
+
<tr><td class="name">matched</td><td class="type">boolean</td><td class="desc">Whether the heading matched one of the grid's own columns.</td></tr>
|
|
8105
|
+
</tbody>
|
|
8106
|
+
</table>
|
|
8107
|
+
</div>
|
|
8108
|
+
<h3 id="type-ImportPreview">ImportPreview</h3>
|
|
8109
|
+
<p class="section-note">What a preview carries — everything a confirm dialog needs (§14).</p>
|
|
8110
|
+
<div class="table-wrap">
|
|
8111
|
+
<table>
|
|
8112
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
8113
|
+
<tbody>
|
|
8114
|
+
<tr><td class="name">delimiter</td><td class="type">string</td><td class="desc">The delimiter that was used, detected or supplied.</td></tr>
|
|
8115
|
+
<tr><td class="name">header</td><td class="type">string[]</td><td class="desc">The source column headings.</td></tr>
|
|
8116
|
+
<tr><td class="name">columns</td><td class="type">ImportColumn[]</td><td class="desc">The per-column mapping and inference the user may edit before confirming.</td></tr>
|
|
8117
|
+
<tr><td class="name">records</td><td class="type">Record<string, unknown>[]</td><td class="desc">Every mapped, coerced record the import would add.</td></tr>
|
|
8118
|
+
<tr><td class="name">sample</td><td class="type">Record<string, unknown>[]</td><td class="desc">The leading records, for a preview table.</td></tr>
|
|
8119
|
+
<tr><td class="name">rowCount</td><td class="type">number</td><td class="desc">How many data rows the file holds.</td></tr>
|
|
8120
|
+
<tr><td class="name">warnings</td><td class="type">string[]</td><td class="desc">Anything worth flagging before confirming — a ragged file, a bad quote.</td></tr>
|
|
8121
|
+
</tbody>
|
|
8122
|
+
</table>
|
|
8123
|
+
</div>
|
|
8124
|
+
<h3 id="type-ImportSettings">ImportSettings</h3>
|
|
8125
|
+
<p class="section-note">How `config.import` tunes the DOM import affordances (§14).</p>
|
|
8126
|
+
<div class="table-wrap">
|
|
8127
|
+
<table>
|
|
8128
|
+
<thead><tr><th>Member</th><th>Type</th><th>Description</th></tr></thead>
|
|
8129
|
+
<tbody>
|
|
8130
|
+
<tr><td class="name">file</td><td class="type">boolean</td><td class="desc">Add the cell-menu item and open a file picker for CSV/TSV. Default true. <small>(optional)</small></td></tr>
|
|
8131
|
+
<tr><td class="name">drop</td><td class="type">boolean</td><td class="desc">Make the grid a drop target for `.csv`/`.tsv` files. Default true. <small>(optional)</small></td></tr>
|
|
8132
|
+
<tr><td class="name">paste</td><td class="type">boolean</td><td class="desc">Read a pasted spreadsheet block into a preview. Default true. <small>(optional)</small></td></tr>
|
|
8133
|
+
<tr><td class="name">mode</td><td class="type">'append' | 'replace'</td><td class="desc">How a confirmed import lands: append (default) or replace the dataset. <small>(optional)</small></td></tr>
|
|
8134
|
+
</tbody>
|
|
8135
|
+
</table>
|
|
8136
|
+
</div>
|
|
7961
8137
|
<h3 id="type-IngestConfig">IngestConfig</h3>
|
|
7962
8138
|
<p class="section-note">How rows are ingested into the column store.</p>
|
|
7963
8139
|
<div class="table-wrap">
|
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.38.0</p>
|
|
441
441
|
<nav>
|
|
442
442
|
<div class="rail__group">
|
|
443
443
|
<span class="rail__label">Start here</span>
|
|
@@ -3370,6 +3370,27 @@ columns: [
|
|
|
3370
3370
|
}}</code></pre>
|
|
3371
3371
|
</div>
|
|
3372
3372
|
|
|
3373
|
+
<h3 id="deleting-rows">Deleting rows</h3>
|
|
3374
|
+
<p class="lead-in">
|
|
3375
|
+
Set <code>rowDelete: true</code> for the built-in delete gesture: Delete or Backspace on the
|
|
3376
|
+
selected rows, and a "Delete row" item in the cell menu. It works on a memory grid, not only a
|
|
3377
|
+
remote one, and every deletion flows through the cancellable <code>beforeDelete</code> event —
|
|
3378
|
+
so a confirm dialog is a handler that calls <code>e.preventDefault(reason)</code>. It is off by
|
|
3379
|
+
default because deleting data on a keystroke is destructive.
|
|
3380
|
+
</p>
|
|
3381
|
+
<div class="example">
|
|
3382
|
+
<p class="example__label">Confirm before delete</p>
|
|
3383
|
+
<pre><code>const grid = createGrid(el, { columns, rows, rowKey: 'id', selection: 'multiple', rowDelete: true });
|
|
3384
|
+
|
|
3385
|
+
grid.on('beforeDelete', async (e) => {
|
|
3386
|
+
const ok = await confirmDialog(`Delete ${e.rows.length} row(s)?`);
|
|
3387
|
+
if (!ok) e.preventDefault('cancelled'); <span class="cmt">// the rows stay; delete:cancelled fires</span>
|
|
3388
|
+
});
|
|
3389
|
+
|
|
3390
|
+
<span class="cmt">// The gesture calls this; you can call it too. Defaults to the selection.</span>
|
|
3391
|
+
grid.edit.deleteRows();</code></pre>
|
|
3392
|
+
</div>
|
|
3393
|
+
|
|
3373
3394
|
<h2 id="appearance">Grid lines and corners</h2>
|
|
3374
3395
|
<p class="lead-in">
|
|
3375
3396
|
Two settings that change how the grid is drawn rather than what it draws.
|
|
@@ -6208,6 +6229,28 @@ grid.state.apply(savedView.state);
|
|
|
6208
6229
|
to CSV takes about 100ms.</p>
|
|
6209
6230
|
</div>
|
|
6210
6231
|
|
|
6232
|
+
<h2 id="import-guide">Import</h2>
|
|
6233
|
+
<p class="lead-in">
|
|
6234
|
+
The mirror of export: rows coming in from a CSV or TSV file, a drop, or a pasted spreadsheet
|
|
6235
|
+
block. The pipeline is parse, infer each column's type, map the columns onto your fields, then
|
|
6236
|
+
preview and confirm — nothing lands until the user says so.
|
|
6237
|
+
</p>
|
|
6238
|
+
<div class="example">
|
|
6239
|
+
<p class="example__label">Preview, then confirm</p>
|
|
6240
|
+
<pre><code><span class="cmt">// Parse and map without touching the grid — this is what the dialog shows.</span>
|
|
6241
|
+
<span class="kw">const</span> preview = grid.import.preview(csvText);
|
|
6242
|
+
<span class="cmt">// preview.columns is the mapping the user can edit; preview.warnings flags a</span>
|
|
6243
|
+
<span class="cmt">// ragged file. Confirming appends (or, with { mode: 'replace' }, swaps).</span>
|
|
6244
|
+
grid.import.apply(preview);</code></pre>
|
|
6245
|
+
</div>
|
|
6246
|
+
<p class="lead-in">
|
|
6247
|
+
Set <code>config.import</code> to <code>true</code> to add the DOM affordances — a
|
|
6248
|
+
"Import rows from CSV…" cell-menu item, a file drop target, and paste — each opening the same
|
|
6249
|
+
preview dialog. The <code>grid.import</code> API is present whether or not you do, so a server-side
|
|
6250
|
+
or headless import runs the identical pipeline. <code>.xlsx</code> is not read (it needs an inflate
|
|
6251
|
+
and XML reader the zero-dependency envelope does not carry); save the sheet as CSV.
|
|
6252
|
+
</p>
|
|
6253
|
+
|
|
6211
6254
|
<h2 id="less-common">Options and calls you may not have met</h2>
|
|
6212
6255
|
<p class="lead-in">
|
|
6213
6256
|
The rest of the surface, in one place. Each of these is documented in full in the
|