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 --- .../ViewModels/ChartsViewVM.cs | 362 +++++++++++++++++++++ .../ViewModels/JobRunsViewVM.cs | 209 ++++++++++++ .../ViewModels/MainViewVM.cs | 339 +------------------ 3 files changed, 585 insertions(+), 325 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs new file mode 100644 index 000000000..b06261306 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs @@ -0,0 +1,362 @@ +using LiveCharts; +using LiveCharts.Wpf; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Media; +using Tango.BL.Enumerations; +using Tango.MachineStudio.Common; +using Tango.MachineStudio.Statistics.Models; +using Tango.BL.Entities; +using Tango.SharedUI; +using Tango.BL; +using Tango.MachineStudio.Common.Notifications; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Statistics.ViewModels +{ + public class ChartsViewVM : ViewModel + { + private INotificationProvider _notification; + private ObservablesContext _context; + private List _job_runs; + private bool _loaded; + + #region Properties + private LabeledSeriesCollection _timelineJobStatusSeries; + public LabeledSeriesCollection TimelineJobStatusSeries + { + get { return _timelineJobStatusSeries; } + set { _timelineJobStatusSeries = value; RaisePropertyChangedAuto(); } + } + + private LabeledSeriesCollection _pieJobFailedReasons; + public LabeledSeriesCollection PieJobFailedReasons + { + get { return _pieJobFailedReasons; } + set { _pieJobFailedReasons = value; RaisePropertyChangedAuto(); } + } + + private LabeledSeriesCollection _printPerWeekSeries; + public LabeledSeriesCollection PrintPerWeekSeries + { + get { return _printPerWeekSeries; } + set { _printPerWeekSeries = value; RaisePropertyChangedAuto(); } + } + + private DateTime _startDate; + public DateTime StartDate + { + get { return _startDate; } + set { _startDate = value; RaisePropertyChangedAuto(); OnDateRangeChanged(); } + } + + private DateTime _endDate; + public DateTime EndDate + { + get { return _endDate; } + set { _endDate = value; RaisePropertyChangedAuto(); OnDateRangeChanged(); } + } + + private DateTime _minDate; + public DateTime MinDate + { + get { return _minDate; } + set { _minDate = value; RaisePropertyChangedAuto(); } + } + + private DateTime _maxDate; + public DateTime MaxDate + { + get { return _maxDate; } + set { _maxDate = value; RaisePropertyChangedAuto(); } + } + #endregion + + public ChartsViewVM(INotificationProvider notificationProvider) + { + _notification = notificationProvider; + StartDate = DateTime.Now.AddMonths(-1); + EndDate = DateTime.Now; + } + + #region Generate Charts + + public async void Init() + { + using (_notification.PushTaskItem("Loading statistics...")) + { + IsFree = false; + + await Task.Factory.StartNew(() => + { + _context = ObservablesContext.CreateDefault(); + _job_runs = _context.JobRuns.OrderBy(x => x.StartDate).ToList().Select(x => new JobRunStatisticsModel(x)).ToList(); + foreach (var run in _job_runs) + { + run.LoadMachine(_context).GetAwaiter().GetResult(); + } + }); + + if (_job_runs.Count > 0) + { + MinDate = _job_runs.Min(x => x.StartDate); + MaxDate = _job_runs.Max(x => x.StartDate); + } + + InvokeUIOnIdle(() => + { + if (_loaded) + { + OnDateRangeChanged(); + } + }); + + _loaded = true; + IsFree = true; + } + } + + private List GetJobRunsByDateRange(DateTime startDate, DateTime endTime, JobRunStatus? status = null) + { + return _job_runs.Where(x => x.StartDate.ToLocalTime() >= startDate && x.StartDate.ToLocalTime() <= endTime && (status == null || x.JobRunStatus == status)).ToList(); + } + + private List GetJobRunsByDate(DateTime date, JobRunStatus? status = null) + { + return _job_runs.Where(x => x.StartDate.ToLocalTime().Date == date.Date && (status == null || x.JobRunStatus == status)).ToList(); + } + + private IEnumerable CreateDates(DateTime start, DateTime end) + { + for (DateTime date = start.Date; date.Date <= end.Date; date = date.AddDays(1)) + { + yield return date; + } + } + + private void GenerateTimelineJobStatusChart() + { + TimelineJobStatusSeries = new LabeledSeriesCollection() + { + Title = "Job Runs Status", + ChartTitle = "Number Of Runs", + LabelsTitle = "Date", + SeriesColors = new List() + { + Colors.Green, + Colors.Orange, + Colors.Red, + }, + }; + + Series completed_job_runs = new ColumnSeries() + { + Title = "Completed", + Values = new ChartValues(), + Fill = Brushes.Green, + MinWidth = 1, + + }; + Series aborted_job_runs = new ColumnSeries() + { + Title = "Aborted", + Values = new ChartValues(), + Fill = Brushes.Orange, + MinWidth = 1, + }; + Series failed_job_runs = new ColumnSeries() + { + Title = "Failed", + Values = new ChartValues(), + Fill = Brushes.Red, + MinWidth = 1, + }; + + if (EndDate - StartDate > TimeSpan.FromDays(40)) + { + completed_job_runs = new LineSeries() + { + Title = "Completed", + Values = new ChartValues(), + Fill = new SolidColorBrush(Colors.Green) { Opacity = 0.5 }, + MinWidth = 1, + PointGeometry = null, + StrokeThickness = 0, + + }; + aborted_job_runs = new LineSeries() + { + Title = "Aborted", + Values = new ChartValues(), + Fill = new SolidColorBrush(Colors.Orange) { Opacity = 0.5 }, + MinWidth = 1, + PointGeometry = null, + StrokeThickness = 0, + }; + failed_job_runs = new LineSeries() + { + Title = "Failed", + Values = new ChartValues(), + Fill = new SolidColorBrush(Colors.Red) { Opacity = 0.5 }, + MinWidth = 1, + PointGeometry = null, + StrokeThickness = 0, + }; + } + + foreach (var date in CreateDates(StartDate, EndDate)) + { + completed_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Completed).Count()); + aborted_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Aborted).Count()); + failed_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Failed).Count()); + + TimelineJobStatusSeries.Labels.Add(date.ToShortDateString()); + } + + + + TimelineJobStatusSeries.SeriesCollection.Add(failed_job_runs); + TimelineJobStatusSeries.SeriesCollection.Add(aborted_job_runs); + TimelineJobStatusSeries.SeriesCollection.Add(completed_job_runs); + } + + private void GeneratePieFailedReasonsChart() + { + var groups = GetJobRunsByDateRange(StartDate, EndDate, JobRunStatus.Failed).GroupBy(x => x.FailedMessage).OrderBy(x => x.Count()); + + List colors = new List(); + + int max = groups.Count() > 0 ? groups.Max(x => x.Count()) : 0; + + for (int i = 0; i < groups.Count(); i++) + { + int count = groups.ElementAt(i).Count(); + double alpha = Math.Max(((double)(count) / max * 200), 20); + colors.Add(Color.FromArgb((byte)alpha, 200, 0, 0)); + } + + PieJobFailedReasons = new LabeledSeriesCollection() + { + Title = "Job Failure Reasons", + SeriesColors = colors, + }; + + int index = 0; + + foreach (var group in groups) + { + int count = group.Count(); + + var series = new PieSeries() + { + Title = group.First().FailedMessage, + Values = new ChartValues() { count }, + Fill = new SolidColorBrush(colors[index++]), + DataLabels = true, + ToolTip = group.First().FailedMessage, + }; + + PieJobFailedReasons.SeriesCollection.Add(series); + } + } + + private void GeneratePrintPerWeekChart() + { + List range_job_runs = GetJobRunsByDateRange(StartDate, EndDate); + + Dictionary> weeks_print_avg = new Dictionary>(); + + //Init machines weeks averages dictionary. + foreach (var machine in range_job_runs.Select(x => x.Machine).OrderBy(x => x.Name).DistinctBy(x => x.Guid)) + { + weeks_print_avg[machine] = new List(); + } + + //Create all available dates + List all_dates = range_job_runs.Select(x => x.StartDate).ToList(); + + //get first Sunday. + DateTime current_sunday = all_dates.FirstOrDefault(x => x.DayOfWeek == DayOfWeek.Sunday); + + if (current_sunday != null && all_dates.Count > 0) + { + //Iterate over each week starting from the earliest Sunday. + while (current_sunday <= all_dates.Last()) + { + var week_job_runs = range_job_runs.Where(x => x.EndPosition > 10 && x.StartDate >= current_sunday && x.StartDate <= current_sunday.AddDays(7)).ToList(); + + foreach (var machine_job_runs in week_job_runs.GroupBy(x => x.Machine)) + { + weeks_print_avg[machine_job_runs.Key].Add(machine_job_runs.Select(x => x.EndPosition).Average()); + } + + current_sunday = current_sunday.AddDays(8); + } + } + + Dictionary week_print_avg = new Dictionary(); + + //Init machines week average dictionary. + foreach (var machine in weeks_print_avg) + { + if (machine.Value.Count > 0) + { + week_print_avg[machine.Key] = machine.Value.Average(); + } + } + + //Init chart series + PrintPerWeekSeries = new LabeledSeriesCollection() + { + Title = "Average Printed Thread Per Week (m)", + ChartTitle = "Average Print Per Week (m)", + LabelsTitle = "Date", + SeriesColors = new List() + { + + }, + }; + + //Init series colors intensity by number of prints. + double max = week_print_avg.Count > 0 ? week_print_avg.Max(x => x.Value) : 0; + foreach (var machine in week_print_avg) + { + double a = (machine.Value / max); + PrintPerWeekSeries.SeriesColors.Add(Color.FromArgb((byte)(255d * (machine.Value / max)), 0, 200, 0)); + } + + //Init columns. + int index = 0; + + foreach (var machine in week_print_avg) + { + var series = new ColumnSeries() + { + Title = machine.Key.Name, + Values = new ChartValues() { (int)machine.Value }, + Fill = new SolidColorBrush(PrintPerWeekSeries.SeriesColors[index++]), + DataLabels = true, + ToolTip = machine.Key.SerialNumber, + }; + + PrintPerWeekSeries.SeriesCollection.Add(series); + } + } + + #endregion + + #region Filter by Date + public void OnDateRangeChanged() + { + if (_job_runs != null && _job_runs.Count > 0)// && _loaded) + { + GenerateTimelineJobStatusChart(); + GeneratePieFailedReasonsChart(); + GeneratePrintPerWeekChart(); + } + } + #endregion + + } +} 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 new file mode 100644 index 000000000..f03e7f67d --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs @@ -0,0 +1,209 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Data.Entity; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; +using Tango.BL.Enumerations; +using Tango.Core.Commands; +using Tango.MachineStudio.Common; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Statistics.Models; +using Tango.SharedUI; +using Tango.SharedUI.Components; + +namespace Tango.MachineStudio.Statistics.ViewModels +{ + public class JobRunsViewVM : ViewModel + { + private INotificationProvider _notification; + private List _allMachines; + private List _allUsers; + + #region Properties + + private List _jobRuns; + public List JobRuns + { + get { return _jobRuns; } + set + { + _jobRuns = value; + RaisePropertyChangedAuto(); + } + } + + private JobRunModel _selectedJobRun = null; + public JobRunModel SelectedJobRun + { + get { return _selectedJobRun; } + set + { + _selectedJobRun = value; + RaisePropertyChangedAuto(); + } + } + + private SelectedObjectCollection _selectedMachines; + public SelectedObjectCollection SelectedMachines + { + get { return _selectedMachines; } + set + { + _selectedMachines = value; + RaisePropertyChangedAuto(); + } + } + + private DateTime _startSelectedDate; + public DateTime StartSelectedDate + { + get { return _startSelectedDate; } + set { _startSelectedDate = value; RaisePropertyChangedAuto(); } + } + + private DateTime _endSelectedDate; + public DateTime EndSelectedDate + { + get { return _endSelectedDate; } + set { _endSelectedDate = value; RaisePropertyChangedAuto(); } + } + + protected Double _length; + public Double Length + { + get { return _length; } + set + { + _length = value; + RaisePropertyChangedAuto(); + } + } + + private JobSource _jobRunSource; + + public JobSource JobRunSource + { + get { return _jobRunSource; } + set { _jobRunSource = value; RaisePropertyChangedAuto(); } + } + + private JobRunStatus _jobRunStatus; + + public JobRunStatus JobRunStatus + { + get { return _jobRunStatus; } + set { _jobRunStatus = value; RaisePropertyChangedAuto(); } + } + + private bool? _isGradient; + + public bool? IsGradient + { + get { return _isGradient; } + set { + _isGradient = value; + RaisePropertyChangedAuto(); } + } + + private string _jobName; + + public string JobName + { + get { return _jobName; } + set { _jobName = value; } + } + + + #endregion + + public RelayCommand LoadJobRunsCommand { get; set; } + + public JobRunsViewVM(INotificationProvider notificationProvider) + { + _notification = notificationProvider; + JobRuns = new List(); + LoadJobRunsCommand = new RelayCommand( GetJobRuns); + } + + + public async void Init() + { + using (_notification.PushTaskItem("Loading job runs...")) + { + try + { + IsFree = false; + + using (var db = ObservablesContext.CreateDefault()) + { + _allMachines = await db.Machines.ToListAsync(); + _allUsers = await db.Users.ToListAsync(); + SelectedMachines = new SelectedObjectCollection(_allMachines.ToObservableCollection(), new ObservableCollection()); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading job runs."); + } + finally + { + IsFree = true; + } + } + } + + private async void GetJobRuns() + { + await LoadJobRuns(); + } + + private async Task LoadJobRuns() + { + using (_notification.PushTaskItem("Loading job runs...")) + { + try + { + IsFree = false; + + using (var db = ObservablesContext.CreateDefault()) + { + DateTime startUtc = StartSelectedDate.ToUniversalTime(); + 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() + { + JobRun = x, + Machine = _allMachines.FirstOrDefault(y => y.Guid == x.MachineGuid), + User = _allUsers.SingleOrDefault(y => y.Guid == x.UserGuid), + }).ToListAsync(); + + // .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; + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading job runs."); + } + finally + { + IsFree = true; + } + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs index dfbfe2648..4a75a41c8 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/MainViewVM.cs @@ -19,349 +19,38 @@ namespace Tango.MachineStudio.Statistics.ViewModels { public class MainViewVM : StudioViewModel { - private ObservablesContext _context; - private List _job_runs; - private bool rendered; private INotificationProvider _notification; - private bool _loaded; - private LabeledSeriesCollection _timelineJobStatusSeries; - public LabeledSeriesCollection TimelineJobStatusSeries + private ChartsViewVM _chartsViewVM; + public ChartsViewVM ChartsViewVM { - get { return _timelineJobStatusSeries; } - set { _timelineJobStatusSeries = value; RaisePropertyChangedAuto(); } + get { return _chartsViewVM; } + set { _chartsViewVM = value; RaisePropertyChangedAuto(); } } - private LabeledSeriesCollection _pieJobFailedReasons; - public LabeledSeriesCollection PieJobFailedReasons + private JobRunsViewVM _jobRunsViewVM; + public JobRunsViewVM JobRunsViewVM { - get { return _pieJobFailedReasons; } - set { _pieJobFailedReasons = value; RaisePropertyChangedAuto(); } + get { return _jobRunsViewVM; } + set { _jobRunsViewVM = value; RaisePropertyChangedAuto(); } } - - private LabeledSeriesCollection _printPerWeekSeries; - public LabeledSeriesCollection PrintPerWeekSeries - { - get { return _printPerWeekSeries; } - set { _printPerWeekSeries = value; RaisePropertyChangedAuto(); } - } - - private DateTime _startDate; - public DateTime StartDate - { - get { return _startDate; } - set { _startDate = value; RaisePropertyChangedAuto(); OnDateRangeChanged(); } - } - - private DateTime _endDate; - public DateTime EndDate - { - get { return _endDate; } - set { _endDate = value; RaisePropertyChangedAuto(); OnDateRangeChanged(); } - } - - private DateTime _minDate; - public DateTime MinDate - { - get { return _minDate; } - set { _minDate = value; RaisePropertyChangedAuto(); } - } - - private DateTime _maxDate; - public DateTime MaxDate - { - get { return _maxDate; } - set { _maxDate = value; RaisePropertyChangedAuto(); } - } - + public MainViewVM(INotificationProvider notificationProvider) { _notification = notificationProvider; - - StartDate = DateTime.Now.AddMonths(-1); - EndDate = DateTime.Now; + ChartsViewVM = new ChartsViewVM(_notification); + JobRunsViewVM = new JobRunsViewVM(_notification); } public override void OnApplicationReady() { - - } - - private List GetJobRunsByDateRange(DateTime startDate, DateTime endTime, JobRunStatus? status = null) - { - return _job_runs.Where(x => x.StartDate.ToLocalTime() >= startDate && x.StartDate.ToLocalTime() <= endTime && (status == null || x.JobRunStatus == status)).ToList(); - } - - private List GetJobRunsByDate(DateTime date, JobRunStatus? status = null) - { - return _job_runs.Where(x => x.StartDate.ToLocalTime().Date == date.Date && (status == null || x.JobRunStatus == status)).ToList(); - } - - private IEnumerable CreateDates(DateTime start, DateTime end) - { - for (DateTime date = start.Date; date.Date <= end.Date; date = date.AddDays(1)) - { - yield return date; - } + JobRunsViewVM.Init(); } - public override async void OnNavigatedTo() + public override void OnNavigatedTo() { base.OnNavigatedTo(); - - if (rendered) return; - - rendered = true; - - - using (_notification.PushTaskItem("Loading statistics...")) - { - IsFree = false; - - await Task.Factory.StartNew(() => - { - _context = ObservablesContext.CreateDefault(); - _job_runs = _context.JobRuns.OrderBy(x => x.StartDate).ToList().Select(x => new JobRunModel(x)).ToList(); - foreach (var run in _job_runs) - { - run.LoadMachine(_context).GetAwaiter().GetResult(); - } - }); - - if (_job_runs.Count > 0) - { - MinDate = _job_runs.Min(x => x.StartDate); - MaxDate = _job_runs.Max(x => x.StartDate); - } - - InvokeUIOnIdle(() => - { - OnDateRangeChanged(); - }); - - _loaded = true; - - IsFree = true; - } - } - - private void OnDateRangeChanged() - { - if (_job_runs != null && _job_runs.Count > 0 && _loaded) - { - GenerateTimelineJobStatusChart(); - GeneratePieFailedReasonsChart(); - GeneratePrintPerWeekChart(); - } - } - - private void GenerateTimelineJobStatusChart() - { - TimelineJobStatusSeries = new LabeledSeriesCollection() - { - Title = "Job Runs Status", - ChartTitle = "Number Of Runs", - LabelsTitle = "Date", - SeriesColors = new List() - { - Colors.Green, - Colors.Orange, - Colors.Red, - }, - }; - - Series completed_job_runs = new ColumnSeries() - { - Title = "Completed", - Values = new ChartValues(), - Fill = Brushes.Green, - MinWidth = 1, - - }; - Series aborted_job_runs = new ColumnSeries() - { - Title = "Aborted", - Values = new ChartValues(), - Fill = Brushes.Orange, - MinWidth = 1, - }; - Series failed_job_runs = new ColumnSeries() - { - Title = "Failed", - Values = new ChartValues(), - Fill = Brushes.Red, - MinWidth = 1, - }; - - if (EndDate - StartDate > TimeSpan.FromDays(40)) - { - completed_job_runs = new LineSeries() - { - Title = "Completed", - Values = new ChartValues(), - Fill = new SolidColorBrush(Colors.Green) { Opacity = 0.5 }, - MinWidth = 1, - PointGeometry = null, - StrokeThickness = 0, - - }; - aborted_job_runs = new LineSeries() - { - Title = "Aborted", - Values = new ChartValues(), - Fill = new SolidColorBrush(Colors.Orange) { Opacity = 0.5 }, - MinWidth = 1, - PointGeometry = null, - StrokeThickness = 0, - }; - failed_job_runs = new LineSeries() - { - Title = "Failed", - Values = new ChartValues(), - Fill = new SolidColorBrush(Colors.Red) { Opacity = 0.5 }, - MinWidth = 1, - PointGeometry = null, - StrokeThickness = 0, - }; - } - - foreach (var date in CreateDates(StartDate, EndDate)) - { - completed_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Completed).Count()); - aborted_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Aborted).Count()); - failed_job_runs.Values.Add(GetJobRunsByDate(date, JobRunStatus.Failed).Count()); - - TimelineJobStatusSeries.Labels.Add(date.ToShortDateString()); - } - - - - TimelineJobStatusSeries.SeriesCollection.Add(failed_job_runs); - TimelineJobStatusSeries.SeriesCollection.Add(aborted_job_runs); - TimelineJobStatusSeries.SeriesCollection.Add(completed_job_runs); - } - - private void GeneratePieFailedReasonsChart() - { - var groups = GetJobRunsByDateRange(StartDate, EndDate, JobRunStatus.Failed).GroupBy(x => x.FailedMessage).OrderBy(x => x.Count()); - - List colors = new List(); - - int max = groups.Count() > 0 ? groups.Max(x => x.Count()) : 0; - - for (int i = 0; i < groups.Count(); i++) - { - int count = groups.ElementAt(i).Count(); - double alpha = Math.Max(((double)(count) / max * 200), 20); - colors.Add(Color.FromArgb((byte)alpha, 200, 0, 0)); - } - - PieJobFailedReasons = new LabeledSeriesCollection() - { - Title = "Job Failure Reasons", - SeriesColors = colors, - }; - - int index = 0; - - foreach (var group in groups) - { - int count = group.Count(); - - var series = new PieSeries() - { - Title = group.First().FailedMessage, - Values = new ChartValues() { count }, - Fill = new SolidColorBrush(colors[index++]), - DataLabels = true, - ToolTip = group.First().FailedMessage, - }; - - PieJobFailedReasons.SeriesCollection.Add(series); - } - } - - private void GeneratePrintPerWeekChart() - { - List range_job_runs = GetJobRunsByDateRange(StartDate, EndDate); - - Dictionary> weeks_print_avg = new Dictionary>(); - - //Init machines weeks averages dictionary. - foreach (var machine in range_job_runs.Select(x => x.Machine).OrderBy(x => x.Name).DistinctBy(x => x.Guid)) - { - weeks_print_avg[machine] = new List(); - } - - //Create all available dates - List all_dates = range_job_runs.Select(x => x.StartDate).ToList(); - - //get first Sunday. - DateTime current_sunday = all_dates.FirstOrDefault(x => x.DayOfWeek == DayOfWeek.Sunday); - - if (current_sunday != null && all_dates.Count > 0) - { - //Iterate over each week starting from the earliest Sunday. - while (current_sunday <= all_dates.Last()) - { - var week_job_runs = range_job_runs.Where(x => x.EndPosition > 10 && x.StartDate >= current_sunday && x.StartDate <= current_sunday.AddDays(7)).ToList(); - - foreach (var machine_job_runs in week_job_runs.GroupBy(x => x.Machine)) - { - weeks_print_avg[machine_job_runs.Key].Add(machine_job_runs.Select(x => x.EndPosition).Average()); - } - - current_sunday = current_sunday.AddDays(8); - } - } - - Dictionary week_print_avg = new Dictionary(); - - //Init machines week average dictionary. - foreach (var machine in weeks_print_avg) - { - if (machine.Value.Count > 0) - { - week_print_avg[machine.Key] = machine.Value.Average(); - } - } - - //Init chart series - PrintPerWeekSeries = new LabeledSeriesCollection() - { - Title = "Average Printed Thread Per Week (m)", - ChartTitle = "Average Print Per Week (m)", - LabelsTitle = "Date", - SeriesColors = new List() - { - - }, - }; - - //Init series colors intensity by number of prints. - double max = week_print_avg.Count > 0 ? week_print_avg.Max(x => x.Value) : 0; - foreach (var machine in week_print_avg) - { - double a = (machine.Value / max); - PrintPerWeekSeries.SeriesColors.Add(Color.FromArgb((byte)(255d * (machine.Value / max)), 0, 200, 0)); - } - - //Init columns. - int index = 0; - - foreach (var machine in week_print_avg) - { - var series = new ColumnSeries() - { - Title = machine.Key.Name, - Values = new ChartValues() { (int)machine.Value }, - Fill = new SolidColorBrush(PrintPerWeekSeries.SeriesColors[index++]), - DataLabels = true, - ToolTip = machine.Key.SerialNumber, - }; - - PrintPerWeekSeries.SeriesCollection.Add(series); - } + ChartsViewVM.Init(); } } } -- 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/ViewModels') 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 228dca3384369f23d6dcad6a696cf491ab9d8840 Mon Sep 17 00:00:00 2001 From: Victoria Plitt Date: Wed, 26 Feb 2020 13:27:25 +0200 Subject: Fixed job runs collection builder. --- .../ViewModels/JobRunsViewVM.cs | 2 +- .../Tango.BL/Builders/JobRunsBuilder.cs | 86 ---------------------- .../Tango.BL/Builders/JobRunsCollectionBuilder.cs | 86 ++++++++++++++++++++++ Software/Visual_Studio/Tango.BL/Tango.BL.csproj | 4 +- 4 files changed, 89 insertions(+), 89 deletions(-) delete mode 100644 Software/Visual_Studio/Tango.BL/Builders/JobRunsBuilder.cs create mode 100644 Software/Visual_Studio/Tango.BL/Builders/JobRunsCollectionBuilder.cs (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels') 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 5c80a9564..cf74071c9 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 @@ -268,7 +268,7 @@ 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 new JobRunsBuilder(db).Set(x => x.ActualStartDate <= DbFunctions.TruncateTime(endUtc) && x.ActualStartDate >= DbFunctions.TruncateTime(startUtc.Date)) + var runs = await new JobRunsCollectionBuilder(db).Set(x => x.ActualStartDate <= DbFunctions.TruncateTime(endUtc) && x.ActualStartDate >= DbFunctions.TruncateTime(startUtc.Date)) .WithMachines(SelectedMachines.SynchedSource.ToList()) .WithJobSource(JobRunSelectedSources.SynchedSource) .WithJobStatus(JobRunSelectedStatuses.SynchedSource) diff --git a/Software/Visual_Studio/Tango.BL/Builders/JobRunsBuilder.cs b/Software/Visual_Studio/Tango.BL/Builders/JobRunsBuilder.cs deleted file mode 100644 index dd6852c44..000000000 --- a/Software/Visual_Studio/Tango.BL/Builders/JobRunsBuilder.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -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 : 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/Builders/JobRunsCollectionBuilder.cs b/Software/Visual_Studio/Tango.BL/Builders/JobRunsCollectionBuilder.cs new file mode 100644 index 000000000..a1990c9ea --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/Builders/JobRunsCollectionBuilder.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +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 JobRunsCollectionBuilder : EntityCollectionBuilderBase + { + public JobRunsCollectionBuilder(ObservablesContext context) : base(context) + { + + } + + public virtual JobRunsCollectionBuilder 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 JobRunsCollectionBuilder 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 JobRunsCollectionBuilder 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 JobRunsCollectionBuilder 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 JobRunsCollectionBuilder WithRmls(List rmlGuids) + { + return AddQueryStep(5, (query) => + { + if (rmlGuids != null && rmlGuids.Count > 0) + { + return query.Where(x => rmlGuids.Contains(x.RmlGuid)); + } + return query; + }); + } + } +} diff --git a/Software/Visual_Studio/Tango.BL/Tango.BL.csproj b/Software/Visual_Studio/Tango.BL/Tango.BL.csproj index 2a5090c2e..6b6e8864d 100644 --- a/Software/Visual_Studio/Tango.BL/Tango.BL.csproj +++ b/Software/Visual_Studio/Tango.BL/Tango.BL.csproj @@ -107,7 +107,7 @@ - + @@ -610,7 +610,7 @@ - + \ No newline at end of file -- cgit v1.3.1