demo D281
Flag the readings that do not fit
A column that marks the outliers in a series, scored by a robust measure a single spike cannot skew, with a chip that counts them and filters the grid to exactly those rows
shadow: { kind: 'anomalyFlag' } · anomalySummary
Loading a live grid…
The configuration
'anomaly-detection': () => {
const rows = Array.from({ length: 48 }, (_, i) => {
let value = 200 + Math.round(Math.sin(i / 4) * 12);
if (i === 9) value = 340;
if (i === 22) value = 70;
if (i === 31) value = 360;
if (i === 40) value = 95;
return { id: i + 1, day: i + 1, value };
});
return {
rows,
config: {
rowKey: 'id',
anomalySummary: { label: 'Anomalies' },
columns: [
{ field: 'day', title: 'Day', type: 'number', layout: { width: 80, pin: 'start' } },
{ field: 'value', title: 'Reading', type: 'number', total: 'median', layout: { flex: 1, min: 120 } },
{ id: 'score', title: 'Anomaly score', shadow: { of: 'value', kind: 'anomalyScore' }, type: 'number', format: { decimals: 2, signed: true }, layout: { width: 150 } },
{ id: 'flag', title: 'Anomaly', shadow: { of: 'value', kind: 'anomalyFlag' }, layout: { width: 120 } },
],
},
foot: [
'the anomaly column flags the readings that sit too far from the rest, scored by a robust measure that a single outlier cannot skew',
'the score says how far out each reading is, signed so a spike and a dip read apart',
'the chip in the toolbar counts how many were flagged; click it to filter the grid to exactly those rows',
],
};
},