Improved UI
This commit is contained in:
+112
-54
@@ -24,58 +24,97 @@ In the initial version all users share the same access level. Role-based access
|
||||
|
||||
The default mode when opening the application.
|
||||
|
||||
**Interface list pane (left, collapsible)**
|
||||
- Displays all interfaces saved on the server, grouped into a tree by folder.
|
||||
**Interface list pane (left, collapsible, resizable)**
|
||||
- Displays all interfaces saved on the server.
|
||||
- Right-click on an interface: options to open in Edit mode or clone it.
|
||||
- "New interface" button opens Edit mode with a blank canvas.
|
||||
- "Import" option loads an interface from a local XML file.
|
||||
- The pane width can be adjusted by dragging the resize handle on its right edge.
|
||||
|
||||
**Tabs**
|
||||
- **HMI tab**: the live widget canvas (described below).
|
||||
- **Plot tab**: a dedicated live multi-signal plot panel (see §3.3).
|
||||
- **Info tab**: signal info and metadata display for the last right-clicked signal.
|
||||
|
||||
**HMI canvas (center)**
|
||||
- Renders the selected interface as a live, interactive panel.
|
||||
- Widgets display real-time data; controls (set-value, buttons) are active.
|
||||
- No drag, resize, or layout operations are possible in this mode.
|
||||
- Right-clicking any widget opens a context menu:
|
||||
- **Signal info** — floating window showing DS name, type, unit, range, current value and timestamp.
|
||||
- **Signal info** — switches to the Info tab showing DS name, type, unit, range, current value and timestamp.
|
||||
- **Copy signal name** — copies the signal identifier to the clipboard.
|
||||
- **Export data to CSV** — downloads buffered/historical data for the signal(s) used by the widget.
|
||||
- **Export data to CSV** — downloads buffered data for the signal(s) used by the widget.
|
||||
- **Plot** — adds the signal(s) to the Plot tab.
|
||||
|
||||
**Top toolbar**
|
||||
- Show/hide interface list pane.
|
||||
- Time selector: navigate to a past timestamp (enabled only when the server has archive access for all signals on the canvas).
|
||||
- "Live" button: return to real-time data after historical navigation.
|
||||
- **⏱ History** button: toggle historical time navigation bar.
|
||||
- Zoom control (A− / % / A+): adjust the UI scale (see §3.4).
|
||||
- Edit button: switch to Edit mode for the current interface.
|
||||
- Connection status indicator.
|
||||
|
||||
**Historical time navigation bar** (shown when History is active)
|
||||
- Date/time range pickers (start and end).
|
||||
- **Load** button fetches archive data and replaces live data in all widgets.
|
||||
- **Live** button discards archive data and resumes real-time streaming.
|
||||
- Status shown on plot widgets: "Loading history…", "No archive data for this range", "Archive unavailable".
|
||||
|
||||
### 3.2 Edit Mode
|
||||
|
||||
Activated via the "New interface" button or by right-clicking an existing interface.
|
||||
Activated via the "New interface" button or by clicking Edit in the toolbar.
|
||||
|
||||
**Signal tree pane (left, resizable and collapsible)**
|
||||
- Shows all signals known to each connected data source.
|
||||
- Sources are shown as top-level nodes; signals are nested within.
|
||||
- User can add custom entries:
|
||||
- For EPICS: manually enter a PV name.
|
||||
- For Synthetic: define a new synthetic signal (see §5.2).
|
||||
- User can load a CSV file with columns `NAME, DataSource, DS_PARAMETERS` to import a batch of signals.
|
||||
- For Synthetic: define a new synthetic signal via the Synthetic Wizard (see §5.2).
|
||||
- Filter/search box to narrow the list.
|
||||
- Synthetic signals show an edit (✎) button to reopen the wizard.
|
||||
|
||||
**Widget canvas (center)**
|
||||
- Free-form canvas where widgets can be placed at arbitrary pixel positions.
|
||||
- Background grid with optional snap-to-grid.
|
||||
- Background grid with snap-to-grid.
|
||||
|
||||
**Properties pane (right, collapsible)**
|
||||
**Properties pane (right, resizable and collapsible)**
|
||||
- Appears when one or more widgets are selected.
|
||||
- Displays and edits all options for the selected widget (see §4).
|
||||
- Width is adjustable by dragging the resize handle on its left edge.
|
||||
|
||||
**Top toolbar**
|
||||
- Show/hide signal pane.
|
||||
- Show/hide properties pane.
|
||||
- Show/hide signal pane / properties pane.
|
||||
- Undo / Redo (also Ctrl+Z / Ctrl+Shift+Z).
|
||||
- Import / Export interface to/from local XML file.
|
||||
- Save interface to server.
|
||||
- Load interface from server.
|
||||
- Export interface to local XML file.
|
||||
- Import interface from local XML file.
|
||||
- "Add text" tool — inserts a static text label.
|
||||
- "Add image" tool — inserts a static image (uploaded to server or embedded as base64).
|
||||
- "Add link" tool — inserts a button that opens another interface.
|
||||
- Close (return to View mode).
|
||||
- Zoom control (A− / % / A+).
|
||||
|
||||
### 3.3 Plot Tab (Live Multi-Signal Plot)
|
||||
|
||||
A dedicated panel for live time-series plotting of any signals, independent of the interface layout.
|
||||
|
||||
**Adding signals:** right-click any widget in the HMI tab → **Plot**. The signal is added to the Plot tab immediately.
|
||||
|
||||
**Time window selector:** 10s / 30s / 1m / 5m / 15m / 1h buttons control how much history is displayed.
|
||||
|
||||
**Per-signal legend:**
|
||||
- Color swatch and signal name.
|
||||
- Statistics table: Last / Min / Max / Mean over the current window.
|
||||
- ✎ button opens an inline style editor:
|
||||
- **Color**: color picker.
|
||||
- **Width**: line width (none, 1, 1.5, 2, 3 px).
|
||||
- **Line**: solid / dashed / dotted.
|
||||
- **Markers**: none, S (3 px), M (5 px), L (8 px).
|
||||
- ✕ button removes the signal from the plot.
|
||||
|
||||
**Chart area:** rendered with uPlot; auto-scaled Y axis; time axis tracks the rolling window in real time.
|
||||
|
||||
### 3.4 UI Zoom
|
||||
|
||||
The toolbar in both modes contains a zoom control (**A−** / **nn%** / **A+**) that adjusts the base font size of the entire UI:
|
||||
|
||||
- 11 zoom steps from 50% to 250% (50, 60, 75, 85, 100, 115, 130, 150, 175, 200, 250%).
|
||||
- The selected zoom level is persisted in `localStorage` and restored on the next page load.
|
||||
- At 100%, the base font size adapts to viewport height via `clamp(13px, 1.5vh, 18px)`, making the UI naturally usable on 4K displays without any manual adjustment.
|
||||
|
||||
---
|
||||
|
||||
@@ -83,7 +122,7 @@ Activated via the "New interface" button or by right-clicking an existing interf
|
||||
|
||||
### 4.1 Creating Widgets
|
||||
|
||||
Drag a signal from the signal tree and drop it onto the canvas. A picker appears showing all widget types compatible with the signal's data type (iconised). The user selects one and the widget is placed at the drop location with default size.
|
||||
Drag a signal from the signal tree and drop it onto the canvas. A picker appears showing all widget types compatible with the signal's data type. The user selects one and the widget is placed at the drop location with default size.
|
||||
|
||||
### 4.2 Selecting Widgets
|
||||
|
||||
@@ -104,8 +143,7 @@ When multiple widgets are selected:
|
||||
- An align/distribute toolbar appears above the canvas with:
|
||||
- Align left / center horizontal / right.
|
||||
- Align top / center vertical / bottom.
|
||||
- Distribute evenly — by center spacing (horizontal/vertical).
|
||||
- Distribute evenly — by gap size (horizontal/vertical).
|
||||
- Distribute evenly (horizontal/vertical).
|
||||
|
||||
### 4.4 Widget Catalogue
|
||||
|
||||
@@ -115,7 +153,7 @@ When multiple widgets are selected:
|
||||
| Gauge | numeric scalar | Circular or arc gauge with configurable range |
|
||||
| Vertical bar | numeric scalar | Vertical level indicator |
|
||||
| Horizontal bar | numeric scalar | Horizontal level indicator |
|
||||
| Set value | numeric or string, writable | Shows `name: [input field] current_value unit` + Set button |
|
||||
| Set value | numeric, string, or enum; writable | Input field or enum dropdown + Set button |
|
||||
| LED | boolean / numeric | Coloured indicator with configurable condition and label |
|
||||
| Multi-LED | integer (bitset) | One LED per bit with individual labels and conditions |
|
||||
| Button | writable | Sends a fixed value or command on click |
|
||||
@@ -140,45 +178,62 @@ When multiple widgets are selected:
|
||||
Common to all:
|
||||
- Label text, font size, text colour.
|
||||
- Position (X, Y) and size (W, H) — editable numerically.
|
||||
- Data source and signal name (read-only after creation; reassignable via drag).
|
||||
- Data source and signal name.
|
||||
|
||||
Per type:
|
||||
- **Gauge / Bar**: min value, max value, alert thresholds with colours, unit label.
|
||||
- **LED / Multi-LED**: condition expression (e.g. `value > 0`), colours for true/false states.
|
||||
- **Plot**: plot sub-type selector, Y-axis range (auto or manual), time window duration, legend position, colour per signal, line style.
|
||||
- **Set value**: input type (numeric / string / enum), confirmation prompt toggle.
|
||||
- **LED / Multi-LED**: condition expression (e.g. `value > 0`), colours for true/false states, label.
|
||||
- **Plot**: plot sub-type selector, Y-axis range (auto or manual min/max), time window duration, legend position (top / bottom / none), value format string.
|
||||
- **Set value**: no special options — enum mode is detected automatically from signal metadata.
|
||||
- **Link**: target interface name.
|
||||
|
||||
### 4.6 Set-value Widget — Enum Mode
|
||||
|
||||
When the signal's metadata reports enum strings (e.g. EPICS mbbi/mbbo records):
|
||||
- The input field is replaced by a `<select>` dropdown showing all enum options.
|
||||
- The current live value is shown as the pre-selected option (display only).
|
||||
- The user selects a value from the dropdown, then clicks **Set** to write it.
|
||||
- The Set button is always required; changing the dropdown does not write immediately.
|
||||
|
||||
---
|
||||
|
||||
## 5. Data Sources
|
||||
|
||||
### 5.1 EPICS
|
||||
|
||||
- Connects to an EPICS environment via Channel Access (CA) or PVAccess (PVA).
|
||||
- On connect, retrieves full metadata from the PV name: data type, engineering units, display range (DRVL/DRVH, LOPR/HOPR), alarm limits, enum strings (for mbbi/mbbo records), read/write mode, acquisition mode.
|
||||
- Prefers monitor/subscription over polling. Falls back to polling only when monitors are unavailable.
|
||||
- Attempts to enumerate available PV names from the IOC (e.g. via PV lists or Channel Finder). Unknown PVs can still be manually added by the user.
|
||||
- When an EPICS Archive Appliance or Channel Archiver is configured, the server can satisfy historical data requests.
|
||||
- Connects to an EPICS environment via Channel Access (CA).
|
||||
- On connect, retrieves full metadata from the PV name: data type, engineering units, display range, alarm limits, enum strings (for mbbi/mbbo records), read/write mode.
|
||||
- Uses `ca_add_event` monitors — no polling.
|
||||
- When an EPICS Archive Appliance is configured, the server can satisfy historical data requests from the toolbar time navigator.
|
||||
|
||||
### 5.2 Synthetic
|
||||
### 5.2 Synthetic Signals
|
||||
|
||||
A signal defined by composing one or more input signals (from any data source) through a chain of processing functions.
|
||||
A signal defined by composing one or more input signals through a chain of processing nodes.
|
||||
|
||||
**Built-in processing functions (non-exhaustive):**
|
||||
- Arithmetic: gain, offset, add, subtract, multiply, divide.
|
||||
- Signal processing: moving average (N samples or time window), RMS, bandpass filter (IIR/FIR), lowpass / highpass filter, derivative, integral.
|
||||
- FFT, inverse FFT.
|
||||
- Peak detection, threshold crossing.
|
||||
- Custom formula: inline expression (`a * sin(b) + c`).
|
||||
- Lua script block: arbitrary Lua code with access to input values and state.
|
||||
|
||||
**User workflow:**
|
||||
**New Synthetic Signal Wizard:**
|
||||
1. Click "New synthetic signal" in the signal tree.
|
||||
2. Name the signal and choose input signals.
|
||||
3. Build a processing pipeline by chaining function blocks (UI similar to a node graph or an ordered list).
|
||||
4. Optionally write a Lua snippet for custom logic.
|
||||
5. The synthetic signal appears in the tree and can be used like any other signal.
|
||||
2. Name the signal and optionally set a unit.
|
||||
3. Add processing nodes from the node type dropdown and connect them.
|
||||
4. Configure each node's parameters inline.
|
||||
5. Click Create — the signal appears in the tree and updates live.
|
||||
|
||||
The wizard dialog is resizable (drag its corner) and defaults to 600 px wide to accommodate the Lua editor.
|
||||
|
||||
**Editing an existing synthetic signal:** click the ✎ button next to the signal in the tree to reopen the wizard.
|
||||
|
||||
**Built-in node types:**
|
||||
|
||||
| Node | Parameters | Description |
|
||||
|------|------------|-------------|
|
||||
| Source | DS, signal name | Input from any data source |
|
||||
| Gain | factor | Multiply by constant |
|
||||
| Offset | value | Add constant |
|
||||
| Moving average | window (samples) | Rolling mean |
|
||||
| Low-pass filter | frequency (Hz), order (1–8) | IIR low-pass; correct for non-uniform sample rates |
|
||||
| Formula | expression | Inline math (variables: `a`, `b`, …) |
|
||||
| Lua script | script | Arbitrary Lua 5.1 with persistent state table |
|
||||
|
||||
**Lua editor:** the Lua node parameter uses a code editor with syntax highlighting (keywords, strings, comments, numbers rendered in distinct colours). The editor is a full-height multi-line input that grows with the dialog.
|
||||
|
||||
---
|
||||
|
||||
@@ -192,11 +247,13 @@ A signal defined by composing one or more input signals (from any data source) t
|
||||
|
||||
## 7. Historical Data Navigation
|
||||
|
||||
When the server has archive access for all signals on the current canvas:
|
||||
- The top toolbar shows a date/time picker.
|
||||
- Selecting a past time replays data from the archive into all widgets.
|
||||
- The "Live" button resumes real-time streaming.
|
||||
- Widgets that support time-axis (plots) show the historical range; point-value widgets show the value at the selected time.
|
||||
When the server has archive access configured:
|
||||
- The **⏱ History** button in the View mode toolbar reveals a time range bar.
|
||||
- Users set a start and end date/time and click **Load**.
|
||||
- Plot widgets fetch and display the archived data for the selected range.
|
||||
- Point-value widgets (text view, gauge, bar, LED) show the value at the end of the selected range.
|
||||
- The **Live** button resumes real-time streaming.
|
||||
- Status overlays on plot widgets indicate loading, empty, or error states.
|
||||
|
||||
---
|
||||
|
||||
@@ -210,4 +267,5 @@ When the server has archive access for all signals on the current canvas:
|
||||
| Concurrent clients | ≥ 20 simultaneous browser clients |
|
||||
| Data fan-out latency | < 5 ms added latency vs. raw EPICS update rate |
|
||||
| Frontend responsiveness | 60 fps canvas rendering during live updates |
|
||||
| Screen DPI | Frontend adapts to device pixel ratio |
|
||||
| Screen DPI | UI scales with viewport height; manual zoom 50–250% |
|
||||
| Plot buffer | 200,000 samples per signal retained in-browser |
|
||||
|
||||
Reference in New Issue
Block a user