Files
cgm-remote-monitor/docs/audits/dashboard-ui-audit.md
T
bewestandBen West 14f92611dd Update documentation links and project references
Adjusted internal documentation links and updated references within various Markdown files to reflect a new directory structure for audit and meta documents.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 4dee684a-a4b9-4c32-a818-3a27dae1b027
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: 971b8c75-c322-4ede-98ea-eb5ae31d4e5c
Replit-Helium-Checkpoint-Created: true
2026-01-19 13:14:21 -08:00

601 lines
14 KiB
Markdown

# Dashboard UI Audit
**Document Version:** 1.0
**Last Updated:** January 2026
**Scope:** Client bundle structure, D3 charting, clock displays, browser settings, rendering pipeline
---
## 1. Executive Summary
The Nightscout web dashboard provides real-time glucose visualization with extensive customization options. This audit examines the frontend architecture, rendering pipeline, and modernization opportunities.
### Dashboard Overview
| Metric | Value |
|--------|-------|
| Bundle System | Webpack 5 |
| UI Framework | jQuery + D3.js |
| Charting | D3.js v5 + Flot |
| Real-time Updates | Socket.IO |
| Bundle Size | ~1MB+ (production) |
---
## 2. Client Bundle Architecture
### 2.1 Entry Point
**Location:** `bundle/bundle.source.js`
```javascript
import '../static/css/drawer.css';
import '../static/css/dropdown.css';
import '../static/css/sgv.css';
$ = require("jquery");
require('jquery-ui-bundle');
window._ = require('lodash');
window.d3 = require('d3');
require('jquery.tooltips');
window.Storage = require('js-storage');
require('flot');
require('../node_modules/flot/jquery.flot.time');
```
### 2.2 Module Structure
```
bundle/
└── bundle.source.js # Main entry point
lib/client/
├── index.js # Client initialization
├── chart.js # D3 chart rendering
├── renderer.js # UI rendering utilities
├── hashauth.js # Client-side authentication
├── browser-settings.js # User preferences
├── receiveddata.js # Data merge/cache logic
└── socket.js # WebSocket handling
```
### 2.3 Build Configuration
**Location:** `webpack/webpack.config.js`
**Key Settings:**
- Output: `static/bundle.js`
- Mode: production/development
- Moment locale optimization
- Babel transpilation
**Scripts:**
```json
{
"bundle": "webpack --mode production --config webpack/webpack.config.js",
"bundle-dev": "webpack --mode development --config webpack/webpack.config.js",
"bundle-analyzer": "webpack --mode development ... --json > stats.json && webpack-bundle-analyzer stats.json"
}
```
---
## 3. UI Framework Components
### 3.1 jQuery Usage
**Version:** ^3.5.1
**Primary Uses:**
- DOM manipulation
- Event handling
- AJAX requests (deprecated pattern)
- jQuery UI for dialogs, datepickers
**Code Pattern:**
```javascript
$('#container').html(content);
$('.sgv-pill').removeClass('urgent').addClass('info');
$('#currentBG').text(utils.scaleMgdl(bg));
```
### 3.2 D3.js Usage
**Version:** ^5.16.0
**Primary Uses:**
- SVG chart rendering
- Data binding
- Scales and axes
- Transitions and animations
**Chart Types:**
- Main glucose chart (focus area)
- Context brush chart (overview)
- Treatment overlays
- Prediction lines
### 3.3 Flot Usage
**Version:** ^0.8.3 (legacy)
**Primary Uses:**
- Report charts
- Pie charts (glucose distribution)
- Time-series in reports
**Status:** Legacy dependency, candidate for removal
---
## 4. Main Chart Implementation
### 4.1 Chart Structure
**Location:** `lib/client/chart.js`
```
┌─────────────────────────────────────────────────────────────┐
│ Focus Chart Area │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Glucose readings (SGV dots) │ │
│ │ Trend line │ │
│ │ Predictions (if enabled) │ │
│ │ Treatment markers │ │
│ │ Basal profile (if enabled) │ │
│ │ │ │
│ │ Y-axis: mg/dL or mmol/L │ │
│ │ X-axis: Time │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Context Chart (Brush Selector) │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### 4.2 Chart Initialization
```javascript
function init (client, d3, $) {
var chart = {};
var utils = client.utils;
var renderer = client.renderer;
// Define scales
chart.xScale = d3.scaleTime();
chart.yScale = d3.scaleLinear();
// Define axes
chart.xAxis = d3.axisBottom(chart.xScale);
chart.yAxis = d3.axisLeft(chart.yScale);
// Define brush for context chart
chart.brush = d3.brushX();
return chart;
}
```
### 4.3 Data Rendering
**Glucose Readings:**
```javascript
chart.bindData(sgvs)
.enter()
.append('circle')
.attr('class', function(d) { return 'sgv ' + getColorClass(d); })
.attr('cx', function(d) { return chart.xScale(d.mills); })
.attr('cy', function(d) { return chart.yScale(d.sgv); })
.attr('r', 3);
```
**Treatments:**
```javascript
chart.renderTreatments(treatments)
.enter()
.append('g')
.attr('class', 'treatment')
.attr('transform', function(d) {
return 'translate(' + chart.xScale(d.mills) + ',' + y + ')';
});
```
### 4.4 Color Coding
| Range | Class | Default Color |
|-------|-------|---------------|
| Urgent High | `urgent` | Red |
| High | `warn` | Yellow |
| In Range | `inrange` | Green |
| Low | `warn` | Yellow |
| Urgent Low | `urgent` | Red |
**Thresholds (configurable):**
```javascript
BG_HIGH=260
BG_TARGET_TOP=180
BG_TARGET_BOTTOM=80
BG_LOW=55
```
---
## 5. Clock Display Views
### 5.1 Clock View Types
**Location:** `views/clockviews/`
| View | Purpose | Features |
|------|---------|----------|
| Clock | Simple clock display | BG, time, trend |
| Color Clock | Color-coded by range | Visual range indication |
| BGClock | BG-focused display | Large BG, delta |
| Simple BG | Minimal display | BG only |
### 5.2 Clock CSS Structure
**Location:** `views/clockviews/clock-shared.css`
```css
body {
text-align: center;
background-color: black;
color: grey;
overflow: hidden;
}
#currentBG {
font-size: 20vmin;
font-weight: bold;
}
#currentDelta {
font-size: 10vmin;
}
```
### 5.3 Clock Configuration
**Location:** `views/clockviews/clock-config.css`
Configuration panel for:
- Time format (12h/24h)
- Units (mg/dL, mmol/L)
- Display elements visibility
- Color themes
---
## 6. Browser Settings
### 6.1 Settings Storage
**Location:** `lib/client/browser-settings.js`
Uses `js-storage` for localStorage management:
```javascript
var Storages = require('js-storage');
var storage = Storages.localStorage;
browserSettings.load = function() {
return storage.get(STORAGE_KEY) || {};
};
browserSettings.save = function(settings) {
storage.set(STORAGE_KEY, settings);
};
```
### 6.2 Available Settings
| Setting | Type | Default | Description |
|---------|------|---------|-------------|
| `units` | string | "mg/dl" | Display units |
| `timeFormat` | number | 12 | Time format (12/24) |
| `nightMode` | boolean | false | Dark theme |
| `showRawbg` | string | "never" | Raw BG display |
| `customTitle` | string | "Nightscout" | Custom page title |
| `theme` | string | "default" | Color theme |
| `alarmUrgentHigh` | boolean | true | Enable urgent high alarm |
| `alarmHigh` | boolean | true | Enable high alarm |
| `alarmLow` | boolean | true | Enable low alarm |
| `alarmUrgentLow` | boolean | true | Enable urgent low alarm |
| `alarmTimeagoWarn` | boolean | true | Enable stale data warning |
### 6.3 Settings Sync
Settings are stored locally and not synced:
- Each browser has independent settings
- No server-side storage of preferences
- Token-based URL sharing possible
---
## 7. Rendering Pipeline
### 7.1 Initial Load
```
Page Load
Load bundle.js (~1MB)
Initialize client
Fetch /api/v1/status
Connect WebSocket
Fetch initial data (/api/v1/entries, /api/v1/treatments)
Render chart
Subscribe to updates
```
### 7.2 Real-Time Update Cycle
```
WebSocket dataUpdate event
receiveDData.mergeDataUpdate()
Update local data cache
Run plugins (setProperties)
Update pills and status
chart.update()
D3 data binding
DOM update
```
### 7.3 Performance Metrics
| Metric | Typical Value | Target |
|--------|--------------|--------|
| Initial bundle load | 1-2s | <1s |
| First paint | 2-3s | <1.5s |
| Chart render | 100-200ms | <100ms |
| Data update | 50-100ms | <50ms |
---
## 8. View Templates
### 8.1 Template Engine
**Engine:** EJS (Embedded JavaScript)
**Main Template:** `views/index.html`
### 8.2 Page Structure
```html
<!DOCTYPE html>
<html>
<head>
<title>Nightscout</title>
<link rel="stylesheet" href="/bundle/bundle.css">
</head>
<body>
<nav id="navbar">
<!-- Navigation and pills -->
</nav>
<main>
<div id="container">
<svg id="chartContainer"></svg>
</div>
</main>
<script src="/bundle/bundle.js"></script>
</body>
</html>
```
### 8.3 Available Views
| Route | View | Purpose |
|-------|------|---------|
| `/` | index | Main dashboard |
| `/report` | report | Reports viewer |
| `/profile` | profile | Profile editor |
| `/admin` | admin | Admin tools |
| `/food` | food | Food database |
| `/clock` | clock | Simple clock |
| `/clock-color` | clock-color | Color clock |
| `/bgclock` | bgclock | BG clock |
| `/simplebg` | simplebg | Simple BG |
---
## 9. Responsive Design
### 9.1 Current State
- Desktop-first design
- Limited mobile optimization
- Fixed breakpoints
### 9.2 Breakpoints
```css
/* Example from existing CSS */
@media (max-width: 768px) {
.toolbar { display: none; }
#container { width: 100%; }
}
```
### 9.3 Mobile Issues
| Issue | Impact | Status |
|-------|--------|--------|
| Touch events | Poor mobile interaction | Partial |
| Chart zoom | Pinch zoom not supported | Open |
| Portrait mode | Layout issues | Partial |
| PWA support | Not installable | Open |
---
## 10. Accessibility
### 10.1 Current State
- Limited ARIA labels
- No keyboard navigation
- Color-only status indication
- No screen reader support
### 10.2 Accessibility Issues
| Issue | WCAG | Priority |
|-------|------|----------|
| Missing alt text | 1.1.1 | High |
| Color contrast | 1.4.3 | Medium |
| Focus indicators | 2.4.7 | Medium |
| Status announcements | 4.1.3 | High |
### 10.3 Recommendations
1. Add ARIA labels to interactive elements
2. Implement keyboard navigation
3. Add screen reader announcements for alarms
4. Improve color contrast ratios
5. Add focus visible styles
---
## 11. Performance Optimization
### 11.1 Bundle Size Analysis
**Current Bundle (~1MB+):**
| Library | Size (approx) | Optimization |
|---------|--------------|--------------|
| D3.js | 250KB | Tree-shake unused |
| jQuery | 90KB | Consider removal |
| Lodash | 70KB | Use lodash-es |
| Moment.js | 230KB | Replace with dayjs |
| Socket.IO | 50KB | Current |
| Flot | 100KB | Remove (legacy) |
### 11.2 Optimization Strategies
1. **Code Splitting:**
```javascript
// Dynamic import for reports
const reports = await import('./reports');
```
2. **Tree Shaking:**
```javascript
// Instead of:
import _ from 'lodash';
// Use:
import { debounce, throttle } from 'lodash-es';
```
3. **Lazy Loading:**
- Load reports module on demand
- Defer non-critical CSS
4. **Asset Optimization:**
- Compress images
- Use WebP format
- Implement caching headers
### 11.3 Performance Budget
| Metric | Current | Target |
|--------|---------|--------|
| Bundle size (gzip) | ~300KB | <200KB |
| First contentful paint | 2.5s | <1.5s |
| Time to interactive | 4s | <2s |
| Lighthouse score | ~60 | >80 |
---
## 12. Issues and Recommendations
### 12.1 Critical Issues
| Issue | Impact | Recommendation |
|-------|--------|----------------|
| Large bundle size | Slow initial load | Code splitting |
| No PWA support | Mobile experience | Add service worker |
| jQuery dependency | Maintenance burden | Migrate to vanilla JS |
### 12.2 UI Framework Migration
**Options:**
1. **Vanilla JavaScript:**
- Pros: No framework overhead
- Cons: More code to maintain
2. **React:**
- Pros: Large ecosystem, component model
- Cons: Significant rewrite
3. **Vue.js:**
- Pros: Gentle learning curve
- Cons: Less ecosystem than React
4. **Svelte:**
- Pros: Small bundle, no virtual DOM
- Cons: Smaller ecosystem
**Recommendation:** Consider incremental migration to Svelte or Vue for new features while maintaining existing code.
### 12.3 Chart Library Migration
**D3.js v5 → v7:**
- Breaking changes in API
- Worth migrating for bundle size
- Better TypeScript support
**Alternative: Chart.js:**
- Pros: Simpler API, smaller bundle
- Cons: Less customization
- Suitable for reports
### 12.4 Modernization Roadmap
1. **Phase 1 (0-3 months):**
- Add service worker for PWA
- Implement code splitting
- Replace Moment.js with dayjs
2. **Phase 2 (3-6 months):**
- Migrate from jQuery to vanilla JS
- Add responsive design improvements
- Implement accessibility basics
3. **Phase 3 (6-12 months):**
- Consider framework adoption
- Upgrade D3.js to v7
- Remove Flot dependency
---
## 13. Related Documents
- [Architecture Overview](../meta/architecture-overview.md)
- [Plugin Architecture Audit](./plugin-architecture-audit.md)
- [Real-Time Systems Audit](./realtime-systems-audit.md)
- [Modernization Roadmap](../meta/modernization-roadmap.md)