@toclocoinc/lattice-grid 1.71.1 → 1.71.3

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.
Files changed (195) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +1 -1
  3. package/angular/package.json +1 -1
  4. package/docs/API.html +42 -8
  5. package/docs/api/adapters.html +1 -1
  6. package/docs/api/ai.html +1 -1
  7. package/docs/api/alarms.html +1 -1
  8. package/docs/api/charts.html +39 -5
  9. package/docs/api/data-router.html +1 -1
  10. package/docs/api/gantt.html +1 -1
  11. package/docs/api/grid.html +2 -2
  12. package/docs/api/index.html +2 -2
  13. package/docs/api/kanban.html +1 -1
  14. package/docs/api/kpi.html +1 -1
  15. package/docs/api/layout.html +1 -1
  16. package/docs/api/mock-socket.html +1 -1
  17. package/docs/api/tabs.html +1 -1
  18. package/docs/api/types.html +1 -1
  19. package/docs/api-detail.html +4 -4
  20. package/docs/warnings.json +13 -2
  21. package/lattice-grid.d.ts +31 -7
  22. package/lattice-grid.esm.min.js +3 -3
  23. package/lattice-grid.min.cjs +3 -3
  24. package/lattice-grid.min.js +3 -3
  25. package/modules/ai.d.ts +1 -1
  26. package/modules/ai.esm.min.js +2 -2
  27. package/modules/ai.min.cjs +2 -2
  28. package/modules/ai.min.js +2 -2
  29. package/modules/alarms.d.ts +1 -1
  30. package/modules/alarms.esm.min.js +2 -2
  31. package/modules/alarms.min.cjs +2 -2
  32. package/modules/alarms.min.js +2 -2
  33. package/modules/angular.d.ts +1 -1
  34. package/modules/angular.esm.min.js +2 -2
  35. package/modules/angular.min.cjs +2 -2
  36. package/modules/angular.min.js +2 -2
  37. package/modules/chart-alluvial.d.ts +1 -1
  38. package/modules/chart-alluvial.esm.min.js +1 -1
  39. package/modules/chart-alluvial.min.cjs +1 -1
  40. package/modules/chart-alluvial.min.js +1 -1
  41. package/modules/chart-arc.d.ts +1 -1
  42. package/modules/chart-arc.esm.min.js +1 -1
  43. package/modules/chart-arc.min.cjs +1 -1
  44. package/modules/chart-arc.min.js +1 -1
  45. package/modules/chart-bubblemap.d.ts +1 -1
  46. package/modules/chart-bubblemap.esm.min.js +1 -1
  47. package/modules/chart-bubblemap.min.cjs +1 -1
  48. package/modules/chart-bubblemap.min.js +1 -1
  49. package/modules/chart-bump.d.ts +1 -1
  50. package/modules/chart-bump.esm.min.js +1 -1
  51. package/modules/chart-bump.min.cjs +1 -1
  52. package/modules/chart-bump.min.js +1 -1
  53. package/modules/chart-calendar.d.ts +1 -1
  54. package/modules/chart-calendar.esm.min.js +1 -1
  55. package/modules/chart-calendar.min.cjs +1 -1
  56. package/modules/chart-calendar.min.js +1 -1
  57. package/modules/chart-decomposition.d.ts +1 -1
  58. package/modules/chart-decomposition.esm.min.js +1 -1
  59. package/modules/chart-decomposition.min.cjs +1 -1
  60. package/modules/chart-decomposition.min.js +1 -1
  61. package/modules/chart-diverging.d.ts +1 -1
  62. package/modules/chart-diverging.esm.min.js +1 -1
  63. package/modules/chart-diverging.min.cjs +1 -1
  64. package/modules/chart-diverging.min.js +1 -1
  65. package/modules/chart-dumbbell.d.ts +1 -1
  66. package/modules/chart-dumbbell.esm.min.js +1 -1
  67. package/modules/chart-dumbbell.min.cjs +1 -1
  68. package/modules/chart-dumbbell.min.js +1 -1
  69. package/modules/chart-fan.d.ts +1 -1
  70. package/modules/chart-fan.esm.min.js +1 -1
  71. package/modules/chart-fan.min.cjs +1 -1
  72. package/modules/chart-fan.min.js +1 -1
  73. package/modules/chart-hexbin.d.ts +1 -1
  74. package/modules/chart-hexbin.esm.min.js +1 -1
  75. package/modules/chart-hexbin.min.cjs +1 -1
  76. package/modules/chart-hexbin.min.js +1 -1
  77. package/modules/chart-hexmap.d.ts +1 -1
  78. package/modules/chart-hexmap.esm.min.js +1 -1
  79. package/modules/chart-hexmap.min.cjs +1 -1
  80. package/modules/chart-hexmap.min.js +1 -1
  81. package/modules/chart-icicle.d.ts +1 -1
  82. package/modules/chart-icicle.esm.min.js +1 -1
  83. package/modules/chart-icicle.min.cjs +1 -1
  84. package/modules/chart-icicle.min.js +1 -1
  85. package/modules/chart-markermap.d.ts +1 -1
  86. package/modules/chart-markermap.esm.min.js +1 -1
  87. package/modules/chart-markermap.min.cjs +1 -1
  88. package/modules/chart-markermap.min.js +1 -1
  89. package/modules/chart-parallel.d.ts +1 -1
  90. package/modules/chart-parallel.esm.min.js +1 -1
  91. package/modules/chart-parallel.min.cjs +1 -1
  92. package/modules/chart-parallel.min.js +1 -1
  93. package/modules/chart-ridgeline.d.ts +1 -1
  94. package/modules/chart-ridgeline.esm.min.js +1 -1
  95. package/modules/chart-ridgeline.min.cjs +1 -1
  96. package/modules/chart-ridgeline.min.js +1 -1
  97. package/modules/chart-roc.d.ts +1 -1
  98. package/modules/chart-roc.esm.min.js +1 -1
  99. package/modules/chart-roc.min.cjs +1 -1
  100. package/modules/chart-roc.min.js +1 -1
  101. package/modules/chart-slope.d.ts +1 -1
  102. package/modules/chart-slope.esm.min.js +1 -1
  103. package/modules/chart-slope.min.cjs +1 -1
  104. package/modules/chart-slope.min.js +1 -1
  105. package/modules/chart-splom.d.ts +1 -1
  106. package/modules/chart-splom.esm.min.js +1 -1
  107. package/modules/chart-splom.min.cjs +1 -1
  108. package/modules/chart-splom.min.js +1 -1
  109. package/modules/chart-waffle.d.ts +1 -1
  110. package/modules/chart-waffle.esm.min.js +1 -1
  111. package/modules/chart-waffle.min.cjs +1 -1
  112. package/modules/chart-waffle.min.js +1 -1
  113. package/modules/charts.d.ts +1 -1
  114. package/modules/charts.esm.min.js +13 -9
  115. package/modules/charts.esm.min.js.map +2 -2
  116. package/modules/charts.min.cjs +141 -137
  117. package/modules/charts.min.js +141 -137
  118. package/modules/charts.min.js.map +2 -2
  119. package/modules/data-router.d.ts +1 -1
  120. package/modules/data-router.esm.min.js +2 -2
  121. package/modules/data-router.min.cjs +2 -2
  122. package/modules/data-router.min.js +2 -2
  123. package/modules/devtools.d.ts +1 -1
  124. package/modules/devtools.esm.min.js +1 -1
  125. package/modules/devtools.min.cjs +1 -1
  126. package/modules/devtools.min.js +1 -1
  127. package/modules/dhtmlx-compat.d.ts +1 -1
  128. package/modules/dhtmlx-compat.esm.min.js +2 -2
  129. package/modules/dhtmlx-compat.min.cjs +2 -2
  130. package/modules/dhtmlx-compat.min.js +2 -2
  131. package/modules/gantt.d.ts +1 -1
  132. package/modules/gantt.esm.min.js +2 -2
  133. package/modules/gantt.min.cjs +2 -2
  134. package/modules/gantt.min.js +2 -2
  135. package/modules/geo-europe-nuts.d.ts +1 -1
  136. package/modules/geo-europe-nuts.esm.min.js +1 -1
  137. package/modules/geo-europe-nuts.min.cjs +1 -1
  138. package/modules/geo-europe-nuts.min.js +1 -1
  139. package/modules/geo-uk.d.ts +1 -1
  140. package/modules/geo-uk.esm.min.js +1 -1
  141. package/modules/geo-uk.min.cjs +1 -1
  142. package/modules/geo-uk.min.js +1 -1
  143. package/modules/geo-us-states.d.ts +1 -1
  144. package/modules/geo-us-states.esm.min.js +1 -1
  145. package/modules/geo-us-states.min.cjs +1 -1
  146. package/modules/geo-us-states.min.js +1 -1
  147. package/modules/geo-world-110m.d.ts +1 -1
  148. package/modules/geo-world-110m.esm.min.js +1 -1
  149. package/modules/geo-world-110m.min.cjs +1 -1
  150. package/modules/geo-world-110m.min.js +1 -1
  151. package/modules/geo-world-50m.d.ts +1 -1
  152. package/modules/geo-world-50m.esm.min.js +1 -1
  153. package/modules/geo-world-50m.min.cjs +1 -1
  154. package/modules/geo-world-50m.min.js +1 -1
  155. package/modules/htmx.d.ts +1 -1
  156. package/modules/htmx.esm.min.js +3 -3
  157. package/modules/htmx.min.cjs +3 -3
  158. package/modules/htmx.min.js +3 -3
  159. package/modules/kanban.d.ts +1 -1
  160. package/modules/kanban.esm.min.js +2 -2
  161. package/modules/kanban.min.cjs +2 -2
  162. package/modules/kanban.min.js +2 -2
  163. package/modules/kpi.d.ts +1 -1
  164. package/modules/kpi.esm.min.js +2 -2
  165. package/modules/kpi.min.cjs +2 -2
  166. package/modules/kpi.min.js +2 -2
  167. package/modules/layout.d.ts +1 -1
  168. package/modules/layout.esm.min.js +2 -2
  169. package/modules/layout.min.cjs +2 -2
  170. package/modules/layout.min.js +2 -2
  171. package/modules/mock-socket.d.ts +1 -1
  172. package/modules/mock-socket.esm.min.js +1 -1
  173. package/modules/mock-socket.min.cjs +1 -1
  174. package/modules/mock-socket.min.js +1 -1
  175. package/modules/react.d.ts +1 -1
  176. package/modules/react.esm.min.js +2 -2
  177. package/modules/react.min.cjs +2 -2
  178. package/modules/react.min.js +2 -2
  179. package/modules/svelte.d.ts +1 -1
  180. package/modules/svelte.esm.min.js +2 -2
  181. package/modules/svelte.min.cjs +2 -2
  182. package/modules/svelte.min.js +2 -2
  183. package/modules/tabs.d.ts +1 -1
  184. package/modules/tabs.esm.min.js +2 -2
  185. package/modules/tabs.min.cjs +2 -2
  186. package/modules/tabs.min.js +2 -2
  187. package/modules/vue.d.ts +1 -1
  188. package/modules/vue.esm.min.js +2 -2
  189. package/modules/vue.min.cjs +2 -2
  190. package/modules/vue.min.js +2 -2
  191. package/modules/webcomponent.d.ts +1 -1
  192. package/modules/webcomponent.esm.min.js +3 -3
  193. package/modules/webcomponent.min.cjs +3 -3
  194. package/modules/webcomponent.min.js +3 -3
  195. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -9,6 +9,14 @@ and what it means for a grid already in production.
9
9
 
10
10
  ## [Unreleased]
11
11
 
12
+ ## [1.71.3] - 2026-09-25
13
+
14
+ ### Added
15
+
16
+ - A `scheme` array coloured slices and series by position, so a category or series a filter removed shifted every colour after it — a sites-by-status donut and a severity-stacked bar could not hold "Operational" green and "Offline" red once one status disappeared for a quarter (BACKLOG-0001453). `scheme` now also accepts a `{ name: colour }` map: it keys on the category for `pie`/`donut`/`sunburst`, on the series value for any cartesian type with `series`, and on the `x` category for a single-series `bar`/`horizontalBar`. A name absent from the map falls back to the ordered scheme by its position among the other unmapped names only, so an explicit assignment is never disturbed by a name the map does not mention. A map and an array `palette` do not combine — the map wins, once, with a warning (`chart:scheme:array-and-map`).
17
+ - `legend: { values: true }` appends each entry's own total after its name and a thin space — a category's for `pie`/`donut`, a series' for a series legend — formatted by the measure column.
18
+ - A `donut` now takes `centre: { value: 'total' | number | string, label? }`, drawn in the hole: `'total'` sums the slices actually drawn, a number is formatted the same way, a string is written through unchanged; both the value and an optional label are sized to fit the hole and never drawn past its edge.
19
+
12
20
  ## [1.71.1] - 2026-09-24
13
21
 
14
22
  ### Added
package/README.md CHANGED
@@ -5,7 +5,7 @@ dependencies, no build step required. Optional adapters for React, Vue, Svelte
5
5
  and Web Components ship alongside it, and Angular has compiled components of its
6
6
  own at `@toclocoinc/lattice-grid/angular` — inside this package, not beside it.
7
7
 
8
- Version 1.71.1 · [latticegrid.dev](https://www.latticegrid.dev) · TOCLOCO Inc
8
+ Version 1.71.3 · [latticegrid.dev](https://www.latticegrid.dev) · TOCLOCO Inc
9
9
 
10
10
  ---
11
11
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.71.1",
2
+ "version": "1.71.3",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
5
  "module": "./fesm2022/toclocoinc-lattice-grid-angular.mjs",
package/docs/API.html CHANGED
@@ -382,7 +382,7 @@
382
382
  <div class="shell">
383
383
  <aside class="rail">
384
384
  <p class="rail__brand">Lattice Grid</p>
385
- <p class="rail__sub">API reference · v1.71.1</p>
385
+ <p class="rail__sub">API reference · v1.71.3</p>
386
386
  <nav>
387
387
  <div class="rail__group">
388
388
  <span class="rail__label">Start</span>
@@ -553,7 +553,7 @@
553
553
  </header>
554
554
 
555
555
  <p class="chips">
556
- <span class="chip">Version 1.71.1</span>
556
+ <span class="chip">Version 1.71.3</span>
557
557
  <span class="chip">Zero dependencies</span>
558
558
  <span class="chip"><a href="api-detail.html">Developer guide &rarr;</a></span>
559
559
  </p>
@@ -2180,7 +2180,7 @@ grid.destroy();
2180
2180
  <table>
2181
2181
  <thead><tr><th>Member</th><th>Returns</th><th>Description</th></tr></thead>
2182
2182
  <tbody>
2183
- <tr><td class="sig">getVersion()</td><td class="type">string</td><td class="desc">The version this grid came from, e.g. <code>'1.71.1'</code>. Also on the module as <code>getVersion()</code>, for when you have no grid to hand.</td></tr>
2183
+ <tr><td class="sig">getVersion()</td><td class="type">string</td><td class="desc">The version this grid came from, e.g. <code>'1.71.3'</code>. Also on the module as <code>getVersion()</code>, for when you have no grid to hand.</td></tr>
2184
2184
  <tr><td class="sig">get(key)</td><td class="type">unknown</td><td class="desc">Read any configuration key.</td></tr>
2185
2185
  <tr><td class="sig">set(key, value)</td><td class="type">void</td><td class="desc">Write one key. Every key is live; nothing needs a rebuild.</td></tr>
2186
2186
  <tr><td class="sig">setAll(values)</td><td class="type">void</td><td class="desc">Write several in one pass. Emits one <code>config:changed</code> for the batch, not one per key.</td></tr>
@@ -5816,8 +5816,9 @@ const chart = createChart({
5816
5816
  <tr><td class="name">series</td><td class="type">string</td><td class="desc">Splits the measure into one series per distinct value.</td></tr>
5817
5817
  <tr><td class="name">measures</td><td class="type">object[]</td><td class="desc"><code>{col, fn, type, axis}</code>: several measures at once, each reduced by an aggregation. <code>fn</code> is one of <code>sum</code>, <code>avg</code> (alias <code>mean</code>), <code>min</code>, <code>max</code>, <code>count</code>, <code>countValues</code>, <code>first</code>, <code>last</code>; it defaults to <code>sum</code>. An <code>fn</code> that is none of these is a mistake, not a silent <code>sum</code>: it warns once, naming the value and the supported set, and falls back to <code>sum</code> so the chart still draws.</td></tr>
5818
5818
  <tr><td class="name">title</td><td class="type">string</td><td class="desc">Drawn above the plot.</td></tr>
5819
- <tr><td class="name">scheme</td><td class="type">string | string[]</td><td class="desc">A named scheme or your own colours. <code>schemeNames()</code> lists the built-in ones, including a colour-blind-safe palette.</td></tr>
5820
- <tr><td class="name">legend</td><td class="type">boolean | object</td><td class="desc"><code>position</code>, and <code>isolate</code> so a click shows only that series, which is what a reader with eight series wants, and what plain toggling makes them do in seven clicks.</td></tr>
5819
+ <tr><td class="name">scheme</td><td class="type">string | string[] | object</td><td class="desc">A named scheme, your own ordered colours, or a <code>{ name: colour }</code> map (BACKLOG-0001453). <code>schemeNames()</code> lists the built-in ones, including a colour-blind-safe palette. The map is what survives a filter: a pie or donut keys it on the category, a chart with <code>series</code> keys it on the series value, and a single-series bar or column keys it on the <code>x</code> category instead. A name the map does not mention falls back to the ordered scheme by its position among the other unmapped names, so <code>{ Operational: 'green', Offline: 'red' }</code> keeps "Operational" exactly as green whichever categories a filter leaves. A map and a <code>palette</code> array do not combine — the map wins, and the array is ignored once, with a warning.</td></tr>
5820
+ <tr><td class="name">legend</td><td class="type">boolean | object</td><td class="desc"><code>position</code>, <code>isolate</code> so a click shows only that series (what plain toggling makes a reader with eight series do in seven clicks), and <code>values: true</code>, which appends each entry's own total after its name and a thin space — a category's for pie and donut, a series' for a series legend — formatted by the measure column (BACKLOG-0001453).</td></tr>
5821
+ <tr><td class="name">centre</td><td class="type">object</td><td class="desc">A donut's own figure, drawn in its hole (BACKLOG-0001453); every other type ignores it, having no hole. <code>{ value: 'total' | number | string, label? }</code> — <code>'total'</code> sums the slices actually drawn, so hiding a category from the legend moves the figure with them; a number is formatted the same way; a string is written through unchanged. <code>label</code> is a second line beneath it. Both are sized to fit the hole and never drawn past its edge.</td></tr>
5821
5822
  <tr><td class="name">labels</td><td class="type">boolean | object</td><td class="desc">Values beside each mark. <code>position</code>, <code>format</code>, <code>minGap</code>. A label that would overlap one already placed is dropped rather than drawn over it. <code>horizontalBar</code> draws them exactly as <code>bar</code> does: the figure sits past the end of the bar and, where that would spill past the plot's right edge, inside the bar instead (BACKLOG-0001451).</td></tr>
5822
5823
  <tr><td class="name">axis</td><td class="type">object</td><td class="desc">Titles, tick density and formatting per axis.</td></tr>
5823
5824
  <tr><td class="name">reference</td><td class="type">object[]</td><td class="desc">Horizontal lines: <code>{value, label}</code>.</td></tr>
@@ -5938,6 +5939,38 @@ grid.destroy();
5938
5939
  exactly as before &mdash; a rule and a series both mean &ldquo;colour by something&rdquo;,
5939
5940
  and only one is read at a time.
5940
5941
  </p>
5942
+ <p class="section-note">
5943
+ <strong>A <code>scheme</code> can colour by name instead of by position</strong>
5944
+ (BACKLOG-0001453). <code>scheme: { Operational: 'green', Degraded: 'amber', Offline: 'red' }</code>
5945
+ keys on the category for a <code>pie</code>, <code>donut</code> or <code>sunburst</code>; on
5946
+ the series value for any cartesian type with a <code>series</code> column; and on the
5947
+ <code>x</code> category for a single-series <code>bar</code> or <code>horizontalBar</code>
5948
+ &mdash; the same "no <code>series</code>" case the rule colour above reads, and a rule still
5949
+ outranks the map where both apply. The point of the map is what an ordered array cannot do: a
5950
+ category a filter removes never shifts the colour of the ones that stay, because each name's
5951
+ colour comes from the map rather than from where it happens to sort. A name the map does not
5952
+ mention falls back to the ordered scheme by its position among the <em>other unmapped</em>
5953
+ names only. A map and an array <code>palette</code> are two ways of choosing the same thing
5954
+ and do not combine &mdash; given both, the map wins and the array is ignored, once, with a
5955
+ warning (<code>chart:scheme:array-and-map</code>).
5956
+ </p>
5957
+ <p class="section-note">
5958
+ <strong><code>legend: { values: true }</code> writes the number beside the name</strong>
5959
+ (BACKLOG-0001453). Each entry gets its own total appended after a thin space &mdash; the
5960
+ category's for a <code>pie</code> or <code>donut</code>, the series' for a series legend
5961
+ &mdash; formatted by the measure column exactly as a cell in that column would be, so a
5962
+ legend reading "Operational&nbsp;42" and a filtered grid never disagree about what 42 means.
5963
+ </p>
5964
+ <p class="section-note">
5965
+ <strong>A donut can carry a figure in its own hole</strong> (BACKLOG-0001453):
5966
+ <code>centre: { value: 'total', label: 'sites' }</code>. <code>'total'</code> sums the slices
5967
+ actually drawn, so hiding a category from the legend moves the figure with the slices rather
5968
+ than leaving it stale; a number is a caller's own figure, formatted the same way; a string is
5969
+ written through unchanged, for a centre naming something a sum cannot. <code>label</code> is a
5970
+ second line beneath the value. Both are sized to the hole a donut cuts &mdash; never a pie's,
5971
+ which has none &mdash; and are shrunk together, proportionally, and truncated rather than
5972
+ drawn past its edge.
5973
+ </p>
5941
5974
 
5942
5975
  <h3>The chart</h3>
5943
5976
  <div class="table-wrap">
@@ -14740,8 +14773,9 @@ return `next ${p.mean.toFixed(1)}; r2 ${f.r2.toFixed(1)}; band ${p.upper - p.low
14740
14773
  <tr><td class="name">start</td><td class="type">string</td><td class="desc">The start-date column, for a gantt chart. <small>(optional)</small></td></tr>
14741
14774
  <tr><td class="name">end</td><td class="type">string</td><td class="desc">The end-date column, for a gantt chart. <small>(optional)</small></td></tr>
14742
14775
  <tr><td class="name">title</td><td class="type">string</td><td class="desc">A heading above the plot, drawn in the figure's caption alongside any `subtitle`. <small>(optional)</small></td></tr>
14743
- <tr><td class="name">scheme</td><td class="type"><a href="#type-ChartSchemeName">ChartSchemeName</a> | string | string[]</td><td class="desc">A named scheme, or an array of colours. The built-in names are {@link ChartSchemeName} (`'default'`, `'bright'`, `'earth'`, `'mono'`); a name registered with `registerScheme` is a plain string alongside them. <small>(optional)</small></td></tr>
14744
- <tr><td class="name">legend</td><td class="type">boolean | { position?: 'top' | 'bottom' | 'left' | 'right'; isolate?: boolean }</td><td class="desc">Show the series legend. The object form places it, and `isolate` lets a click on a legend entry show that series alone. <small>(optional)</small></td></tr>
14776
+ <tr><td class="name">scheme</td><td class="type"><a href="#type-ChartSchemeName">ChartSchemeName</a> | string | string[] | Record&lt;string, string&gt;</td><td class="desc">A named scheme, an array of colours, or a `{ [name]: colour }` map (BACKLOG-0001453). The built-in names are {@link ChartSchemeName} (`'default'`, `'bright'`, `'earth'`, `'mono'`); a name registered with `registerScheme` is a plain string alongside them. The map is the form that survives a filter: a pie or donut keys it on the category (`x`) value, a chart with a `series` column keys it on the series value, and a single-series bar or column — no `series` — keys it on the `x` category instead. A name absent from the map falls back to the ordered scheme by its position among the *other unmapped* names, so `{ Operational: 'green' }` keeps every other category exactly as it was whichever ones a filter removes — an ordered array reassigns every colour after the gap. A map and an array `palette` do not combine; given both, the map wins and the array is ignored, once, with a warning. <small>(optional)</small></td></tr>
14777
+ <tr><td class="name">legend</td><td class="type">boolean | { position?: 'top' | 'bottom' | 'left' | 'right'; isolate?: boolean; values?: boolean; }</td><td class="desc">Show the series legend. The object form places it, and `isolate` lets a click on a legend entry show that series alone. `values: true` appends each entry's own total — a category's for pie and donut, a series' for a series legend — formatted by the measure column, after the name and a thin space (BACKLOG-0001453). <small>(optional)</small></td></tr>
14778
+ <tr><td class="name">centre</td><td class="type">{ value: 'total' | number | string; label?: string }</td><td class="desc">The figure a donut draws in its own hole (BACKLOG-0001453); ignored by every other type, which has no hole to draw into. `value: 'total'` sums the slices actually drawn — a legend click that hides a category moves the figure with them — formatted by the measure column; a number is a caller's own figure, formatted the same way; a string is written through unchanged. `label` is a second line beneath it. Both are sized to fit the hole and are never drawn past its edge. <small>(optional)</small></td></tr>
14745
14779
  <tr><td class="name">labels</td><td class="type">boolean | <a href="#type-ChartLabels">ChartLabels</a></td><td class="desc">Print the value beside each mark. `true` takes the defaults; the object form sets the position, the format and the minimum gap. Only the chart types that support labels honour it. <small>(optional)</small></td></tr>
14746
14780
  <tr><td class="name">axis</td><td class="type">{ x?: string | <a href="#type-ChartAxis">ChartAxis</a>; y?: string | <a href="#type-ChartAxis">ChartAxis</a>; y2?: string | <a href="#type-ChartAxis">ChartAxis</a>; right?: string | <a href="#type-ChartAxis">ChartAxis</a>; }</td><td class="desc">Per-axis configuration. Each side is a title string or an object of `{ title, min, max, ticks, format, grid, labels }`. `y2` (or `right`) configures the second measure axis of a dual-axis or combo chart (BACKLOG-0000743); a dual-axis chart labels both axes by default so it cannot silently mislead. <small>(optional)</small></td></tr>
14747
14781
  <tr><td class="name">brush</td><td class="type">boolean | 'filter' | 'zoom' | 'select' | { mode: 'filter' | 'zoom' | 'select'; axis?: 'x' | 'y' | 'y2' }</td><td class="desc">Dragging across the plot. `true` or `'filter'` writes a range condition into the grid; `'zoom'` changes only this chart's own domain; `'select'` selects the rows under the drag. The object form names which axis the drag acts on — `axis: 'y'` or `'y2'` brushes a value axis, which on a dual-axis chart must say which one it means (BACKLOG-0000743). <small>(optional)</small></td></tr>
@@ -20337,7 +20371,7 @@ return `next ${p.mean.toFixed(1)}; r2 ${f.r2.toFixed(1)}; band ${p.upper - p.low
20337
20371
  <!-- END GENERATED TYPE REFERENCE -->
20338
20372
 
20339
20373
  <footer>
20340
- Lattice Grid 1.71.1 · Copyright © 2026 TOCLOCO Inc. All rights reserved.
20374
+ Lattice Grid 1.71.3 · Copyright © 2026 TOCLOCO Inc. All rights reserved.
20341
20375
  This document describes the behaviour of the shipped library. Where this guide and the code
20342
20376
  disagree, the code wins: please <a href="https://www.latticegrid.dev">tell us</a>.
20343
20377
  </footer>
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>Adapters API Reference — Lattice Grid 1.71.1</title>
16
+ <title>Adapters API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
package/docs/api/ai.html CHANGED
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>AI API Reference — Lattice Grid 1.71.1</title>
16
+ <title>AI API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>Alarms API Reference — Lattice Grid 1.71.1</title>
16
+ <title>Alarms API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>Charts API Reference — Lattice Grid 1.71.1</title>
16
+ <title>Charts API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -478,8 +478,9 @@ const chart = createChart({
478
478
  <tr><td class="name">series</td><td class="type">string</td><td class="desc">Splits the measure into one series per distinct value.</td></tr>
479
479
  <tr><td class="name">measures</td><td class="type">object[]</td><td class="desc"><code>{col, fn, type, axis}</code>: several measures at once, each reduced by an aggregation. <code>fn</code> is one of <code>sum</code>, <code>avg</code> (alias <code>mean</code>), <code>min</code>, <code>max</code>, <code>count</code>, <code>countValues</code>, <code>first</code>, <code>last</code>; it defaults to <code>sum</code>. An <code>fn</code> that is none of these is a mistake, not a silent <code>sum</code>: it warns once, naming the value and the supported set, and falls back to <code>sum</code> so the chart still draws.</td></tr>
480
480
  <tr><td class="name">title</td><td class="type">string</td><td class="desc">Drawn above the plot.</td></tr>
481
- <tr><td class="name">scheme</td><td class="type">string | string[]</td><td class="desc">A named scheme or your own colours. <code>schemeNames()</code> lists the built-in ones, including a colour-blind-safe palette.</td></tr>
482
- <tr><td class="name">legend</td><td class="type">boolean | object</td><td class="desc"><code>position</code>, and <code>isolate</code> so a click shows only that series, which is what a reader with eight series wants, and what plain toggling makes them do in seven clicks.</td></tr>
481
+ <tr><td class="name">scheme</td><td class="type">string | string[] | object</td><td class="desc">A named scheme, your own ordered colours, or a <code>{ name: colour }</code> map (BACKLOG-0001453). <code>schemeNames()</code> lists the built-in ones, including a colour-blind-safe palette. The map is what survives a filter: a pie or donut keys it on the category, a chart with <code>series</code> keys it on the series value, and a single-series bar or column keys it on the <code>x</code> category instead. A name the map does not mention falls back to the ordered scheme by its position among the other unmapped names, so <code>{ Operational: 'green', Offline: 'red' }</code> keeps "Operational" exactly as green whichever categories a filter leaves. A map and a <code>palette</code> array do not combine — the map wins, and the array is ignored once, with a warning.</td></tr>
482
+ <tr><td class="name">legend</td><td class="type">boolean | object</td><td class="desc"><code>position</code>, <code>isolate</code> so a click shows only that series (what plain toggling makes a reader with eight series do in seven clicks), and <code>values: true</code>, which appends each entry's own total after its name and a thin space — a category's for pie and donut, a series' for a series legend — formatted by the measure column (BACKLOG-0001453).</td></tr>
483
+ <tr><td class="name">centre</td><td class="type">object</td><td class="desc">A donut's own figure, drawn in its hole (BACKLOG-0001453); every other type ignores it, having no hole. <code>{ value: 'total' | number | string, label? }</code> — <code>'total'</code> sums the slices actually drawn, so hiding a category from the legend moves the figure with them; a number is formatted the same way; a string is written through unchanged. <code>label</code> is a second line beneath it. Both are sized to fit the hole and never drawn past its edge.</td></tr>
483
484
  <tr><td class="name">labels</td><td class="type">boolean | object</td><td class="desc">Values beside each mark. <code>position</code>, <code>format</code>, <code>minGap</code>. A label that would overlap one already placed is dropped rather than drawn over it. <code>horizontalBar</code> draws them exactly as <code>bar</code> does: the figure sits past the end of the bar and, where that would spill past the plot's right edge, inside the bar instead (BACKLOG-0001451).</td></tr>
484
485
  <tr><td class="name">axis</td><td class="type">object</td><td class="desc">Titles, tick density and formatting per axis.</td></tr>
485
486
  <tr><td class="name">reference</td><td class="type">object[]</td><td class="desc">Horizontal lines: <code>{value, label}</code>.</td></tr>
@@ -600,6 +601,38 @@ grid.destroy();
600
601
  exactly as before &mdash; a rule and a series both mean &ldquo;colour by something&rdquo;,
601
602
  and only one is read at a time.
602
603
  </p>
604
+ <p class="section-note">
605
+ <strong>A <code>scheme</code> can colour by name instead of by position</strong>
606
+ (BACKLOG-0001453). <code>scheme: { Operational: 'green', Degraded: 'amber', Offline: 'red' }</code>
607
+ keys on the category for a <code>pie</code>, <code>donut</code> or <code>sunburst</code>; on
608
+ the series value for any cartesian type with a <code>series</code> column; and on the
609
+ <code>x</code> category for a single-series <code>bar</code> or <code>horizontalBar</code>
610
+ &mdash; the same "no <code>series</code>" case the rule colour above reads, and a rule still
611
+ outranks the map where both apply. The point of the map is what an ordered array cannot do: a
612
+ category a filter removes never shifts the colour of the ones that stay, because each name's
613
+ colour comes from the map rather than from where it happens to sort. A name the map does not
614
+ mention falls back to the ordered scheme by its position among the <em>other unmapped</em>
615
+ names only. A map and an array <code>palette</code> are two ways of choosing the same thing
616
+ and do not combine &mdash; given both, the map wins and the array is ignored, once, with a
617
+ warning (<code>chart:scheme:array-and-map</code>).
618
+ </p>
619
+ <p class="section-note">
620
+ <strong><code>legend: { values: true }</code> writes the number beside the name</strong>
621
+ (BACKLOG-0001453). Each entry gets its own total appended after a thin space &mdash; the
622
+ category's for a <code>pie</code> or <code>donut</code>, the series' for a series legend
623
+ &mdash; formatted by the measure column exactly as a cell in that column would be, so a
624
+ legend reading "Operational&nbsp;42" and a filtered grid never disagree about what 42 means.
625
+ </p>
626
+ <p class="section-note">
627
+ <strong>A donut can carry a figure in its own hole</strong> (BACKLOG-0001453):
628
+ <code>centre: { value: 'total', label: 'sites' }</code>. <code>'total'</code> sums the slices
629
+ actually drawn, so hiding a category from the legend moves the figure with the slices rather
630
+ than leaving it stale; a number is a caller's own figure, formatted the same way; a string is
631
+ written through unchanged, for a centre naming something a sum cannot. <code>label</code> is a
632
+ second line beneath the value. Both are sized to the hole a donut cuts &mdash; never a pie's,
633
+ which has none &mdash; and are shrunk together, proportionally, and truncated rather than
634
+ drawn past its edge.
635
+ </p>
603
636
 
604
637
  <h3>The chart</h3>
605
638
  <div class="table-wrap">
@@ -1155,8 +1188,9 @@ chart.destroy();
1155
1188
  <tr><td class="name">start</td><td class="type">string</td><td class="desc">The start-date column, for a gantt chart. <small>(optional)</small></td></tr>
1156
1189
  <tr><td class="name">end</td><td class="type">string</td><td class="desc">The end-date column, for a gantt chart. <small>(optional)</small></td></tr>
1157
1190
  <tr><td class="name">title</td><td class="type">string</td><td class="desc">A heading above the plot, drawn in the figure's caption alongside any `subtitle`. <small>(optional)</small></td></tr>
1158
- <tr><td class="name">scheme</td><td class="type"><a href="types.html#type-ChartSchemeName">ChartSchemeName</a> | string | string[]</td><td class="desc">A named scheme, or an array of colours. The built-in names are {@link ChartSchemeName} (`'default'`, `'bright'`, `'earth'`, `'mono'`); a name registered with `registerScheme` is a plain string alongside them. <small>(optional)</small></td></tr>
1159
- <tr><td class="name">legend</td><td class="type">boolean | { position?: 'top' | 'bottom' | 'left' | 'right'; isolate?: boolean }</td><td class="desc">Show the series legend. The object form places it, and `isolate` lets a click on a legend entry show that series alone. <small>(optional)</small></td></tr>
1191
+ <tr><td class="name">scheme</td><td class="type"><a href="types.html#type-ChartSchemeName">ChartSchemeName</a> | string | string[] | Record&lt;string, string&gt;</td><td class="desc">A named scheme, an array of colours, or a `{ [name]: colour }` map (BACKLOG-0001453). The built-in names are {@link ChartSchemeName} (`'default'`, `'bright'`, `'earth'`, `'mono'`); a name registered with `registerScheme` is a plain string alongside them. The map is the form that survives a filter: a pie or donut keys it on the category (`x`) value, a chart with a `series` column keys it on the series value, and a single-series bar or column — no `series` — keys it on the `x` category instead. A name absent from the map falls back to the ordered scheme by its position among the *other unmapped* names, so `{ Operational: 'green' }` keeps every other category exactly as it was whichever ones a filter removes — an ordered array reassigns every colour after the gap. A map and an array `palette` do not combine; given both, the map wins and the array is ignored, once, with a warning. <small>(optional)</small></td></tr>
1192
+ <tr><td class="name">legend</td><td class="type">boolean | { position?: 'top' | 'bottom' | 'left' | 'right'; isolate?: boolean; values?: boolean; }</td><td class="desc">Show the series legend. The object form places it, and `isolate` lets a click on a legend entry show that series alone. `values: true` appends each entry's own total — a category's for pie and donut, a series' for a series legend — formatted by the measure column, after the name and a thin space (BACKLOG-0001453). <small>(optional)</small></td></tr>
1193
+ <tr><td class="name">centre</td><td class="type">{ value: 'total' | number | string; label?: string }</td><td class="desc">The figure a donut draws in its own hole (BACKLOG-0001453); ignored by every other type, which has no hole to draw into. `value: 'total'` sums the slices actually drawn — a legend click that hides a category moves the figure with them — formatted by the measure column; a number is a caller's own figure, formatted the same way; a string is written through unchanged. `label` is a second line beneath it. Both are sized to fit the hole and are never drawn past its edge. <small>(optional)</small></td></tr>
1160
1194
  <tr><td class="name">labels</td><td class="type">boolean | <a href="types.html#type-ChartLabels">ChartLabels</a></td><td class="desc">Print the value beside each mark. `true` takes the defaults; the object form sets the position, the format and the minimum gap. Only the chart types that support labels honour it. <small>(optional)</small></td></tr>
1161
1195
  <tr><td class="name">axis</td><td class="type">{ x?: string | <a href="types.html#type-ChartAxis">ChartAxis</a>; y?: string | <a href="types.html#type-ChartAxis">ChartAxis</a>; y2?: string | <a href="types.html#type-ChartAxis">ChartAxis</a>; right?: string | <a href="types.html#type-ChartAxis">ChartAxis</a>; }</td><td class="desc">Per-axis configuration. Each side is a title string or an object of `{ title, min, max, ticks, format, grid, labels }`. `y2` (or `right`) configures the second measure axis of a dual-axis or combo chart (BACKLOG-0000743); a dual-axis chart labels both axes by default so it cannot silently mislead. <small>(optional)</small></td></tr>
1162
1196
  <tr><td class="name">brush</td><td class="type">boolean | 'filter' | 'zoom' | 'select' | { mode: 'filter' | 'zoom' | 'select'; axis?: 'x' | 'y' | 'y2' }</td><td class="desc">Dragging across the plot. `true` or `'filter'` writes a range condition into the grid; `'zoom'` changes only this chart's own domain; `'select'` selects the rows under the drag. The object form names which axis the drag acts on — `axis: 'y'` or `'y2'` brushes a value axis, which on a dual-axis chart must say which one it means (BACKLOG-0000743). <small>(optional)</small></td></tr>
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>Data router API Reference — Lattice Grid 1.71.1</title>
16
+ <title>Data router API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>Gantt API Reference — Lattice Grid 1.71.1</title>
16
+ <title>Gantt API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>Grid API Reference — Lattice Grid 1.71.1</title>
16
+ <title>Grid API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -1115,7 +1115,7 @@ grid.destroy();
1115
1115
  <table>
1116
1116
  <thead><tr><th>Member</th><th>Returns</th><th>Description</th></tr></thead>
1117
1117
  <tbody>
1118
- <tr><td class="sig">getVersion()</td><td class="type">string</td><td class="desc">The version this grid came from, e.g. <code>'1.71.1'</code>. Also on the module as <code>getVersion()</code>, for when you have no grid to hand.</td></tr>
1118
+ <tr><td class="sig">getVersion()</td><td class="type">string</td><td class="desc">The version this grid came from, e.g. <code>'1.71.3'</code>. Also on the module as <code>getVersion()</code>, for when you have no grid to hand.</td></tr>
1119
1119
  <tr><td class="sig">get(key)</td><td class="type">unknown</td><td class="desc">Read any configuration key.</td></tr>
1120
1120
  <tr><td class="sig">set(key, value)</td><td class="type">void</td><td class="desc">Write one key. Every key is live; nothing needs a rebuild.</td></tr>
1121
1121
  <tr><td class="sig">setAll(values)</td><td class="type">void</td><td class="desc">Write several in one pass. Emits one <code>config:changed</code> for the batch, not one per key.</td></tr>
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>API Reference — Lattice Grid 1.71.1</title>
16
+ <title>API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -427,7 +427,7 @@
427
427
  <thead><tr><th>Page</th><th>What is on it</th><th>Sections</th><th>Interfaces</th><th>Members</th></tr></thead>
428
428
  <tbody>
429
429
  <tr><td class="name"><a href="grid.html">The grid</a></td><td class="desc">Constructing a grid, every configuration property, the column definition, each <code>grid.*</code> sub-API, the sources rows come from, and every event the grid raises.</td><td class="type">56</td><td class="type">269</td><td class="type">1891</td></tr>
430
- <tr><td class="name"><a href="charts.html">The charts module</a></td><td class="desc"><code>createChart</code>, the chart types and their options, the axes, annotations and tooltips, and the geographic packs.</td><td class="type">1</td><td class="type">5</td><td class="type">108</td></tr>
430
+ <tr><td class="name"><a href="charts.html">The charts module</a></td><td class="desc"><code>createChart</code>, the chart types and their options, the axes, annotations and tooltips, and the geographic packs.</td><td class="type">1</td><td class="type">5</td><td class="type">109</td></tr>
431
431
  <tr><td class="name"><a href="data-router.html">The data router</a></td><td class="desc"><code>createDataRouter</code>: one stream or one dataset split across many viewers, keyed-diff snapshots, join and rollup routes, and backpressure.</td><td class="type">1</td><td class="type">12</td><td class="type">110</td></tr>
432
432
  <tr><td class="name"><a href="kpi.html">The KPI (stat-tile) view</a></td><td class="desc"><code>createKPI</code>: stat tiles over a dataset, the aggregations, baselines and delta, threshold bands, sparklines and the tile tree.</td><td class="type">1</td><td class="type">17</td><td class="type">130</td></tr>
433
433
  <tr><td class="name"><a href="alarms.html">The alarms module</a></td><td class="desc"><code>createAlarms</code>: levelled alarm events from KPI tiles, grid cells and router routes — raise and clear, with a hold timer that swallows a flapping feed.</td><td class="type">1</td><td class="type">8</td><td class="type">44</td></tr>
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>Kanban API Reference — Lattice Grid 1.71.1</title>
16
+ <title>Kanban API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
package/docs/api/kpi.html CHANGED
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>KPI API Reference — Lattice Grid 1.71.1</title>
16
+ <title>KPI API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>Layout API Reference — Lattice Grid 1.71.1</title>
16
+ <title>Layout API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>Mock socket API Reference — Lattice Grid 1.71.1</title>
16
+ <title>Mock socket API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>Tabs API Reference — Lattice Grid 1.71.1</title>
16
+ <title>Tabs API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -13,7 +13,7 @@
13
13
  Self-contained: no stylesheet, script or font is fetched, so this opens from disk, from
14
14
  a file share or from behind a firewall with nothing else present.
15
15
  -->
16
- <title>Types API Reference — Lattice Grid 1.71.1</title>
16
+ <title>Types API Reference — Lattice Grid 1.71.3</title>
17
17
  <style>
18
18
  /* ---------------------------------------------------------------
19
19
  Palette lifted from the grid's own theme, so the reference reads as an
@@ -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.71.1</p>
440
+ <p class="rail__sub">Developer guide · v1.71.3</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.71.1</span>
557
+ <span class="chip">Version 1.71.3</span>
558
558
  <span class="chip">Zero dependencies</span>
559
559
  <span class="chip">No build step</span>
560
560
  </p>
@@ -1493,7 +1493,7 @@ off(); <span class="cmt">// every subscrip
1493
1493
  </p>
1494
1494
  <div class="example">
1495
1495
  <p class="example__label">Which version am I running?</p>
1496
- <pre><code>grid.getVersion(); <span class="cmt">// '1.71.1'</span>
1496
+ <pre><code>grid.getVersion(); <span class="cmt">// '1.71.3'</span>
1497
1497
  LatticeGrid.getVersion(); <span class="cmt">// the same, when you have no grid to hand</span></code></pre>
1498
1498
  </div>
1499
1499
  <p class="lead-in">
@@ -10175,7 +10175,7 @@ grid.licence.state(); <span class="cmt">// 'licensed' | 'localhost' | 'trial'<
10175
10175
 
10176
10176
  <footer>
10177
10177
  <p>
10178
- Lattice Grid 1.71.1 · Copyright © 2026 TOCLOCO Inc. All rights reserved.
10178
+ Lattice Grid 1.71.3 · Copyright © 2026 TOCLOCO Inc. All rights reserved.
10179
10179
  Written against the shipped source. Where this guide and the code disagree, the code wins,
10180
10180
  please <a href="https://www.latticegrid.dev">tell us</a>.
10181
10181
  </p>
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.71.1",
2
+ "version": "1.71.3",
3
3
  "generated": "tools/build.js from docs/warnings/catalogue.json",
4
4
  "about": "Every developer-facing diagnostic Lattice Grid prints to the console, by the key it de-duplicates on. The key is the stable identifier: it is the `id` of every reported entry `grid.diagnostics.warnings()` hands back, what the devtools panel lists, and what to quote in a support conversation. A `*` in an id stands for a value filled in at runtime (a column id, a chart id, an event name), so `icon:*` is one entry covering every column the icon renderer refuses.",
5
5
  "fields": {
@@ -14,7 +14,7 @@
14
14
  "snippet": "the smallest configuration that fixes it, where configuration is the answer",
15
15
  "docs": "the section of the API reference that covers the feature"
16
16
  },
17
- "count": 474,
17
+ "count": 475,
18
18
  "warnings": [
19
19
  {
20
20
  "id": "ai:actorbar:no-el",
@@ -4975,6 +4975,17 @@
4975
4975
  "fix": "Pass the router instance (`createRouter()`'s return, or the one an adapter exposes) and, optionally, the partition kind to publish under.",
4976
4976
  "snippet": "alarms.publish(router, 'alarms');\nrouter.attach(alarmGrid, 'alarms');",
4977
4977
  "docs": "api/alarms.html#ref-alarms-reference"
4978
+ },
4979
+ {
4980
+ "id": "chart:scheme:array-and-map",
4981
+ "module": "charts",
4982
+ "severity": "warn",
4983
+ "since": "1.71.2",
4984
+ "message": "chart \"scheme\" was given as a name map together with a \"palette\" array; the two do not combine. Colours came from the map and the array was ignored. Pass one or the other.",
4985
+ "meaning": "A `scheme` name map and an array `palette` are two different ways of choosing a chart's colours, and only one can be read. Given both, the map is treated as the caller's intent and the array is dropped, because a map names an explicit colour per category or series while an array only orders them — the more specific instruction wins.",
4986
+ "fix": "Pass either a `scheme` name map (`{ [name]: colour }`) or a `palette` array, not both.",
4987
+ "snippet": "createChart({ grid, container, type: 'donut', x: 'status', y: 'count', scheme: { Operational: 'green', Offline: 'red' } });",
4988
+ "docs": "api/charts.html#chartsmodule"
4978
4989
  }
4979
4990
  ]
4980
4991
  }
package/lattice-grid.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Lattice Grid 1.71.1, type declarations
2
+ * Lattice Grid 1.71.3, type declarations
3
3
  * Copyright (c) 2026 TOCLOCO Inc. All rights reserved.
4
4
  * https://latticegrid.dev
5
5
  */
@@ -12100,16 +12100,40 @@ export interface ChartSpec {
12100
12100
  /** A heading above the plot, drawn in the figure's caption alongside any `subtitle`. */
12101
12101
  title?: string;
12102
12102
  /**
12103
- * A named scheme, or an array of colours. The built-in names are
12104
- * {@link ChartSchemeName} (`'default'`, `'bright'`, `'earth'`, `'mono'`);
12105
- * a name registered with `registerScheme` is a plain string alongside them.
12103
+ * A named scheme, an array of colours, or a `{ [name]: colour }` map. The built-in names are {@link ChartSchemeName}
12104
+ * (`'default'`, `'bright'`, `'earth'`, `'mono'`); a name registered with
12105
+ * `registerScheme` is a plain string alongside them.
12106
+ *
12107
+ * The map is the form that survives a filter: a pie or donut keys it on the
12108
+ * category (`x`) value, a chart with a `series` column keys it on the
12109
+ * series value, and a single-series bar or column — no `series` — keys it
12110
+ * on the `x` category instead. A name absent from the map falls back to the
12111
+ * ordered scheme by its position among the *other unmapped* names, so
12112
+ * `{ Operational: 'green' }` keeps every other category exactly as it was
12113
+ * whichever ones a filter removes — an ordered array reassigns every colour
12114
+ * after the gap. A map and an array `palette` do not combine; given both,
12115
+ * the map wins and the array is ignored, once, with a warning.
12106
12116
  */
12107
- scheme?: ChartSchemeName | string | string[];
12117
+ scheme?: ChartSchemeName | string | string[] | Record<string, string>;
12108
12118
  /**
12109
12119
  * Show the series legend. The object form places it, and `isolate` lets a click on a
12110
- * legend entry show that series alone.
12120
+ * legend entry show that series alone. `values: true` appends each entry's own total —
12121
+ * a category's for pie and donut, a series' for a series legend — formatted by the
12122
+ * measure column, after the name and a thin space.
12123
+ */
12124
+ legend?: boolean | {
12125
+ position?: 'top' | 'bottom' | 'left' | 'right'; isolate?: boolean; values?: boolean;
12126
+ };
12127
+ /**
12128
+ * The figure a donut draws in its own hole; ignored by
12129
+ * every other type, which has no hole to draw into. `value: 'total'` sums
12130
+ * the slices actually drawn — a legend click that hides a category moves
12131
+ * the figure with them — formatted by the measure column; a number is a
12132
+ * caller's own figure, formatted the same way; a string is written through
12133
+ * unchanged. `label` is a second line beneath it. Both are sized to fit the
12134
+ * hole and are never drawn past its edge.
12111
12135
  */
12112
- legend?: boolean | { position?: 'top' | 'bottom' | 'left' | 'right'; isolate?: boolean };
12136
+ centre?: { value: 'total' | number | string; label?: string };
12113
12137
  /**
12114
12138
  * Print the value beside each mark. `true` takes the defaults; the object form sets the
12115
12139
  * position, the format and the minimum gap. Only the chart types that support labels