diff --git a/src/Common/ChartDrawing/Chart/LineSpectrumControlSlim.cs b/src/Common/ChartDrawing/Chart/LineSpectrumControlSlim.cs index 709e73ce4..5103b43c1 100644 --- a/src/Common/ChartDrawing/Chart/LineSpectrumControlSlim.cs +++ b/src/Common/ChartDrawing/Chart/LineSpectrumControlSlim.cs @@ -250,7 +250,7 @@ private static void OnLineBrushPropertyChanged(DependencyObject d, DependencyPro [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "")] private void OnLineBrushPropertyChanged(IBrushMapper oldValue, IBrushMapper newValue) { - Selector.Update(newValue, LineThickness); + Selector.Update(newValue, LineThickness, StrokeDashArray); } public static readonly DependencyProperty HuePropertyProperty = @@ -310,7 +310,32 @@ private static void OnLineThicknessChanged(DependencyObject d, DependencyPropert [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "")] private void OnLineThicknessChanged(double oldValue, double newValue) { - Selector.Update(LineBrush, newValue); + Selector.Update(LineBrush, newValue, StrokeDashArray); + } + + public static readonly DependencyProperty StrokeDashArrayProperty = + DependencyProperty.Register( + nameof(StrokeDashArray), + typeof(DoubleCollection), + typeof(LineSpectrumControlSlim), + new FrameworkPropertyMetadata( + null, + FrameworkPropertyMetadataOptions.AffectsRender, + OnStrokeDashArrayChanged)); + + public DoubleCollection StrokeDashArray { + get => (DoubleCollection)GetValue(StrokeDashArrayProperty); + set => SetValue(StrokeDashArrayProperty, value); + } + + private static void OnStrokeDashArrayChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { + var c = (LineSpectrumControlSlim)d; + c.OnStrokeDashArrayChanged((DoubleCollection)e.OldValue, (DoubleCollection)e.NewValue); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "")] + private void OnStrokeDashArrayChanged(DoubleCollection oldValue, DoubleCollection newValue) { + Selector.Update(LineBrush, LineThickness, newValue); } private PenSelector Selector { @@ -318,7 +343,7 @@ private PenSelector Selector { if (selector is null) { selector = new PenSelector(); if (!(LineBrush is null)) { - selector.Update(LineBrush, LineThickness); + selector.Update(LineBrush, LineThickness, StrokeDashArray); } } return selector; diff --git a/src/Common/ChartDrawing/Design/PenSelector.cs b/src/Common/ChartDrawing/Design/PenSelector.cs index 4d9cf500b..36ca2505f 100644 --- a/src/Common/ChartDrawing/Design/PenSelector.cs +++ b/src/Common/ChartDrawing/Design/PenSelector.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Windows.Media; using CompMs.Graphics.Base; @@ -31,11 +32,15 @@ public void Update(Pen pen) { } public void Update(IBrushMapper mapper, double thickness) { + Update(mapper, thickness, null); + } + + public void Update(IBrushMapper mapper, double thickness, DoubleCollection strokeDashArray) { if (mapper is null) { Reset(); } else { - strategy = new BrushMapStrategy(mapper, thickness); + strategy = new BrushMapStrategy(mapper, thickness, strokeDashArray); } } @@ -62,13 +67,15 @@ public Pen Get(object o) { class BrushMapStrategy : ISelectStrategy { - public BrushMapStrategy(IBrushMapper mapper, double thickness) { + public BrushMapStrategy(IBrushMapper mapper, double thickness, DoubleCollection strokeDashArray) { Mapper = mapper; Thickness = thickness; + StrokeDashArray = strokeDashArray?.ToArray(); } private readonly IBrushMapper Mapper; private readonly double Thickness; + private readonly double[] StrokeDashArray; private readonly Dictionary cache = new Dictionary(); public Pen Get(object o) { @@ -77,6 +84,9 @@ public Pen Get(object o) { } var brush = Mapper.Map(o); var pen = new Pen(brush, Thickness); + if (StrokeDashArray is { Length: > 0 }) { + pen.DashStyle = new DashStyle(new DoubleCollection(StrokeDashArray), 0d); + } pen.Freeze(); if (cache.Count > 1_000_000) { cache.Clear(); diff --git a/src/MSDIAL5/MsdialGuiApp/Model/Chart/RawDecSpectrumsModel.cs b/src/MSDIAL5/MsdialGuiApp/Model/Chart/RawDecSpectrumsModel.cs index 6da62850c..23cb9e7a5 100644 --- a/src/MSDIAL5/MsdialGuiApp/Model/Chart/RawDecSpectrumsModel.cs +++ b/src/MSDIAL5/MsdialGuiApp/Model/Chart/RawDecSpectrumsModel.cs @@ -1,8 +1,11 @@ using CompMs.App.Msdial.Model.Loader; using CompMs.Common.Algorithm.Scoring; using CompMs.CommonMVVM; +using CompMs.Graphics.Design; +using Reactive.Bindings; using Reactive.Bindings.Extensions; using System; +using System.Windows.Media; namespace CompMs.App.Msdial.Model.Chart { @@ -37,17 +40,37 @@ public RawDecSpectrumsModel(SingleSpectrumModel rawSpectrumModel, SingleSpectrum HorizontalTitle = "m/z", VerticalTitle = "Relative abundance", }.AddTo(Disposables); + + IsRawSpectrumOverlayVisible = new ReactivePropertySlim(true).AddTo(Disposables); + + + var decRawOverlaySpectrumModel = rawSpectrumModel.Clone().AddTo(Disposables); + decRawOverlaySpectrumModel.IsVisible.Value = false; + decRawOverlaySpectrumModel.IsAnnotationVisible.Value = false; + decRawOverlaySpectrumModel.LineThickness.Value = 1d; + decRawOverlaySpectrumModel.StrokeDashArray.Value = new DoubleCollection { 3d, 3d }; + decRawOverlaySpectrumModel.Brush = new ConstantBrushMapper(Brushes.DarkGray); + DecRefSpectrumModels = new MsSpectrumModel(decSpectrumModel, referenceSpectrumModel, ms2ScanMatching) { GraphTitle = "Deconvolution vs. Reference", HorizontalTitle = "m/z", - VerticalTitle = "Relative abundacne", + VerticalTitle = "Relative abundance", }.AddTo(Disposables); + DecRefSpectrumModels.UpperSpectraModel.Insert(0, decRawOverlaySpectrumModel); + + IsRawSpectrumOverlayVisible + .Subscribe(isVisible => { + decRawOverlaySpectrumModel.IsVisible.Value = isVisible; + }) + .AddTo(Disposables); + RawLoader = loader; } public MsSpectrumModel RawRefSpectrumModels { get; } public MsSpectrumModel DecRefSpectrumModels { get; } + public ReactivePropertySlim IsRawSpectrumOverlayVisible { get; } public MultiMsmsRawSpectrumLoader? RawLoader { get; } } } diff --git a/src/MSDIAL5/MsdialGuiApp/Model/Chart/SingleSpectrumModel.cs b/src/MSDIAL5/MsdialGuiApp/Model/Chart/SingleSpectrumModel.cs index f7f07411f..41ce421d4 100644 --- a/src/MSDIAL5/MsdialGuiApp/Model/Chart/SingleSpectrumModel.cs +++ b/src/MSDIAL5/MsdialGuiApp/Model/Chart/SingleSpectrumModel.cs @@ -9,6 +9,7 @@ using System.IO; using System.Linq; using System.Reactive.Linq; +using System.Windows.Media; namespace CompMs.App.Msdial.Model.Chart { @@ -24,10 +25,13 @@ public SingleSpectrumModel(ObservableMsSpectrum observableMsSpectrum, AxisProper HorizontalProperty = HorizontalPropertySelectors.GetSelector(typeof(SpectrumPeak))?.Property ?? throw new Exception("Valid PropertySelector is not found."); VerticalProperty = VerticalPropertySelectors.GetSelector(typeof(SpectrumPeak))?.Property ?? throw new Exception("Valid PropertySelector is not found."); _hueItem = hueItem; + Brush = hueItem.Brush; Labels = graphLabels; IsVisible = new ReactivePropertySlim(true).AddTo(Disposables); + IsAnnotationVisible = new ReactivePropertySlim(true).AddTo(Disposables); LineThickness = new ReactivePropertySlim(2d).AddTo(Disposables); + StrokeDashArray = new ReactivePropertySlim(null).AddTo(Disposables); } public IObservable MsSpectrum => _observableMsSpectrum.MsSpectrum; @@ -38,12 +42,14 @@ public SingleSpectrumModel(ObservableMsSpectrum observableMsSpectrum, AxisProper public IObservable> VerticalAxis => VerticalPropertySelectors.AxisItemSelector.GetAxisItemAsObservable().SkipNull().Select(item => item.AxisManager); public AxisItemSelector VerticalAxisItemSelector => VerticalPropertySelectors.AxisItemSelector; public string VerticalProperty { get; } - public IBrushMapper Brush => _hueItem.Brush; + public IBrushMapper Brush { get; set; } public string HueProperty => _hueItem.Property; public GraphLabels Labels { get; } public ReadOnlyReactivePropertySlim SpectrumLoaded => _observableMsSpectrum.Loaded; public ReactivePropertySlim IsVisible { get; } + public ReactivePropertySlim IsAnnotationVisible { get; } public ReactivePropertySlim LineThickness { get; } + public ReactivePropertySlim StrokeDashArray { get; } public IObservable CanSave => _observableMsSpectrum.CanSave; @@ -81,5 +87,9 @@ private SingleSpectrumModel CreateFromMsSpectrum(ObservableMsSpectrum msSpectrum spectrumModel.Disposables.Add(msSpectrum); return spectrumModel; } + + public SingleSpectrumModel Clone() { + return new SingleSpectrumModel(_observableMsSpectrum, HorizontalPropertySelectors, VerticalPropertySelectors, _hueItem, Labels); + } } } diff --git a/src/MSDIAL5/MsdialGuiApp/View/Chart/ExpRefView.xaml b/src/MSDIAL5/MsdialGuiApp/View/Chart/ExpRefView.xaml index 6aa1466e4..9bd150aac 100644 --- a/src/MSDIAL5/MsdialGuiApp/View/Chart/ExpRefView.xaml +++ b/src/MSDIAL5/MsdialGuiApp/View/Chart/ExpRefView.xaml @@ -56,6 +56,12 @@ ToolTip="Show deconvoluted spectra vs. reference spectra" Style="{StaticResource IconRadioButton}"/> + +