diff options
| author | Roy Ben-Shabat <Roy@Twine-s.com> | 2020-02-26 18:43:43 +0200 |
|---|---|---|
| committer | Roy Ben-Shabat <Roy@Twine-s.com> | 2020-02-26 18:43:43 +0200 |
| commit | 8e5ab17ced647a8c9fbba764c6fa0c06d56269c9 (patch) | |
| tree | 4d958c4775ac237f5d67803192aa530a80d978b7 /Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels | |
| parent | afb6bbb2123932b3562e1af993eb847d8147bf58 (diff) | |
| parent | 228dca3384369f23d6dcad6a696cf491ab9d8840 (diff) | |
| download | Tango-8e5ab17ced647a8c9fbba764c6fa0c06d56269c9.tar.gz Tango-8e5ab17ced647a8c9fbba764c6fa0c06d56269c9.zip | |
Merge branch 'master' of https://twinetfs.visualstudio.com/_git/Tango
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels')
3 files changed, 680 insertions, 325 deletions
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<JobRunStatisticsModel> _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<JobRunStatisticsModel> 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<JobRunStatisticsModel> 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<DateTime> 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<Color>() + { + Colors.Green, + Colors.Orange, + Colors.Red, + }, + }; + + Series completed_job_runs = new ColumnSeries() + { + Title = "Completed", + Values = new ChartValues<int>(), + Fill = Brushes.Green, + MinWidth = 1, + + }; + Series aborted_job_runs = new ColumnSeries() + { + Title = "Aborted", + Values = new ChartValues<int>(), + Fill = Brushes.Orange, + MinWidth = 1, + }; + Series failed_job_runs = new ColumnSeries() + { + Title = "Failed", + Values = new ChartValues<int>(), + Fill = Brushes.Red, + MinWidth = 1, + }; + + if (EndDate - StartDate > TimeSpan.FromDays(40)) + { + completed_job_runs = new LineSeries() + { + Title = "Completed", + Values = new ChartValues<int>(), + Fill = new SolidColorBrush(Colors.Green) { Opacity = 0.5 }, + MinWidth = 1, + PointGeometry = null, + StrokeThickness = 0, + + }; + aborted_job_runs = new LineSeries() + { + Title = "Aborted", + Values = new ChartValues<int>(), + Fill = new SolidColorBrush(Colors.Orange) { Opacity = 0.5 }, + MinWidth = 1, + PointGeometry = null, + StrokeThickness = 0, + }; + failed_job_runs = new LineSeries() + { + Title = "Failed", + Values = new ChartValues<int>(), + 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<Color> colors = new List<Color>(); + + 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<int>() { count }, + Fill = new SolidColorBrush(colors[index++]), + DataLabels = true, + ToolTip = group.First().FailedMessage, + }; + + PieJobFailedReasons.SeriesCollection.Add(series); + } + } + + private void GeneratePrintPerWeekChart() + { + List<JobRunStatisticsModel> range_job_runs = GetJobRunsByDateRange(StartDate, EndDate); + + Dictionary<Machine, List<double>> weeks_print_avg = new Dictionary<Machine, List<double>>(); + + //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<double>(); + } + + //Create all available dates + List<DateTime> 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<Machine, double> week_print_avg = new Dictionary<Machine, double>(); + + //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<Color>() + { + + }, + }; + + //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>() { (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..cf74071c9 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/JobRunsViewVM.cs @@ -0,0 +1,304 @@ +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.Builders; +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; +using Tango.AutoComplete.Editors; + +namespace Tango.MachineStudio.Statistics.ViewModels +{ + public class JobRunsViewVM : ViewModel + { + private INotificationProvider _notification; + private List<Machine> _allMachines; + private List<User> _allUsers; + private List<RmlModel> _rmlsModels; + private List<JobRun> _allJobRuns; + + #region Properties + + private ObservableCollection<JobRunModel> _jobRuns; + public ObservableCollection<JobRunModel> JobRuns + { + get { return _jobRuns; } + set + { + _jobRuns = value; + RaisePropertyChangedAuto(); + } + } + + private JobRunModel _selectedJobRun = null; + public JobRunModel SelectedJobRun + { + get { return _selectedJobRun; } + set + { + _selectedJobRun = value; + RaisePropertyChangedAuto(); + } + } + + private SelectedObjectCollection<Machine> _selectedMachines; + public SelectedObjectCollection<Machine> 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 _lengthLowerValue; + public Double LengthLowerValue + { + get { return _lengthLowerValue; } + set + { + _lengthLowerValue = value; + RaisePropertyChangedAuto(); + } + } + + protected Double _lengthUpperValue; + public Double LengthUpperValue + { + get { return _lengthUpperValue; } + set + { + _lengthUpperValue = value; + RaisePropertyChangedAuto(); + } + } + + private SelectedObjectCollection<JobSource> _jobRunSelectedSources; + public SelectedObjectCollection<JobSource> JobRunSelectedSources + { + get { return _jobRunSelectedSources; } + set { _jobRunSelectedSources = value; RaisePropertyChangedAuto(); } + } + + private SelectedObjectCollection<JobRunStatus> _jobRunSelectedStatuses; + public SelectedObjectCollection<JobRunStatus> JobRunSelectedStatuses + { + get { return _jobRunSelectedStatuses; } + set { _jobRunSelectedStatuses = value; RaisePropertyChangedAuto(); } + } + + public SelectedObjectCollection<bool> _isGradientSelection; + public SelectedObjectCollection<bool> IsGradientSelection + { + get { return _isGradientSelection; } + set + { + _isGradientSelection = value; + RaisePropertyChangedAuto(); + } + } + + private SelectedObjectCollection<RmlModel> _selectedThreads; + public SelectedObjectCollection<RmlModel> SelectedThreads + { + get { return _selectedThreads; } + set + { + _selectedThreads = value; + RaisePropertyChangedAuto(); + } + } + + /// <summary> + /// Gets or sets the JobRuns providers. + /// </summary> + public ISuggestionProvider JobRunsProvider { get; set; } + + private JobRun _jobRun; + public JobRun JobRun + { + get { return _jobRun; } + set { + _jobRun = value; + if (_jobRun != null) + { + SelectedJobName = _jobRun.JobName; + } + RaisePropertyChangedAuto(); } + } + + private string SelectedJobName { get; set; } + + + #endregion + + public RelayCommand LoadJobRunsCommand { get; set; } + + public JobRunsViewVM(INotificationProvider notificationProvider) + { + _notification = notificationProvider; + JobRuns = new ObservableCollection<JobRunModel>(); + 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<JobSource>(new ObservableCollection<JobSource>() + { + JobSource.Local, + JobSource.Remote + }, new ObservableCollection<JobSource>() + { + JobSource.Local, + JobSource.Remote + }); + JobRunSelectedSources.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(JobRunSelectedSources)); + JobRunSelectedSources.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(JobRunSelectedSources)); + + JobRunSelectedStatuses = new SelectedObjectCollection<JobRunStatus>(new ObservableCollection<JobRunStatus>() + { + JobRunStatus.Aborted, + JobRunStatus.Completed, + JobRunStatus.Failed, + + }, new ObservableCollection<JobRunStatus>() + { + JobRunStatus.Aborted, + JobRunStatus.Completed, + JobRunStatus.Failed, + + }); + JobRunSelectedStatuses.SelectionChanged -= (x,y)=> RaisePropertyChanged(nameof(JobRunSelectedStatuses)); + JobRunSelectedStatuses.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(JobRunSelectedStatuses)); + + IsGradientSelection = new SelectedObjectCollection<bool>(new ObservableCollection<bool> + { + true, + false + }, new ObservableCollection<bool> + { + 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...")) + { + try + { + IsFree = false; + + using (var db = ObservablesContext.CreateDefault()) + { + _allJobRuns = await db.JobRuns.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(); + SelectedMachines = new SelectedObjectCollection<Machine>(_allMachines.ToObservableCollection(), new ObservableCollection<Machine>()); + SelectedThreads = new SelectedObjectCollection<RmlModel>(_rmlsModels.ToObservableCollection(), new ObservableCollection<RmlModel>()); + + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading job runs."); + } + finally + { + IsFree = true; + } + } + } + + 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 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) + .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), + }).ToList(); + + modelList.ForEach(x => x.Init()); + JobRuns = modelList.ToObservableCollection(); + } + } + 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<JobRunModel> _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<JobRunModel> 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<JobRunModel> 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<DateTime> 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<Color>() - { - Colors.Green, - Colors.Orange, - Colors.Red, - }, - }; - - Series completed_job_runs = new ColumnSeries() - { - Title = "Completed", - Values = new ChartValues<int>(), - Fill = Brushes.Green, - MinWidth = 1, - - }; - Series aborted_job_runs = new ColumnSeries() - { - Title = "Aborted", - Values = new ChartValues<int>(), - Fill = Brushes.Orange, - MinWidth = 1, - }; - Series failed_job_runs = new ColumnSeries() - { - Title = "Failed", - Values = new ChartValues<int>(), - Fill = Brushes.Red, - MinWidth = 1, - }; - - if (EndDate - StartDate > TimeSpan.FromDays(40)) - { - completed_job_runs = new LineSeries() - { - Title = "Completed", - Values = new ChartValues<int>(), - Fill = new SolidColorBrush(Colors.Green) { Opacity = 0.5 }, - MinWidth = 1, - PointGeometry = null, - StrokeThickness = 0, - - }; - aborted_job_runs = new LineSeries() - { - Title = "Aborted", - Values = new ChartValues<int>(), - Fill = new SolidColorBrush(Colors.Orange) { Opacity = 0.5 }, - MinWidth = 1, - PointGeometry = null, - StrokeThickness = 0, - }; - failed_job_runs = new LineSeries() - { - Title = "Failed", - Values = new ChartValues<int>(), - 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<Color> colors = new List<Color>(); - - 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<int>() { count }, - Fill = new SolidColorBrush(colors[index++]), - DataLabels = true, - ToolTip = group.First().FailedMessage, - }; - - PieJobFailedReasons.SeriesCollection.Add(series); - } - } - - private void GeneratePrintPerWeekChart() - { - List<JobRunModel> range_job_runs = GetJobRunsByDateRange(StartDate, EndDate); - - Dictionary<Machine, List<double>> weeks_print_avg = new Dictionary<Machine, List<double>>(); - - //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<double>(); - } - - //Create all available dates - List<DateTime> 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<Machine, double> week_print_avg = new Dictionary<Machine, double>(); - - //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<Color>() - { - - }, - }; - - //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>() { (int)machine.Value }, - Fill = new SolidColorBrush(PrintPerWeekSeries.SeriesColors[index++]), - DataLabels = true, - ToolTip = machine.Key.SerialNumber, - }; - - PrintPerWeekSeries.SeriesCollection.Add(series); - } + ChartsViewVM.Init(); } } } |
