Loading INAF.Apps.Uwp.SLabDataManager/App.xaml.cs +4 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ using Microsoft.Toolkit.Mvvm.DependencyInjection; using System; using System.Collections.Generic; using Windows.ApplicationModel.Activation; using Windows.UI; using Windows.UI.WindowManagement; using Windows.UI.Xaml; namespace INAF.Apps.Uwp.SLabDataManager Loading @@ -36,7 +38,7 @@ namespace INAF.Apps.Uwp.SLabDataManager private Lazy<ActivationService> _activationService; public static Dictionary<string, object> AppDictionary; //public static Dictionary<UIContext, AppWindow> AppWindows; public static Dictionary<UIContext, AppWindow> AppWindows; private ActivationService ActivationService { Loading Loading @@ -107,7 +109,7 @@ namespace INAF.Apps.Uwp.SLabDataManager AppDictionary = new Dictionary<string, object>(); /* create app dictionary for AppWindow instances */ //AppWindows = new Dictionary<UIContext, AppWindow>(); AppWindows = new Dictionary<UIContext, AppWindow>(); /* init logger */ Logger logger = new Logger(); Loading INAF.Apps.Uwp.SLabDataManager/Converters/Converters.cs +24 −78 Original line number Diff line number Diff line using INAF.Apps.Uwp.SLabDataManager.Charts; using INAF.Apps.Uwp.SLabDataManager.Charts.Containers; using INAF.Apps.Uwp.SLabDataManager.Charts.Containers; using INAF.Apps.Uwp.SLabDataManager.Helpers; using INAF.Apps.Uwp.SLabDataManager.Models; using INAF.Apps.Uwp.SLabDataManager.Models.Fit; using INAF.Apps.Uwp.SLabDataManager.Models.Fit.Parameters; using INAF.Libraries.NetStandard.Extensions; using INAF.Libraries.NetStandard.ScienceModels.Extensions; using Microsoft.Toolkit.Mvvm.DependencyInjection; Loading @@ -11,13 +8,35 @@ using System; using System.Collections.Generic; using System.IO; using Telerik.Charting; using Windows.UI.Xaml; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Media; using static INAF.Libraries.NetStandard.SLabCommonModels.Enums.Enums; namespace INAF.Apps.Uwp.SLabDataManager.Converters { public sealed class DimWithParameterConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { try { double dim = (double)value; double offset = System.Convert.ToDouble(parameter); return dim - offset; } catch (Exception) { return 0; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } public sealed class IsSpectrumAvailablelWithParameterConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) Loading Loading @@ -126,34 +145,6 @@ namespace INAF.Apps.Uwp.SLabDataManager.Converters } } public sealed class ParameterConstraintVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { try { if (value == null ) return Visibility.Collapsed; ParameterConstraintModel parameterConstraint = (ParameterConstraintModel)value; if (parameterConstraint != null) return Visibility.Visible; else return Visibility.Collapsed; } catch (Exception) { return Visibility.Collapsed; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } public sealed class ShortFilepathConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) Loading Loading @@ -257,51 +248,6 @@ namespace INAF.Apps.Uwp.SLabDataManager.Converters } } public sealed class WidthConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { try { double width = (double)value; return width - 60; } catch (Exception) { return 0; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } public sealed class WidthWithParameterConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { try { double width = (double)value; double offset = System.Convert.ToDouble(parameter); return width - offset; } catch (Exception) { return 0; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } public sealed class XAxisTitleConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) Loading INAF.Apps.Uwp.SLabDataManager/Converters/FitMethodsConverters.cs 0 → 100644 +35 −0 Original line number Diff line number Diff line using INAF.Apps.Uwp.SLabDataManager.Models.Fit.Parameters; using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Data; namespace INAF.Apps.Uwp.SLabDataManager.Converters { public sealed class ParameterConstraintVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { try { if (value == null) return Visibility.Collapsed; ParameterConstraintModel parameterConstraint = (ParameterConstraintModel)value; if (parameterConstraint != null) return Visibility.Visible; else return Visibility.Collapsed; } catch (Exception) { return Visibility.Collapsed; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } } INAF.Apps.Uwp.SLabDataManager/Helpers/SecondaryWindowHelper.cs +34 −5 Original line number Diff line number Diff line Loading @@ -8,29 +8,58 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers { public sealed class SecondaryWindowHelper { public async Task openContinuumAnalysisWindowAsync(Type pageType) public async Task openContinuumAnalysisWindowAsync(Type pageType, string pageTitle, int? width = null, int? height = null, Action action = null) { AppWindow appWindow = await AppWindow.TryCreateAsync(); Frame frame = new Frame(); if (width != null && height != null) { appWindow.RequestSize(new Windows.Foundation.Size((int)width, 900)); frame.Width = (int)width; frame.Height = (int)height; } frame.Navigate(pageType); // Attach the XAML content to the window. ElementCompositionPreview.SetAppWindowContent(appWindow, frame); /* save relationship into App-related dictionary */ //App.AppWindows.Add(frame.UIContext, appWindow); appWindow.Title = "ContinuumAnalysisPageTitle".GetText(); App.AppWindows.Add(frame.UIContext, appWindow); appWindow.Title = pageTitle; appWindow.Closed += delegate { //MainPage.AppWindows.Remove(appWindowContentFrame.UIContext); App.AppWindows.Remove(frame.UIContext); frame.Content = null; appWindow = null; /* execute action, if required */ if (action != null) action(); }; // Show the window. await appWindow.TryShowAsync(); appWindow.Changed += (s, e) => { if (e.DidSizeChange) { /* trick to avoid window resize (content is repositioned in a wrong way) */ s.RequestSize(new Windows.Foundation.Size((int)width, (int)height)); //var placement = s.GetPlacement(); //frame.Width = placement.Size.Width; //frame.Height = placement.Size.Height; //frame.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center; //frame.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Left; } }; } } } INAF.Apps.Uwp.SLabDataManager/Helpers/UI/Chart/ChartAnnotationsHelper.cs +91 −77 Original line number Diff line number Diff line using INAF.Apps.Uwp.SLabDataManager.Extensions; using INAF.Apps.Uwp.SLabDataManager.Models; using INAF.Apps.Uwp.SLabDataManager.Models.Fit; using INAF.Apps.Uwp.SLabDataManager.Models.Spectrum; using INAF.Apps.Uwp.SLabDataManager.ViewModels; using INAF.Libraries.NetStandard.Math.Fit.Linear; using INAF.Libraries.NetStandard.Math.Fit.Linear.Models; using INAF.Libraries.NetStandard.Math.Models; using INAF.Libraries.NetStandard.ScienceModels.Spectra; using INAF.Libraries.Uwp.Logging; using Microsoft.Extensions.DependencyInjection; using System; Loading @@ -13,9 +14,10 @@ using System.Linq; using System.Threading.Tasks; using Telerik.UI.Xaml.Controls.Chart; using Windows.Foundation; using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; using static INAF.Apps.Uwp.SLabDataManager.Constants.Enums; using static INAF.Libraries.NetStandard.SLabCommonModels.Enums.Enums; using SpectrumModel = INAF.Apps.Uwp.SLabDataManager.Models.Spectrum.SpectrumModel; namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart { Loading Loading @@ -47,9 +49,14 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart /* recover tapped-point y-value on spectrum */ /* find mouse position boundaris on spectrum */ var spectrum = workingItems.SpectraContainer.tryGetSpectrumOfType(Libraries.NetStandard.SLabCommonModels.Enums.Enums.SpectrumType.Raw); var lowerBoundaryPoint = spectrum.Elements.Where(x => x.X <= (double)point.Item1).LastOrDefault().ToPointModel(); var higherBoundaryPoint = spectrum.Elements.Where(x => x.X >= (double)point.Item1).FirstOrDefault().ToPointModel(); var spectrum = workingItems.SpectraContainer.tryGetSpectrumOfType(SpectrumType.Raw); (PointModel lowBoundary, PointModel highBoundary) boundaries = getSegmentBoundaries(spectrum, (double)point.Item1, (double)point.Item2); //var lowerBoundaryPoint = spectrum.Elements.Where(x => x.X <= (double)point.Item1).LastOrDefault().ToPointModel(); //var higherBoundaryPoint = spectrum.Elements.Where(x => x.X >= (double)point.Item1).FirstOrDefault().ToPointModel(); var lowerBoundaryPoint = boundaries.lowBoundary; var higherBoundaryPoint = boundaries.highBoundary; if (lowerBoundaryPoint == null || higherBoundaryPoint == null) return; Loading @@ -75,20 +82,10 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart var yOnSpectrum = line.calculateY((double)point.Item1); /* ...otherwise add a new point */ CartesianCustomAnnotation customAnnotation = new CartesianCustomAnnotation() { HorizontalValue = point.Item1, HorizontalAlignment = HorizontalAlignment.Center, VerticalValue = yOnSpectrum, VerticalAlignment = VerticalAlignment.Center, ContentTemplate = tappedPointTemplate, }; chart.Annotations.Add(customAnnotation); chart.Annotations.Add(getCustomAnnotation((double)point.Item1, yOnSpectrum, tappedPointTemplate)); } chart.UpdateLayout(); chart.InvalidateUI(); /* if only a point is added, then avoid trying create segments */ var pointsNum = chart.Annotations.Count(x => x is CartesianCustomAnnotation); Loading @@ -96,7 +93,7 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart return; /* try to create lines connecting selected points */ createLines(chart); await createLinesAsync(chart); } catch (Exception ex) { Loading @@ -104,7 +101,7 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart } } private void createLines(RadCartesianChart chart) private async Task createLinesAsync(RadCartesianChart chart) { /* recover points on chart and order them for creating segments */ var orderedPoints = chart.Annotations Loading @@ -122,66 +119,11 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart segmentsFitModelContainer.tryAddSegment(orderedPoints.ElementAt(i).ToPointModel(), orderedPoints.ElementAt(i + 1).ToPointModel()); } var viewModel = serviceProvider.GetRequiredService<ChartViewModel>(); await viewModel.fitSegmentsAsync(); /* await viewModel.fitSegmentsAsync(); is automatically called by selection of 1st fit method in SegmentFitModel constructor */ } //private void tryCreateLines(RadCartesianChart chart, // ChartViewModel viewModel) //{ // try // { // if (chart.Annotations.Count(x => x is CartesianCustomAnnotation) <= 1) // return; // /* remove existing points/lines from chart before re-generating all */ // int annotationsNum = chart.Annotations.Count(); // for (int i = annotationsNum - 1; i >= 0; i--) // { // if (chart.Annotations.ElementAt(i).GetType() == typeof(CartesianCustomLineAnnotation)) // chart.Annotations.Remove(chart.Annotations.ElementAt(i)); // } // /* clear existing lines before re-generating all */ // linearFitHelper.clear(); // /* order points by increasing X */ // var orderedPoints = chart.Annotations // .Where(x => x is CartesianCustomAnnotation) // .Cast<CartesianCustomAnnotation>() // .OrderBy(x => x.HorizontalValue); // /* generate lines from existing points */ // int count = orderedPoints.Count(); // for (int i = 0; i < count - 1; i++) // { // linearFitHelper.add(orderedPoints.ElementAt(i).ToPointModel(), orderedPoints.ElementAt(i + 1).ToPointModel()); // } // foreach (var line in linearFitHelper.Lines) // { // viewModel.tryAddSegment(line.P1, line.P2); // var lineAnnotation = new CartesianCustomLineAnnotation() // { // HorizontalFrom = line.P1.X, // VerticalFrom = line.P1.Y, // HorizontalTo = line.P2.X, // VerticalTo = line.P2.Y, // Stroke = new SolidColorBrush(Colors.Red), // StrokeThickness = 2 // }; // chart.Annotations.Add(lineAnnotation); // } // chart.UpdateLayout(); // } // catch (Exception ex) // { // logger.Write<ChartAnnotationsHelper>($"{nameof(tryCreateLines)} - ex: {ex.Message}", Serilog.Events.LogEventLevel.Error); // } //} public void removePointsForContinuum(RadCartesianChart chart) { Loading @@ -193,5 +135,77 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart chart.Annotations.Remove(chart.Annotations.ElementAt(i)); } } #region highlight/lowlight public void setSegmentHighlight(RadCartesianChart chart, SegmentFitModel segmentFit, DataTemplate tappedPointTemplate) { var segmentPoints = getSegmentSpectrumElements(segmentFit, SpectrumType.Continuum); if (segmentPoints?.Count() > 0) { int segmentPointsNum = segmentPoints.Count(); for (int i = 0; i < segmentPointsNum; i++) { chart.Annotations.Add(getCustomAnnotation(segmentPoints.ElementAt(i).X, segmentPoints.ElementAt(i).Y, tappedPointTemplate)); } } chart.InvalidateUI(); } public void setSegmentLowlight(RadCartesianChart chart, SegmentFitModel segmentFit) { var segmentPoints = getSegmentSpectrumElements(segmentFit, SpectrumType.Continuum); if (segmentPoints?.Count() > 0) { int segmentPointsNum = segmentPoints.Count(); for (int i = 0; i < segmentPointsNum; i++) { var existantItem = chart.Annotations.FirstOrDefault(x => x is CartesianCustomAnnotation && (Convert.ToDouble((x as CartesianCustomAnnotation).HorizontalValue) == segmentPoints.ElementAt(i).X)); if (existantItem != null) /* if already existant, then remove point from chart */ chart.Annotations.Remove(existantItem); } } } public IEnumerable<ElementModel> getSegmentSpectrumElements(SegmentFitModel segmentFit, SpectrumType spectrumType) { var spectrum = workingItems.SpectraContainer.tryGetSpectrumOfType(spectrumType); return spectrum.Elements.Where(x => x.X >= segmentFit.P1.X && x.X <= segmentFit.P2.X); } #endregion #region common private CartesianCustomAnnotation getCustomAnnotation(double x, double y, DataTemplate tappedPointTemplate) { return new CartesianCustomAnnotation() { HorizontalValue = x, HorizontalAlignment = HorizontalAlignment.Center, VerticalValue = y, VerticalAlignment = VerticalAlignment.Center, ContentTemplate = tappedPointTemplate, }; } private (PointModel lowBoundary, PointModel highBoundary) getSegmentBoundaries(SpectrumModel spectrum, double x1, double x2) { var lowerBoundaryPoint = spectrum.Elements.Where(x => x.X <= x1).LastOrDefault().ToPointModel(); var higherBoundaryPoint = spectrum.Elements.Where(x => x.X >= x2).FirstOrDefault().ToPointModel(); return (lowerBoundaryPoint, higherBoundaryPoint); } #endregion } } Loading
INAF.Apps.Uwp.SLabDataManager/App.xaml.cs +4 −2 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ using Microsoft.Toolkit.Mvvm.DependencyInjection; using System; using System.Collections.Generic; using Windows.ApplicationModel.Activation; using Windows.UI; using Windows.UI.WindowManagement; using Windows.UI.Xaml; namespace INAF.Apps.Uwp.SLabDataManager Loading @@ -36,7 +38,7 @@ namespace INAF.Apps.Uwp.SLabDataManager private Lazy<ActivationService> _activationService; public static Dictionary<string, object> AppDictionary; //public static Dictionary<UIContext, AppWindow> AppWindows; public static Dictionary<UIContext, AppWindow> AppWindows; private ActivationService ActivationService { Loading Loading @@ -107,7 +109,7 @@ namespace INAF.Apps.Uwp.SLabDataManager AppDictionary = new Dictionary<string, object>(); /* create app dictionary for AppWindow instances */ //AppWindows = new Dictionary<UIContext, AppWindow>(); AppWindows = new Dictionary<UIContext, AppWindow>(); /* init logger */ Logger logger = new Logger(); Loading
INAF.Apps.Uwp.SLabDataManager/Converters/Converters.cs +24 −78 Original line number Diff line number Diff line using INAF.Apps.Uwp.SLabDataManager.Charts; using INAF.Apps.Uwp.SLabDataManager.Charts.Containers; using INAF.Apps.Uwp.SLabDataManager.Charts.Containers; using INAF.Apps.Uwp.SLabDataManager.Helpers; using INAF.Apps.Uwp.SLabDataManager.Models; using INAF.Apps.Uwp.SLabDataManager.Models.Fit; using INAF.Apps.Uwp.SLabDataManager.Models.Fit.Parameters; using INAF.Libraries.NetStandard.Extensions; using INAF.Libraries.NetStandard.ScienceModels.Extensions; using Microsoft.Toolkit.Mvvm.DependencyInjection; Loading @@ -11,13 +8,35 @@ using System; using System.Collections.Generic; using System.IO; using Telerik.Charting; using Windows.UI.Xaml; using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Media; using static INAF.Libraries.NetStandard.SLabCommonModels.Enums.Enums; namespace INAF.Apps.Uwp.SLabDataManager.Converters { public sealed class DimWithParameterConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { try { double dim = (double)value; double offset = System.Convert.ToDouble(parameter); return dim - offset; } catch (Exception) { return 0; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } public sealed class IsSpectrumAvailablelWithParameterConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) Loading Loading @@ -126,34 +145,6 @@ namespace INAF.Apps.Uwp.SLabDataManager.Converters } } public sealed class ParameterConstraintVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { try { if (value == null ) return Visibility.Collapsed; ParameterConstraintModel parameterConstraint = (ParameterConstraintModel)value; if (parameterConstraint != null) return Visibility.Visible; else return Visibility.Collapsed; } catch (Exception) { return Visibility.Collapsed; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } public sealed class ShortFilepathConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) Loading Loading @@ -257,51 +248,6 @@ namespace INAF.Apps.Uwp.SLabDataManager.Converters } } public sealed class WidthConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { try { double width = (double)value; return width - 60; } catch (Exception) { return 0; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } public sealed class WidthWithParameterConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { try { double width = (double)value; double offset = System.Convert.ToDouble(parameter); return width - offset; } catch (Exception) { return 0; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } public sealed class XAxisTitleConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) Loading
INAF.Apps.Uwp.SLabDataManager/Converters/FitMethodsConverters.cs 0 → 100644 +35 −0 Original line number Diff line number Diff line using INAF.Apps.Uwp.SLabDataManager.Models.Fit.Parameters; using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Data; namespace INAF.Apps.Uwp.SLabDataManager.Converters { public sealed class ParameterConstraintVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { try { if (value == null) return Visibility.Collapsed; ParameterConstraintModel parameterConstraint = (ParameterConstraintModel)value; if (parameterConstraint != null) return Visibility.Visible; else return Visibility.Collapsed; } catch (Exception) { return Visibility.Collapsed; } } public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } }
INAF.Apps.Uwp.SLabDataManager/Helpers/SecondaryWindowHelper.cs +34 −5 Original line number Diff line number Diff line Loading @@ -8,29 +8,58 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers { public sealed class SecondaryWindowHelper { public async Task openContinuumAnalysisWindowAsync(Type pageType) public async Task openContinuumAnalysisWindowAsync(Type pageType, string pageTitle, int? width = null, int? height = null, Action action = null) { AppWindow appWindow = await AppWindow.TryCreateAsync(); Frame frame = new Frame(); if (width != null && height != null) { appWindow.RequestSize(new Windows.Foundation.Size((int)width, 900)); frame.Width = (int)width; frame.Height = (int)height; } frame.Navigate(pageType); // Attach the XAML content to the window. ElementCompositionPreview.SetAppWindowContent(appWindow, frame); /* save relationship into App-related dictionary */ //App.AppWindows.Add(frame.UIContext, appWindow); appWindow.Title = "ContinuumAnalysisPageTitle".GetText(); App.AppWindows.Add(frame.UIContext, appWindow); appWindow.Title = pageTitle; appWindow.Closed += delegate { //MainPage.AppWindows.Remove(appWindowContentFrame.UIContext); App.AppWindows.Remove(frame.UIContext); frame.Content = null; appWindow = null; /* execute action, if required */ if (action != null) action(); }; // Show the window. await appWindow.TryShowAsync(); appWindow.Changed += (s, e) => { if (e.DidSizeChange) { /* trick to avoid window resize (content is repositioned in a wrong way) */ s.RequestSize(new Windows.Foundation.Size((int)width, (int)height)); //var placement = s.GetPlacement(); //frame.Width = placement.Size.Width; //frame.Height = placement.Size.Height; //frame.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center; //frame.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Left; } }; } } }
INAF.Apps.Uwp.SLabDataManager/Helpers/UI/Chart/ChartAnnotationsHelper.cs +91 −77 Original line number Diff line number Diff line using INAF.Apps.Uwp.SLabDataManager.Extensions; using INAF.Apps.Uwp.SLabDataManager.Models; using INAF.Apps.Uwp.SLabDataManager.Models.Fit; using INAF.Apps.Uwp.SLabDataManager.Models.Spectrum; using INAF.Apps.Uwp.SLabDataManager.ViewModels; using INAF.Libraries.NetStandard.Math.Fit.Linear; using INAF.Libraries.NetStandard.Math.Fit.Linear.Models; using INAF.Libraries.NetStandard.Math.Models; using INAF.Libraries.NetStandard.ScienceModels.Spectra; using INAF.Libraries.Uwp.Logging; using Microsoft.Extensions.DependencyInjection; using System; Loading @@ -13,9 +14,10 @@ using System.Linq; using System.Threading.Tasks; using Telerik.UI.Xaml.Controls.Chart; using Windows.Foundation; using Windows.UI; using Windows.UI.Xaml; using Windows.UI.Xaml.Media; using static INAF.Apps.Uwp.SLabDataManager.Constants.Enums; using static INAF.Libraries.NetStandard.SLabCommonModels.Enums.Enums; using SpectrumModel = INAF.Apps.Uwp.SLabDataManager.Models.Spectrum.SpectrumModel; namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart { Loading Loading @@ -47,9 +49,14 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart /* recover tapped-point y-value on spectrum */ /* find mouse position boundaris on spectrum */ var spectrum = workingItems.SpectraContainer.tryGetSpectrumOfType(Libraries.NetStandard.SLabCommonModels.Enums.Enums.SpectrumType.Raw); var lowerBoundaryPoint = spectrum.Elements.Where(x => x.X <= (double)point.Item1).LastOrDefault().ToPointModel(); var higherBoundaryPoint = spectrum.Elements.Where(x => x.X >= (double)point.Item1).FirstOrDefault().ToPointModel(); var spectrum = workingItems.SpectraContainer.tryGetSpectrumOfType(SpectrumType.Raw); (PointModel lowBoundary, PointModel highBoundary) boundaries = getSegmentBoundaries(spectrum, (double)point.Item1, (double)point.Item2); //var lowerBoundaryPoint = spectrum.Elements.Where(x => x.X <= (double)point.Item1).LastOrDefault().ToPointModel(); //var higherBoundaryPoint = spectrum.Elements.Where(x => x.X >= (double)point.Item1).FirstOrDefault().ToPointModel(); var lowerBoundaryPoint = boundaries.lowBoundary; var higherBoundaryPoint = boundaries.highBoundary; if (lowerBoundaryPoint == null || higherBoundaryPoint == null) return; Loading @@ -75,20 +82,10 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart var yOnSpectrum = line.calculateY((double)point.Item1); /* ...otherwise add a new point */ CartesianCustomAnnotation customAnnotation = new CartesianCustomAnnotation() { HorizontalValue = point.Item1, HorizontalAlignment = HorizontalAlignment.Center, VerticalValue = yOnSpectrum, VerticalAlignment = VerticalAlignment.Center, ContentTemplate = tappedPointTemplate, }; chart.Annotations.Add(customAnnotation); chart.Annotations.Add(getCustomAnnotation((double)point.Item1, yOnSpectrum, tappedPointTemplate)); } chart.UpdateLayout(); chart.InvalidateUI(); /* if only a point is added, then avoid trying create segments */ var pointsNum = chart.Annotations.Count(x => x is CartesianCustomAnnotation); Loading @@ -96,7 +93,7 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart return; /* try to create lines connecting selected points */ createLines(chart); await createLinesAsync(chart); } catch (Exception ex) { Loading @@ -104,7 +101,7 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart } } private void createLines(RadCartesianChart chart) private async Task createLinesAsync(RadCartesianChart chart) { /* recover points on chart and order them for creating segments */ var orderedPoints = chart.Annotations Loading @@ -122,66 +119,11 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart segmentsFitModelContainer.tryAddSegment(orderedPoints.ElementAt(i).ToPointModel(), orderedPoints.ElementAt(i + 1).ToPointModel()); } var viewModel = serviceProvider.GetRequiredService<ChartViewModel>(); await viewModel.fitSegmentsAsync(); /* await viewModel.fitSegmentsAsync(); is automatically called by selection of 1st fit method in SegmentFitModel constructor */ } //private void tryCreateLines(RadCartesianChart chart, // ChartViewModel viewModel) //{ // try // { // if (chart.Annotations.Count(x => x is CartesianCustomAnnotation) <= 1) // return; // /* remove existing points/lines from chart before re-generating all */ // int annotationsNum = chart.Annotations.Count(); // for (int i = annotationsNum - 1; i >= 0; i--) // { // if (chart.Annotations.ElementAt(i).GetType() == typeof(CartesianCustomLineAnnotation)) // chart.Annotations.Remove(chart.Annotations.ElementAt(i)); // } // /* clear existing lines before re-generating all */ // linearFitHelper.clear(); // /* order points by increasing X */ // var orderedPoints = chart.Annotations // .Where(x => x is CartesianCustomAnnotation) // .Cast<CartesianCustomAnnotation>() // .OrderBy(x => x.HorizontalValue); // /* generate lines from existing points */ // int count = orderedPoints.Count(); // for (int i = 0; i < count - 1; i++) // { // linearFitHelper.add(orderedPoints.ElementAt(i).ToPointModel(), orderedPoints.ElementAt(i + 1).ToPointModel()); // } // foreach (var line in linearFitHelper.Lines) // { // viewModel.tryAddSegment(line.P1, line.P2); // var lineAnnotation = new CartesianCustomLineAnnotation() // { // HorizontalFrom = line.P1.X, // VerticalFrom = line.P1.Y, // HorizontalTo = line.P2.X, // VerticalTo = line.P2.Y, // Stroke = new SolidColorBrush(Colors.Red), // StrokeThickness = 2 // }; // chart.Annotations.Add(lineAnnotation); // } // chart.UpdateLayout(); // } // catch (Exception ex) // { // logger.Write<ChartAnnotationsHelper>($"{nameof(tryCreateLines)} - ex: {ex.Message}", Serilog.Events.LogEventLevel.Error); // } //} public void removePointsForContinuum(RadCartesianChart chart) { Loading @@ -193,5 +135,77 @@ namespace INAF.Apps.Uwp.SLabDataManager.Helpers.UI.Chart chart.Annotations.Remove(chart.Annotations.ElementAt(i)); } } #region highlight/lowlight public void setSegmentHighlight(RadCartesianChart chart, SegmentFitModel segmentFit, DataTemplate tappedPointTemplate) { var segmentPoints = getSegmentSpectrumElements(segmentFit, SpectrumType.Continuum); if (segmentPoints?.Count() > 0) { int segmentPointsNum = segmentPoints.Count(); for (int i = 0; i < segmentPointsNum; i++) { chart.Annotations.Add(getCustomAnnotation(segmentPoints.ElementAt(i).X, segmentPoints.ElementAt(i).Y, tappedPointTemplate)); } } chart.InvalidateUI(); } public void setSegmentLowlight(RadCartesianChart chart, SegmentFitModel segmentFit) { var segmentPoints = getSegmentSpectrumElements(segmentFit, SpectrumType.Continuum); if (segmentPoints?.Count() > 0) { int segmentPointsNum = segmentPoints.Count(); for (int i = 0; i < segmentPointsNum; i++) { var existantItem = chart.Annotations.FirstOrDefault(x => x is CartesianCustomAnnotation && (Convert.ToDouble((x as CartesianCustomAnnotation).HorizontalValue) == segmentPoints.ElementAt(i).X)); if (existantItem != null) /* if already existant, then remove point from chart */ chart.Annotations.Remove(existantItem); } } } public IEnumerable<ElementModel> getSegmentSpectrumElements(SegmentFitModel segmentFit, SpectrumType spectrumType) { var spectrum = workingItems.SpectraContainer.tryGetSpectrumOfType(spectrumType); return spectrum.Elements.Where(x => x.X >= segmentFit.P1.X && x.X <= segmentFit.P2.X); } #endregion #region common private CartesianCustomAnnotation getCustomAnnotation(double x, double y, DataTemplate tappedPointTemplate) { return new CartesianCustomAnnotation() { HorizontalValue = x, HorizontalAlignment = HorizontalAlignment.Center, VerticalValue = y, VerticalAlignment = VerticalAlignment.Center, ContentTemplate = tappedPointTemplate, }; } private (PointModel lowBoundary, PointModel highBoundary) getSegmentBoundaries(SpectrumModel spectrum, double x1, double x2) { var lowerBoundaryPoint = spectrum.Elements.Where(x => x.X <= x1).LastOrDefault().ToPointModel(); var higherBoundaryPoint = spectrum.Elements.Where(x => x.X >= x2).FirstOrDefault().ToPointModel(); return (lowerBoundaryPoint, higherBoundaryPoint); } #endregion } }