SignalScope is a WPF visual laboratory for mathematical signal visualization. The first module focuses on Fourier series reconstruction of a rich synthetic vibration waveform, with the source pipeline prepared for future API-backed data streams such as market prices, weather metrics, sensors, or files.
- Swappable signal source abstraction through
IWaveformSource. - Centralized source registration through
DataSourceManager. - Synthetic high-density vibration source with harmonics, drift, bursts, chirps, impulses, and deterministic noise.
- Mock API source presets for market, weather, and sensor-like streams.
- HTTP JSON API source with configurable endpoint, JSON selector, timeout, and normalization.
- Fourier coefficient analysis with Rectangular, Hann, and Blackman window functions.
- Live reconstruction using adjustable harmonic count.
- Dedicated Signal View workspace with source/reconstruction overlay, cursor readout, time-domain metrics, and streaming status.
- Frequency spectrum view with active harmonic highlighting, hover readout, and click-to-select harmonics.
- Phase response view for each harmonic.
- STFT spectrogram view for time-frequency analysis.
- Rotating-vector epicycle visualization.
- Dominant component readout, cursor values, selected harmonic amplitude/phase, and RMS reconstruction error.
- Built-in study signals: square, sawtooth, triangle, pulse train, and Gibbs step.
- CSV/TXT/TSV waveform loading.
- CSV analysis export and PNG dashboard snapshots.
- Streaming buffer mode with adjustable sample step.
- Frequency filters: low-pass, high-pass, band-pass, and band-stop.
- Signal metrics: mean, RMS, peak, crest factor, and dominant harmonic.
- Save/load
.signalscope.jsonanalysis sessions. - Event detection for peaks, zero crossings, and spikes.
- Waveform event markers and event table with CSV export.
SignalScope/
SignalScope/
Domain/Analysis/ Fourier analysis, STFT, metrics, events, and domain models
Application/Services/ Analysis, export, and session services
Application/Sessions/ Serializable application/session state DTOs
Application/Workspaces/ Workspace state, requests, update results, and analysis-flow controller
Infrastructure/Sources/ Replaceable waveform providers: synthetic, CSV, mock API, HTTP JSON
Presentation/Adapters/ UI request/source adapters used before full MVVM
Presentation/Coordinators/ WPF command coordinators for source, file, and playback workflows
Presentation/Controls/ Custom WPF drawing surfaces
Presentation/Mappers/ UI-to-domain/session mapping helpers
Presentation/Presenters/ Plot, readout, settings display, and event presentation adapters
Presentation/ViewModels/ Read-only view state projected from workspace state
Presentation/Shell/ Main workspace shell display services
Presentation/Views/ WPF windows and view composition
Presentation/Views/Panels/ Shell-level UserControl panels used by the main workspace
Presentation/Views/Settings/ Dedicated settings panels grouped by workspace/capability
Presentation/Views/Workspaces/ Dedicated workspace panels for each analysis task
App.xaml Application startup and resources
SignalScope.Tests/ Lightweight console-based regression tests
docs/ Architecture notes and development documentation
Layering intent:
Domainshould stay UI-independent and contain the math/signal-analysis rules.Applicationcoordinates workflows such as analysis, workspace state transitions, export, and session persistence.Infrastructureowns external/input details such as files, mock APIs, and HTTP JSON.Presentationowns WPF views, drawing controls, UI adapters, presenters, shell display, and command coordinators.
See docs/DEVELOPMENT.md for the full project progress, architecture notes, roadmap, and development cautions.
dotnet build .\SignalScope.slnx
dotnet run --project .\SignalScope\SignalScope.csproj
dotnet run --project .\SignalScope.Tests\SignalScope.Tests.csprojCreate a new class that implements IWaveformSource, return a WaveformSnapshot, then register it in DataSourceManager:
Register(new YourApiBackedSource());The Fourier analyzer and rendering controls do not need to change when a new source is added.
- Drag on the waveform to move the time cursor.
- Move over the spectrum to inspect a harmonic.
- Click a spectrum bar to select a harmonic.
- Open the
Spectrogramtab to inspect how frequency energy changes over time. - Enable
STFT heatmapin the left panel before using the spectrogram view. - Drag or click the spectrogram to sync the waveform cursor.
- Enable
Solo selected harmonicor chooseSoloSelectedmode to isolate the selected component. - Choose
DominantOnlymode to reconstruct from the strongest harmonics instead of the first N harmonics. - Enable
Streaming bufferto switch from whole-frame generation into a rolling oscilloscope-style buffer. - Use
Frequency filtercontrols to restrict reconstruction by harmonic range. - Select
Mock API - Market,Mock API - Weather, orMock API - Sensorto test API-style streams before wiring a real endpoint. - Select
HTTP JSON API, enter an endpoint, then useTest Fetchto validate real JSON data. - JSON selectors support forms like
values[],data.prices[].close, or empty selector to collect every numeric value. - Source status shows kind, state, last update time, and normalized range.
- Open the
Event Detectionworkspace to tune peak threshold, minimum distance, and spike z-score. - Event markers are drawn directly on the waveform: high/low peaks, zero crossings, and spikes.
- Export detected events with
Export Events CSV.
The HTTP source is intentionally conservative:
- It only performs GET requests.
- It does not store or send secrets/tokens.
- Fetch failures keep the previous successful sample buffer when available.
- Errors are shown in source status instead of crashing the dashboard.
Supported JSON shapes include:
[1, 2, 3, 4]{ "values": [1, 2, 3, 4] }{ "data": { "prices": [{ "close": 10.1 }, { "close": 10.4 }] } }MainWindow now owns the shell layout and orchestration logic, while major UI regions live under Presentation/Views/Panels:
SettingsPanel: source, Fourier, filter, spectrogram, shaping, playback controls.ChartWorkspacePanel: waveform, spectrum, phase, and spectrogram plots.RotatingVectorsPanel: enlarged epicycle / rotating vectors view.AnalysisSidePanel: readout, signal metrics, detector controls, and event list.
Event handlers are still subscribed by MainWindow.xaml.cs to avoid a large MVVM rewrite in this phase.
MainWindow.xaml.cs has been reduced to the shell-level fields, panel accessors, constructor, and event subscription wiring. The remaining code-behind responsibilities are split into partial files:
MainWindow.EventHandlers.cs: initial catch-all event handler file from Phase 4, replaced in Phase 7 by command-focused partial files.MainWindow.Analysis.cs: sample generation, streaming buffer updates, analysis execution, and reconstruction refresh entry points.MainWindow.PresentationState.cs: coordinates plot/readout/source-status presenters and keeps presentation refresh flow centralized.MainWindow.Settings.cs: current UI setting capture, filter mode helpers, and analysis settings construction.MainWindow.Session.cs: save/load session state mapping.MainWindow.Utilities.cs: small shared helpers and row records used by the view.
This phase intentionally keeps behavior in the MainWindow partial class instead of introducing MVVM all at once. The next safer step is to move settings/session mapping into dedicated presenter or view-state classes.
Settings and session conversion are now handled by dedicated mapper classes instead of being handwritten directly in MainWindow:
Presentation/Mappers/AnalysisSettingsMapper.cs: reads settings/detector panels and buildsAnalysisSettings.Presentation/Mappers/AppSessionMapper.cs: captures/restoresAppSessionfrom UI panels plusDataSourceManager.
MainWindow.Settings.cs and MainWindow.Session.cs now delegate to these mappers, so the window is closer to a shell/orchestrator and the next refactor can target plot/readout presenters.
Plot and readout output logic has moved out of MainWindow into dedicated presenter classes:
Presentation/Presenters/PlotPresenter.cs: updates waveform, spectrum, phase, spectrogram, and rotating-vector plots.Presentation/Presenters/ReadoutPresenter.cs: updates cursor values, selected harmonic readout, metrics, and dominant components.Presentation/Presenters/EventSummaryPresenter.cs: updates event counts, estimated frequency, and event table rows.Presentation/Presenters/SettingsDisplayPresenter.cs: updates slider/value labels and source status readouts.
MainWindow.PresentationState.cs now mainly builds presentation state objects and delegates rendering to presenters. This keeps the current event-driven behavior while making the UI output layer easier to test or move toward MVVM later.
The previous catch-all MainWindow.EventHandlers.cs has been split into focused partial files:
MainWindow.SourceEvents.cs: source selection, mock API, HTTP settings, and HTTP test command.MainWindow.AnalysisSettingEvents.cs: harmonic/sample/window/filter/reconstruction/detector/spectrogram setting events.MainWindow.PlaybackEvents.cs: timer tick, play/pause, regenerate, streaming mode, and stream step display.MainWindow.FileCommands.cs: CSV import/export, snapshot export, session save/load, and event export dialogs.MainWindow.PlotInteractionEvents.cs: waveform, spectrum, and spectrogram cursor/selection mouse interactions.
MainWindow.xaml.cs still owns event subscription, but the event behavior is no longer concentrated in one large file. This keeps behavior stable while preparing for a later command service or ViewModel binding migration.
Source, file, and playback event workflows are now delegated to command coordinator classes:
Presentation/Coordinators/SourceCommandCoordinator.cs: source switching, mock API settings, HTTP JSON settings, and HTTP test fetch.Presentation/Coordinators/FileCommandCoordinator.cs: CSV load, analysis CSV export, snapshot save, session save/load, and event CSV export dialogs.Presentation/Coordinators/PlaybackCommandCoordinator.cs: play/pause state, regenerate behavior, streaming mode changes, stream-step display, and timer-step decisions.
MainWindow.*Events.cs files now mostly translate WPF events into coordinator calls. This keeps the existing code-behind event model but moves command behavior into focused, testable classes before a larger MVVM migration.
Mutable analysis and interaction state has been centralized in a lightweight state container:
Application/Workspaces/WorkspaceState.cs: owns samples, reconstruction, Fourier components, metrics, spectrogram, detected events, stream buffer, cursor, source offset, hovered harmonic, selected harmonic, and playback state.
MainWindow now keeps a single _state field instead of many independent mutable fields. This is not a full MVVM conversion yet; it is a safer intermediate step that makes the current state model explicit before introducing observable ViewModels or command bindings.
Workspace state transitions and analysis execution have moved out of MainWindow.Analysis.cs into a focused controller:
Application/Workspaces/WorkspaceController.cs: coordinates waveform generation requests, streaming buffer initialization/appending, analysis execution, reconstruction refresh, and application of analysis results toWorkspaceState.
MainWindow.Analysis.cs now primarily adapts UI values into controller requests, supplies the selected waveform source snapshot, and updates the few shell-level labels that still live in the main window. This keeps the current event-driven UI intact while reducing the amount of state mutation directly performed by the window.
UI-derived workspace request values are now centralized in:
Presentation/Adapters/WorkspaceRequestAdapter.cs: converts Settings/Analysis panel control values intoWorkspaceGenerationRequest,WorkspaceStreamRequest,WaveformRequest,SettingsDisplayViewModel, active harmonic count, and plot-title decisions.
MainWindow.Analysis.cs no longer directly reads sample/stream/complexity/noise/seed sliders to build controller requests. MainWindow.PresentationState.cs also delegates settings-display and plot-title value capture to the adapter. This keeps the current code-behind event model but reduces direct control-value coupling inside MainWindow.
Source-selection and shell-status responsibilities have been moved behind dedicated presentation services/adapters:
Presentation/Adapters/SourceSelectionAdapter.cs: owns active source lookup, source list initialization/refresh, CSV/HTTP source selection, Mock API source updates, HTTP JSON settings synchronization, and waveform snapshot generation.Presentation/Shell/WorkspaceShellService.cs: updates shell-level source/sample labels and delegates source-status rendering toSettingsDisplayPresenter.
MainWindow.Analysis.cs no longer reads SourceCombo.SelectedItem directly when generating snapshots, and no longer writes the shell source/sample labels directly. This keeps the current event-driven UI stable while reducing remaining source/UI coupling inside MainWindow.
Phase 13 clarified the logical layer boundaries created during the previous refactors:
Application/Workspaces/WorkspaceState.csreplaces the UI-flavoredMainWorkspaceStatename.Application/Workspaces/WorkspaceController.csnow owns workspace state transitions outside the WPF presentation namespace.Application/Workspaces/WorkspaceRequests.csandWorkspaceUpdateResult.csmake controller request/result contracts explicit.Presentation/Coordinators/replacesPresentation/Commands/because these classes still coordinate WPF events/dialogs rather than pureICommandobjects.Presentation/Shell/WorkspaceShellService.csmakes shell-label/status updates distinct from application services.
Rule of thumb after this phase: WPF control references stay in Presentation; pure workspace state and analysis-flow transitions belong in Application/Workspaces.
Phase 14 introduces a lightweight read-only presentation ViewModel layer without converting the application to full binding-based MVVM yet:
Presentation/ViewModels/WorkspaceViewModel.cs: projectsWorkspaceStateplus UI-derived settings into display-ready models for plots, readouts, event summaries, and settings labels.ReadoutPresenter,EventSummaryPresenter,PlotPresenter, andSettingsDisplayPresenternow render ViewModel objects instead of computing presentation rows and formatted strings themselves.MainWindow.PresentationState.csnow refreshes a single_viewModelfirst, then delegates each section to the presenters.
This phase keeps the existing code-behind event model stable, but creates a clear next step toward observable ViewModels and WPF binding later.
Phase 15 reduces MainWindow.xaml.cs noise by separating two shell-only concerns into focused partial files:
Presentation/Views/MainWindow.Controls.cs: centralizes panel control accessor properties such as settings controls, plot controls, and analysis side-panel controls.Presentation/Views/MainWindow.EventSubscriptions.cs: centralizes WPF event wiring and groups subscriptions by source, analysis settings, playback, plot interaction, detector settings, and file commands.
MainWindow.xaml.cs now mainly contains fields, service/coordinator/presenter initialization, UI default initialization, timer setup, and first recompute. This keeps the current code-behind architecture stable while making it easier to migrate selected areas to binding or command objects later.
Main window startup defaults and timer setup have been separated from the constructor into a focused partial file:
Presentation/Views/MainWindow.Initialization.cs: initializes source defaults, analysis defaults, playback defaults, and creates the UI refresh timer.
MainWindow.xaml.cs now keeps the constructor focused on dependency creation, event subscription, default initialization, timer creation, and the first recompute. This preserves the current event-driven behavior while making future startup/default-setting changes easier to review.
Main window dependency wiring has been moved into a dedicated composition layer:
Presentation/Composition/MainWindowComposition.cs: creates source/application services, workspace state/view model, presenters, adapters, coordinators, shell service, and workspace controller.MainWindow.xaml.csnow requests a composition object and assigns the dependencies it needs, instead of manually constructing every collaborator inline.
This phase does not change runtime behavior; it only centralizes object composition so the WPF shell remains focused on orchestration, event subscription, initialization, timer startup, and first recompute.
Phase 18 strengthens the refactoring with test-project guardrails:
SignalScope.Tests/Program.csnow includes architecture boundary checks forDomain,Application, andInfrastructuresource folders.Domainis guarded from referencingApplication,Infrastructure,Presentation, or WPF APIs.Applicationis guarded from referencingPresentationor WPF APIs.Infrastructureis guarded from referencingApplication,Presentation, or WPF APIs.- WPF snapshot export moved from
Application/Services/ExportService.cstoPresentation/Exporting/SnapshotExportService.cs.
This keeps CSV/session/analysis behavior unchanged while making future boundary regressions visible when the test project is run.
Phase 19 starts the product-level UI split for vibration-analysis workflows instead of placing every feature on the first page or in one global left settings panel.
New UI structure:
Presentation/Navigation/WorkspacePage.cs: defines the main analysis workspaces.Presentation/Views/Panels/WorkspaceNavigationPanel.xaml: adds a left navigation rail for Dashboard, Signal View, Frequency Analysis, Rotating Vectors, Spectrogram, Event Detection, and Data Sources.Presentation/Views/MainWindow.WorkspaceNavigation.cs: applies the selected workspace by updating the workspace header, selecting the relevant plot tab, showing/hiding rotating-vector and event/readout areas, and filtering the visible settings sections.
The old SettingsPanel still exists so existing controls and event handlers remain stable, but its sections are now workspace-filtered. This is an intentionally low-risk transition before splitting each workspace into its own dedicated page/control later.
The central analysis canvas no longer keeps every plot inside a single all-purpose ChartWorkspacePanel. Phase 20 introduces dedicated workspace panels under Presentation/Views/Workspaces:
DashboardWorkspacePanel: navigation-oriented overview and recommended analysis flow.SignalViewWorkspacePanel: time-domain waveform and reconstruction inspection.FrequencyAnalysisWorkspacePanel: spectrum and phase analysis.SpectrogramWorkspacePanel: STFT / time-frequency analysis.EventDetectionWorkspacePanel: dedicated event-analysis workspace with detector controls, summary cards, and event list.DataSourcesWorkspacePanel: dedicated source-management workspace with source status and workflow guidance.
ChartWorkspacePanel now acts as a workspace host and forwards the existing plot controls to presenters, so the rendering pipeline remains stable while the UI is prepared for page-specific layouts.
The left settings area is no longer one monolithic SettingsPanel.xaml containing every source, Fourier, filter, STFT, shaping, and playback control. Phase 21 introduces dedicated settings panels under Presentation/Views/Settings:
SourceSettingsPanel: source selection, CSV/session commands, mock API, HTTP JSON, and source status.FourierSettingsPanel: harmonic count, sample count, window function, and reconstruction mode.FrequencyFilterSettingsPanel: frequency-domain filter mode and low/high harmonic range.SpectrogramSettingsPanel: STFT enable, window, hop, bin, and intensity controls.SignalShapingSettingsPanel: synthetic signal complexity, noise, and seed controls.PlaybackSettingsPanel: playback, regeneration, snapshot, streaming, and cursor controls.
SettingsPanel now acts as a settings host and exposes the same control properties as before. This keeps existing event subscriptions, mappers, adapters, and presenters stable while making each settings area independently movable in later phases.
Phase 22 moves the settings host from the main window's global left column into the active workspace area. The left rail is now dedicated to navigation, while workspace-specific controls appear beside the current analysis canvas.
Key changes:
MainWindow.xamlno longer hosts a standalone settings column.ChartWorkspacePanelnow ownsWorkspaceSettingsPaneland exposes it for existing code paths.- Existing settings forwarding remains intact, so event subscriptions, mappers, adapters, coordinators, and presenters continue to use the same control API.
- Workspace navigation still filters the relevant settings sections, but the settings now feel attached to the current analysis workspace instead of being a global catch-all panel.
Phase 23 moves workspace settings from the shared workspace settings rail into the workspaces that own them. The left navigation now selects the analysis context, while each workspace carries its own settings rail:
- Data Sources owns source configuration.
- Signal View owns signal shaping and playback controls.
- Frequency Analysis owns Fourier, reconstruction, filter, and playback controls.
- Spectrogram owns STFT, signal-shaping, and playback controls.
- Event Detection owns local playback controls while detector tuning remains in the right Events panel.
The implementation keeps the existing settings control instances and reparents them into the active workspace. This keeps event subscriptions, mappers, session restore, and command coordinators stable while changing the information architecture.
Event detection is now a dedicated workspace rather than a tab hidden in the side panel. Detector settings, event summary, event export, and the detected-event table live inside EventDetectionWorkspacePanel, while the right-side AnalysisSidePanel focuses on readout and signal metrics.
The Data Sources page is now a real source-management workspace. It shows the active source, sample buffer count, source status, data range, and a recommended analysis flow while keeping CSV / mock API / HTTP JSON controls inside the page-owned settings rail.
The Frequency Analysis workspace now has its own frequency-domain dashboard: selected harmonic, amplitude, phase, dominant harmonic, filter range, hover state, spectrum, phase plot, and dominant component list are shown directly in the workspace. This reduces dependence on the right-side readout and makes frequency-domain inspection a first-class workflow.
- Added a dedicated
RotatingVectorsWorkspacePanelso epicycle / Fourier vector visualization is no longer limited to the compact right-side helper panel. - Moved the rotating-vector page to a full central workspace with its own settings rail, metric cards, large
EpicyclePlot, selected vector detail, and dominant vector component list. - Kept the existing side
RotatingVectorsPanelas a compact auxiliary view for other workspaces, but hide it when the dedicated Rotating Vectors workspace is active. - Updated plot, readout, settings display, workspace navigation, and composition wiring so both the central and compact epicycle plots stay synchronized without duplicating control state.
The Spectrogram workspace is now a dedicated time-frequency analysis page with STFT summary cards, selected time-slice readouts, and workspace-local window / hop / bin / intensity status. The existing spectrogram plot is still driven by the shared presenter flow, but the page now exposes enough context to inspect how energy changes across frames and frequency bins.
Dashboard is now a live overview workspace instead of a workflow-description placeholder. It summarizes the current vibration-analysis state across source health, time-domain metrics, frequency-domain status, event detection, and recommended workflow.
Key updates:
DashboardWorkspacePanelnow displays source name/description, sample count, RMS/peak, dominant harmonic, cursor/stream status, selected harmonic, amplitude, phase, event counts, estimated frequency, and source status.ReadoutPresentermirrors time-domain and frequency-domain readouts into Dashboard.EventSummaryPresentermirrors peak / zero-crossing / spike counts into Dashboard.SettingsDisplayPresentermirrors active harmonics, cursor, stream step, and source status into Dashboard.WorkspaceShellServicemirrors source name, description, and sample count into Dashboard whenever the workspace state updates.
This makes Dashboard a real first stop for vibration-analysis triage before jumping into Signal View, Frequency Analysis, Spectrogram, Rotating Vectors, Event Detection, or Data Sources.
Dashboard workflow cards are now actionable navigation shortcuts instead of static guidance text. Users can jump from the live overview directly into Data Sources, Signal View, Frequency Analysis, Spectrogram, Rotating Vectors, or Event Detection.
Key updates:
DashboardWorkspacePanelnow raises navigation requests from its workflow buttons.MainWindow.WorkspaceNavigationroutes Dashboard shortcut requests through the existing workspace navigation panel so selected navigation state stays synchronized.- Dashboard now functions as both a status overview and a real entry point into the dedicated analysis workspaces.
Phase 32 standardizes the visual language across the dedicated workspaces introduced in Phases 24-31.
Key updates:
- Added shared workspace styles in
App.xamlfor settings rails, header cards, section cards, metric cards, pill badges, rail titles, workspace titles, card titles, metric values, and grid splitters. - Updated workspace panels to use the shared styles instead of repeating hard-coded border colors, padding, splitter brushes, and title formatting.
- Tightened the shared card radius and spacing so Dashboard, Signal View, Frequency Analysis, Rotating Vectors, Spectrogram, Event Detection, and Data Sources read as one product family.
- Kept the existing presenter/coordinator/event flow unchanged; this is a visual consistency pass rather than a behavior change.
Design intent: after splitting the product into focused analysis pages, each workspace should still feel like part of the same vibration-analysis application.
Phase 33 formalizes how the right-side auxiliary rail behaves per workspace instead of relying on ad-hoc visibility logic.
Key updates:
- Added
WorkspaceSidePanelStrategyandWorkspaceSidePanelModeunderPresentation/Shell. - The right rail now has three explicit modes:
FullAuxiliary: compact rotating vectors plus readout.ReadoutOnly: readout/metrics only; compact rotating vectors are hidden.Hidden: the entire right rail and splitter are collapsed.
- Dashboard and Frequency Analysis keep the compact rotating-vector helper because it adds context while reviewing global or harmonic data.
- Signal View, Rotating Vectors, Spectrogram, and Event Detection use readout-only mode to keep their central workspace as the primary visual focus.
- Data Sources hides the right rail so source configuration and status can use the full workspace width.
- The bottom status note now reflects the active side-panel strategy for the selected workspace.
Design intent: each workspace should have a predictable auxiliary area instead of feeling like the right panel randomly changes size or content.
Phase 34 adds a lightweight interaction status layer across workspaces. Cursor, harmonic hover/selection, STFT frame/bin, event severity, and source readiness summaries are projected by WorkspaceViewModel and rendered through InteractionStatusPresenter.
This keeps the user oriented while switching between Signal View, Frequency Analysis, Rotating Vectors, Spectrogram, Event Detection, Data Sources, and Dashboard without changing the underlying analysis pipeline.
Workspace empty/loading/error states were added. Each workspace now receives an availability message when required inputs or derived outputs are missing, such as no samples, missing Fourier components, no STFT frames, no detected events, or source errors from CSV/HTTP-style inputs.
The current UI pass improves visual quality and layout resilience after the workspace split:
- Dark-theme control styling for inputs and common controls.
- Higher contrast muted text.
- More responsive workspace rail/content widths.
- Dashboard summary cards and workflow shortcuts adjusted to reduce clipping.
- Compact Rotating Vectors header spacing fixed.
- Epicycle scaling adjusted so the vector diagram remains readable in compact and dedicated views.
Follow-up UI polish fixes based on runtime screenshots:
- Fixed
WorkspaceViewModelsample readiness check to use array length forWorkspaceState.Samples. - Reworked ComboBox and ComboBoxItem templates so dropdowns stay dark-themed in the closed and popup states.
- Added custom Slider thumb/track styling and custom ScrollBar styling to align with the dark workspace theme.
- Added dark ListView/GridView header and row styles so event-table headers no longer render with white system colors.
- Reworked TabItem styling so the Readout tab header no longer appears as a white label block.
- Increased EpicyclePlot visual zoom for dense harmonic sets so compact Rotating Vectors are more readable.
- Adjusted Dashboard event summary layout to reduce clipped labels and values.
Phase 37 introduces an in-workspace chart expansion overlay. Core plots now expose an Expand action so the user can inspect Signal, Spectrum, Phase, Spectrogram, and Rotating Vectors at a larger size without opening a separate window or leaving the current workspace.
Key changes:
- Added
Presentation/Views/Overlays/ChartExpandOverlay. - Added expand actions to Signal View, Frequency Analysis, Spectrogram, and Rotating Vectors workspaces.
- Kept the overlay synchronized with live plot updates during playback/streaming.
- Kept the implementation as a reusable overlay instead of re-parenting existing WPF plot controls.
Chart expansion now uses a reusable hover overlay on the entire chart section. Fixed Expand buttons were removed so the plot layout remains clean and the affordance does not consume chart header or plot area space.
- Tightened Dashboard grid gutters and card margins so summary cards and workflow shortcuts align consistently.
- Removed the extra workflow-right label that could clip inside narrow dashboard widths.
- Reduced dashboard/frequency right-rail widths to preserve central workspace space.
- Aligned workspace header hints with
LastChildFill=Falseso hints stay on the right. - Reset active workspace scroll viewers on navigation so pages reopen from the top instead of retaining a mid-scroll offset.