# 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