Lattice Grid 1.77: dashboards from a spec, and Elasticsearch
A dashboard is usually the slowest thing to build and the first thing a stakeholder asks to change. This release turns it into data: one JSON spec builds the whole thing, and the same spec hands itself back for saving, restoring, or asking a model to draft. Two more sources join the list a grid reads directly, rows can now be put in order by hand without losing a sort, and comparing two extracts got a real fix rather than a workaround.
A dashboard is now a spec, not a page of wiring
The new dashboard module builds a layout of windows, each holding a grid,
chart, KPI tiles, a map or an html panel, from one object: a layout, the
panels, the sources they read, and links between them. A chart or a
KPI tile can read grid:<panel> to follow another panel’s own grid
directly, so filtering the table narrows the chart beside it with no glue
code in between.
const dashboard = createDashboard(el, {
layout: { columns: 3, rows: 2 },
sources: { sales: { kind: 'rows', rows, rowKey: 'id' } },
panels: [
{ id: 'table', kind: 'grid', source: 'sales', options: { selection: 'multiple' } },
{ id: 'byRegion', kind: 'chart', source: 'grid:table', options: { type: 'bar', x: 'region', y: 'sales' } },
],
}, { createGrid, createHeadlessGrid, createLayout, createChart });
dashboard.spec() hands the whole arrangement back, every window exactly
where a reader dragged it, so an application can store and version a
dashboard the way it already stores anything else, and rebuild the same
screen from it later. With the AI module and your own model behind an
ask() callback, dashboard.propose('sales by region with a map', { source }) drafts a spec from a source’s column names alone, never its rows, and
builds nothing until you accept it. See the dashboard
guide and a dashboard from one JSON
spec, with a Show spec button that prints the spec
and rebuilds the dashboard from exactly that.
Rows in an order of your own, even sorted
A Manual order control lets a reader hand-order rows without losing the
sort that got them there: press it, the rows keep their current places, and
a drag (or the keyboard) sets an explicit order from then on; pressing it
again returns to the sort. A row can also be dragged into another group,
handled as an edit of its grouping value with every rule and event an edit
already carries. Both are opt-in, rowReorder: { manualOrder: true, betweenGroups: true }, so nothing changes in a grid that does not ask for
it.
Elasticsearch and OpenSearch, first-class sources
elasticsearchAdapter({ url, index }) turns filtering, sorting, paging,
counting and grouped aggregates into the cluster’s own Query DSL, sent as
JSON with no value ever pasted into a query string. A text field is
compared, sorted and grouped through its own .keyword sub-field
automatically, and a field with none is refused by name before anything is
sent, never a bare error back from the cluster. engine: 'opensearch'
switches the point-in-time endpoints used for paging past the result window;
everything else is identical between the two. See the Elasticsearch and
OpenSearch guide and reading Elasticsearch
live, with the generated Query DSL on
screen beside the grid.
Audit mode ignores a computed column by default
Comparing two extracts with grid.diff now looks at stored fields only
unless a column opts in: a computed column, one with no field of its own,
never contributes to a row’s status, summary() or before() unless it
carries diff: true, and a stored field can opt out the same way with
diff: false. Previously a computed column read through grid.diff could
mark rows changed that had not moved at all. See how to compare two
extracts with audit mode, and the
reconcile showcase application this rule makes simpler to
build.
Frame diagnostics report the real number
grid.diagnostics.snapshot().render.frames now measures actual animation
frames rather than how often a fast feed flushed its updates, so a page
updating many times a second no longer reads as dropping frames it never
dropped. A threshold read against the old figures should be re-baselined
against the corrected ones.
See it running
A dashboard from one JSON spec and reading Elasticsearch live are both live, alongside comparing two extracts and the reconcile and local-file showcase applications. The full list of what changed is in the changelog.