Lattice Grid Buy a licence

developer guide

Statistics and capability: JavaScript Data Grid Guide

What the grid knows about its own numbers: column profiling, process control and capability, confidence intervals, the tiles that put a figure above the table, and a summary that counts and filters the rows that look wrong.

Developer guide › Statistics and capability

Profiling and statistics

grid.statistics answers questions about the rows the filters left, so every figure describes what the user is looking at rather than the whole table.

Everything worth knowing about a column, in one pass

const p = grid.statistics.profile('capacity');

p.count; p.missing; p.distinct;
p.min; p.q1; p.median; p.q3; p.max;
p.mean; p.stdDev;
p.outliers;      // by the interquartile rule
p.histogram;     // bins, ready to draw
p.alerts;        // what is worth looking at

alerts is the part that saves time: a column that never varies, a key that turns out not to be unique, a fifth of the rows missing. A profile that reports only numbers leaves the reader to notice those, and readers reliably do not.

The profile of a column the grid does not hold, computed by the source

const { createHeadlessGrid, createPushdownSource } = await import('../packages/core/src/index.js');
const rows = Array.from({ length: 100 }, (_, i) => ({ id: i, price: i + 1 }));
const adapter = {
  name: 'demo',
  capabilities: { filter: 'tree', operators: ['equals'], range: true, total: true },
  async execute(q) { return { rows: rows.slice(q.range.start, q.range.end), total: rows.length }; },
  async executeAggregates(q, aggs) {
    const by = { count: 100, countValues: 100, distinct: 100, min: 1, max: 100, avg: 50.5, median: 50.5, p25: 25.75, p75: 75.25, stddev: 29.01 };
    return Object.fromEntries(aggs.map((a) => [a.id, by[a.fn]]));
  },
};
const grid = createHeadlessGrid({
  rowKey: 'id',
  columns: [{ field: 'id', type: 'number' }, { field: 'price', type: 'number', facet: { buckets: 5 } }],
  source: createPushdownSource({ adapter, pageSize: 50, aggregates: { default: 'engine' } }),
});
const held = grid.statistics.profile('price') === null;  // true: the grid holds no rows to read
const p = await grid.statistics.profileAsync('price');  // the engine's answer
const named = p.unavailable.map((u) => u.stat).join('+'); // what it could not push down
const buckets = grid.columns.get('price').facet.buckets;  // a column's own facet settings
grid.destroy();
return [held, p.computed, p.rows, p.median, named, buckets].join('|');
MethodAnswers
reduceA column through any of the thirty-eight named kernels, or one of your own.
profileAsyncgrid.statistics.profileAsync(colId): the same profile when the grid does not hold the rows. Over a pushdown source without fullDataset the source's engine computes the count, distinct count, min, max, mean, quartiles, median and standard deviation the adapter supports, over the grid's filters; a figure it could not push down is named under unavailable with the reason rather than left blank. Everywhere else it is profile(), resolved.
correlationPearson's r between two columns. spearman resists an outlier; kendall is tau-b.
regressionA least-squares fit of one column on another, with slope, intercept and r².
weightedAverageOne column averaged by another. weightedQuantile for the median and beyond.
seriesHow a column varies along an ordering. by is required and never guessed.
shadowWhat the grid knows about a row over time: updates, delta, rate, rank, percentile, streak.

The filters are part of the question. Every one of these reads the filtered rows. Narrow the grid and the statistics narrow with it, which is the behaviour you want when the filter is the analysis.

Kernels see arrival order, not display order. Anything order-dependent takes an explicit by rather than inferring one from the current sort, so the answer does not change when a user clicks a column header.

Process control and capability

Whether a process sits inside the tolerance it was given, and whether it is behaving or drifting. The tolerance is declared once, on the column.

Confidence intervals

How firmly the data pins a figure down. An interval narrows as the grid does, because it describes the filtered rows and not the whole table.

Statistic tiles

A headline figure over a grid, with the change since a baseline, a tone from thresholds, and the interval underneath.

Anomaly summary chip

Give a column an anomalyFlag shadow () and turn on anomalySummary, and the grid shows a small chip reading how many rows that column flags. Click it to filter the grid to exactly those rows; click again to clear.