-
Notifications
You must be signed in to change notification settings - Fork 0
API Reference: Dashboard
Inherits from:
handle
obj = DashboardEngine(name, varargin)| Property | Default | Description |
|---|---|---|
| Name | '' |
|
| Theme | 'light' |
|
| LiveInterval | 5 |
|
| InfoFile | '' |
|
| ProgressMode | 'auto' |
'auto' | 'on' | 'off' — render progress bar visibility |
| ShowTimePanel | true |
hide the bottom time slider panel |
| EventMarkersVisible | true |
global toggle for event markers across all widgets (runtime UI state, not serialized) |
| DebugPreview_ | false |
260508-das — opt-in: surface preview/marker pipeline failures as warnings |
| BannerHeight | 0.035 |
ADDPAGE Add a named page and make it the active page for addWidget. pg = d.addPage('Overview') creates a DashboardPage and appends it to Pages. Sets ActivePage to the last-added page index. When Pages is non-empty, addWidget routes to the active page.
SETEVENTMARKERSVISIBLE Globally show/hide event markers on every widget. Iterates every widget (across all pages in multi-page mode) and calls setEventMarkersVisible(tf) on any widget that implements it. Unsupported widgets are silently skipped. Also updates the toolbar indicator if a Toolbar is present. Default state on dashboard create is true so existing scripts are unaffected.
SWITCHPAGE Switch the active page using panel visibility toggling. d.switchPage(2) sets ActivePage = 2 and toggles panel visibility.
Accept a pre-constructed widget object directly
ADDCOLLAPSIBLE Convenience: add a GroupWidget with Mode='collapsible'. w = d.addCollapsible('Sensors', {w1, w2}) w = d.addCollapsible('Sensors', {w1, w2}, 'Collapsed', true)
GETCACHEDTHEME Return cached theme struct, recomputing only when Theme changes.
Clear IsLive FIRST so any in-flight onLiveTimerError callback
does not re-start(obj.LiveTimer) on the timer we are about to
delete (observed on CI as a runaway 500k+ stderr loop in
testTimerContinuesAfterError). Then stop/delete the timer with
isvalid + try/catch guards, matching LiveTagPipeline.stop().
EXPORTIMAGE Save the rendered dashboard figure as PNG or JPEG at 150 DPI. d.exportImage('out.png') % format inferred from extension d.exportImage('out.png', 'png') d.exportImage('out.jpg', 'jpeg')
PREVIEW Print ASCII representation of the dashboard to console. d.preview() % default 120 chars wide d.preview('Width', 120) % custom width
SHOWINFO Display the linked Markdown info file in a browser. When InfoFile is empty, displays a built-in placeholder page describing how to attach a custom info file.
WRITEANDOPENINFOHTML Write rendered HTML to the cached temp file and open it.
SHOWINFOMODAL_ Render the info HTML in an in-app modal uifigure (260508-n8h). Replaces the previous browser handoff via web(). Reuses an existing modal if still open so repeated Info-button clicks refocus rather than stack windows. Falls back silently on uifigure construction errors (older MATLAB releases without uihtml support keep the temp HTML file as the user-facing artifact).
ONINFOMODALRESIZE_ Keep the uihtml panel filling the modal figure.
ONINFOMODALCLOSE_ Clear the cached modal handle and dispose the figure.
BUILDPLACEHOLDERINFOMARKDOWN Default info page shown when no InfoFile is set.
CLEANUPINFOTEMPFILE Delete the temporary HTML file if it exists.
REMOVEWIDGET Remove widget at given index and re-layout.
SETWIDGETPOSITION Set the grid position of a widget by index. Clamps width to grid columns and resolves overlaps with other widgets.
GETWIDGETBYTITLE Find a widget by its Title property. Returns the widget object, or empty if not found.
DETACHWIDGET Pop a widget out as a standalone figure window.
REMOVEDETACHED Remove stale mirrors from the registry.
SETCONTENTAREA Update the Layout content area. Provided so that DashboardBuilder can modify the layout without direct write-access to the Layout property (required for Octave compatibility).
APPLYCHROMEVISIBILITY Set chrome Visible state + return effective heights. Respects ShowToolbar and ShowTimePanel flags. Returns the heights that should be used for the content-area calculation (0 when the corresponding chrome element is hidden).
APPLYVISIBILITYANDRELAYOUT Re-apply ShowToolbar/ShowTimePanel + re-layout widgets.
APPLYTHEMETOCHROME Restyle figure + non-widget chrome using the current Theme. Widget panels are NOT touched here — call rerenderWidgets() after this method to recreate widget content with the new theme.
RERENDERWIDGETS Delete all widget panels and recreate them.
UPDATEGLOBALTIMERANGE Scan all widgets for data time bounds.
UPDATELIVETIMERANGE Update DataTimeRange without resetting sliders. Called during live mode to expand the time range as data grows.
UPDATELIVETIMERANGEFROM Update DataTimeRange from pre-fetched widget list. Like updateLiveTimeRange but accepts ws to avoid re-fetching activePageWidgets(). Returns the new tMax (or NaN when no widget has finite time data).
CREATESTALEBANNER Create the hidden stale-data warning banner. Permanent reserved strip at the very TOP of the figure. Toolbar, page tabs, and content area all sit BELOW this strip — the banner is never an overlay (260508-jyh). Hidden by default; shown when staleness is detected and not previously dismissed by the user. toolbarH is retained for signature compat; banner now lives in the reserved top strip independent of chrome heights.
REPOSITIONSTALEBANNER_ Park banner in the reserved top strip. Banner now lives in a permanent strip at the figure top; no chrome-height dependence (260508-jyh). Safe to call before render or after teardown — no-ops when the handle is empty/invalid.
SHOWSTALEBANNER Display the warning listing the widgets without new data. staleTitles is a cell array of widget Title strings whose tMax did not advance on the last live tick.
HIDESTALEBANNER Clear the stale-data warning overlay.
ONSTALEBANNERCLOSE User dismissed the warning; stay hidden until data resumes.
BUILDSTALEMESSAGE Compose the banner text listing stale widgets.
DETECTSTALEWIDGETS Return titles of widgets whose tMax did not advance. Updates LastTMaxPerWidget_ with the current observation.
BROADCASTTIMERANGE Push time range to widgets across ALL pages (not just active). Time sync is a dashboard-wide control: dragging the slider, clicking "Sync all", or calling broadcastTimeRangeNow updates every page's widgets so switching tabs preserves the synced window. Per-widget UseGlobalTime=false (manually zoomed) widgets opt out via their own setTimeRange guard. (260508-llw — was activePageWidgets, caused a per-tab desync bug.)
RESETGLOBALTIME Re-attach all widgets across ALL pages to global time and apply. (260508-llw — was activePageWidgets, leaving widgets on inactive pages still detached after a "Reset" toolbar action.)
REALIZEBATCH Render widgets in batches with drawnow between.
ACTIVEPAGELABEL Index and name of the active page, or (1, '') if single-page.
ONSCROLLREALIZE Realize widgets that scroll into view.
MARKALLDIRTY Flag all widgets as needing refresh. Called on theme change, figure resize, or other global state changes.
ONRESIZE Handle figure resize: reposition all widget panels.
TRIGGERTIMESLIDERSCHANGEDFORTEST Test-only hook to invoke the slider callback without going through UI events. Exposes the private onTimeSlidersChanged() debounce path to tests. (Hidden, not the narrower Access = {?matlab.unittest.TestCase}, so Octave parsing survives — Octave has no matlab.unittest.)
BROADCASTTIMERANGENOW Test-only synchronous broadcast bypassing the SliderDebounceTimer. Stock Octave 7 batch mode has unreliable timer scheduling; tests should use this entry point to drive the broadcast deterministically. Also updates the time labels (skipping the debounced onRangeSelectorChanged path).
COMPUTEPREVIEWENVELOPEFORTEST Test-only wrapper around the private computePreviewEnvelopeReturning_. Runs the real aggregation and returns the envelope struct so tests can assert shape/monotonicity without scraping the selector's patch handles. When nBuckets is omitted, uses the method's own width-derived default.
FORMATTIMEVAL Format a numeric time value as a human-readable string. Supports three numeric ranges: posix epoch seconds (9e8 < t < 5e9) — converts via datenum(1970,...)+t/86400 MATLAB datenum (t > 700000, not posix) — uses datestr directly raw numeric (t <= 700000) — formats as s/m/h/d suffix
WIDGETTYPES List supported widget type strings.
Inherits from:
handle
Provides drag/resize overlays, a widget palette sidebar, and a properties panel. Activated via the Edit button in DashboardToolbar.
builder = DashboardBuilder(engine); builder.enterEditMode(); builder.exitEditMode();
obj = DashboardBuilder(engine)| Property | Default | Description |
|---|---|---|
| IsActive | false |
|
| MockCurrentPoint | [] |
ADDICONCARD Add an IconCardWidget via the builder.
ADDCHIPBAR Add a ChipBarWidget via the builder.
ADDSPARKLINE Add a SparklineCardWidget via the builder.
Inherits from:
handle
Subclasses must implement: render(parentPanel) — create graphics objects inside the panel refresh() — update data/display (called by live timer) getType() — return widget type string (e.g. 'fastsense')
Subclasses must also provide a static fromStruct(s) method.
obj = DashboardWidget(varargin)Map legacy 'Sensor' NV pair to 'Tag' for backward compat of serialized dashboards.
| Property | Default | Description |
|---|---|---|
| Title | '' |
Widget title displayed in header |
| Position | [1 1 6 2] |
[col, row, width, height] in grid units |
| ThemeOverride | struct() |
Per-widget theme overrides (merged on top of dashboard theme) |
| UseGlobalTime | true |
false when user manually zooms this widget |
| Description | '' |
Optional tooltip text shown via info icon hover |
| Tag | [] |
v2.0 Tag API — any Tag subclass |
| ParentTheme | [] |
Theme inherited from DashboardEngine |
| Dirty | true |
true when widget needs refresh (data changed) |
| hPanel | [] |
Handle to the panel where this widget's content lives. |
| hCellPanel | [] |
Handle to the outer grid-cell uipanel that owns |
GET.SENSOR Backward-compat alias for Tag (v1.x API).
SET.SENSOR Backward-compat alias — maps to Tag property.
MARKDIRTY Flag this widget as needing a refresh.
MARKREALIZED Mark this widget as having been rendered.
MARKUNREALIZED Mark this widget as needing re-render.
Override in subclasses to respond to global time changes.
Override in subclasses to report data time range.
GETPREVIEWSERIES Optional preview data for the time-range envelope. series = getPreviewSeries(obj, nBuckets) returns a struct with fields xCenters, yMin, yMax — each a 1xnBuckets row vector; yMin/yMax MUST be normalized to [0,1] within the widget's own y-range. Base returns [] to opt out of the preview envelope.
GETEVENTTIMES Optional list of event times for the time-slider overlay. t = getEventTimes(obj) returns a row vector of event start times in the dashboard's time axis. Override to expose events to the TimeRangeSelector event-marker overlay; base returns [] so widgets without events contribute nothing.
GETNESTEDWIDGETS Optional list of nested DashboardWidgets for engine traversal. children = getNestedWidgets(obj) returns a cell array of DashboardWidget subclasses that this widget logically contains (e.g., a GroupWidget's Children + Tabs widgets). The DashboardEngine uses this to flatten the active-page widget tree when collecting preview series and event markers so that data/events inside container widgets contribute to the slider overlay. Base returns {} — leaf widgets are not containers.
ASCIIRENDER Return ASCII representation of this widget. lines = asciiRender(obj, width, height) returns a cell array of strings, each exactly WIDTH characters. HEIGHT is the available number of lines. Default implementation shows [type] Title; subclasses override for richer content.
Inherits from:
DashboardWidget
Supports data binding modes: Tag: w = FastSenseWidget('Tag', tagObj) DataStore: w = FastSenseWidget('DataStore', dsObj) Inline: w = FastSenseWidget('XData', x, 'YData', y) File: w = FastSenseWidget('File', 'path.mat', 'XVar', 'x', 'YVar', 'y')
obj = FastSenseWidget(varargin)| Property | Default | Description |
|---|---|---|
| DataStoreObj | [] |
|
| XData | [] |
|
| YData | [] |
|
| File | '' |
|
| XVar | '' |
|
| YVar | '' |
|
| Thresholds | 'auto' |
|
| XLabel | '' |
X-axis label (auto-set from Sensor if empty) |
| YLabel | '' |
Y-axis label (auto-set from Sensor if empty) |
| YLimits | [] |
Fixed Y-axis range [min max]; empty = auto-scale |
| ShowThresholdLabels | false |
show inline name labels on threshold lines |
| ShowEventMarkers | false |
Phase 1012 — toggle event round-marker overlay |
| EventStore | [] |
Phase 1012 — EventStore handle forwarded to inner FastSense |
| LiveViewMode | 'reset' |
Re-render Tag-bound widgets so updated data shows. Uses incremental updateData() path when tag identity is unchanged (PERF2-01); falls back to full teardown/rebuild on first render, tag swap, or error. Zoom state (xlim) is preserved in both paths.
UPDATE Incrementally update Tag data without full axes rebuild. Uses FastSenseObj.updateData() to replace data and re-downsample, avoiding the expensive delete/recreate cycle of refresh(). Falls back to refresh() if FastSenseObj is not in a renderable state.
SETEVENTMARKERSVISIBLE Pass-through to FastSense event-marker toggle. No-op when no FastSense instance exists yet (pre-render). When rendered, delegates to FastSense.setShowEventMarkers which re-draws the overlay in place without disturbing zoom state or live refresh cadence.
AUTOSCALEY_ Rescale the Y axis to cover current data + thresholds. FastSense locks YLim to manual mode at first render, so new samples outside the initial range would fall off the chart. This helper recomputes the Y extent every tick (including any threshold values so MonitorTag lines stay visible) and updates the axes. Skipped when: - the widget has a user-pinned YLimits NV-pair, or - the user manually zoomed Y via mouse (UserZoomedY), so we never fight an explicit human interaction.
ONYLIMCHANGED Detach widget from automatic Y rescale after user zoom. Fired by the YLim PostSet listener. When the YLim change came from inside autoScaleY_ (IsSettingYLim==true) we ignore it; any other source — mouse scroll, drag, zoom toolbar, programmatic ylim() from user code — counts as a manual override and latches UserZoomedY so live ticks stop fighting the user.
If xlim changed by user zoom/pan (not by setTimeRange), detach this widget from global time.
Return cached min/max in O(1). Cache is kept up to date by updateTimeRangeCache() which is called from render/refresh/update.
GETPREVIEWSERIES Per-bucket min/max preview for the dashboard envelope. series = getPreviewSeries(obj, nBuckets) returns a struct with fields xCenters, yMin, yMax — each a 1xnBucketsEff row vector; yMin and yMax are normalized into [0,1] across the widget's own current y-range. Returns [] only when no data is bound or when the sample count is genuinely too sparse (<4) to downsample.
GETEVENTTIMES Event start times for the dashboard time-slider markers. Looks up events in this priority order: 1. obj.EventStore (widget-level — the modern attachment point) 2. obj.FastSenseObj.EventStore (legacy: events on inner FastSense) 3. obj.FastSenseObj.Events / .EventTimes (defensive: extra hooks)
GETEVENTMARKERS Per-event time + severity + color for slider markers. m = getEventMarkers(obj) returns a struct array with fields: m(k).Time — numeric timestamp (StartTime) m(k).Severity — numeric severity in {1,2,3} (default 1 if absent) m(k).Color — 1x3 RGB triplet from severityColor(theme, sev)
INVALIDATEPREVIEWCACHE_ Clear PreviewCache_ so getPreviewSeries recomputes. Called from refresh() / update() / rebuildForTag_() whenever the underlying data may have changed. Cheap (no graphics).
Inherits from:
DashboardWidget
w = GaugeWidget('Title', 'Pressure', 'ValueFcn', @() getPressure(), ... 'Range', [0 100], 'Units', 'bar'); w = GaugeWidget('Sensor', mySensor, 'Style', 'donut'); w = GaugeWidget('Threshold', t, 'StaticValue', 50);
obj = GaugeWidget(varargin)| Property | Default | Description |
|---|---|---|
| ValueFcn | [] |
|
| Range | [] |
Empty default for auto-derivation cascade |
| Units | '' |
|
| StaticValue | [] |
|
| Style | 'arc' |
'arc', 'donut', 'bar', 'thermometer' |
| Threshold | [] |
Threshold object or registry key string (per D-01) |
Inherits from:
DashboardWidget
w = NumberWidget('Title', 'Temp', 'ValueFcn', @() readTemp(), 'Units', 'degC');
ValueFcn returns either: - A scalar (displayed as-is) - A struct with fields: value, unit, trend ('up'/'down'/'flat')
obj = NumberWidget(varargin)| Property | Default | Description |
|---|---|---|
| ValueFcn | [] |
function_handle returning scalar or struct |
| Units | '' |
unit label string |
| Format | '%.1f' |
sprintf format for value |
| StaticValue | [] |
fixed value (no callback needed) |
Inherits from:
DashboardWidget
Sensor-first: w = StatusWidget('Sensor', sensorObj);
Threshold-bound (no Sensor required): w = StatusWidget('Title', 'Temp', 'Threshold', t, 'Value', 85); w = StatusWidget('Title', 'Temp', 'Threshold', 'temp_hi', 'ValueFcn', @getTemp);
Legacy (still supported): w = StatusWidget('Title', 'Pump 1', 'StatusFcn', @() 'ok');
obj = StatusWidget(varargin)| Property | Default | Description |
|---|---|---|
| StatusFcn | [] |
function_handle returning 'ok'/'warning'/'alarm' (legacy) |
| StaticStatus | '' |
fixed status string (legacy) |
| Threshold | [] |
Threshold object or registry key string (per D-01) |
| Value | [] |
Scalar numeric value for threshold comparison (per D-03) |
| ValueFcn | [] |
Function handle returning scalar value (per D-03, D-09) |
Inherits from:
DashboardWidget
w = TextWidget('Title', 'Section A', 'Content', 'Sensor overview');
obj = TextWidget(varargin)| Property | Default | Description |
|---|---|---|
| Content | '' |
body text |
| FontSize | 0 |
0 = use theme default |
| Alignment | 'left' |
'left', 'center', 'right' |
Static widget — nothing to refresh
Inherits from:
DashboardWidget
w = TableWidget('Title', 'Sensor Data', 'DataFcn', @() getData()); w = TableWidget('Title', 'Static', 'Data', {{'A',1;'B',2}}, ... 'ColumnNames', {'Name','Value'}); w = TableWidget('Sensor', sensorObj); % last N data rows w = TableWidget('Sensor', sensorObj, 'Mode', 'events', 'EventStoreObj', store);
obj = TableWidget(varargin)| Property | Default | Description |
|---|---|---|
| DataFcn | [] |
|
| Data | {} |
|
| ColumnNames | {} |
|
| Mode | 'data' |
'data' or 'events' |
| N | 10 |
number of rows to display |
| EventStoreObj | [] |
EventStore for event mode |
Inherits from:
DashboardWidget
w = RawAxesWidget('Title', 'Histogram', ... 'PlotFcn', @(ax) histogram(ax, randn(1,1000)));
When bound to a Sensor, the PlotFcn receives (ax, sensor) or (ax, sensor, timeRange) depending on its nargin.
obj = RawAxesWidget(varargin)| Property | Default | Description |
|---|---|---|
| PlotFcn | [] |
@(ax) or @(ax, sensor[, tRange]) or @(ax, tRange) |
| DataRangeFcn | [] |
@() returning [tMin tMax] for global time range detection |
Inherits from:
DashboardWidget
Preferred: bind to an EventStore from the event detection system: w = EventTimelineWidget('Title', 'Events', 'EventStoreObj', store);
Legacy (still supported for backwards compatibility): w = EventTimelineWidget('Title', 'Events', 'EventFcn', @() getEvents()); w = EventTimelineWidget('Title', 'Events', 'Events', eventArray);
Events must be a struct array with fields: startTime, endTime, label, color (optional)
obj = EventTimelineWidget(varargin)| Property | Default | Description |
|---|---|---|
| EventStoreObj | [] |
EventStore handle — primary data source |
| Events | [] |
struct array of events (legacy) |
| EventFcn | [] |
function_handle returning events (legacy) |
| FilterSensors | {} |
Cell array of Sensor names to filter |
| FilterTagKey | '' |
Tag-key filter (MONITOR-05 carrier: SensorName OR ThresholdLabel match) |
| ColorSource | 'event' |
'event' or 'theme' |
GETEVENTTIMES Event start times from resolveEvents (override). Mirrors the same filtering pipeline the widget uses to draw bars, so the time-slider overlay always matches what the widget itself renders.
GETEVENTMARKERS Per-event time + severity + color for slider markers. m = getEventMarkers(obj) returns a struct array with fields: m(k).Time — numeric timestamp (startTime) m(k).Severity — numeric severity (default 1 if absent) m(k).Color — 1x3 RGB triplet from severityColor(theme, sev)
SAVE Write dashboard config as a MATLAB function file. The output is a function returning a DashboardEngine.
SAVEJSON Write dashboard config struct to JSON file. Handles both single-page (widgets field) and multi-page (pages field). Widgets/pages may have heterogeneous fields, so encode each entry individually and assemble the JSON array by hand.
LOAD Load dashboard config from file. For .m files: uses feval to execute the function and return the engine. For .json files: uses legacy JSON parsing.
LOADJSON Legacy: read dashboard config from JSON file.
WIDGETSTOCONFIG Build a config struct from widget objects.
DashboardSerializer.config = widgetsPagesToConfig(name, theme, liveInterval, pages, activePage, infoFile)
WIDGETSPAGESTOCONFIG Build a multi-page config struct from page objects. pages is a cell array of DashboardPage objects. activePage is the Name string of the active page.
CONFIGTOWIDGETS Create widget objects from config struct. configToWidgets(config) — no sensor resolution configToWidgets(config, resolver) — resolver is a function handle @(name) that returns a Sensor object by name.
CREATEWIDGETFROMSTRUCT Create a single widget from a struct.
EXPORTSCRIPT Generate a readable .m script from config.
EXPORTSCRIPTPAGES Generate a MATLAB function file from a multi-page config. The output is a function returning a DashboardEngine so that DashboardEngine.load() can use feval(funcname) to reconstruct it. Emits d.addPage('Name') + d.switchPage(N) before each page's widget block so that addWidget routes to the correct page.
EMITCHILDWIDGET Emit .m constructor lines for a child widget. Used by DashboardSerializer.save() to emit child code for GroupWidget children. Children are created by constructor, not d.addWidget(). Returns the generated code lines, the variable name assigned, and the updated groupCount (in case the child is itself a GroupWidget).
Inherits from:
handle
Converts widget grid positions [col, row, width, height] to normalized canvas coordinates [x, y, w, h]. Handles overlap resolution, row calculation, and scrollable canvas when content exceeds the viewport.
obj = DashboardLayout(varargin)| Property | Default | Description |
|---|---|---|
| Columns | 24 |
|
| TotalRows | 4 |
|
| ContentArea | [0 0 1 1] |
|
| Padding | [0 0 0 0] |
|
| GapH | 0 |
|
| GapV | 0 |
|
| RowHeight | 0.22 |
|
| ScrollbarWidth | 0.015 |
|
| OnScrollCallback | [] |
function handle: @(topRow, bottomRow) |
| DetachCallback | [] |
function handle: @(widget) — set by DashboardEngine |
| VisibleRows | [1 Inf] |
[topRow bottomRow] currently visible |
| hFigure | [] |
Figure handle for popup dismiss callbacks |
| hInfoPopup | [] |
Handle to active info popup uipanel (at most one) |
CANVASRATIO Ratio of canvas height to viewport height. Returns 1 when content fits, >1 when scrolling is needed.
COMPUTEPOSITION Convert grid position to canvas-normalized coords.
CANVASSTEPSIZES Grid step sizes in canvas-normalized coords.
FIGURETOCANVASDELTA Convert figure-normalized deltas to canvas deltas.
ENSUREVIEWPORT Create viewport/canvas/scrollbar only if they do not exist yet. Idempotent: if the viewport handle is already valid, returns immediately without deleting or recreating anything. On the first call the viewport, canvas, and (if needed) scrollbar are created and TotalRows is reset to 0 so that subsequent additive allocatePanels calls accumulate row counts.
RESETVIEWPORT Destroy the current viewport so the next ensureViewport call rebuilds it. Use when a full layout rebuild is required (e.g. single-page reflow).
ALLOCATEPANELS Create placeholder panels for widgets (additive; no viewport destruction). Calls ensureViewport (idempotent) to guarantee hViewport/hCanvas exist, then accumulates TotalRows and appends widget panels to the shared canvas. Multiple calls for different page-widget sets are safe: earlier panels survive. Ensure viewport exists (idempotent — no-op if already live)
REALIZEWIDGET Render a single widget into its pre-allocated panel. Creates the chrome (full-width WidgetButtonBar + WidgetContentPanel sub-panel below the bar) BEFORE calling widget.render so the widget's own graphics children (titles, axes, status text, group headers) land in the visible content area, never under the bar.
CREATEPANELS Create and render all widget panels (legacy path).
Re-run layout after dynamic changes (e.g., group collapse/expand). Tears down and recreates all panels, calling render() on each widget.
ONSCROLL Adjust canvas position from scrollbar value. val=1 shows top, val=0 shows bottom.
COMPUTEVISIBLEROWS Derive visible row range from scroll position.
ISWIDGETVISIBLE Check if widget rows overlap visible range + buffer.
OPENINFOPOPUP Open a modal figure window showing widget Description.
CLOSEINFOPOPUP Close and delete the active info popup panel.
ONFIGURECLICKFORDISMISS Dismiss popup if click was outside the popup panel.
ONKEYPRESSFORDISMISS Dismiss popup when Escape is pressed.
REFLOWCHROME_ SizeChangedFcn handler — re-anchor the WidgetButtonBar AND resize the WidgetContentPanel after the parent cell panel resizes. Public so tests can drive a deterministic resize without relying on SizeChangedFcn firing under -batch. No-op when the cell has been deleted or chrome isn't there yet.
REFLOWBUTTONBAR_ Deprecated alias — forwards to reflowChrome_. Kept temporarily for any external callers that still reference the m52-era name.
Inherits from:
handle
Provides buttons for: Sync, Live (toggle with blue border when active), Config (opens DashboardConfigDialog), Image, Export, and Info (always present — shows a placeholder page when no InfoFile is configured). Every button has a descriptive tooltip. Sits at the top of the dashboard figure.
obj = DashboardToolbar(engine, hFigure, theme)| Property | Default | Description |
|---|---|---|
| Height | 0.04 |
SETLASTUPDATETIME Update the last-update label with a timestamp.
SETLIVEACTIVEINDICATOR Show a blue surround when live mode is active.
ONEVENTSTOGGLE Fire engine-level event-marker toggle from button state. Engine.setEventMarkersVisible already calls back into setEventsActiveIndicator, but call it directly here too in case the engine's call path skips the toolbar (e.g. tests that temporarily reassign Engine.Toolbar).
SETEVENTSACTIVEINDICATOR Blue border when event markers are visible. Matches the Live button's visual treatment so the toolbar reads consistently. Keeps the button label constant — the border colour is the active indicator; the tooltip explains the function.
ONCONFIG Open the dashboard config dialog.
ONRESET Manual recovery — re-render all widgets on the active page. Delegates to DashboardEngine.rerenderWidgets which deletes every widget panel, marks widgets unrealized, then re-allocates and re-realizes them. Use when widgets get stuck (stale axes, zombie state, transient render error). Safe to call while Live mode is active — rerenderWidgets does not touch the Live timer state.
ONIMAGE Open save dialog and export dashboard figure as PNG/JPEG. Pops a uiputfile with PNG+JPEG filters, defaults to the sanitized dashboard name plus timestamp. On cancel, returns silently. On engine error, surfaces message via warndlg.
DISPATCHIMAGEEXPORT Post-dialog dispatcher — testable without uiputfile. file — filename string, or 0 on user-cancel path — directory path from uiputfile idx — filter index (1=PNG, 2=JPEG). Defaults to PNG.
DEFAULTIMAGEFILENAME Build sanitized default filename for the dialog. Pattern: {sanitized Engine.Name}{yyyymmdd_HHMMSS}.png Sanitization: replace [/:*?"<>|] and whitespace with ''. NOTE: datestr format 'yyyymmdd_HHMMSS' (lowercase mm=month here, HHMMSS=seconds). This differs from datetime/ISO notation — see libs/EventDetection/generateEventSnapshot.m:28 for the in-codebase precedent.
GETCONTENTAREA Compute the widget content area in normalized units. Subtracts the reserved banner strip at the top, the toolbar, and the time-panel height (260508-jyh). DashboardEngine computes ContentArea inline in render() and applyVisibilityAndRelayout(); this helper exists for consistency with consumers that read directly from the toolbar (e.g. DashboardBuilder canvas calc).
Inherits from:
DashboardWidget
obj = BarChartWidget(varargin)| Property | Default | Description |
|---|---|---|
| DataFcn | [] |
@() struct('categories',{},'values',[]) |
| Orientation | 'vertical' |
'vertical' or 'horizontal' |
| Stacked | false |
Inherits from:
DashboardWidget
Displays N colored circle icons with labels in a compact horizontal strip. Designed as a dense multi-sensor status overview at a glance.
obj = ChipBarWidget(varargin)CHIPBARWIDGET Construct a ChipBarWidget with optional name-value pairs.
| Property | Default | Description |
|---|---|---|
| Chips | {} |
Cell array of chip structs (label, statusFcn, sensor, iconColor) |
RENDER Draw all chips in a single shared axes inside parentPanel. Re-entrancy guard: parenting an axes to parentPanel and toggling its Units below can synchronously fire the panel's SizeChangedFcn -> relayout_ -> render. Without this lock the nested call deletes the axes the outer render is populating and the outer render then crashes on text(obj.hAx, ...).
REFRESH Update chip circle colors from statusFcn or sensor state.
GETTYPE Return widget type string.
TOSTRUCT Serialize widget to struct for JSON export.
FROMSTRUCT Reconstruct ChipBarWidget from a saved struct.
Inherits from:
handle
Opens a figure listing every public DashboardEngine property with an editable control. Apply writes values back to the engine and propagates visible changes (figure title, theme re-render, live timer restart). Close dismisses without additional changes.
Enum-like properties get a popup menu: Theme — {'light', 'dark'} ProgressMode — {'auto', 'on', 'off'} Numeric properties get a numeric edit control. Everything else gets a plain text edit.
Usage (usually invoked by the toolbar Config button): dlg = DashboardConfigDialog(engine); % ...user edits fields, clicks Apply/Close...
obj = DashboardConfigDialog(engine)CLOSE Destroy the dialog figure.
APPLY Write all control values back to the engine and propagate.
Inherits from:
handle
Each DashboardPage holds a list of widgets to be rendered when the page is active. DashboardEngine maintains a Pages cell array of DashboardPage objects and routes addWidget() to the active page.
obj = DashboardPage(name)DASHBOARDPAGE Construct a named page container. pg = DashboardPage() creates page with Name = '' pg = DashboardPage('Name') creates page with given Name
| Property | Default | Description |
|---|---|---|
| Name | '' |
|
| Widgets | {} |
ADDWIDGET Append widget w to the Widgets list. pg.addWidget(w) appends w to obj.Widgets.
TOSTRUCT Serialize the page to a struct with name and widgets fields. s = pg.toStruct() returns s.name (char) and s.widgets (cell).
Inherits from:
handle
Emits a self-updating progress line to stdout as widgets are realized during DashboardEngine.render() / rerenderWidgets(), and a final summary line on completion.
Silent outside interactive sessions so test / CI output stays clean.
obj = DashboardProgress(name, totalWidgets, totalPages, mode)Inherits from:
handle
DetachedMirror wraps a cloned DashboardWidget in a standalone MATLAB figure window. The clone is produced via toStruct/fromStruct with post- clone live-reference restoration for FastSenseWidget and RawAxesWidget.
The mirror is NOT a DashboardWidget subclass — it wraps one. It belongs to DashboardEngine.DetachedMirrors and is ticked by the engine's existing LiveTimer via the engine's onLiveTick() loop.
Usage (called internally by DashboardEngine.detachWidget()): theme = DashboardTheme(obj.Theme); cb = @() obj.removeDetached(mirror); mirror = DetachedMirror(originalWidget, theme, cb);
Properties (SetAccess = private): hFigure — standalone MATLAB figure window handle hPanel — full-figure uipanel that hosts the cloned widget Widget — cloned DashboardWidget instance RemoveCallback — @() called by onFigureClose() before delete(hFigure)
obj = DetachedMirror(originalWidget, themeStruct, removeCallback)DETACHEDMIRROR Create a detached live-mirror window for originalWidget.
TICK Refresh the cloned widget; no-op if figure is stale.
ISSTALE Return true when the mirror's figure has been closed or destroyed.
Inherits from:
DashboardWidget
DividerWidget renders a horizontal colored line using the theme's WidgetBorderColor (or a custom Color override). It is a static widget with no data binding.
obj = DividerWidget(varargin)DIVIDERWIDGET Construct a DividerWidget. obj = DividerWidget() creates with defaults. obj = DividerWidget('Thickness', 2, 'Color', [1 0 0]) sets props.
| Property | Default | Description |
|---|---|---|
| Thickness | 1 |
Relative line thickness (1=thin, 2=medium, 3=thick) |
| Color | [] |
RGB override; empty = use theme WidgetBorderColor |
RENDER Create the divider line inside parentPanel. render(obj, parentPanel) creates a uipanel that acts as a horizontal colored line centered vertically in the panel.
REFRESH No-op for static widget.
GETTYPE Return widget type string.
ASCIIRENDER Return ASCII representation of the divider. First line is a row of dashes; remaining lines are blank.
TOSTRUCT Serialize to struct. Omits 'thickness' at default (1) and 'color' when empty.
FROMSTRUCT Reconstruct DividerWidget from serialized struct.
Inherits from:
DashboardWidget
obj = GroupWidget(varargin)| Property | Default | Description |
|---|---|---|
| Mode | 'panel' |
'panel', 'collapsible', 'tabbed' |
| Label | '' |
Title shown in header bar |
| Collapsed | false |
Collapsed state (collapsible mode only) |
| Children | {} |
Cell array of DashboardWidget (panel/collapsible) |
| Tabs | {} |
Cell array of struct('name','...','widgets',{{}}) |
| ActiveTab | '' |
Current tab name (tabbed mode) |
| ChildColumns | 24 |
Sub-grid column count |
| ChildAutoFlow | true |
Auto-arrange children |
| ReflowCallback | [] |
Callback invoked after collapse/expand (injected by DashboardEngine) |
Check nesting depth for GroupWidget children
GETTIMERANGE Aggregate time range from all children and tabs.
GETNESTEDWIDGETS Return Children plus all Tabs widgets as a flat cell. Used by DashboardEngine.flattenWidgetsForPreview_ to surface nested data/event widgets to the time-slider preview and marker overlay. Order: Children first, then Tabs widgets in declaration order. Empty Group returns {}.
Inherits from:
DashboardWidget
obj = HeatmapWidget(varargin)| Property | Default | Description |
|---|---|---|
| DataFcn | [] |
function_handle returning matrix |
| Colormap | 'parula' |
colormap name or Nx3 matrix |
| ShowColorbar | true |
|
| XLabels | {} |
cell array of axis labels |
| YLabels | {} |
cell array of axis labels |
Inherits from:
DashboardWidget
obj = HistogramWidget(varargin)| Property | Default | Description |
|---|---|---|
| DataFcn | [] |
|
| NumBins | [] |
empty = auto |
| ShowNormalFit | false |
|
| EdgeColor | [] |
RGB or empty for default |
Inherits from:
DashboardWidget
Displays a state-colored circle icon at the left, a primary numeric value in the center, and a secondary label below the value. Icon color reflects the current threshold state (ok/warn/alarm/info/inactive).
obj = IconCardWidget(varargin)ICONCARDWIDGET Construct an IconCardWidget with optional name-value pairs.
| Property | Default | Description |
|---|---|---|
| IconColor | 'auto' |
RGB triplet or 'auto' (derive from state) |
| StaticValue | [] |
Fixed static value (number) |
| ValueFcn | [] |
Function handle returning scalar or struct |
| StaticState | '' |
'ok','warn','alarm','info','inactive','' |
| Units | '' |
Display units string |
| Format | '%.1f' |
sprintf format for numeric value |
| SecondaryLabel | '' |
Subtitle text below primary value |
| Threshold | [] |
Threshold object or registry key string (per D-01) |
RENDER Create icon, value text, and label inside parentPanel.
REFRESH Update icon color, value display, and label.
GETTYPE Return widget type string.
TOSTRUCT Serialize widget to struct for JSON export.
FROMSTRUCT Reconstruct IconCardWidget from a serialized struct.
Inherits from:
DashboardWidget
obj = ImageWidget(varargin)| Property | Default | Description |
|---|---|---|
| File | '' |
Path to image file (PNG, JPG) |
| ImageFcn | [] |
function_handle returning image matrix |
| Scaling | 'fit' |
'fit', 'fill', 'stretch' |
| Caption | '' |
html = MarkdownRenderer.render(mdText) html = MarkdownRenderer.render(mdText, themeName) html = MarkdownRenderer.render(mdText, themeName, basePath)
Converts a subset of Markdown to a self-contained HTML document.
Supported: headings (#-###), bold, italic, inline code,
fenced code blocks, [links](url), , unordered/ordered
lists, horizontal rules (---), tables (pipe-delimited), and paragraph
breaks.
The optional themeName ('light', 'dark', etc.) controls the CSS color scheme. Unrecognized themes default to 'light'.
Inherits from:
DashboardWidget
obj = MultiStatusWidget(varargin)| Property | Default | Description |
|---|---|---|
| Sensors | {} |
Cell array of Sensor objects |
| Columns | [] |
Grid columns (empty = auto) |
| ShowLabels | true |
|
| IconStyle | 'dot' |
'dot', 'square', 'icon' |
Fully override — does not use base Sensor property
Inherits from:
DashboardWidget
obj = ScatterWidget(varargin)| Property | Default | Description |
|---|---|---|
| SensorX | [] |
Sensor for X axis |
| SensorY | [] |
Sensor for Y axis |
| SensorColor | [] |
Optional: color-code by third sensor |
| MarkerSize | 6 |
|
| Colormap | 'parula' |
SparklineCardWidget --- KPI card combining a big-number display with a mini sparkline chart and delta indicator.
Inherits from:
DashboardWidget
w = SparklineCardWidget('Title', 'CPU', 'StaticValue', 42.0, ... 'SparkData', cpuHistory, 'Units', '%');
The card is divided into three zones: Top row — title (left) and delta indicator (right) Middle — large primary value Bottom — sparkline mini-chart (bottom 35% of card)
Data binding (three-path, resolved in priority order): 1. Sensor — uses Sensor.Y for both value and sparkline 2. ValueFcn — function_handle returning scalar or struct 3. StaticValue + SparkData — static numeric value with separate sparkline vector
Properties: StaticValue — fixed scalar value ValueFcn — function handle returning scalar or struct(.value, .unit) Units — display unit string Format — sprintf format for primary value (default '%.1f') NSparkPoints — number of tail points shown in sparkline (default 50) ShowDelta — show delta indicator (default true) DeltaFormat — sprintf format for delta (default '%+.1f') SparkColor — sparkline line color; empty => theme.DragHandleColor SparkData — numeric vector for sparkline (used when no Sensor)
obj = SparklineCardWidget(varargin)SPARKLINECARDWIDGET Construct a SparklineCardWidget. Accepts name-value pairs for any public property.
| Property | Default | Description |
|---|---|---|
| StaticValue | [] |
Fixed scalar value displayed in the card |
| ValueFcn | [] |
Function handle returning scalar or struct |
| Units | '' |
Unit label appended to primary value |
| Format | '%.1f' |
sprintf format string for primary value |
| NSparkPoints | 50 |
Number of tail data points in sparkline |
| ShowDelta | true |
Whether to show the delta indicator |
| DeltaFormat | '%+.1f' |
sprintf format string for delta value |
| SparkColor | [] |
Sparkline line color (empty = theme default) |
| SparkData | [] |
Numeric vector for sparkline (alternative to Sensor) |
RENDER Create all graphics objects inside parentPanel.
REFRESH Update displayed value, sparkline, and delta indicator.
GETTYPE Return widget type string.
TOSTRUCT Serialize widget to a struct for JSON export.
FROMSTRUCT Deserialize a SparklineCardWidget from a struct.
Inherits from:
handle
selector = TimeRangeSelector(hPanel) attaches a time-range selector to a uipanel. The selector owns its own axes inside the panel and draws:
* an (optional) aggregate min/max envelope patch behind the selection,
* a semi-transparent selection rectangle that can be panned by dragging
its middle and resized by dragging either of its two edge handles,
* two line handles at the left and right edges of the selection window.
Interaction uses figure-level WindowButton{Down,Motion,Up}Fcn. Any previously installed callbacks are saved on construction and restored on delete().
Usage (the contract plan 03 uses to wire this into DashboardEngine):
selector = TimeRangeSelector(hPanel, ...
'OnRangeChanged', @(tStart, tEnd) onRangeChanged(tStart, tEnd), ...
'Theme', themeStruct);
selector.setDataRange(tMin, tMax); % full extent user can scrub
selector.setSelection(tStart, tEnd); % fires OnRangeChanged
selector.setEnvelope(xC, yMin, yMax); % optional preview
[tS, tE] = selector.getSelection();
delete(selector); % restores figure callbacks
Properties (public, configurable): OnRangeChanged Function handle @(tStart, tEnd). May be []. Theme Theme struct (or []). MinWidthFrac Minimum selection width as fraction of DataRange span. EdgeTolPx Pixel tolerance for edge hit-testing.
Properties (read-only, set internally): hPanel, hFigure, hAxes, hEnvelope, hSelection, hEdgeLeft, hEdgeRight DataRange 1x2 [tMin tMax]. Selection 1x2 [tStart tEnd]. DragState 'idle' | 'panning' | 'resizeLeft' | 'resizeRight'.
Methods: setDataRange(tMin, tMax) Set full extent; rescales selection. setSelection(tStart, tEnd) Set/clamp/reorder selection; fires callback. getSelection() Return [tStart, tEnd]. setEnvelope(xC, yMin, yMax) Update or hide aggregate envelope. delete() Restore saved figure callbacks.
Compatible with MATLAB R2020b+ and Octave 7+ (D-11): uses only axes, patch, line, uipanel primitives and WindowButton{Down,Motion,Up}Fcn — no matlab.graphics.*, no uifigure/uiaxes, no addlistener on primitive properties.
obj = TimeRangeSelector(hPanel, varargin)TimeRangeSelector Construct a selector attached to a uipanel.
| Property | Default | Description |
|---|---|---|
| OnRangeChanged | [] |
function handle @(tStart, tEnd) |
| Theme | [] |
struct from DashboardTheme, or [] |
| MinWidthFrac | 0.005 |
minimum selection width as fraction of DataRange span |
| EdgeTolPx | 10 |
pixel tolerance for edge hit-test |
setDataRange Set the full extent the user can scrub over. The current selection is rescaled proportionally so that a 50%-selected window remains 50% wide after the change. Programmatic — does NOT fire OnRangeChanged; only user drag interactions do.
setSelection Update the selection window, clamping and reordering. Swapped inputs (tStart > tEnd) are reordered. Values outside DataRange are clamped. Widths smaller than MinWidthFrac * span are widened around the requested midpoint. Fires OnRangeChanged with the final [tStart, tEnd] (if the callback is set). Reorder swapped bounds (tStart < tEnd).
getSelection Return the current selection as [tStart, tEnd].
setLabels Update the inline edge labels that track the selection. Pass empty strings to hide a side's label. The text sits at the mid-height of the selector, inside each edge handle.
setEnvelope (Legacy) Draw the aggregate min/max preview envelope. Kept for backward compat with tests. New code should prefer setPreviewLines for per-widget line previews.
setPreviewLines Draw one downsampled line per widget preview. lines is a cell array of structs, each with fields x and y (equal-length row vectors; y already normalized to [0,1]). Each line is rendered with a distinct color from a fixed palette, placed behind the selection rectangle so drag interactions remain unaffected. Clear previous preview lines.
setEventMarkers Draw a faint full-height line per event time.
setEventMarkers(times) clears any existing markers and draws
one vertical line per finite time in times. Non-finite
values (NaN, +/-Inf) are silently dropped. Empty input just
clears the markers.
FastPlot Wiki
API Reference
Guides
Use Cases
Internals
Resources