@toclocoinc/lattice-grid 1.63.3 → 1.64.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 +2 -1
- package/docs/API.html +285 -24
- package/docs/CHART-CODES.md +24 -0
- package/docs/api-detail.html +80 -5
- package/lattice-grid.d.ts +93 -1
- package/lattice-grid.esm.min.js +154 -95
- package/lattice-grid.min.cjs +154 -95
- package/lattice-grid.min.js +154 -95
- package/modules/ai.d.ts +1 -1
- package/modules/ai.esm.min.js +3 -6
- package/modules/ai.min.cjs +3 -6
- package/modules/ai.min.js +3 -6
- package/modules/angular.d.ts +1 -1
- package/modules/angular.esm.min.js +1 -4
- package/modules/angular.min.cjs +1 -4
- package/modules/angular.min.js +1 -4
- package/modules/chart-alluvial.d.ts +1 -1
- package/modules/chart-alluvial.esm.min.js +1 -1
- package/modules/chart-alluvial.min.cjs +1 -1
- package/modules/chart-alluvial.min.js +1 -1
- package/modules/chart-arc.d.ts +1 -1
- package/modules/chart-arc.esm.min.js +1 -1
- package/modules/chart-arc.min.cjs +1 -1
- package/modules/chart-arc.min.js +1 -1
- package/modules/chart-bubblemap.d.ts +1 -1
- package/modules/chart-bubblemap.esm.min.js +1 -1
- package/modules/chart-bubblemap.min.cjs +1 -1
- package/modules/chart-bubblemap.min.js +1 -1
- package/modules/chart-bump.d.ts +1 -1
- package/modules/chart-bump.esm.min.js +1 -1
- package/modules/chart-bump.min.cjs +1 -1
- package/modules/chart-bump.min.js +1 -1
- package/modules/chart-calendar.d.ts +1 -1
- package/modules/chart-calendar.esm.min.js +1 -1
- package/modules/chart-calendar.min.cjs +1 -1
- package/modules/chart-calendar.min.js +1 -1
- package/modules/chart-decomposition.d.ts +1 -1
- package/modules/chart-decomposition.esm.min.js +1 -1
- package/modules/chart-decomposition.min.cjs +1 -1
- package/modules/chart-decomposition.min.js +1 -1
- package/modules/chart-diverging.d.ts +1 -1
- package/modules/chart-diverging.esm.min.js +1 -1
- package/modules/chart-diverging.min.cjs +1 -1
- package/modules/chart-diverging.min.js +1 -1
- package/modules/chart-dumbbell.d.ts +1 -1
- package/modules/chart-dumbbell.esm.min.js +1 -1
- package/modules/chart-dumbbell.min.cjs +1 -1
- package/modules/chart-dumbbell.min.js +1 -1
- package/modules/chart-fan.d.ts +1 -1
- package/modules/chart-fan.esm.min.js +1 -1
- package/modules/chart-fan.min.cjs +1 -1
- package/modules/chart-fan.min.js +1 -1
- package/modules/chart-hexbin.d.ts +1 -1
- package/modules/chart-hexbin.esm.min.js +1 -1
- package/modules/chart-hexbin.min.cjs +1 -1
- package/modules/chart-hexbin.min.js +1 -1
- package/modules/chart-hexmap.d.ts +1 -1
- package/modules/chart-hexmap.esm.min.js +1 -1
- package/modules/chart-hexmap.min.cjs +1 -1
- package/modules/chart-hexmap.min.js +1 -1
- package/modules/chart-icicle.d.ts +1 -1
- package/modules/chart-icicle.esm.min.js +1 -1
- package/modules/chart-icicle.min.cjs +1 -1
- package/modules/chart-icicle.min.js +1 -1
- package/modules/chart-markermap.d.ts +29 -0
- package/modules/chart-markermap.esm.min.js +313 -0
- package/modules/chart-markermap.min.cjs +317 -0
- package/modules/chart-markermap.min.js +317 -0
- package/modules/chart-parallel.d.ts +1 -1
- package/modules/chart-parallel.esm.min.js +1 -1
- package/modules/chart-parallel.min.cjs +1 -1
- package/modules/chart-parallel.min.js +1 -1
- package/modules/chart-ridgeline.d.ts +1 -1
- package/modules/chart-ridgeline.esm.min.js +1 -1
- package/modules/chart-ridgeline.min.cjs +1 -1
- package/modules/chart-ridgeline.min.js +1 -1
- package/modules/chart-roc.d.ts +1 -1
- package/modules/chart-roc.esm.min.js +1 -1
- package/modules/chart-roc.min.cjs +1 -1
- package/modules/chart-roc.min.js +1 -1
- package/modules/chart-slope.d.ts +1 -1
- package/modules/chart-slope.esm.min.js +1 -1
- package/modules/chart-slope.min.cjs +1 -1
- package/modules/chart-slope.min.js +1 -1
- package/modules/chart-splom.d.ts +1 -1
- package/modules/chart-splom.esm.min.js +1 -1
- package/modules/chart-splom.min.cjs +1 -1
- package/modules/chart-splom.min.js +1 -1
- package/modules/chart-waffle.d.ts +1 -1
- package/modules/chart-waffle.esm.min.js +1 -1
- package/modules/chart-waffle.min.cjs +1 -1
- package/modules/chart-waffle.min.js +1 -1
- package/modules/charts.d.ts +1 -1
- package/modules/charts.esm.min.js +395 -33
- package/modules/charts.min.cjs +395 -33
- package/modules/charts.min.js +395 -33
- package/modules/data-router.d.ts +1 -1
- package/modules/data-router.esm.min.js +3 -6
- package/modules/data-router.min.cjs +3 -6
- package/modules/data-router.min.js +3 -6
- package/modules/devtools.d.ts +1 -1
- package/modules/devtools.esm.min.js +1 -4
- package/modules/devtools.min.cjs +1 -4
- package/modules/devtools.min.js +1 -4
- package/modules/dhtmlx-compat.d.ts +1 -1
- package/modules/dhtmlx-compat.esm.min.js +3 -6
- package/modules/dhtmlx-compat.min.cjs +3 -6
- package/modules/dhtmlx-compat.min.js +3 -6
- package/modules/gantt.d.ts +1 -1
- package/modules/gantt.esm.min.js +3 -6
- package/modules/gantt.min.cjs +3 -6
- package/modules/gantt.min.js +3 -6
- package/modules/geo-europe-nuts.d.ts +1 -1
- package/modules/geo-europe-nuts.esm.min.js +1 -1
- package/modules/geo-uk.d.ts +1 -1
- package/modules/geo-uk.esm.min.js +1 -1
- package/modules/geo-us-states.d.ts +1 -1
- package/modules/geo-us-states.esm.min.js +1 -1
- package/modules/geo-world-110m.d.ts +1 -1
- package/modules/geo-world-110m.esm.min.js +1 -1
- package/modules/geo-world-50m.d.ts +1 -1
- package/modules/geo-world-50m.esm.min.js +1 -1
- package/modules/htmx.d.ts +1 -1
- package/modules/htmx.esm.min.js +154 -95
- package/modules/htmx.min.cjs +154 -95
- package/modules/htmx.min.js +154 -95
- package/modules/kanban.d.ts +1 -1
- package/modules/kanban.esm.min.js +3 -6
- package/modules/kanban.min.cjs +3 -6
- package/modules/kanban.min.js +3 -6
- package/modules/kpi.d.ts +56 -3
- package/modules/kpi.esm.min.js +202 -10
- package/modules/kpi.min.cjs +202 -10
- package/modules/kpi.min.js +202 -10
- package/modules/layout.d.ts +1 -1
- package/modules/layout.esm.min.js +3 -6
- package/modules/layout.min.cjs +3 -6
- package/modules/layout.min.js +3 -6
- package/modules/mock-socket.d.ts +1 -1
- package/modules/mock-socket.esm.min.js +1 -4
- package/modules/mock-socket.min.cjs +1 -4
- package/modules/mock-socket.min.js +1 -4
- package/modules/react.d.ts +1 -1
- package/modules/react.esm.min.js +3 -6
- package/modules/react.min.cjs +3 -6
- package/modules/react.min.js +3 -6
- package/modules/svelte.d.ts +1 -1
- package/modules/svelte.esm.min.js +1 -4
- package/modules/svelte.min.cjs +1 -4
- package/modules/svelte.min.js +1 -4
- package/modules/tabs.d.ts +1 -1
- package/modules/tabs.esm.min.js +3 -6
- package/modules/tabs.min.cjs +3 -6
- package/modules/tabs.min.js +3 -6
- package/modules/vue.d.ts +1 -1
- package/modules/vue.esm.min.js +1 -4
- package/modules/vue.min.cjs +1 -4
- package/modules/vue.min.js +1 -4
- package/modules/webcomponent.d.ts +1 -1
- package/modules/webcomponent.esm.min.js +154 -95
- package/modules/webcomponent.min.cjs +154 -95
- package/modules/webcomponent.min.js +154 -95
- package/package.json +1 -1
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.64.0</p>
|
|
441
441
|
<nav>
|
|
442
442
|
<div class="rail__group">
|
|
443
443
|
<span class="rail__label">Start here</span>
|
|
@@ -554,7 +554,7 @@
|
|
|
554
554
|
<a href="API.html">reference tables</a> are the shorter version for when you already know.
|
|
555
555
|
</p>
|
|
556
556
|
<p class="chips">
|
|
557
|
-
<span class="chip">Version 1.
|
|
557
|
+
<span class="chip">Version 1.64.0</span>
|
|
558
558
|
<span class="chip">Zero dependencies</span>
|
|
559
559
|
<span class="chip">No build step</span>
|
|
560
560
|
</p>
|
|
@@ -1369,7 +1369,7 @@ off(); <span class="cmt">// every subscrip
|
|
|
1369
1369
|
</p>
|
|
1370
1370
|
<div class="example">
|
|
1371
1371
|
<p class="example__label">Which version am I running?</p>
|
|
1372
|
-
<pre><code>grid.getVersion(); <span class="cmt">// '1.
|
|
1372
|
+
<pre><code>grid.getVersion(); <span class="cmt">// '1.64.0'</span>
|
|
1373
1373
|
LatticeGrid.getVersion(); <span class="cmt">// the same, when you have no grid to hand</span></code></pre>
|
|
1374
1374
|
</div>
|
|
1375
1375
|
<p class="lead-in">
|
|
@@ -7896,6 +7896,81 @@ grid.diff.before('CIR-100042', 'capacity');</code></pre>
|
|
|
7896
7896
|
highlight cannot serve both.
|
|
7897
7897
|
</p>
|
|
7898
7898
|
|
|
7899
|
+
<h3 id="network-map-guide">A network map: icon nodes, links coloured by their value</h3>
|
|
7900
|
+
<p class="lead-in">
|
|
7901
|
+
A <code>network</code> chart draws the rows as a graph — two columns name the endpoints
|
|
7902
|
+
and a third carries the value on the link. Until 1.64 every node was a plain circle, every
|
|
7903
|
+
edge the same grey, and the layout went wherever the simulation put it, so the picture a
|
|
7904
|
+
network team actually draws — core on top, regions below, an icon per device, a colour
|
|
7905
|
+
per circuit — could not be expressed. Three options change that, and every one of them
|
|
7906
|
+
carries a fact that only the host has.
|
|
7907
|
+
</p>
|
|
7908
|
+
<div class="example">
|
|
7909
|
+
<p class="example__label">One <code>nodes</code> list, one rule set, one chart config</p>
|
|
7910
|
+
<pre><code>createGrid(el, {
|
|
7911
|
+
columns: [{ field: 'from' }, { field: 'to' }, { field: 'load', type: 'number' }],
|
|
7912
|
+
rows, <span class="cmt">// one row per circuit</span>
|
|
7913
|
+
selection: 'multiple',
|
|
7914
|
+
<span class="cmt">// The rules live on the column. The cells and the links read the same ones.</span>
|
|
7915
|
+
formatting: {
|
|
7916
|
+
load: [
|
|
7917
|
+
{ label: 'Healthy', when: { op: 'lt', value: 40 }, style: { background: '#107c41' } },
|
|
7918
|
+
{ label: 'Busy', when: { op: 'lt', value: 80 }, style: { background: '#f0b400' } },
|
|
7919
|
+
{ label: 'Saturated', when: { op: 'gte', value: 80 }, style: { background: '#a4262c' } },
|
|
7920
|
+
],
|
|
7921
|
+
},
|
|
7922
|
+
});
|
|
7923
|
+
|
|
7924
|
+
createChart({
|
|
7925
|
+
grid, container: '#topology', type: 'network',
|
|
7926
|
+
source: 'from', target: 'to', y: { col: 'load', fn: 'sum' },
|
|
7927
|
+
selection: true,
|
|
7928
|
+
nodes: [
|
|
7929
|
+
<span class="cmt">// x/y are fractions of the plot: both given pins the node there.</span>
|
|
7930
|
+
{ id: 'core-1', label: 'Core', icon: 'router', x: 0.3, y: 0.15 },
|
|
7931
|
+
{ id: 'core-2', label: 'Core', icon: 'router', x: 0.7, y: 0.15 },
|
|
7932
|
+
{ id: 'emea', label: 'EMEA', icon: 'hub', x: 0.2, y: 0.8 },
|
|
7933
|
+
{ id: 'amer', label: 'AMER', icon: 'hub', x: 0.5, y: 0.8 },
|
|
7934
|
+
{ id: 'apac', label: 'APAC', icon: 'hub', x: 0.8, y: 0.8 },
|
|
7935
|
+
],
|
|
7936
|
+
});</code></pre>
|
|
7937
|
+
</div>
|
|
7938
|
+
<div class="why">
|
|
7939
|
+
<p><strong>The icons come from the grid, not from the chart.</strong> <code>icon</code> is a
|
|
7940
|
+
name in the grid’s own sprite registry — a built-in, or one you registered —
|
|
7941
|
+
and the chart reads it through <code>grid.icons</code>, the grid it is bound to. That is
|
|
7942
|
+
deliberate and it is the only route that works: the charts module ships as its own bundle, so
|
|
7943
|
+
an <code>import</code> of the registry there would hand the chart a <em>second</em>, empty
|
|
7944
|
+
copy, and a glyph you registered would be invisible to it. One registry, reached through the
|
|
7945
|
+
one object both sides already share. Unknown names warn once and draw a plain disc rather
|
|
7946
|
+
than nothing.</p>
|
|
7947
|
+
<p><strong>Pinning steers the layout without replacing it.</strong> A node with both
|
|
7948
|
+
<code>x</code> and <code>y</code> is a fixed body: it still pushes its neighbours apart and
|
|
7949
|
+
still pulls on its links, and the integration step skips it. Everything unpinned settles
|
|
7950
|
+
around it by the same deterministic relaxation as before — and pinning one node does
|
|
7951
|
+
not reshuffle the others, because the layout’s seeding draws for every node whether it
|
|
7952
|
+
is pinned or not, precisely so that it cannot. Half a position is not a position: a node with
|
|
7953
|
+
only <code>x</code> is laid out.</p>
|
|
7954
|
+
<p><strong>Parallel links are not summed.</strong> Three rows between the same pair are three
|
|
7955
|
+
lines, offset 4 px apart, symmetric about the pair’s own line, in row order. One
|
|
7956
|
+
line carrying their total would be a number nothing measured — three circuits at 40% do
|
|
7957
|
+
not make one at 120% — and the pointer picks out the line you are over rather than the
|
|
7958
|
+
pair, so each one’s own value is readable. Links are undirected: no arrowheads, and
|
|
7959
|
+
<code>A,B</code> is the same pair as <code>B,A</code>.</p>
|
|
7960
|
+
<p><strong>There is no chart-level threshold option, on purpose.</strong> The colour comes
|
|
7961
|
+
from <code>grid.formatting.styleFor(col, value)</code> — <code>background</code>, then
|
|
7962
|
+
<code>backgroundColor</code>, then <code>color</code>; a gradient is not a colour and is not
|
|
7963
|
+
read. A second place to say “red above 80” is a second place for the chart and the
|
|
7964
|
+
cell to disagree. The legend lists only the rules that fired, with their own labels and
|
|
7965
|
+
swatches, and changing a rule recolours the links on the next frame without the layout
|
|
7966
|
+
re-running, so nothing moves.</p>
|
|
7967
|
+
<p><strong>Clicking acts on rows, because a link is a row.</strong> With
|
|
7968
|
+
<code>selection: true</code>, clicking a link selects its row and clicking a node selects
|
|
7969
|
+
every row it is an end of; the grid’s selection then lights those marks and dims the
|
|
7970
|
+
rest. The types whose marks are <em>aggregates</em> are deliberately untouched: selecting the
|
|
7971
|
+
forty rows behind a bar is not what a click on a bar means.</p>
|
|
7972
|
+
</div>
|
|
7973
|
+
|
|
7899
7974
|
<h3 id="removed-rows">Showing what was deleted</h3>
|
|
7900
7975
|
<div class="example">
|
|
7901
7976
|
<p class="example__label">A deletion is a change too</p>
|
|
@@ -8078,7 +8153,7 @@ grid.import.apply(preview);</code></pre>
|
|
|
8078
8153
|
<tr><td class="name">createKPI</td><td class="desc">A KPI / stat-tile view (module <code>kpi</code>) of a dataset as a panel of aggregate tiles — each tile a <code>sum</code>, <code>avg</code>, <code>min</code>, <code>max</code>, <code>count</code>, <code>countDistinct</code> or a <code>custom</code> reducer over the routed rows, with an optional <code>filter</code> predicate, number <code>format</code> (<code>number</code>/<code>currency</code>/<code>percent</code>/<code>compact</code>), a <code>baseline</code> for a delta, semantic threshold bands (<code>thresholds</code> with two cut points and a direction, or an explicit <code>bands</code> list, giving a <code>good</code>/<code>warn</code>/<code>critical</code> status kept separate from any accent), and an optional <code>sparkline</code> series. It is a dataset viewer like any other: it consumes data through the same keyed-diff <code>rows.apply({ add, update, remove })</code> contract a grid exposes, so a Data Router can <code>attach(value, kpi)</code> and drive a KPI panel beside a grid, a kanban and a chart off one feed. Updates are incremental — a delta adjusts each tile's running accumulator by only the rows it carries (an add contributes, a remove reverses, an update reverses-then-contributes), the two bounded exceptions being a <code>min</code>/<code>max</code> whose current extreme is removed (a rescan of that tile's own value multiset) and a <code>custom</code> reducer (recomputed over the filtered store, an arbitrary function having no inverse). Each tile is a labelled <code><figure></code>, focusable and keyboard-activatable, its value announced, the sparkline respecting <code>prefers-reduced-motion</code>; a <code>tile:click</code> event (also from the keyboard) lets a host drill down or filter a routed grid. Pass <code>null</code> as the element for a headless panel that computes the same tile model without a DOM. Not a dashboard layout engine (that is the parked dashboard generator) and no charting beyond the minimal sparkline (that is the charts module).</td></tr>
|
|
8079
8154
|
<tr><td class="name">createAI</td><td class="desc">Create an AI narrative / insights controller (module <code>ai</code>) over a live grid. It produces a short, plain-language narrative of the grid's <em>computed</em> figures — a per-KPI / per-chart / per-column <code>explain</code>, or an <code>insights</code> panel over the current filtered view. The grid makes no AI call of its own: <code>createAI</code> imports no provider SDK, holds no key, and makes no network request; it calls one host callback, <code>ask({ system, messages, prompt, tools?, schema?, signal })</code> — your model, your key, your privacy decision — the same philosophy as the data adapters. Two grounding paths feed one guard: where the provider offers tool-use the model is given a curated read-only tool set (<code>getSchema</code>, <code>getProfile</code>, <code>getStatistics</code>, <code>getForecast</code>, <code>runQuery</code>) and the grid's own engine computes what it asks for; otherwise the module builds a facts packet from <code>grid.statistics</code>/the profile/forecasts/view counts and passes it in the prompt. Every figure in the narrative is reconciled against the values the engine produced this render — an ungrounded number is stripped before display (the number-reconciliation guard), so a hallucinated figure never reaches the user. The prompt is constrained to narrate-only; the layer is read-only and never mutates data. <code>redact</code> (a column id, a list, or a predicate) and <code>maxRows</code> bound what the module hands <code>ask()</code>, and the module sends nothing itself; an <code>ask()</code> error surfaces a friendly message and the grid stays fully usable, AI being additive rather than load-bearing. Complementary to <code>grid.ai</code> (the intent/plan skill layer): pass no <code>ask</code> and it adopts the grid's configured <code>ai.ask</code>, running the facts-packet path over it. Pass a headless grid for a DOM-free narrative; <code>facts(target)</code> returns the exact grounded packet without calling <code>ask()</code>. UMD global <code>LatticeGridAI</code>.</td></tr>
|
|
8080
8155
|
<tr><td class="name">createTabs</td><td class="desc">Create a tabbed grid (module <code>tabs</code>): a <code>role="tablist"</code> strip above a stack of <code>role="tabpanel"</code> regions, each hosting its own, independently-configured <code>createGrid</code> instance — "configure each tab as per a normal grid" rather than one grid whose state is swapped (<code>ColumnModel#applyState</code> only repositions/hides/resizes existing columns by id; it carries no field, type or row data, so a state-swap only works when every tab shares one schema). <code>createGrid</code> is injected (<code>createTabs(el, { createGrid, tabs })</code>), the same pattern the React/Vue/Svelte adapters use, so the module imports no engine code and adds nothing to a page that does not load it. A tab that names <code>from: '<tabId>'</code> gets a <code>source: { mode: 'derived', from: <the parent tab’s live grid>, where, group, join, … }</code> wired for it automatically — reusing the shipped derived-source mechanism rather than a new config-inheritance one — and activating a derived tab materialises its whole ancestor chain first; a cyclic <code>from</code> graph is refused (naming the exact cycle) when <code>createTabs</code> is called, not at first click. A tab’s grid mounts on first activation and then stays alive, hidden, so its scroll/selection/filters/sort/grouping/expansion — and an open cell/row editor, left exactly as it was, uncommitted and undiscarded — survive a switch natively; <code>destroy()</code> tears every mounted tab down. The strip is a real tablist with <code>aria-selected</code>, a roving <code>tabindex</code>, and manual-activation keyboard handling (arrows/Home/End move focus, Enter/Space or a click activates). Events: <code>tab:changed</code>, a cancellable <code>beforeTabChange</code> paired with <code>tabChange:cancelled</code>. UMD global <code>LatticeGridTabs</code>.</td></tr>
|
|
8081
|
-
<tr><td class="name">createLayout</td><td class="desc">Create a reconfigurable dashboard layout (module <code>layout</code>): a cell grid inside an element, and a set of windows on it that a user can move, resize and close by drag <em>or</em> by keyboard — the surface a customer would otherwise reach for GridStack to get. It is <strong>payload-agnostic</strong>: a window body is a <code>div</code> with an <code>id</code> that the module creates, sizes and never reads, so it imports no engine code at all (not even <code>createGrid</code>) and
|
|
8156
|
+
<tr><td class="name">createLayout</td><td class="desc">Create a reconfigurable dashboard layout (module <code>layout</code>): a cell grid inside an element, and a set of windows on it that a user can move, resize and close by drag <em>or</em> by keyboard — the surface a customer would otherwise reach for GridStack to get. It is <strong>payload-agnostic</strong>: a window body is a <code>div</code> with an <code>id</code> that the module creates, sizes and never reads, so it imports no engine code at all (not even <code>createGrid</code>) and the whole module is about 17,500 bytes gzipped on the built bundle, of which roughly 2KB is the shared module runtime. <code>columns</code>/<code>rows</code> divide the element; <code>overflowX</code> and <code>overflowY</code> are <em>independent</em> axes, each <code>'static'</code> (tracks divide the container with <code>minmax(0, 1fr)</code>) or <code>'scroll'</code> (tracks take a fixed <code>columnWidth</code>/<code>rowHeight</code> and the canvas extends past the viewport, so a column keeps the size it asked for — measured: shrinking a 600px host to 300px leaves a 200px column at 200px). Spacing takes a real CSS length: a number of pixels, or <code>'200px'</code>, <code>'25%'</code>, <code>'1fr'</code>, <code>'2rem'</code>; anything else is refused by name and replaced by the default, because the value reaches an inline style. Windows are placed by 1-based <code>xPos</code>/<code>yPos</code>/<code>xSize</code>/<code>ySize</code>, or auto-placed in the first free cell; <code>chrome</code> defaults on, and <code>closable</code>/<code>movable</code>/<code>resizable</code> all default <em>off</em>, so a fixed dashboard is fixed without opting out. <code>compact: 'vertical'</code> pushes displaced windows down then pulls them up (<code>window:moved</code> carries both <code>to</code> and <code>landed</code>); <code>'none'</code> keeps every window where it is put. <code>closable</code>/<code>movable</code>/<code>resizable</code> each also take a <em>layout-level</em> default of the same name, which a window's own boolean overrides, and <code>setInteractive(true|false|{movable, resizable, closable})</code> changes that default at runtime — the “Edit layout” button — without destroying the layout or any payload in it, with <code>getInteractive()</code> reading it back. Locking always wins and unlocking never overrides an opt-out: <code>setInteractive(false)</code> pins a window that declared <code>movable: true</code>, while <code>setInteractive(true)</code> leaves a window that declared <code>movable: false</code> pinned. The config key and the method are deliberately different: <code>movable: false</code> in the config states the <em>default</em> for windows that declare nothing and takes nothing away from one that opted in, whereas <code>setInteractive(false)</code> is an <em>active lock</em>. <code>getInteractive()</code> is three-valued — <code>undefined</code> for unset, <code>true</code>, or <code>false</code> for a lock — and a key carrying <code>undefined</code> is treated as absent, so <code>setInteractive(getInteractive())</code> is a no-op in every state. It moves both halves of the enforcement, the rendered handles <em>and</em> the pointer and keyboard gesture checks, and fires no event because a mode is not an arrangement — <code>getLayout()</code> neither carries it nor restores it. A locked layout is not a read-only dashboard: what is inside a window is configured with that payload's own settings. <code>maximise(id)</code>, <code>minimise(id)</code> and <code>restore(id)</code> are the display modes, with <code>maximised()</code> and <code>minimised()</code> reading them back: maximise fills the <em>layout host</em> rather than the browser window (no <code>position: fixed</code>, whose containing block is the nearest ancestor with a <code>transform</code> or a <code>contain</code>; no reparenting; nothing that can disturb the page around the dashboard), hides the other windows, runs <strong>no compaction at all</strong> and keeps the payload container as the very same DOM node — and <kbd>Escape</kbd> restores it from anywhere inside the layout. <code>minimise</code> draws a window as a single row and hides its payload while its chrome stays to carry the way back, so the windows below pull up on screen; in the arrangement nothing moves at all, because the collapse is a projection of the dashboard rather than a change to it, so restoring gives back exactly the arrangement that was there in <em>any</em> order and with any number of other windows still collapsed. A <code>chrome: false</code> window is refused by name. Both controls are opt-in per window (<code>maximisable</code>, <code>minimisable</code>) with a layout-level default of the same name, and <code>setInteractive()</code> deliberately does not touch either: a mode is not an arrangement, so neither appears in <code>getLayout()</code>, which reports the underlying placement in both states. Keyboard parity with the drag: a focusable handle per window running the kanban board's grab/move/drop/cancel model, with a polite live region announcing grabbed, every tentative position, dropped, cancelled and reverted. It owns exactly <strong>one</strong> <code>ResizeObserver</code> for the whole layout, over two targets, and tells payloads their new content box through <code>window:resized</code> — it never calls into a payload, because it cannot know what one is. Events: <code>window:moved</code>, <code>window:resized</code>, <code>window:closed</code>, <code>layout:changed</code>, the cancellable <code>beforeWindowMove</code>/<code>beforeWindowResize</code>/<code>beforeWindowClose</code> and their <code>*:cancelled</code> pairs; drag progress is not emitted per frame. <code>getLayout()</code>/<code>setLayout()</code> round-trip the arrangement as plain JSON, and <code>getState()</code>/<code>setState()</code> are the versioned pair. Closing a window does <strong>not</strong> destroy its payload — the container is handed back on <code>window:closed</code> and the host owns that lifecycle. UMD global <code>LatticeGridLayout</code>.</td></tr>
|
|
8082
8157
|
<tr><td class="name">createDevtools</td><td class="desc">Mount the devtools panel against a grid, including its accessibility checks.</td></tr>
|
|
8083
8158
|
<tr><td class="name">createGantt</td><td class="desc">Create a project-planning Gantt controller (module <code>gantt</code>) over a task list and a dependency list. A CPM engine (<code>computeSchedule</code>) computes each task's early/late start and finish, its slack and the zero-float critical path, honouring the four link types (<code>LINK_TYPES</code>: FS/SS/FF/SF) with lag, and recomputes on every edit — emitting <code>schedule</code> or, on a dependency cycle or bad input, <code>error</code> (a code from <code>SCHEDULE_ERROR</code>). Milestones are zero-duration points; summary (WBS) tasks are derived from their children (earliest start, latest finish, weighted progress) rather than scheduled; <code>findViolations</code> flags a task placed earlier than its predecessors allow, and <code>toISODate</code> maps an engine day-number back to a calendar date.</td></tr>
|
|
8084
8159
|
<tr><td class="name">createLatticeGridElement</td><td class="desc">Build the element class without registering it, for a custom registry.</td></tr>
|
|
@@ -9408,7 +9483,7 @@ grid.licence.state(); <span class="cmt">// 'licensed' | 'localhost' | 'trial'<
|
|
|
9408
9483
|
|
|
9409
9484
|
<footer>
|
|
9410
9485
|
<p>
|
|
9411
|
-
Lattice Grid 1.
|
|
9486
|
+
Lattice Grid 1.64.0 · Copyright © 2026 TOCLOCO Inc. All rights reserved.
|
|
9412
9487
|
Written against the shipped source. Where this guide and the code disagree, the code wins,
|
|
9413
9488
|
please <a href="https://www.latticegrid.dev">tell us</a>.
|
|
9414
9489
|
</p>
|
package/lattice-grid.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* Lattice Grid 1.
|
|
2
|
+
* Lattice Grid 1.64.0, type declarations
|
|
3
3
|
* Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
|
|
4
4
|
* https://latticegrid.dev
|
|
5
5
|
*/
|
|
@@ -5167,6 +5167,21 @@ export interface ColumnsApi {
|
|
|
5167
5167
|
totals(ids: string | string[]): void;
|
|
5168
5168
|
}
|
|
5169
5169
|
|
|
5170
|
+
/** One sprite: its view box, its path data, and how it is painted. */
|
|
5171
|
+
export interface IconGlyph {
|
|
5172
|
+
viewBox: string;
|
|
5173
|
+
paths: string[];
|
|
5174
|
+
paint: 'stroke' | 'fill';
|
|
5175
|
+
}
|
|
5176
|
+
|
|
5177
|
+
/** Read access to the grid's icon sprite set (see {@link Grid.icons}). */
|
|
5178
|
+
export interface IconRegistryApi {
|
|
5179
|
+
/** One glyph, as a copy, or null when the name is not registered. */
|
|
5180
|
+
get(name: string): IconGlyph | null;
|
|
5181
|
+
/** Every registered name, in registration order. */
|
|
5182
|
+
names(): string[];
|
|
5183
|
+
}
|
|
5184
|
+
|
|
5170
5185
|
export interface RowFormApi {
|
|
5171
5186
|
/** Open the form for a row. False when the form is not configured. */
|
|
5172
5187
|
open(key: string): boolean;
|
|
@@ -5642,6 +5657,13 @@ export interface AnnotationMark {
|
|
|
5642
5657
|
fontSize?: number;
|
|
5643
5658
|
/** An optional backing colour drawn behind a `text` mark's label. */
|
|
5644
5659
|
background?: string;
|
|
5660
|
+
/**
|
|
5661
|
+
* Which columns the mark belongs to: a pinned region holds still while the
|
|
5662
|
+
* grid scrolls sideways, the centre moves with it. Set from where a stroke
|
|
5663
|
+
* began; omitted (the centre) for every mark that is not over a pinned
|
|
5664
|
+
* column, so a mark saved before this existed reads unchanged.
|
|
5665
|
+
*/
|
|
5666
|
+
region?: 'start' | 'centre' | 'end';
|
|
5645
5667
|
}
|
|
5646
5668
|
|
|
5647
5669
|
export interface AnnotationApi {
|
|
@@ -6619,6 +6641,17 @@ export interface Grid {
|
|
|
6619
6641
|
/** The row form. Declines when `rowForm` is not configured. */
|
|
6620
6642
|
readonly form: RowFormApi;
|
|
6621
6643
|
|
|
6644
|
+
/**
|
|
6645
|
+
* The grid's icon registry, read-only.
|
|
6646
|
+
*
|
|
6647
|
+
* The same sprite set `registerIcon` writes to and every cell paints from,
|
|
6648
|
+
* reachable from the grid instance so that code outside the grid bundle — an
|
|
6649
|
+
* optional module drawing its own glyph, a network chart putting a `router`
|
|
6650
|
+
* on a node — draws from the one registry rather than a second, empty copy of
|
|
6651
|
+
* it. Register with `registerIcon` or `config.icons`, as before.
|
|
6652
|
+
*/
|
|
6653
|
+
readonly icons: IconRegistryApi;
|
|
6654
|
+
|
|
6622
6655
|
/** The library version. */
|
|
6623
6656
|
getVersion(): string;
|
|
6624
6657
|
/** Release everything: listeners, timers, workers and the DOM the grid made. */
|
|
@@ -7815,6 +7848,25 @@ export interface ChartSpec {
|
|
|
7815
7848
|
*/
|
|
7816
7849
|
shapes?: unknown;
|
|
7817
7850
|
codeProperty?: string;
|
|
7851
|
+
/**
|
|
7852
|
+
* The longitude column, for the types that place a row by where it is rather
|
|
7853
|
+
* than by a code: `markermap`, `bubblemap` and `hexmap`. Degrees east, -180
|
|
7854
|
+
* to 180; a row outside that, or with no reading, is left off the map and
|
|
7855
|
+
* counted.
|
|
7856
|
+
*/
|
|
7857
|
+
lon?: string;
|
|
7858
|
+
/**
|
|
7859
|
+
* The latitude column, beside {@link ChartSpec.lon}. Degrees north, -90 to
|
|
7860
|
+
* 90, on the same terms.
|
|
7861
|
+
*/
|
|
7862
|
+
lat?: string;
|
|
7863
|
+
/**
|
|
7864
|
+
* The measure a `markermap` writes beside each dot and colours it by. Its
|
|
7865
|
+
* text is the column's own formatted cell text and its colour is whatever
|
|
7866
|
+
* the column's conditional-formatting rules give that value, so a map and the
|
|
7867
|
+
* table beside it say the same thing about the same number.
|
|
7868
|
+
*/
|
|
7869
|
+
value?: string;
|
|
7818
7870
|
/**
|
|
7819
7871
|
* Which layer of a multi-layer geometry pack to draw — the UK pack, for
|
|
7820
7872
|
* instance, ships `regions`, `local-authorities` and `constituencies`
|
|
@@ -7882,6 +7934,25 @@ export interface ChartSpec {
|
|
|
7882
7934
|
values?: boolean;
|
|
7883
7935
|
/** Network layouts: how many relaxation passes to run. */
|
|
7884
7936
|
iterations?: number;
|
|
7937
|
+
/**
|
|
7938
|
+
* The nodes of a `network`, named by the host rather than inferred from the
|
|
7939
|
+
* rows: an icon per device, a label, and a position the layout must honour.
|
|
7940
|
+
* A node listed here that appears in no row is still drawn. A node in the
|
|
7941
|
+
* rows that is not listed here takes the chart's `icon` default and its own
|
|
7942
|
+
* id as its label.
|
|
7943
|
+
*/
|
|
7944
|
+
nodes?: ChartNode[];
|
|
7945
|
+
/**
|
|
7946
|
+
* The default glyph for a `network` node that names none of its own: any name
|
|
7947
|
+
* in the grid's icon registry (see {@link Grid.icons}). Unset, a node with no
|
|
7948
|
+
* icon is a plain disc.
|
|
7949
|
+
*/
|
|
7950
|
+
icon?: string;
|
|
7951
|
+
/**
|
|
7952
|
+
* A `network` link's stroke width in pixels, fixed. Unset, width follows the
|
|
7953
|
+
* link's value as a share of the heaviest link, as it always has.
|
|
7954
|
+
*/
|
|
7955
|
+
linkWidth?: number;
|
|
7885
7956
|
|
|
7886
7957
|
/**
|
|
7887
7958
|
* Control and capability charts: a tolerance overriding the column's own
|
|
@@ -7895,6 +7966,27 @@ export interface ChartSpec {
|
|
|
7895
7966
|
confidence?: number;
|
|
7896
7967
|
}
|
|
7897
7968
|
|
|
7969
|
+
/**
|
|
7970
|
+
* One node of a `network` chart, as the host declares it.
|
|
7971
|
+
*
|
|
7972
|
+
* `x` and `y` are fractions of the plot, 0 to 1, measured from its top-left. A
|
|
7973
|
+
* node giving both is **pinned** there and takes no part in the force
|
|
7974
|
+
* simulation; the rest are laid out around it, deterministically. Giving only
|
|
7975
|
+
* one of the two is not a position and the node is laid out.
|
|
7976
|
+
*/
|
|
7977
|
+
export interface ChartNode {
|
|
7978
|
+
/** Matches a value in the `source` or `target` column. */
|
|
7979
|
+
id: string;
|
|
7980
|
+
/** Drawn beneath the node. The id is used when this is absent. */
|
|
7981
|
+
label?: string;
|
|
7982
|
+
/** A name in the grid's icon registry, drawn inside the node's disc. */
|
|
7983
|
+
icon?: string;
|
|
7984
|
+
/** Where to pin it, as a fraction of the plot's width. */
|
|
7985
|
+
x?: number;
|
|
7986
|
+
/** Where to pin it, as a fraction of the plot's height. */
|
|
7987
|
+
y?: number;
|
|
7988
|
+
}
|
|
7989
|
+
|
|
7898
7990
|
/**
|
|
7899
7991
|
* The events a chart raises.
|
|
7900
7992
|
*
|