Files
DP44/enriched-partialglm/DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/ViewModel.md
2026-04-17 14:55:32 -04:00

7.1 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DTS Viewer/DTS.Viewer.Modules/DTS.Viewer.Graph/ViewModel/GraphViewModel.cs
2026-04-16T11:13:10.472796+00:00 zai-org/GLM-5-FP8 1 cd4107fac05f80cd

GraphViewModel Documentation

1. Purpose

GraphViewModel is the ViewModel component for the Graph module within the DTS Viewer application. It serves as the mediator between the graph view (IGraphView) and the underlying data layer, managing chart visualization state, handling user notifications, and coordinating event-driven communication with parent ViewModels. The class supports multiple initialization contexts—either as a child of IViewerMainViewModel or IPSDReportMainViewModel—with different subscription behaviors and UI configurations based on the context (e.g., "DataSelect" mode vs. default/result mode).


2. Public Interface

Constructor

public GraphViewModel(IGraphView view, IRegionManager regionManager, IEventAggregator eventAggregator, IUnityContainer unityContainer)

Initializes the ViewModel with its associated view, region manager for navigation, event aggregator for pub/sub messaging, and Unity container for dependency resolution. Sets the view's DataContext to itself and instantiates interaction requests.

Properties

Property Type Access Description
View IGraphView get; private set The associated graph view instance.
DataSeriesView ITestDataSeriesView get; set The data series view used for chart rendering.
NotificationRequest InteractionRequest<Notification> get; private set Interaction request for displaying notifications.
ConfirmationRequest InteractionRequest<Confirmation> get; private set Interaction request for displaying confirmations (shadows base member).
ContextGraphRegion object get; set Gets/sets the content of the GraphRegion on the view; raises OnPropertyChanged on set.
MessageText string get; set Status message text; default is "Please select Event(s) to export data".
MessageVisibility bool get; set Controls visibility of the message panel; triggers FireVisibilities() on set.
ProgressPercent double get; set Progress percentage for loading operations; default 0D.
ProgressText string get; set Progress status text; default "Reading channel data...".
ProgressVisibility bool get; set Controls visibility of progress indicators; triggers FireVisibilities() on set.
GraphInfoVisibility bool get; set Controls visibility of graph info panel; triggers FireVisibilities() on set.
GraphVisibility bool get Computed as !MessageVisibility.
HeaderInfo string get Returns "GraphRegion".
IsBusy bool get; set Busy state indicator (shadows base member).
IsDirty bool get Always returns false (shadows base member).

Methods

public override void Initialize()

Empty override; no behavior.

public override void Initialize(object parameter)

Primary initialization logic. Behavior depends on parameter type:

  • If IViewerMainViewModel: Calls Subscribe() and sets Parent and DataSeriesView.
  • If Tuple<IBaseViewModel, string> where Item1 is IPSDReportMainViewModel: Calls SubscribeDataSelect() or SubscribeResult() based on Item2 value ("DataSelect" vs. default). Configures chart scrollbars and actions based on mode.

Events

public new event PropertyChangedEventHandler PropertyChanged

Shadows base PropertyChanged event; raised via OnPropertyChanged(string).


3. Invariants

  1. Parent Matching: Event handlers OnTestSelectedCountChanged and OnGraphSelectedCountChanged will early-return if Parent != arg.ParentVM or Parent != arg?.ParentVM respectively.
  2. GraphVM Identity Check: OnGraphChannelsReadCompleted and OnGraphChannelReadCalcProgressChangedEvent require this == arg.GraphVM to proceed.
  3. Null Argument Handling: OnGraphChannelsReadCompleted returns immediately if arg is null.
  4. Progress Bounds: ProgressPercent is only updated if arg.ProgressPercent >= 0.
  5. Visibility Relationships: GraphVisibility is always the logical inverse of MessageVisibility.
  6. Initialization Contract: Initialize(object parameter) expects either IViewerMainViewModel or a specific Tuple<IBaseViewModel, string> pattern; other types result in no initialization.

4. Dependencies

This Module Depends On:

  • C1.WPF.C1Chart - ComponentOne charting library (used for AxisScrollBar type casting)
  • DTS.Common.Base - BaseViewModel<T>, IBaseViewModel, IBaseModel
  • DTS.Common.Events - Event types: RaiseNotification, GraphSelectedChannelCountNotification, TestSummaryCountNotification, TestModificationChangedEvent, GraphChannelsReadCompletedNotification, GraphChannelReadCalcProgressChangedEvent
  • DTS.Common.Interactivity - InteractionRequest<T>, Notification, Confirmation
  • DTS.Common.Interface - IGraphViewModel, IGraphView, ITestDataSeriesView, ITestDataSeriesViewModel, ITestModificationModel, IViewerMainViewModel, IPSDReportMainViewModel
  • Prism.Events - IEventAggregator, ThreadOption
  • Prism.Regions - IRegionManager
  • Unity - IUnityContainer

Concrete Type Dependencies (Internal):

  • GraphView - Referenced in ContextGraphRegion property
  • TestDataSeriesView - Referenced in Initialize() for chart configuration
  • TestDataSeriesViewModel - Referenced in GetTestDataSeriesView() for PSD subscription

5. Gotchas

  1. Shadowed Base Members: Multiple members use the new keyword to shadow base class implementations (PropertyChanged, OnPropertyChanged, IsBusy, IsDirty, ConfirmationRequest, Model). This may cause unexpected behavior if consumers interact through base class references.

  2. Code Duplication: Subscribe(), SubscribeDataSelect(), and SubscribeResult() have nearly identical implementations. The only difference is that Subscribe() additionally subscribes to TestModificationChangedEvent, but the handler OnTestModificationChanged is empty.

  3. Empty Handler: OnTestModificationChanged(ITestModificationModel obj) has no implementation—potential tech debt or placeholder.

  4. Concrete Type Casting: The code directly casts to GraphView and TestDataSeriesView concrete types, breaking the abstraction provided by interfaces. This creates tight coupling and could cause runtime failures if different implementations are registered.

  5. Unused Private Field: Model property is declared but never used (suppressed by // ReSharper disable NotAccessedField.Local).

  6. Hardcoded Strings: Chart type comparison uses literal strings ("DataSelect", "Graph") without constants, risking typos.

  7. Thread Affinity: GraphChannelsReadCompletedNotification and GraphChannelReadCalcProgressChangedEvent are explicitly subscribed with ThreadOption.UIThread, indicating UI updates must occur on the dispatcher thread.