Problem / motivation
A TableWidget is a canonical dashboard tile — a tabular readout of recent alarm events (Mode='events') or recent sensor samples (Mode='data'). Today it is monochrome: nothing in the table signals which rows are out of range or high-severity, so the engineer has to read every number.
This is a verified gap. In events mode the widget already iterates the events and builds the Start/End/Label/Duration rows, but throws away each event's Severity (libs/Dashboard/TableWidget.m:99-108). A grep -niE "color|severity|threshold" over the file finds only the BackgroundColor theme calls (:50, :60) — there is no per-row coloring of any kind. This is the "alarm/threshold ergonomics" sensor-analysis gap applied to the tabular readout.
Proposed feature
Add an opt-in ColorRows flag that paints each row's background by its alarm status:
- events mode → each row colored by its event severity (ok/warn/alarm).
- data mode (bound to a Threshold/MonitorTag) → rows whose value violates the threshold get the alarm color; in-range rows keep the theme background.
Default false ⇒ the table renders exactly as it does today.
Rough sketch
Lib/class: libs/Dashboard/TableWidget.m (single file).
Two supporting primitives already ship in the repo — no new color logic:
severityColor(theme, severity) (libs/Dashboard/severityColor.m) maps 1/2/3 → ok/warn/alarm theme colors and is already used by EventTimelineWidget (EventTimelineWidget.m:221).
Event.Severity (1=ok/info, 2=warn, 3=alarm — libs/EventDetection/Event.m:35) is populated on every event.
- data-mode threshold walk mirrors the
StatusWidget precedent (StatusWidget.m:201-204).
Public API:
w = TableWidget('Sensor', monitorTag, 'Mode', 'events', 'EventStoreObj', store, ...
'ColorRows', true); % rows colored by event severity
ColorRows = false % new public prop; default = byte-identical to today
Render (portable): build an nRows x 3 RGB matrix and set(obj.hTable, 'BackgroundColor', M). Classical uitable maps a BackgroundColor matrix row-by-row (the standard striping mechanism), which is portable across MATLAB and Octave classical uitable — no uistyle/uifigure dependency. Uncolored rows fall back to the existing theme.WidgetBackground.
Serialize: emit s.colorRows in toStruct (TableWidget.m:162-176) only when true; read it in fromStruct (:180-212) defaulting to false when absent.
Value
High. Turns a tabular readout into an at-a-glance alarm panel: an engineer scanning recent events or recent samples sees out-of-range/high-severity rows immediately instead of reading every number. Reuses the exact severity→color mapping the timeline already uses, so it is visually consistent with the rest of the dashboard.
Constraints check
- Toolbox-free: ✅
set('BackgroundColor', M) on a classical uitable + existing severityColor helper — no toolbox.
- Backward-compatible: ✅ default
ColorRows=false ⇒ current rendering; serialized field omitted unless true, so old saves load uncolored exactly as before.
- Pure MATLAB/Octave: ✅ classical
uitable BackgroundColor row-mapping is portable; no uifigure uistyle.
- Widget contract: ✅ works entirely through the existing
DashboardWidget interface — no base-class or layout change.
Effort estimate
S–M, single file: one public prop + an nRows x 3 color-matrix build in refresh (events branch reuses severityColor; data branch reuses the StatusWidget threshold walk) + a set('BackgroundColor', M) + a toStruct/fromStruct round-trip. One test: ColorRows=true in events mode paints a severity-3 row with severityColor(theme,3); default false leaves the table at theme background; the flag round-trips through serialization.
AI-proposed via /feature-scout — needs a human product decision before implementation.
Problem / motivation
A
TableWidgetis a canonical dashboard tile — a tabular readout of recent alarm events (Mode='events') or recent sensor samples (Mode='data'). Today it is monochrome: nothing in the table signals which rows are out of range or high-severity, so the engineer has to read every number.This is a verified gap. In events mode the widget already iterates the events and builds the Start/End/Label/Duration rows, but throws away each event's
Severity(libs/Dashboard/TableWidget.m:99-108). Agrep -niE "color|severity|threshold"over the file finds only theBackgroundColortheme calls (:50,:60) — there is no per-row coloring of any kind. This is the "alarm/threshold ergonomics" sensor-analysis gap applied to the tabular readout.Proposed feature
Add an opt-in
ColorRowsflag that paints each row's background by its alarm status:Default
false⇒ the table renders exactly as it does today.Rough sketch
Lib/class:
libs/Dashboard/TableWidget.m(single file).Two supporting primitives already ship in the repo — no new color logic:
severityColor(theme, severity)(libs/Dashboard/severityColor.m) maps1/2/3 → ok/warn/alarmtheme colors and is already used byEventTimelineWidget(EventTimelineWidget.m:221).Event.Severity(1=ok/info, 2=warn, 3=alarm —libs/EventDetection/Event.m:35) is populated on every event.StatusWidgetprecedent (StatusWidget.m:201-204).Public API:
ColorRows = false% new public prop; default = byte-identical to todayRender (portable): build an
nRows x 3RGB matrix andset(obj.hTable, 'BackgroundColor', M). Classicaluitablemaps aBackgroundColormatrix row-by-row (the standard striping mechanism), which is portable across MATLAB and Octave classical uitable — nouistyle/uifigure dependency. Uncolored rows fall back to the existingtheme.WidgetBackground.Serialize: emit
s.colorRowsintoStruct(TableWidget.m:162-176) only whentrue; read it infromStruct(:180-212) defaulting tofalsewhen absent.Value
High. Turns a tabular readout into an at-a-glance alarm panel: an engineer scanning recent events or recent samples sees out-of-range/high-severity rows immediately instead of reading every number. Reuses the exact severity→color mapping the timeline already uses, so it is visually consistent with the rest of the dashboard.
Constraints check
set('BackgroundColor', M)on a classicaluitable+ existingseverityColorhelper — no toolbox.ColorRows=false⇒ current rendering; serialized field omitted unlesstrue, so old saves load uncolored exactly as before.uitableBackgroundColorrow-mapping is portable; no uifigureuistyle.DashboardWidgetinterface — no base-class or layout change.Effort estimate
S–M, single file: one public prop + an
nRows x 3color-matrix build inrefresh(events branch reusesseverityColor; data branch reuses the StatusWidget threshold walk) + aset('BackgroundColor', M)+ atoStruct/fromStructround-trip. One test:ColorRows=truein events mode paints a severity-3 row withseverityColor(theme,3); defaultfalseleaves the table at theme background; the flag round-trips through serialization.AI-proposed via /feature-scout — needs a human product decision before implementation.