Lattice Grid Buy a licence

blog

Lattice Grid 1.77: dashboards from a spec, and Elasticsearch

Building…
Loading a live grid…

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.

Read next

All posts RSS