From e2fbc8e6047fef09681b994efe2ca1043d25ac9d Mon Sep 17 00:00:00 2001 From: Victoria Plitt Date: Sun, 16 Feb 2020 14:48:33 +0200 Subject: Implement Job Runs View. Create 2 views in Statistics. Implements Part of JobRunsView. Related Work Items: #2509 --- .../Tango.MachineStudio.Statistics.csproj | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj index 36c371165..4b3535f83 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj @@ -73,14 +73,25 @@ + + + PieChartTooltipControl.xaml + + + + ChartsView.xaml + + + JobRunsView.xaml + MainView.xaml @@ -95,6 +106,14 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + Designer MSBuild:Compile -- cgit v1.3.1 From a64cfe8b7dec8417a3d380b55f4ae79c5459f49d Mon Sep 17 00:00:00 2001 From: Victoria Plitt Date: Wed, 26 Feb 2020 13:22:44 +0200 Subject: Implementing JobRuns on Statistics module. --- .../Converters/CollectionConverter .cs | 44 ++ .../Converters/LiquidTypeToColorConverter.cs | 43 ++ .../Models/JobRunModel.cs | 2 - .../Models/RmlModel.cs | 15 + .../Tango.MachineStudio.Statistics.csproj | 7 + .../ViewModels/JobRunsViewVM.cs | 191 ++++++-- .../Views/JobRunsView.xaml | 509 +++++++++++++++------ .../Views/JobRunsView.xaml.cs | 23 + .../Tango.BL/Builders/JobRunsBuilder.cs | 69 ++- Software/Visual_Studio/Tango.BL/Entities/JobRun.cs | 19 +- .../Converters/TimeSpanToTwoDigitsTimeConverter.cs | 3 + .../Analysis/AnalyzerResultBase.cs | 27 +- .../Analyzers/FlowAnalyser.cs | 137 ++++-- .../Analyzers/PressureBuildUpAnalyser.cs | 2 +- .../Tango.DispenserAnalyzer.UI/MainWindow.xaml | 111 ++--- .../Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs | 15 +- .../Tango.DispenserAnalyzer.UI.csproj | 4 +- .../ViewModels/MainWindowVM.cs | 195 ++++++-- .../Utilities/Tango.JobRunsGenerator/Program.cs | 2 +- 19 files changed, 1064 insertions(+), 354 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidTypeToColorConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/RmlModel.cs (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs new file mode 100644 index 000000000..4cea7f69f --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace Tango.MachineStudio.Statistics.Converters +{ + public class CollectionConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if(value != null && value is System.Collections.IEnumerable) + { + var colection = value as System.Collections.IEnumerable; + var text = new StringBuilder(); + foreach(var val in colection) + { + string visibleText = val.ToString(); + if (val is bool) + { + visibleText = (bool)val== true ? "Yes" : "No"; + } + text.Append(visibleText); + text.Append("/"); + } + string str_text = text.ToString(); + if(str_text.Length > 1) + { + str_text = str_text.Remove(str_text.Length - 1); + } + return str_text; + } + return ""; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidTypeToColorConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidTypeToColorConverter.cs new file mode 100644 index 000000000..b36bf608e --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidTypeToColorConverter.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows.Media; +using Tango.BL; +using Tango.BL.Enumerations; + +namespace Tango.MachineStudio.Statistics.Converters +{ + public class LiquidTypeToColorConverter : IValueConverter + { + private static Dictionary liquidTypes; + + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (liquidTypes == null) + { + liquidTypes = new Dictionary(); + + foreach (var type in ObservablesStaticCollections.Instance.LiquidTypes.ToList()) + { + liquidTypes.Add(type.Type, type.LiquidTypeColor); + } + } + + if (value != null) + { + return liquidTypes[(LiquidTypes)value]; + } + + return value; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunModel.cs index e269f761f..2bf3a42a4 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunModel.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/JobRunModel.cs @@ -19,8 +19,6 @@ namespace Tango.MachineStudio.Statistics.Models public TimeSpan? HeatingDuration { get; set; } - - public void Init() { if (JobRun.HeatingStartDate != null) diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/RmlModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/RmlModel.cs new file mode 100644 index 000000000..789779e42 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/RmlModel.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Statistics.Models +{ + public class RmlModel + { + public string Guid { get; set; } + + public string Name { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj index 4b3535f83..fa62578a1 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj @@ -73,11 +73,14 @@ + + + PieChartTooltipControl.xaml @@ -148,6 +151,10 @@ + + {bb2abb74-ba58-4812-83aa-ec8171f42df4} + Tango.AutoComplete + {f441feee-322a-4943-b566-110e12fd3b72} Tango.BL diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs index f03e7f67d..5c80a9564 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL; +using Tango.BL.Builders; using Tango.BL.Entities; using Tango.BL.Enumerations; using Tango.Core.Commands; @@ -14,6 +15,7 @@ using Tango.MachineStudio.Common.Notifications; using Tango.MachineStudio.Statistics.Models; using Tango.SharedUI; using Tango.SharedUI.Components; +using Tango.AutoComplete.Editors; namespace Tango.MachineStudio.Statistics.ViewModels { @@ -22,11 +24,13 @@ namespace Tango.MachineStudio.Statistics.ViewModels private INotificationProvider _notification; private List _allMachines; private List _allUsers; + private List _rmlsModels; + private List _allJobRuns; #region Properties - private List _jobRuns; - public List JobRuns + private ObservableCollection _jobRuns; + public ObservableCollection JobRuns { get { return _jobRuns; } set @@ -72,51 +76,84 @@ namespace Tango.MachineStudio.Statistics.ViewModels set { _endSelectedDate = value; RaisePropertyChangedAuto(); } } - protected Double _length; - public Double Length + protected Double _lengthLowerValue; + public Double LengthLowerValue { - get { return _length; } + get { return _lengthLowerValue; } set { - _length = value; + _lengthLowerValue = value; RaisePropertyChangedAuto(); } } - private JobSource _jobRunSource; + protected Double _lengthUpperValue; + public Double LengthUpperValue + { + get { return _lengthUpperValue; } + set + { + _lengthUpperValue = value; + RaisePropertyChangedAuto(); + } + } - public JobSource JobRunSource + private SelectedObjectCollection _jobRunSelectedSources; + public SelectedObjectCollection JobRunSelectedSources { - get { return _jobRunSource; } - set { _jobRunSource = value; RaisePropertyChangedAuto(); } + get { return _jobRunSelectedSources; } + set { _jobRunSelectedSources = value; RaisePropertyChangedAuto(); } } - private JobRunStatus _jobRunStatus; + private SelectedObjectCollection _jobRunSelectedStatuses; + public SelectedObjectCollection JobRunSelectedStatuses + { + get { return _jobRunSelectedStatuses; } + set { _jobRunSelectedStatuses = value; RaisePropertyChangedAuto(); } + } - public JobRunStatus JobRunStatus + public SelectedObjectCollection _isGradientSelection; + public SelectedObjectCollection IsGradientSelection { - get { return _jobRunStatus; } - set { _jobRunStatus = value; RaisePropertyChangedAuto(); } + get { return _isGradientSelection; } + set + { + _isGradientSelection = value; + RaisePropertyChangedAuto(); + } } - - private bool? _isGradient; - public bool? IsGradient + private SelectedObjectCollection _selectedThreads; + public SelectedObjectCollection SelectedThreads { - get { return _isGradient; } - set { - _isGradient = value; - RaisePropertyChangedAuto(); } + get { return _selectedThreads; } + set + { + _selectedThreads = value; + RaisePropertyChangedAuto(); + } } - private string _jobName; + /// + /// Gets or sets the JobRuns providers. + /// + public ISuggestionProvider JobRunsProvider { get; set; } - public string JobName + private JobRun _jobRun; + public JobRun JobRun { - get { return _jobName; } - set { _jobName = value; } + get { return _jobRun; } + set { + _jobRun = value; + if (_jobRun != null) + { + SelectedJobName = _jobRun.JobName; + } + RaisePropertyChangedAuto(); } } + private string SelectedJobName { get; set; } + #endregion @@ -125,11 +162,68 @@ namespace Tango.MachineStudio.Statistics.ViewModels public JobRunsViewVM(INotificationProvider notificationProvider) { _notification = notificationProvider; - JobRuns = new List(); - LoadJobRunsCommand = new RelayCommand( GetJobRuns); + JobRuns = new ObservableCollection(); + LoadJobRunsCommand = new RelayCommand(async () => await LoadJobRuns(), ()=> IsFree); + LengthUpperValue = 5000.0; + LengthLowerValue = 0.0; + DateTime now = DateTime.Now; + StartSelectedDate = now.AddMonths(-1); + EndSelectedDate = now; + + JobRunSelectedSources = new SelectedObjectCollection(new ObservableCollection() + { + JobSource.Local, + JobSource.Remote + }, new ObservableCollection() + { + JobSource.Local, + JobSource.Remote + }); + JobRunSelectedSources.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(JobRunSelectedSources)); + JobRunSelectedSources.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(JobRunSelectedSources)); + + JobRunSelectedStatuses = new SelectedObjectCollection(new ObservableCollection() + { + JobRunStatus.Aborted, + JobRunStatus.Completed, + JobRunStatus.Failed, + + }, new ObservableCollection() + { + JobRunStatus.Aborted, + JobRunStatus.Completed, + JobRunStatus.Failed, + + }); + JobRunSelectedStatuses.SelectionChanged -= (x,y)=> RaisePropertyChanged(nameof(JobRunSelectedStatuses)); + JobRunSelectedStatuses.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(JobRunSelectedStatuses)); + + IsGradientSelection = new SelectedObjectCollection(new ObservableCollection + { + true, + false + }, new ObservableCollection + { + true, + false + }); + IsGradientSelection.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); + IsGradientSelection.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); + JobRunsProvider = new SuggestionProvider((filter) => + { + try + { + SelectedJobName = filter; + return _allJobRuns.Where(x => x.JobName != null && x.JobName.ToString().StartsWith(filter, StringComparison.CurrentCultureIgnoreCase)).ToList(); + } + catch + { + return null; + } + }); + } - public async void Init() { using (_notification.PushTaskItem("Loading job runs...")) @@ -140,9 +234,13 @@ namespace Tango.MachineStudio.Statistics.ViewModels using (var db = ObservablesContext.CreateDefault()) { + _allJobRuns = await db.JobRuns.ToListAsync(); ; _allMachines = await db.Machines.ToListAsync(); - _allUsers = await db.Users.ToListAsync(); + _allUsers = await db.Users.Include(x => x.Contact).ToListAsync(); + _rmlsModels = await db.Rmls.Select(x=> new RmlModel(){ Name = x.Name, Guid = x.Guid}).ToListAsync(); SelectedMachines = new SelectedObjectCollection(_allMachines.ToObservableCollection(), new ObservableCollection()); + SelectedThreads = new SelectedObjectCollection(_rmlsModels.ToObservableCollection(), new ObservableCollection()); + } } catch (Exception ex) @@ -155,12 +253,7 @@ namespace Tango.MachineStudio.Statistics.ViewModels } } } - - private async void GetJobRuns() - { - await LoadJobRuns(); - } - + private async Task LoadJobRuns() { using (_notification.PushTaskItem("Loading job runs...")) @@ -175,24 +268,25 @@ namespace Tango.MachineStudio.Statistics.ViewModels TimeSpan offsetTime = (EndSelectedDate.Date == DateTime.Now.Date) ? DateTime.Now.TimeOfDay : new TimeSpan(23, 59, 59); DateTime endUtc = EndSelectedDate.ToUniversalTime() + offsetTime; - var runs = await db.JobRuns.Select(x => new JobRunModel() + var runs = await new JobRunsBuilder(db).Set(x => x.ActualStartDate <= DbFunctions.TruncateTime(endUtc) && x.ActualStartDate >= DbFunctions.TruncateTime(startUtc.Date)) + .WithMachines(SelectedMachines.SynchedSource.ToList()) + .WithJobSource(JobRunSelectedSources.SynchedSource) + .WithJobStatus(JobRunSelectedStatuses.SynchedSource) + .WithGradient(IsGradientSelection.SynchedSource) + .Query(y => y.Where(x => (String.IsNullOrEmpty(SelectedJobName) || x.JobName.ToString().ToLower().StartsWith(SelectedJobName.ToLower())) + && ( x.JobLength < LengthUpperValue && x.JobLength >= LengthLowerValue) + )) + .BuildListAsync(); + + var modelList = runs.Select(x => new JobRunModel() { JobRun = x, Machine = _allMachines.FirstOrDefault(y => y.Guid == x.MachineGuid), User = _allUsers.SingleOrDefault(y => y.Guid == x.UserGuid), - }).ToListAsync(); + }).ToList(); - // .Query(y => y.Where - //(x => JobName == null || - //(x.JobName.ToString().ToLower().StartsWith(JobName) - //|| Length == null || (x.JobLength == Length) - //|| IsGradient == null || (x.IsGradient != null && x.IsGradient == IsGradient) - //|| ( x.JobRunSource == JobRunSource)))) - //.BuildAsync(); - - runs.ForEach(x => x.Init()); - - JobRuns = runs; + modelList.ForEach(x => x.Init()); + JobRuns = modelList.ToObservableCollection(); } } catch (Exception ex) @@ -205,5 +299,6 @@ namespace Tango.MachineStudio.Statistics.ViewModels } } } + } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml index 4667959b8..c89cd5819 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml @@ -7,17 +7,24 @@ xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:localConverters="clr-namespace:Tango.MachineStudio.Statistics.Converters" xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" + xmlns:autoComplete="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:enumerations="clr-namespace:Tango.BL.Enumerations;assembly=Tango.BL" xmlns:local="clr-namespace:Tango.MachineStudio.Statistics.Views" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="1200"> + d:DesignHeight="450" d:DesignWidth="1800" Foreground="{StaticResource JobFieldForeground}"> + + + + + + - - - - - - - - - - - - - - - - + - + - + + + + + + + + + + - - - - - - - - - - - - - - () - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + Start Date: + + + + End Date: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs index 0966533b9..39b0d2c02 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs @@ -29,6 +29,23 @@ namespace Tango.MachineStudio.Statistics.Views selectMachineButton.IsChecked = true; e.Handled = true; } + + private void JobRunSourcesButton_Click(object sender, RoutedEventArgs e) + { + selectJobRunSources.IsChecked = true; + e.Handled = true; + } + private void IsGradientButton_Click(object sender, RoutedEventArgs e) + { + selectIsGradient.IsChecked = true; + e.Handled = true; + } + private void JobRunStatusButton_Click(object sender, RoutedEventArgs e) + { + selectJobRunStatus.IsChecked = true; + e.Handled = true; + } + private async void TextBox_GotFocus(object sender, RoutedEventArgs e) { await Task.Delay(200); @@ -40,5 +57,11 @@ namespace Tango.MachineStudio.Statistics.Views { e.Handled = true; } + + private void SelectMachineButton_Click(object sender, RoutedEventArgs e) + { + selectThreadsButton.IsChecked = true; + e.Handled = true; + } } } diff --git a/Software/Visual_Studio/Tango.BL/Builders/JobRunsBuilder.cs b/Software/Visual_Studio/Tango.BL/Builders/JobRunsBuilder.cs index ca755a04c..dd6852c44 100644 --- a/Software/Visual_Studio/Tango.BL/Builders/JobRunsBuilder.cs +++ b/Software/Visual_Studio/Tango.BL/Builders/JobRunsBuilder.cs @@ -5,15 +5,82 @@ using System.Text; using System.Threading.Tasks; using Tango.BL.Entities; using System.Data.Entity; +using Tango.BL.Enumerations; namespace Tango.BL.Builders { - public class JobRunsBuilder : EntityBuilderBase + public class JobRunsBuilder : EntityCollectionBuilderBase { public JobRunsBuilder(ObservablesContext context) : base(context) { } + public virtual JobRunsBuilder WithMachines(List machines) + { + return AddQueryStep(1, (query) => + { + if (machines != null && machines.Count > 0) + { + var machineIDs = new HashSet(machines.Select(p => p.Guid)); + return query.Where(x => machineIDs.Contains(x.MachineGuid)); + } + return query; + }); + } + + public virtual JobRunsBuilder WithJobSource(IEnumerable source) + { + return AddQueryStep(2, (query) => + { + if(source.Count() > 0) + { + int[] jobRunSourceArr = source.Select(x => (int)x).ToArray(); + return query.Where(x => jobRunSourceArr.Contains(x.JobSource)); + } + return query; + + }); + } + + public virtual JobRunsBuilder WithJobStatus(IEnumerable status) + { + return AddQueryStep(3, (query) => + { + if(status.Count() > 0) + { + int[] jobRunStatusArr = status.Select(x => (int)x).ToArray(); + + return query.Where(x => jobRunStatusArr.Contains(x.Status)); + } + return query; + + }); + } + + public virtual JobRunsBuilder WithGradient(IEnumerable isGradient) + { + return AddQueryStep(4, (query) => + { + if(isGradient.Count() > 0) + { + bool[] isGradientArr = isGradient.Select(x => (bool)x).ToArray(); + return query.Where(x => isGradientArr.Contains(x.IsGradient)); + } + return query; + }); + } + + public virtual JobRunsBuilder WithRmls(List rmlGuids) + { + return AddQueryStep(5, (query) => + { + if (rmlGuids != null && rmlGuids.Count > 0) + { + return query.Where(x => rmlGuids.Contains(x.MachineGuid)); + } + return query; + }); + } } } diff --git a/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs b/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs index 6afb493cf..f422447fe 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs @@ -50,21 +50,24 @@ namespace Tango.BL.Entities { get { - if (_liquidQuantities != null) + if (_liquidQuantities == null) { - try + if (LiquidQuantityString != null) { - _liquidQuantities = JsonConvert.DeserializeObject>(LiquidQuantityString); + try + { + _liquidQuantities = JsonConvert.DeserializeObject>(LiquidQuantityString); + } + catch + { + _liquidQuantities = new List(); + } } - catch + else { _liquidQuantities = new List(); } } - else - { - _liquidQuantities = new List(); - } return _liquidQuantities; } diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/TimeSpanToTwoDigitsTimeConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/TimeSpanToTwoDigitsTimeConverter.cs index fb162d29b..8946020bf 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Converters/TimeSpanToTwoDigitsTimeConverter.cs +++ b/Software/Visual_Studio/Tango.SharedUI/Converters/TimeSpanToTwoDigitsTimeConverter.cs @@ -12,6 +12,9 @@ namespace Tango.SharedUI.Converters { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { + if (value == null) + return ""; + TimeSpan time = (TimeSpan)value; if (time.TotalHours > 1) diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/AnalyzerResultBase.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/AnalyzerResultBase.cs index b7ee059b9..ec2940a73 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/AnalyzerResultBase.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analysis/AnalyzerResultBase.cs @@ -6,10 +6,11 @@ using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; +using Tango.Core; namespace Tango.DispenserAnalyzer.UI.Analysis { - public class AnalyzerResultBase : IAnalyzerResult + public class AnalyzerResultBase : ExtendedObject, IAnalyzerResult { public AnalyzerResultValue Result { get; set; } public List PlotValues { get; set; } @@ -25,29 +26,35 @@ namespace Tango.DispenserAnalyzer.UI.Analysis foreach (var prop in this.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly).OrderByAlphaNumeric(x => x.Name)) { AnalyzerResultProperty aProp = new AnalyzerResultProperty(); - - if (prop.GetCustomAttribute() != null) + if (aProp.GetType() == typeof(IEnumerable<>)) { - aProp.Name = prop.GetCustomAttribute().Description; + continue; } - else + if (prop.GetCustomAttribute() != null) { - aProp.Name = prop.Name; + aProp.Name = prop.GetCustomAttribute().Description; + //} + //else + //{ + // aProp.Name = prop.Name; + //} + object val = prop.GetValue(this); + aProp.Value = (val is double) ? ((double)val).ToString("F") : val.ToString(); + props.Add(aProp); } - object val = prop.GetValue(this); - aProp.Value = (val is double) ? ((double)val).ToString("F") : val.ToString(); - - props.Add(aProp); + } return props; } } + public bool IsShowPlotResult { get; set; } public AnalyzerResultBase() { PlotValues = new List(); Result = AnalyzerResultValue.Undetermined; + IsShowPlotResult = false; } } } diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/FlowAnalyser.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/FlowAnalyser.cs index 17122ce66..16b8df8f1 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/FlowAnalyser.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/FlowAnalyser.cs @@ -9,6 +9,8 @@ using Tango.DispenserAnalyzer.UI.Models; using MathNet.Numerics.LinearAlgebra; using System.Linq.Expressions; using System.Diagnostics; +using OxyPlot; +using System.Collections.ObjectModel; namespace Tango.DispenserAnalyzer.UI.Analyzers { @@ -33,40 +35,35 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers if (index % 2 == 1)//testing Flow-error { - List filteredValues = rangeTestValues.Skip(5000).ToList(); - // Move Average data + + List filteredValues = rangeTestValues.Skip(5000).ToList(); + + //Move Average data List tasks = new List(); int calc_count = (int)filteredValues.Count() / 4; int start_index = 0; while (start_index < filteredValues.Count()) { int calc_amount = (start_index + calc_count) >= (filteredValues.Count() - 4) ? filteredValues.Count() - start_index : calc_count; - var sliceToCalcMoveAverage = new List(); - sliceToCalcMoveAverage.AddRange(filteredValues.Skip(start_index).Take(calc_amount).ToList()); - + var source_filter = filteredValues.Skip(start_index).Take(calc_amount).ToList(); tasks.Add(Task.Run(() => { - filter.Filtering(sliceToCalcMoveAverage); + filter.Filtering(source_filter); })); - start_index += calc_amount; } Task.WaitAll(tasks.ToArray()); - //calculate difference Max Min values for each 250 values - int periodCalcMaxMin = 470; - List differenceMaxMin = new List(); - for (int i = 0; i < (filteredValues.Count - periodCalcMaxMin); i+= 200) + //calculate difference Max Min values for each 300 values + int periodCalcMaxMin = 500; + List differenceMaxMin = new List(); + for (int i = 0; i < (filteredValues.Count - periodCalcMaxMin); i+= 300) { var rangeItems =(filteredValues.Skip(i).Take(periodCalcMaxMin).ToList()); - differenceMaxMin.Add(rangeItems.Max(t => t.Pressure) - rangeItems.Min(t => t.Pressure)); + differenceMaxMin.Add((int)(rangeItems.Max(t => t.Pressure) - rangeItems.Min(t => t.Pressure))); } - //var rangeItems = filteredValues.Select((x, i) => new { x, i }).GroupBy(p => (p.i / 250)).Select(x => x.Select(v => v.x).ToList()); - //var differenceMaxMin = rangeItems.Select(x => x.Max(t => t.Pressure) - x.Min(t => t.Pressure)).ToList(); - FlowAnalyzerResult result = new FlowAnalyzerResult(); result.AverageValue = filteredValues.Average(t => t.Pressure); - result.SetLocalErrors(differenceMaxMin); results.Add(result); } @@ -76,59 +73,121 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers int avgMinIndex = rangeTestValues.Select(x => x.Index).Min(); int avgMaxIndex = rangeTestValues.Select(x => x.Index).Max(); double totalsec = TimeSpan.FromMilliseconds((avgMaxIndex - avgMinIndex) * 100).TotalSeconds; - result.Time = totalsec.ToString() + " sec"; + result.Time = totalsec.ToString() + " sec (succeed for period between 8 and 11 sec)"; ; result.Result = (totalsec <= 11 && totalsec >= 8) ? AnalyzerResultValue.Passed : AnalyzerResultValue.Failed; results.Add(result); } } + return results; }); } public class FlowAnalyzerResult : AnalyzerResultBase { + #region Properties [Description("Average Value")] public double AverageValue { get; set; } - [Description("Errors under 15")] - public string LocalErrorsUnder15 { get; set; } - - [Description("Errors greater than or equal to 15 and less than 20")] - public string LocalErrorsUnder20 { get; set; } + [Description("Max Error")] + public string LocalErrors { get; set; } + + private ObservableCollection _points; + public ObservableCollection Points + { + get { return _points; } + set + { + _points = value; + RaisePropertyChangedAuto(); + } + } + private int _step; + public int XStep + { + get { return _step; } + set { _step = value; RaisePropertyChangedAuto(); } + } - [Description("Errors greater than or equal to 20 and less than 25")] - public string LocalErrorsUnder25 { get; set; } + private double _from; + public double From + { + get { return _from; } + set{ _from = value; RaisePropertyChangedAuto(); } + } - [Description("Errors greater than or equal to 25 and less than 30")] - public string LocalErrorsUnder30 { get; set; } + private double _to; + public double To + { + get { return _to; } + set { _to = value; RaisePropertyChangedAuto();} + } + + #endregion Properties - public FlowAnalyzerResult() + public FlowAnalyzerResult():base() { - // AverageValue = MaxValue = MinValue = TotalValue = FilterAverageValue = FilterMaxValue = FilterMinValue = FilterTotalValue = 0.0; AverageValue = 0.0; Result = AnalyzerResultValue.Undetermined; + _from = 0; + _to = 35; + XStep = 1; + this.Points = new ObservableCollection(); } - public void SetLocalErrors(List differenceMaxMin) + /// + /// Calculate result, max error. Set oxy plot column chart. + /// + /// The difference maximum minimum. + public void SetLocalErrors(List differenceMaxMin) { - LocalErrorsUnder15 = BuildErrorLog(differenceMaxMin.Where(x => x < 15).ToList()); - LocalErrorsUnder20 = BuildErrorLog(differenceMaxMin.Where(x => x < 20 && x >= 15).ToList()); int count = differenceMaxMin.Where(x => x < 25 && x >= 20).Count(); Result = (count <= 10) ? AnalyzerResultValue.Passed : AnalyzerResultValue.Failed; - LocalErrorsUnder25 = BuildErrorLog(differenceMaxMin.Where(x => x < 25 && x >= 20).ToList()); - LocalErrorsUnder30 = BuildErrorLog(differenceMaxMin.Where(x => x < 30 && x >= 25).ToList()); + + int max_key = FindMaxErrorObject(differenceMaxMin); + + for (int i = 0; i <= max_key; i++) + { + int val = differenceMaxMin.Count(x => x == i); + if(val > 0 || Points.Count > 0) + { + Points.Add(new DataPoint(i, val)); + } + } + this.IsShowPlotResult = true; + RaisePropertyChanged("Points"); } - private string BuildErrorLog(List range_values) + private double BuildMeasurementError(List range_values) { int count = range_values.Count(); - string logerrors = (count > 10 ? "multiple" : count.ToString()); - if(count > 10 && AverageValue > 0) + return (count - (count * 0.98)); + } + + /// + /// Finds the maximum error object. Init LocalErrors message. Return max range value. + /// + private int FindMaxErrorObject(List range_values) + { + var countValArr = range_values.GroupBy(x => x).Select(t => new { Key = t.Key, Value = t.Count() }).OrderBy(x=>x.Key).ToArray(); + double merror = BuildMeasurementError(range_values); + double sum = 0; + int max_key = 0; + for (int i = countValArr.Count() - 1; i >= 0 ; i--) { - double persentageOfError = (range_values.Max()) / AverageValue * 100; - logerrors = $"multiple{Environment.NewLine} Percentage of errors {persentageOfError.ToString("F2")}"; + sum += countValArr[i].Value; + if (max_key == 0) + max_key = (int)countValArr[i].Key; + if (sum >= merror) + { + double persentageOfError = countValArr[i].Key / AverageValue * 100; + int range = (int)countValArr[i].Key; + int occurrence = countValArr[i].Value; + LocalErrors = $" {persentageOfError.ToString("F2")}% where range = {range.ToString()} and occurrence = {occurrence.ToString()}"; + break; + } } - return logerrors; + return max_key; } } diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PressureBuildUpAnalyser.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PressureBuildUpAnalyser.cs index 66e4eb3fb..52e0e8934 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PressureBuildUpAnalyser.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Analyzers/PressureBuildUpAnalyser.cs @@ -24,7 +24,7 @@ namespace Tango.DispenserAnalyzer.UI.Analyzers List rangeTestValues = csvRows.Where(x => x.Index > pair[0].Index && x.Index < pair[1].Index).ToList(); //testing PBU { - PrimingAnalyzerResult result = new PrimingAnalyzerResult(); + PrimingAnalyzerResult result = new PrimingAnalyzerResult(); int avgMinIndex = rangeTestValues.Select(x => x.Index).Min(); int avgMaxIndex = rangeTestValues.Select(x => x.Index).Max(); double totalsec = TimeSpan.FromMilliseconds((avgMaxIndex - avgMinIndex) * 100).TotalSeconds; diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml index c72bfcf0e..a330b4425 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml @@ -26,7 +26,7 @@ - + @@ -43,6 +43,7 @@ + - + @@ -70,77 +71,83 @@ - + - - - - + + + + + + + diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs index 533a13e29..26d64c995 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/MainWindow.xaml.cs @@ -32,7 +32,7 @@ namespace Tango.DispenserAnalyzer.UI _vm = new MainWindowVM(); DataContext = _vm; _vm.PlotControl = PressurePlot; - CompositionTarget.Rendering += CompositionTargetRendering; + _vm.ResultsPanel = resultItems; foreach (var ax in PressurePlot.Axes) ax.Maximum = ax.Minimum = Double.NaN; @@ -63,17 +63,6 @@ namespace Tango.DispenserAnalyzer.UI } } - private void CompositionTargetRendering(object sender, EventArgs e) - { - //_vm.UpdateModel(); - if(_vm.ResetAllAxes) - { - _vm.ResetAllAxes = false; - foreach (var ax in PressurePlot.Axes) - ax.Maximum = ax.Minimum = Double.NaN; - PressurePlot.ResetAllAxes(); - } - PressurePlot.InvalidatePlot(true); - } + } } diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Tango.DispenserAnalyzer.UI.csproj b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Tango.DispenserAnalyzer.UI.csproj index fc195d7b5..1c2da6a01 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Tango.DispenserAnalyzer.UI.csproj +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/Tango.DispenserAnalyzer.UI.csproj @@ -148,6 +148,8 @@ Tango.SharedUI - + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/MainWindowVM.cs b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/MainWindowVM.cs index 89678dd0e..2f047f88a 100644 --- a/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/MainWindowVM.cs +++ b/Software/Visual_Studio/Utilities/Tango.DispenserAnalyzer.UI/ViewModels/MainWindowVM.cs @@ -12,19 +12,32 @@ using System.Collections.ObjectModel; using System.IO; using System.Windows.Input; using Tango.DispenserAnalyzer.UI.Analysis; -using System.Reflection; -using Tango.DispenserAnalyzer.UI.Analyzers; using System.Windows; using System.Windows.Threading; using OxyPlot; using OxyPlot.Wpf; using OxyPlot.Annotations; using System.Windows.Media; +using System.Diagnostics; +using System.Windows.Documents; +using System.Windows.Controls; +using System.Windows.Xps; +using System.Windows.Xps.Packaging; +using System.Windows.Media.Imaging; namespace Tango.DispenserAnalyzer.UI.ViewModels { public class MainWindowVM: ViewModel { + private const string FILE_EXTENSION = ".xps"; + + public Plot PlotControl { get; set; } + + /// + /// Gets or sets the results panel. Using to save all results in xps file + /// + public System.Windows.Controls.ItemsControl ResultsPanel { get; set; } + private string _openFilePath; public string OpenFilePath { @@ -60,10 +73,11 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels get { return _testName.ToUpper() + " TEST"; } set { _testName = value; RaisePropertyChangedAuto(); } } - - public Plot PlotControl { get; set; } - + private IList _points; + /// + /// Binding to ItemsSource of line chart. + /// public IList Points { get { return _points; } @@ -81,6 +95,9 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels } private double _from; + /// + /// From use to binding to bottom axis min value + /// public double From { get { return _from; } @@ -89,8 +106,11 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels _from = value; RaisePropertyChangedAuto(); } } - + private double _to; + /// + /// To use to binding to bottom axis max value + /// public double To { get { return _to; } @@ -99,8 +119,8 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels _to = value; RaisePropertyChangedAuto(); } } - public bool ResetAllAxes { get; set; } + private bool _isRunning; /// /// Gets or sets a value indicating whether this instance is running. @@ -133,7 +153,6 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels XStep = 1; AnalyzerResults = new ObservableCollection(); _isRunning = false; - ResetAllAxes = false; this.Points = new List(); @@ -212,7 +231,6 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels To = 0; From = 0; int index = 0; - bool in_test_range = false; int last_labelIndex = 0; foreach (var item in data) @@ -243,25 +261,18 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels Command = String.IsNullOrWhiteSpace(item.Command) ? null : item.Command, Index = index }); - - if(!String.IsNullOrWhiteSpace(item.Command)) - { - in_test_range = !in_test_range; - } - if( pressure != 0 ) - { - if (TestName.Contains( "SEAL") && Points.Count ==0) - { - _from = pressure; - } - else - _from = Math.Min(pressure, _from); - _to = Math.Max(pressure, _to); - Points.Add(new DataPoint(index, pressure)); - } index++; } } + List res = await analyzer.Process(samples); + AnalyzerResults = new ObservableCollection(res); + + samples.ForEach(x => { if (x.Pressure != 0.0) + { Points.Add(new DataPoint(x.Index, x.Pressure)); } + }); + _to = Points.Max(x=>x.Y); + _from = TestName.Contains("sealtest") ? Points.FirstOrDefault(x=>x.X == 0).Y : Points.Min(x => x.Y); + data.Clear(); _to += 100; RaisePropertyChanged("To"); @@ -269,22 +280,144 @@ namespace Tango.DispenserAnalyzer.UI.ViewModels _from -= 100; RaisePropertyChanged("From"); XStep = (int)(Points.Count / 5); - - List res = await analyzer.Process(samples); - AnalyzerResults = new ObservableCollection(res); - + + PrintToXpsFile(); + IsRunning = false; + PlotControl.InvalidatePlot(true); } #endregion private void ResetSettings() { Points.Clear(); - ResetAllAxes = true; + AnalyzerResults.Clear(); TestName = ""; + foreach (var ax in PlotControl.Axes) + { + ax.Maximum = ax.Minimum = Double.NaN; + PlotControl.ResetAllAxes(); + } PlotControl.Annotations.Clear(); + PlotControl.InvalidatePlot(true); } - + + #region SaveInXps file + private void PrintToXpsFile() + { + try + { + if (File.Exists(OpenFilePath)) + { + var fileName = Path.GetFileNameWithoutExtension(OpenFilePath); + fileName += "_result"; + var ext = Path.GetExtension(OpenFilePath); + var dir = Path.GetDirectoryName(OpenFilePath); + var resultFile = Path.Combine(dir, string.Format("{0}-result{1}", Path.GetFileNameWithoutExtension(OpenFilePath), FILE_EXTENSION)); + SaveResultsAsXps(resultFile); + } + } + catch(Exception ex) + { + Debug.WriteLine(ex); + } + } + + public void SaveResultsAsXps( string fileName) + { + Panel panel = ResultsPanel.Parent as Panel; + if (panel != null) + { + int index = panel.Children.IndexOf(ResultsPanel); + panel.Children.Remove(ResultsPanel); + CreateDoc( fileName); + panel.Children.Insert(index, ResultsPanel); + } + else + { + ContentControl cc = ResultsPanel.Parent as ContentControl; + if (cc != null) + { + cc.Content = null; + CreateDoc(fileName); + cc.Content = ResultsPanel; + } + } + } + + private void CreateDoc( string fileName) + { + Dispatcher.CurrentDispatcher.Invoke( DispatcherPriority.Loaded, new Action(() => + { + PrintDialog printDlg = new PrintDialog(); + Size pageSize = new Size(printDlg.PrintableAreaWidth, printDlg.PrintableAreaHeight - 100); + Size reportSize = GetReportSize(ResultsPanel, printDlg); + + FixedDocument fixedDoc = new FixedDocument(); + PageContent pageContent = new PageContent(); + FixedPage fixedPage = new FixedPage(); + fixedPage.Children.Add(ResultsPanel); + + pageContent.BeginInit(); + ((System.Windows.Markup.IAddChild)pageContent).AddChild(fixedPage); + pageContent.EndInit(); + + fixedDoc.Pages.Add(pageContent); + + InjectData(fixedDoc, AnalyzerResults); + //DocumentViewer documentViewer = new DocumentViewer(); + //documentViewer.Document = fixedDoc; + //documentViewer.UpdateLayout(); + + using (XpsDocument xpsd = new XpsDocument(fileName, FileAccess.Write)) + { + System.Windows.Xps.XpsDocumentWriter xw = XpsDocument.CreateXpsDocumentWriter(xpsd); + xw.Write(fixedDoc); + } + + fixedPage.Children.Remove(ResultsPanel); + })); + + + } + + /// + /// Injects the data to printed document. Without this the binding data to elements doesn't work. + /// + /// The document. + /// The data source. + protected void InjectData(FixedDocument document, object dataSource) + { + document.DataContext = new { AnalyzerResults = dataSource }; + + // we need to give the binding infrastructure a push as we + // are operating outside of the intended use of WPF + var dispatcher = Dispatcher.CurrentDispatcher; + dispatcher.Invoke(DispatcherPriority.SystemIdle, new DispatcherOperationCallback(delegate { return null; }), null); + } + + private static Size GetReportSize(ItemsControl reportContainer, PrintDialog printDialog = null) + { + if (printDialog == null) + printDialog = new PrintDialog(); + + double reportWidth = reportContainer.ActualWidth; + + double reportHeight = (reportWidth / printDialog.PrintableAreaWidth) * printDialog.PrintableAreaHeight; + + return new Size(reportWidth, reportHeight); + } + + public static void Print(IPlotModel model, string fileName, double width, double height) + { + using (var stream = File.Open(fileName, FileMode.Create, FileAccess.ReadWrite)) + { + var exporter = new XpsExporter { Width = width, Height = height}; + //PngExporter.Export(this.Plot.ActualModel, fileName, 600, 400, OxyColors.White) + exporter.Export(model, stream); + } + } + #endregion } } diff --git a/Software/Visual_Studio/Utilities/Tango.JobRunsGenerator/Program.cs b/Software/Visual_Studio/Utilities/Tango.JobRunsGenerator/Program.cs index c4ceff4e7..b89e83df8 100644 --- a/Software/Visual_Studio/Utilities/Tango.JobRunsGenerator/Program.cs +++ b/Software/Visual_Studio/Utilities/Tango.JobRunsGenerator/Program.cs @@ -70,7 +70,7 @@ namespace Tango.JobRunsGenerator if (run.JobName == null) run.JobName = job.Name; if (run.JobString == null) run.JobString = job.ToJobFileWhenLoaded().ToString(); if (run.LiquidQuantityString == null) run.LiquidQuantities = MachineOperator.CreateJobRunLiquidQuantities(job, machine.Configuration, job.Rml.GetActiveProcessGroup().ProcessParametersTables.First(), run.EndPosition, job.LengthIncludingNumberOfUnits); - if (run.UserGuid != null) run.UserGuid = job.UserGuid; + if (run.UserGuid == null) run.UserGuid = job.UserGuid; if (run.UploadingStartDate == null) run.UploadingStartDate = run.StartDate; if (run.HeatingStartDate == null) run.HeatingStartDate = run.StartDate; if (run.ActualStartDate == null) run.ActualStartDate = run.StartDate; -- cgit v1.3.1 From c9ba7c0b806818cdcbcd10fb03805a61608b4233 Mon Sep 17 00:00:00 2001 From: Victoria Plitt Date: Thu, 27 Feb 2020 16:03:06 +0200 Subject: Liquid quantities implementation in xaml. Related Work Items: #2509 --- .../Converters/DateIsInListToBooleanConverter.cs | 29 -------- .../MidTankLevelToElementHeightConverter.cs | 41 +++++++++++ .../Converters/StringToFirstLetterConverter.cs | 30 ++++++++ .../Tango.MachineStudio.Statistics.csproj | 3 +- .../ViewModels/JobRunsViewVM.cs | 79 +++++++++++++++++----- .../Views/JobRunsView.xaml | 78 ++++++++++++--------- 6 files changed, 181 insertions(+), 79 deletions(-) delete mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/DateIsInListToBooleanConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/MidTankLevelToElementHeightConverter.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/StringToFirstLetterConverter.cs (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/DateIsInListToBooleanConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/DateIsInListToBooleanConverter.cs deleted file mode 100644 index 74e0c61d8..000000000 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/DateIsInListToBooleanConverter.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Data; - -namespace Tango.MachineStudio.Statistics.Converters -{ - public class DateIsInListToBooleanConverter : IMultiValueConverter - { - public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) - { - if (values.Length < 2 || !(values[0] is DateTime) || !(values[1] is IEnumerable)) - return false; - - var date = (DateTime)values[0]; - var dateList = (IEnumerable)values[1]; - - return dateList.ToList().Exists(x => x.ToLocalTime().ToShortDateString() == date.ToLocalTime().ToShortDateString()); - } - - public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - } -} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/MidTankLevelToElementHeightConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/MidTankLevelToElementHeightConverter.cs new file mode 100644 index 000000000..e9f513cc3 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/MidTankLevelToElementHeightConverter.cs @@ -0,0 +1,41 @@ +using System; +using System.Globalization; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace Tango.MachineStudio.Statistics.Converters +{ + public class MidTankLevelToElementHeightConverter : IMultiValueConverter + { + public const double MAX_QUANTITY = 130000000; + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + try + { + double parentActualHeight; + Double.TryParse(values[0].ToString(), out parentActualHeight); + double quantity; + Double.TryParse(values[1].ToString(), out quantity); + + double midTankLevel = (double)Math.Min(quantity, MAX_QUANTITY); + double delta = ((midTankLevel / MAX_QUANTITY) * parentActualHeight); + if (midTankLevel < (MAX_QUANTITY/10))// if quantity < 10|% set 2 pixel + delta = 2.0; + var test = delta; + return test;// (parentActualHeight - (midTankLevel / MAX_QUANTITY) * parentActualHeight); + } + catch + { + return 0d; + } + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/StringToFirstLetterConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/StringToFirstLetterConverter.cs new file mode 100644 index 000000000..a1c9561b9 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/StringToFirstLetterConverter.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace Tango.MachineStudio.Statistics.Converters +{ + public class StringToFirstLetterConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value != null && value.ToString().Length > 1) + { + return value.ToString().First().ToString(); + } + else + { + return value; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj index fa62578a1..603429f94 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tango.MachineStudio.Statistics.csproj @@ -75,8 +75,9 @@ + - + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs index cf74071c9..07e431751 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs @@ -25,11 +25,14 @@ namespace Tango.MachineStudio.Statistics.ViewModels private List _allMachines; private List _allUsers; private List _rmlsModels; - private List _allJobRuns; + private List _allJobRuns; #region Properties private ObservableCollection _jobRuns; + /// + /// Gets or sets the job runs. Contains filtered data of JobRunModel. + /// public ObservableCollection JobRuns { get { return _jobRuns; } @@ -41,6 +44,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels } private JobRunModel _selectedJobRun = null; + /// + /// Gets or sets the JobRunModel. Binding to selected item of grid items. + /// public JobRunModel SelectedJobRun { get { return _selectedJobRun; } @@ -52,6 +58,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels } private SelectedObjectCollection _selectedMachines; + /// + /// Gets or sets the selected machines. Contains all available machines and selected machines. Binding to ComboBox Machines. + /// public SelectedObjectCollection SelectedMachines { get { return _selectedMachines; } @@ -63,6 +72,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels } private DateTime _startSelectedDate; + /// + /// Gets or sets the start selected date. + /// public DateTime StartSelectedDate { get { return _startSelectedDate; } @@ -70,6 +82,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels } private DateTime _endSelectedDate; + /// + /// Gets or sets the end selected date. + /// public DateTime EndSelectedDate { get { return _endSelectedDate; } @@ -77,6 +92,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels } protected Double _lengthLowerValue; + /// + /// Gets or sets the length lower value of Range Slider + /// public Double LengthLowerValue { get { return _lengthLowerValue; } @@ -88,6 +106,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels } protected Double _lengthUpperValue; + /// + /// Gets or sets the length upper value of Range Slider. + /// public Double LengthUpperValue { get { return _lengthUpperValue; } @@ -99,6 +120,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels } private SelectedObjectCollection _jobRunSelectedSources; + /// + /// Gets or sets the job run selected sources. Binding to ComboBox "Source". + /// public SelectedObjectCollection JobRunSelectedSources { get { return _jobRunSelectedSources; } @@ -106,6 +130,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels } private SelectedObjectCollection _jobRunSelectedStatuses; + /// + /// Gets or sets the job run selected statuses. Binding to ComboBox "Status". + /// public SelectedObjectCollection JobRunSelectedStatuses { get { return _jobRunSelectedStatuses; } @@ -113,6 +140,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels } public SelectedObjectCollection _isGradientSelection; + /// + /// Gets or sets the is gradient selection. Binding to ComboBox "IsGradient". + /// public SelectedObjectCollection IsGradientSelection { get { return _isGradientSelection; } @@ -124,6 +154,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels } private SelectedObjectCollection _selectedThreads; + /// + /// Gets or sets the selected threads. Contains all available threads and selected threads. Binding to ComboBox "Thread". + /// public SelectedObjectCollection SelectedThreads { get { return _selectedThreads; } @@ -137,21 +170,26 @@ namespace Tango.MachineStudio.Statistics.ViewModels /// /// Gets or sets the JobRuns providers. /// - public ISuggestionProvider JobRunsProvider { get; set; } + public ISuggestionProvider JobsProvider { get; set; } - private JobRun _jobRun; - public JobRun JobRun + private Job _selectedJob; + /// + /// Gets or sets the job. Used as Sele + /// + public Job SelectedJob { - get { return _jobRun; } - set { - _jobRun = value; - if (_jobRun != null) - { - SelectedJobName = _jobRun.JobName; - } - RaisePropertyChangedAuto(); } + get { return _selectedJob; } + set + { + _selectedJob = value; + SelectedJobName = _selectedJob != null ? _selectedJob.Name : ""; + RaisePropertyChangedAuto(); + } } + /// + /// Gets or sets the name of the selected job. Used in filter. + /// private string SelectedJobName { get; set; } @@ -209,12 +247,12 @@ namespace Tango.MachineStudio.Statistics.ViewModels }); IsGradientSelection.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); IsGradientSelection.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); - JobRunsProvider = new SuggestionProvider((filter) => + JobsProvider = new SuggestionProvider((filter) => { try { SelectedJobName = filter; - return _allJobRuns.Where(x => x.JobName != null && x.JobName.ToString().StartsWith(filter, StringComparison.CurrentCultureIgnoreCase)).ToList(); + return _allJobRuns.Where(x => x.Name != null && x.Name.ToString().StartsWith(filter, StringComparison.CurrentCultureIgnoreCase)).ToList(); } catch { @@ -223,7 +261,10 @@ namespace Tango.MachineStudio.Statistics.ViewModels }); } - + + /// + /// Initializes this instance. Called form main view VM in OnApplicationReady + /// public async void Init() { using (_notification.PushTaskItem("Loading job runs...")) @@ -234,7 +275,7 @@ namespace Tango.MachineStudio.Statistics.ViewModels using (var db = ObservablesContext.CreateDefault()) { - _allJobRuns = await db.JobRuns.ToListAsync(); ; + _allJobRuns = await db.Jobs.ToListAsync(); ; _allMachines = await db.Machines.ToListAsync(); _allUsers = await db.Users.Include(x => x.Contact).ToListAsync(); _rmlsModels = await db.Rmls.Select(x=> new RmlModel(){ Name = x.Name, Guid = x.Guid}).ToListAsync(); @@ -253,7 +294,10 @@ namespace Tango.MachineStudio.Statistics.ViewModels } } } - + + /// + /// Loads the job runs by filters. + /// private async Task LoadJobRuns() { using (_notification.PushTaskItem("Loading job runs...")) @@ -273,6 +317,7 @@ namespace Tango.MachineStudio.Statistics.ViewModels .WithJobSource(JobRunSelectedSources.SynchedSource) .WithJobStatus(JobRunSelectedStatuses.SynchedSource) .WithGradient(IsGradientSelection.SynchedSource) + .WithRmls(SelectedThreads.SynchedSource.Select(x => x.Guid).ToList()) .Query(y => y.Where(x => (String.IsNullOrEmpty(SelectedJobName) || x.JobName.ToString().ToLower().StartsWith(SelectedJobName.ToLower())) && ( x.JobLength < LengthUpperValue && x.JobLength >= LengthLowerValue) )) diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml index c89cd5819..c82fa3beb 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml @@ -17,14 +17,13 @@ - - - + + + + + + + + + + + + + + + + + + + + + + @@ -92,7 +120,7 @@ - + @@ -100,7 +128,7 @@ - + @@ -129,12 +157,11 @@ - + - - + @@ -237,7 +264,7 @@ - + @@ -259,7 +286,7 @@ - + @@ -268,10 +295,10 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + @@ -50,7 +82,7 @@ - + @@ -65,6 +97,11 @@ + + @@ -85,7 +122,7 @@ - + @@ -96,7 +133,7 @@ - + @@ -120,20 +157,13 @@ - - - - - - - - - - - - - - + + + + + + + @@ -154,10 +184,9 @@ - - - - + + + @@ -167,7 +196,7 @@ - + @@ -181,19 +210,13 @@ - - - - - - - - - - - - - + + + + + + + @@ -201,7 +224,7 @@ - + @@ -217,19 +240,13 @@ - - - - - - - - - - - - - + + + + + + + @@ -239,14 +256,14 @@ - - - - + + + - + @@ -264,19 +281,12 @@ - - - - - - - - - - - - - + + + + + + @@ -310,20 +320,14 @@ - - + + + + + - - - - - - - - - - - + + @@ -334,30 +338,41 @@ - + - - + + + + + + + + + @@ -68,34 +84,6 @@ - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -475,11 +537,142 @@ - - - TOTALS: - Cyan: - + + + + + + + + + + + + + + + + + + + + + + + + Total Thread Consumption per thread: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs index c460e2a9b..2b3ed79ca 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs @@ -1,4 +1,6 @@ -using System; +using LiveCharts; +using LiveCharts.Wpf; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -79,5 +81,6 @@ namespace Tango.MachineStudio.Statistics.Views } } } + } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/packages.config index 31c5f029f..6938c8a4b 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/packages.config +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/packages.config @@ -1,6 +1,7 @@  + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config index 59f92d6b9..d70e2180b 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/App.config @@ -152,6 +152,10 @@ + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs b/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs index f422447fe..45bfd9840 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading.Tasks; using Tango.BL.Enumerations; using Tango.BL.ValueObjects; +using Tango.PMR.Exports; namespace Tango.BL.Entities { @@ -82,6 +83,28 @@ namespace Tango.BL.Entities } } + private JobFile _jobFile; + [NotMapped] + [JsonIgnore] + public JobFile JobFile + { + get + { + if (_jobFile == null && JobString != null) + { + _jobFile = JobFile.Parser.ParseJson(JobString); + } + + return _jobFile; + } + set { _jobFile = value; } + } + + public Task CreateAssociatedJob() + { + return Job.FromJobFile(JobFile, MachineGuid, UserGuid); + } + protected override void RaisePropertyChanged(string propName) { base.RaisePropertyChanged(propName); -- cgit v1.3.1