|
6 | 6 | % Number/Gauge/Status: driven by sensor data (latest value / threshold check) |
7 | 7 | % Text/Table: static display (no interactivity needed) |
8 | 8 | % Timeline: derived from threshold violations |
| 9 | +% Heatmap: 2D colour grid (DataFcn returning matrix) |
| 10 | +% BarChart: categorical bar chart (DataFcn returning struct) |
| 11 | +% Histogram: sensor value distribution with optional normal fit |
| 12 | +% Scatter: two-sensor X-vs-Y correlation plot |
| 13 | +% Image: generated test pattern via ImageFcn |
| 14 | +% MultiStatus: per-sensor status grid (dot indicators) |
9 | 15 | % |
10 | 16 | % Usage: |
11 | 17 | % example_dashboard_all_widgets |
|
247 | 253 | 'Position', [1 19 24 3], ... |
248 | 254 | 'Events', events); |
249 | 255 |
|
| 256 | +% --- Row 22-27: Phase B widgets — Heatmap, BarChart, Histogram --- |
| 257 | + |
| 258 | +% Heatmap: temperature binned by hour-of-day (24 cols) vs machine mode (3 rows) |
| 259 | +% Pre-compute mode at every sample to avoid calling valueAt N*24*3 times. |
| 260 | +tMode = zeros(1, N); |
| 261 | +for k = 1:N |
| 262 | + tMode(k) = scMode.valueAt(t(k)); |
| 263 | +end |
| 264 | +hourBins = zeros(3, 24); |
| 265 | +for h = 0:23 |
| 266 | + hourIdx = (floor(t / 3600) == h); |
| 267 | + for m = 0:2 |
| 268 | + mIdx = hourIdx & (tMode == m); |
| 269 | + if any(mIdx) |
| 270 | + hourBins(m+1, h+1) = mean(temp(mIdx)); |
| 271 | + end |
| 272 | + end |
| 273 | +end |
| 274 | +hourXLabels = cell(1, 24); |
| 275 | +for h = 0:23 |
| 276 | + hourXLabels{h+1} = sprintf('%dh', h); |
| 277 | +end |
| 278 | +d.addWidget('heatmap', 'Title', 'Temp by Hour & Machine Mode', ... |
| 279 | + 'Position', [1 22 14 6], ... |
| 280 | + 'DataFcn', @() hourBins, ... |
| 281 | + 'Colormap', 'jet', ... |
| 282 | + 'XLabels', hourXLabels, ... |
| 283 | + 'YLabels', {'Idle','Running','Maint'}); |
| 284 | + |
| 285 | +% BarChart: alarm counts by sensor tag |
| 286 | +alarmCounts = struct( ... |
| 287 | + 'categories', {{'T-401','P-201','F-301'}}, ... |
| 288 | + 'values', [sTemp.countViolations(), sPress.countViolations(), sFlow.countViolations()]); |
| 289 | +d.addWidget('barchart', 'Title', 'Violation Count by Sensor', ... |
| 290 | + 'Position', [15 22 10 6], ... |
| 291 | + 'DataFcn', @() alarmCounts, ... |
| 292 | + 'Orientation', 'vertical'); |
| 293 | + |
| 294 | +% --- Row 28-33: Histogram, Scatter, Image, MultiStatus --- |
| 295 | + |
| 296 | +% Histogram: temperature distribution with normal fit |
| 297 | +d.addWidget('histogram', 'Title', 'Temperature Distribution', ... |
| 298 | + 'Position', [1 28 8 6], ... |
| 299 | + 'Sensor', sTemp, ... |
| 300 | + 'ShowNormalFit', true, ... |
| 301 | + 'NumBins', 40); |
| 302 | + |
| 303 | +% Scatter: temperature vs pressure, color-coded by flow rate |
| 304 | +d.addWidget('scatter', 'Title', 'Temp vs Pressure (color=Flow)', ... |
| 305 | + 'Position', [9 28 8 6], ... |
| 306 | + 'SensorX', sTemp, ... |
| 307 | + 'SensorY', sPress, ... |
| 308 | + 'SensorColor', sFlow, ... |
| 309 | + 'MarkerSize', 4, ... |
| 310 | + 'Colormap', 'parula'); |
| 311 | + |
| 312 | +% Image: procedural test pattern (no external file dependency) |
| 313 | +d.addWidget('image', 'Title', 'Process Diagram', ... |
| 314 | + 'Position', [17 28 8 6], ... |
| 315 | + 'ImageFcn', @() makePeaksThumb(), ... |
| 316 | + 'Caption', 'Elevation map (peaks function)', ... |
| 317 | + 'Scaling', 'fit'); |
| 318 | + |
| 319 | +% MultiStatus: all three process sensors at a glance |
| 320 | +d.addWidget('multistatus', 'Title', 'Sensor Status', ... |
| 321 | + 'Position', [1 34 24 3], ... |
| 322 | + 'Sensors', {sTemp, sPress, sFlow}, ... |
| 323 | + 'Columns', 3, ... |
| 324 | + 'IconStyle', 'dot', ... |
| 325 | + 'ShowLabels', true); |
| 326 | + |
250 | 327 | %% Render |
251 | 328 | d.render(); |
252 | 329 |
|
253 | 330 | fprintf('Dashboard rendered with %d widgets.\n', numel(d.Widgets)); |
254 | 331 | fprintf('Sensors: T-401 (%d violations), P-201 (%d violations), F-301 (%d violations)\n', ... |
255 | 332 | sTemp.countViolations(), sPress.countViolations(), sFlow.countViolations()); |
| 333 | +fprintf('Phase B widgets added: heatmap, barchart, histogram, scatter, image, multistatus.\n'); |
256 | 334 | fprintf('Click "Edit" to enter GUI builder mode.\n'); |
257 | 335 | fprintf('Click "Save" to export as JSON, "Export" to generate .m script.\n'); |
| 336 | + |
| 337 | +%% ---- Helper function ---- |
| 338 | +function img = makePeaksThumb() |
| 339 | +% Return a grayscale uint8 image derived from peaks(64). |
| 340 | +Z = peaks(64); |
| 341 | +Z = Z - min(Z(:)); |
| 342 | +Z = Z ./ max(Z(:)); |
| 343 | +img = uint8(round(Z * 255)); |
| 344 | +end |
0 commit comments