diff options
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics')
14 files changed, 608 insertions, 133 deletions
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 index 4cea7f69f..2d9a3cfd9 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/CollectionConverter .cs @@ -19,9 +19,13 @@ namespace Tango.MachineStudio.Statistics.Converters foreach(var val in colection) { string visibleText = val.ToString(); - if (val is bool) + if(val is bool && parameter is string) { - visibleText = (bool)val== true ? "Yes" : "No"; + string[] tokens = (parameter as string).Split(','); + if(tokens.Count() > 1) + { + visibleText = (bool)val == true ? tokens[1] : tokens[0]; + } } text.Append(visibleText); text.Append("/"); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidQuantityToFormatStringConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidQuantityToFormatStringConverter.cs new file mode 100644 index 000000000..3ab013ab3 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/LiquidQuantityToFormatStringConverter.cs @@ -0,0 +1,41 @@ +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 LiquidQuantityToFormatStringConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + try + { + string format = ""; + if (parameter is string) + { + format = (string)parameter; + } + + var longValue = System.Convert.ToUInt64(value.ToString()); + double liters_val = (longValue / 1000000000d); + double cc_val = (longValue / 1000000d); + double dispensers_val = (longValue / 130000000d); + string tooltip = String.Format($"Nanoliters: {longValue.ToString(format)}\nCubic Centimeters: {cc_val}\nLiters: {liters_val}\nDispensers: {dispensers_val}"); + return tooltip; + } + catch { } + + 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/NanoLiterToLiterFormatConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/NanoLiterToLiterFormatConverter.cs index 32050cdb1..97f4ec066 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/NanoLiterToLiterFormatConverter.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/NanoLiterToLiterFormatConverter.cs @@ -16,7 +16,12 @@ namespace Tango.MachineStudio.Statistics.Converters { var longValue = System.Convert.ToUInt64(value.ToString()); double val = (longValue / 1000000000d); - return val.ToString("0.0"); + if (parameter is string) + { + string format= (string)parameter; + return val.ToString(format); + } + return val.ToString(); } catch { } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/TooltipLiquidQuantityFormatConverter.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/TooltipLiquidQuantityFormatConverter.cs new file mode 100644 index 000000000..6c4d1347f --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Converters/TooltipLiquidQuantityFormatConverter.cs @@ -0,0 +1,38 @@ +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 +{ + class TooltipLiquidQuantityFormatConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + try + { + string format = ""; + if (parameter is string) + { + format = (string)parameter; + } + var longValue = System.Convert.ToUInt64(value.ToString()); + decimal liters_val = (decimal)(longValue / 1000000000d); + decimal cc_val = (decimal)(longValue / 1000000d); + decimal dispensers_val = (decimal)(longValue / 130000000d); + string tooltip = String.Format($"Nanoliters: {longValue.ToString(format)}\nCubic Centimeters: {cc_val}\nLiters: {liters_val}\nDispensers: {dispensers_val}"); + return tooltip; + } + catch { } + + 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/Models/ExcelModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/ExcelModel.cs new file mode 100644 index 000000000..f06b9fe60 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Models/ExcelModel.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Statistics.Models +{ + public class ExcelModel + { + public String ID { get; set; } + public String Machine { get; set; } + public String User { get; set; } + public String JobName { get; set; } + public String Thread { get; set; } + public String Length { get; set; } + public String Source { get; set; } + public String UploadDuration { get; set; } + public String HeatingDuration { get; set; } + public String StartTime { get; set; } + public String IsGradient { get; set; } + public String GR { get; set; } + public String Status { get; set; } + public String EndTime { get; set; } + public String EndPosition { get; set; } + public String Cyan { get; set; } + public String Magenta { get; set; } + public String Yellow { get; set; } + public String Black { get; set; } + public String Transparent { get; set; } + public String Lubricant { get; set; } + public String Cleaner { 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 f77dbd482..4ce0ea87d 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 @@ -79,11 +79,14 @@ <Compile Include="Converters\CollectionConverter .cs" /> <Compile Include="Converters\DateTimeToStringFormatConverter.cs" /> <Compile Include="Converters\JobLengthConverter.cs" /> + <Compile Include="Converters\LiquidQuantityToFormatStringConverter.cs" /> <Compile Include="Converters\LiquidTypeToColorConverter.cs" /> <Compile Include="Converters\MidTankLevelToElementHeightConverter.cs" /> <Compile Include="Converters\NanoLiterToLiterFormatConverter.cs" /> <Compile Include="Converters\StringToBoolYesNoNullConverter.cs" /> <Compile Include="Converters\StringToFirstLetterConverter.cs" /> + <Compile Include="Converters\TooltipLiquidQuantityFormatConverter.cs" /> + <Compile Include="Models\ExcelModel.cs" /> <Compile Include="Models\TotalLiquidQuantityModel.cs" /> <Compile Include="Models\JobRunModel.cs" /> <Compile Include="Models\JobRunStatisticsModel.cs" /> @@ -94,6 +97,7 @@ <DependentUpon>PieChartTooltipControl.xaml</DependentUpon> </Compile> <Compile Include="StatisticsModule.cs" /> + <Compile Include="ValidationRules\DateExpiredRule.cs" /> <Compile Include="ViewModelLocator.cs" /> <Compile Include="ViewModels\ChartsViewVM.cs" /> <Compile Include="ViewModels\JobRunsViewVM.cs" /> @@ -172,6 +176,10 @@ <Project>{a34ee0f0-649d-41c8-8489-b6f1cc6924ee}</Project> <Name>Tango.Core</Name> </ProjectReference> + <ProjectReference Include="..\..\..\Tango.CSV\Tango.CSV.csproj"> + <Project>{58e8825f-0c96-449c-b320-1e82b0aa876b}</Project> + <Name>Tango.CSV</Name> + </ProjectReference> <ProjectReference Include="..\..\..\Tango.Logging\Tango.Logging.csproj"> <Project>{bc932dbd-7cdb-488c-99e4-f02cf441f55e}</Project> <Name>Tango.Logging</Name> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tooltips/PieChartTooltipControl.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tooltips/PieChartTooltipControl.xaml index 07f1308ec..b03f02249 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tooltips/PieChartTooltipControl.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Tooltips/PieChartTooltipControl.xaml @@ -7,7 +7,7 @@ mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> - <Border Padding="10" Background="White" CornerRadius="5" BorderThickness="1" BorderBrush="Silver" MaxWidth="400"> + <Border Padding="10" Background="{StaticResource TransparentBackgroundBrush450}" CornerRadius="5" BorderThickness="1" BorderBrush="{StaticResource borderBrush}" MaxWidth="400"> <TextBlock Text="{Binding Title}" TextWrapping="Wrap"></TextBlock> </Border> </Grid> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ValidationRules/DateExpiredRule.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ValidationRules/DateExpiredRule.cs new file mode 100644 index 000000000..98b90f855 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ValidationRules/DateExpiredRule.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Controls; + + +namespace Tango.MachineStudio.Statistics.ValidationRules +{ + public class DateExpiredRule : ValidationRule + { + public override ValidationResult Validate(object value, CultureInfo cultureInfo) + { + DateTime orderDate = (DateTime)value; + + return new ValidationResult(orderDate < DateTime.Now, "Please enter a date until today."); + } + } +} 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 index 38c1cc24a..a98257086 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/ViewModels/ChartsViewVM.cs @@ -49,30 +49,16 @@ namespace Tango.MachineStudio.Statistics.ViewModels public DateTime StartDate { get { return _startDate; } - set { _startDate = value; RaisePropertyChangedAuto();} + set { _startDate = value; RaisePropertyChangedAuto(); RaisePropertyChanged("EndDate"); } } private DateTime _endDate; public DateTime EndDate { get { return _endDate; } - set { _endDate = value; RaisePropertyChangedAuto();} + set { _endDate = value; RaisePropertyChangedAuto(); RaisePropertyChanged("StartDate"); } } - - 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 RelayCommand LoadJobRunsCommand { get; set; } #endregion @@ -85,41 +71,7 @@ namespace Tango.MachineStudio.Statistics.ViewModels } #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 async Task LoadJobRuns() { using (_notification.PushTaskItem("Loading statistics...")) @@ -127,25 +79,24 @@ namespace Tango.MachineStudio.Statistics.ViewModels try { IsFree = false; - + await Task.Factory.StartNew(() => { using (var db = ObservablesContext.CreateDefault()) { - _job_runs = db.JobRuns.OrderBy(x => x.StartDate).ToList().Select(x => new JobRunStatisticsModel(x)).ToList(); + DateTime startUtc = new DateTime(StartDate.Year, StartDate.Month, StartDate.Day, 0, 0, 0).ToUniversalTime(); + TimeSpan offsetTime = (EndDate.Date == DateTime.Now.Date) ? DateTime.Now.TimeOfDay : new TimeSpan(23, 59, 59); + DateTime endUtc = EndDate.ToUniversalTime() + offsetTime; + + _job_runs = db.JobRuns.Where(x => (x.StartDate <= endUtc && x.StartDate >= startUtc)).OrderBy(x => x.StartDate).ToList().Select(x => new JobRunStatisticsModel(x)).ToList(); + foreach (var run in _job_runs) { run.LoadMachine(db).GetAwaiter().GetResult(); } - } }); - if (_job_runs.Count > 0) - { - MinDate = _job_runs.Min(x => x.StartDate); - MaxDate = _job_runs.Max(x => x.StartDate); - } - + InvokeUIOnIdle(() => { if (_loaded) @@ -400,7 +351,7 @@ namespace Tango.MachineStudio.Statistics.ViewModels #region Filter by Date public void OnDateRangeChanged() { - if (_job_runs != null && _job_runs.Count > 0)// && _loaded) + if (_job_runs != null)// && _job_runs.Count > 0)// && _loaded) { GenerateTimelineJobStatusChart(); GeneratePieFailedReasonsChart(); 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 800346ff9..ae1592d8d 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 @@ -21,9 +21,23 @@ using LiveCharts.Wpf; using LiveCharts; using Tango.BL.ValueObjects; using System.Diagnostics; +using Microsoft.Win32; +using Tango.CSV; +using System.ComponentModel; namespace Tango.MachineStudio.Statistics.ViewModels { + public enum HeadCleaningSelectionEnum + { + [Description("Exclude")] + Exclude = 0, + [Description("Include")] + Include = 1, + [Description("Only")] + Only = 2 + }; + + public class JobRunsViewVM : ViewModel { private INotificationProvider _notification; @@ -31,6 +45,8 @@ namespace Tango.MachineStudio.Statistics.ViewModels private List<User> _allUsers; private List<RmlModel> _rmlsModels; + + #region Properties private ObservableCollection<JobRunModel> _jobRuns; @@ -83,7 +99,8 @@ namespace Tango.MachineStudio.Statistics.ViewModels { get { return _startSelectedDate; } set { _startSelectedDate = value; - RaisePropertyChangedAuto(); } + RaisePropertyChangedAuto(); + } } private DateTime _endSelectedDate; @@ -172,6 +189,19 @@ namespace Tango.MachineStudio.Statistics.ViewModels } } + private HeadCleaningSelectionEnum _headCleaningSelected; + + public HeadCleaningSelectionEnum HeadCleaningSelected + { + get { return _headCleaningSelected; } + set + { + _headCleaningSelected = value; + RaisePropertyChangedAuto(); + } + } + + /// <summary> /// Gets or sets the JobRuns providers. /// </summary> @@ -200,12 +230,15 @@ namespace Tango.MachineStudio.Statistics.ViewModels public RelayCommand LoadJobRunsCommand { get; set; } + public RelayCommand ExportToExcelCommand { get; set; } + public JobRunsViewVM(INotificationProvider notificationProvider) { _notification = notificationProvider; JobRuns = new ObservableCollection<JobRunModel>(); LoadJobRunsCommand = new RelayCommand(async () => await LoadJobRuns(), () => IsFree); - LengthUpperValue = 5000.0; + ExportToExcelCommand = new RelayCommand(ExportToExcel, () => IsFree); + LengthUpperValue = 10000.0; LengthLowerValue = 0.0; DateTime now = DateTime.Now; StartSelectedDate = now.AddMonths(-1); @@ -250,6 +283,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels }); IsGradientSelection.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); IsGradientSelection.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(IsGradientSelection)); + + HeadCleaningSelected = HeadCleaningSelectionEnum.Exclude; + JobsProvider = new SuggestionProvider((filter) => { try @@ -305,8 +341,9 @@ namespace Tango.MachineStudio.Statistics.ViewModels IsFree = true; } } + } - + /// <summary> /// Loads the job runs by filters. /// </summary> @@ -353,7 +390,8 @@ namespace Tango.MachineStudio.Statistics.ViewModels x.BlackQuantity, x.TransparentQuantity, x.LubricantQuantity, - x.CleanerQuantity + x.CleanerQuantity, + x.IsHeadCleaning }); var machineIDs = new HashSet<string>(SelectedMachines.SynchedSource.ToList().Select(p => p.Guid)); if (machineIDs.Count > 0) @@ -375,6 +413,13 @@ namespace Tango.MachineStudio.Statistics.ViewModels { db_JobRuns = db_JobRuns.Where(x => isGradientArr.Contains(x.IsGradient)); } + + if(HeadCleaningSelected != HeadCleaningSelectionEnum.Include) + { + bool isHeadCleaning = HeadCleaningSelected == HeadCleaningSelectionEnum.Only; + db_JobRuns = db_JobRuns.Where(x => isHeadCleaning == x.IsHeadCleaning); + } + List<String> rmlGuids = SelectedThreads.SynchedSource.Select(y => y.Guid).ToList(); if (rmlGuids != null && rmlGuids.Count > 0) { @@ -415,7 +460,8 @@ namespace Tango.MachineStudio.Statistics.ViewModels BlackQuantity = x.BlackQuantity, TransparentQuantity = x.TransparentQuantity, LubricantQuantity = x.LubricantQuantity, - CleanerQuantity = x.CleanerQuantity + CleanerQuantity = x.CleanerQuantity, + IsHeadCleaning = x.IsHeadCleaning }).ToList(); var modelList = runs.Select(x => new JobRunModel() @@ -444,12 +490,91 @@ namespace Tango.MachineStudio.Statistics.ViewModels } } - #region GenerateS_StatisticsValueCollection + private void ExportToExcel() + { + SaveFileDialog dlg = new SaveFileDialog(); + dlg.Title = "Job Runs Statistic Report"; + dlg.Filter = "CSV Files|*.csv"; + dlg.FileName = $"Statistics_Job_runs"; + dlg.DefaultExt = ".csv"; + if (dlg.ShowDialog().Value) + { + try + { + CsvFile<ExcelModel> csvFile = new CsvFile<ExcelModel>(new CsvDestination(dlg.FileName), new CsvDefinition() + { + Columns = new List<String>() + { + "ID", + "Machine", + "User", + "Job Name", + "Thread", + "Length", + "Source", + "Upload Duration", + "Heating Duration", + "Start Time", + "IsGradient", + "Gradient Resolution", + "Status", + "End Date", + "End Position", + "Cyan", + "Magenta", + "Yellow", + "Black", + "Transparent", + "Lubricant", + "Cleaner" + }, + }); + var selection = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.JobRun.EndDate != null && z.JobRun.ActualStartDate != null); + foreach (var jobRunModel in selection) + { + ExcelModel excel_model = new ExcelModel(); + excel_model.ID = jobRunModel.JobRun.ID.ToString(); + excel_model.Machine = jobRunModel.Machine != null ? jobRunModel.Machine.SerialNumber : ""; + excel_model.User = jobRunModel.User != null ? jobRunModel.User.Contact.FullName: ""; + excel_model.JobName = jobRunModel.JobRun.JobName; + excel_model.Thread = jobRunModel.Rml != null ? jobRunModel.Rml.Name : ""; + excel_model.Length = String.Format("{0:0.##}", jobRunModel.JobRun.JobLength); + excel_model.Source = jobRunModel.JobRun.Source.ToString(); + excel_model.UploadDuration = jobRunModel.UploadDuration != null ? ((TimeSpan)(jobRunModel.UploadDuration)).ToString(@"hh\:mm\:ss") : TimeSpan.FromSeconds(0).ToString(@"hh\:mm\:ss"); + excel_model.HeatingDuration = jobRunModel.HeatingDuration != null ? ((TimeSpan)(jobRunModel.HeatingDuration)).ToString(@"hh\:mm\:ss") : TimeSpan.FromSeconds(0).ToString(@"hh\:mm\:ss"); + excel_model.StartTime = jobRunModel.JobRun.ActualStartDate != null ? ((DateTime)jobRunModel.JobRun.ActualStartDate).ToLocalTime().ToString("MM/dd/yy HH:mm"): ""; + excel_model.IsGradient = jobRunModel.JobRun.IsGradient ? "Yes" : "No"; + excel_model.GR = jobRunModel.JobRun.GradientResolutionCm.ToString(); + excel_model.Status = jobRunModel.JobRun.JobRunStatus.ToString(); + excel_model.EndTime = jobRunModel.JobRun.EndDate != null ? ((DateTime)jobRunModel.JobRun.EndDate).ToLocalTime().ToString("MM/dd/yy HH:mm"): ""; + excel_model.EndPosition = String.Format("{0:0.##}", jobRunModel.JobRun.EndPosition); + excel_model.Cyan = jobRunModel.JobRun.CyanQuantity < 0 ? "" :jobRunModel.JobRun.CyanQuantity.ToString(); + excel_model.Magenta = jobRunModel.JobRun.MagentaQuantity < 0 ? "" : jobRunModel.JobRun.MagentaQuantity.ToString(); + excel_model.Yellow = jobRunModel.JobRun.YellowQuantity < 0 ? "" : jobRunModel.JobRun.YellowQuantity.ToString(); + excel_model.Black = jobRunModel.JobRun.BlackQuantity < 0 ? "" : jobRunModel.JobRun.BlackQuantity.ToString(); + excel_model.Transparent = jobRunModel.JobRun.TransparentQuantity < 0 ? "" : jobRunModel.JobRun.TransparentQuantity.ToString(); + excel_model.Lubricant = jobRunModel.JobRun.LubricantQuantity < 0 ? "" : jobRunModel.JobRun.LubricantQuantity.ToString(); + excel_model.Cleaner = jobRunModel.JobRun.CleanerQuantity < 0 ? "" : jobRunModel.JobRun.CleanerQuantity.ToString(); + csvFile.Append(excel_model); + + } - /// <summary> - /// Generates the statistics. - /// </summary> - protected void GenerateStatistics() + csvFile.Dispose(); + _notification.ShowInfo("Report generated successfully."); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error generating Statistics Job Runs report."); + _notification.ShowError($"Error generating Statistics Job Runs report..\n{ex.Message}"); + } + } + } + #region GenerateS_StatisticsValueCollection + + /// <summary> + /// Generates the statistics. + /// </summary> + protected void GenerateStatistics() { StatisticsValueCollection.Clean(); if (JobRuns.Count() == 0) @@ -495,7 +620,7 @@ namespace Tango.MachineStudio.Statistics.ViewModels average = selection.Average(x => (x.JobRun.EndDate - x.JobRun.ActualStartDate).Value.TotalMilliseconds); } StatisticsValueCollection.AddStatisticsValue("Total Dyeing Time", val, " hours"); - StatisticsValueCollection.AddStatisticsValue("Total Dyeing Time", Math.Max(TimeSpan.FromMilliseconds(average).TotalHours, 0), " hours"); + StatisticsValueCollection.AddStatisticsValue("Average Dyeing Time", Math.Max(TimeSpan.FromMilliseconds(average).TotalHours, 0), " hours"); } /// <summary> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml index ae4bf1d46..b76154941 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml @@ -6,6 +6,7 @@ xmlns:vm="clr-namespace:Tango.MachineStudio.Statistics.ViewModels" xmlns:global="clr-namespace:Tango.MachineStudio.Statistics" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:localrule="clr-namespace:Tango.MachineStudio.Statistics.ValidationRules" xmlns:local="clr-namespace:Tango.MachineStudio.Statistics.Views" xmlns:tooltips="clr-namespace:Tango.MachineStudio.Statistics.Tooltips" xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" @@ -21,14 +22,45 @@ <StackPanel Margin="60 20 0 0" VerticalAlignment="Center" HorizontalAlignment="Left" Orientation="Horizontal" DockPanel.Dock="Left"> <StackPanel> <TextBlock FontSize="10">Start Date:</TextBlock> - <DatePicker DisplayDateStart="{Binding MinDate}" DisplayDateEnd="{Binding MaxDate}" SelectedDate="{Binding StartDate}" materialDesign:HintAssist.Hint="Pick start date" Width="200" VerticalAlignment="Bottom" FontSize="16"></DatePicker> + <DatePicker x:Name="startdatePicker" SelectedDateChanged="StartDatePicker_SelectedDateChanged" materialDesign:HintAssist.Hint="Pick start date" Width="200" VerticalAlignment="Bottom" FontSize="16"> + <DatePicker.SelectedDate> + <Binding Path="StartDate" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> + <Binding.ValidationRules> + <localrule:DateExpiredRule x:Name="StartDateExpiredRule"/> + </Binding.ValidationRules> + </Binding> + </DatePicker.SelectedDate> + </DatePicker> </StackPanel> <StackPanel Margin="40 0 0 0"> <TextBlock FontSize="10">End Date:</TextBlock> - <DatePicker DisplayDateStart="{Binding MinDate}" DisplayDateEnd="{Binding MaxDate}" SelectedDate="{Binding EndDate}" materialDesign:HintAssist.Hint="Pick end date" Width="200" VerticalAlignment="Bottom" FontSize="16"></DatePicker> + <DatePicker x:Name="endDatePicker" materialDesign:HintAssist.Hint="Pick end date" Width="200" VerticalAlignment="Bottom" FontSize="16" SelectedDateChanged="EndDatePicker_SelectedDateChanged"> + <DatePicker.SelectedDate> + <Binding Path="EndDate" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> + <Binding.ValidationRules> + <localrule:DateExpiredRule x:Name="EndDateExpiredRule"/> + </Binding.ValidationRules> + </Binding> + </DatePicker.SelectedDate> + </DatePicker> </StackPanel> - <Button Width="100" Margin="60 0 0 0" Command="{Binding LoadJobRunsCommand}" VerticalAlignment="Bottom" HorizontalAlignment="Right">LOAD</Button> + <Button Width="100" Margin="60 0 0 0" Command="{Binding LoadJobRunsCommand}" VerticalAlignment="Bottom" HorizontalAlignment="Right" Content="LOAD"> + <Button.Style> + <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}"> + <Setter Property="IsEnabled" Value="False"/> + <Style.Triggers> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding Path=(Validation.HasError), Source={x:Reference startdatePicker}}" Value="False"/> + <Condition Binding="{Binding Path=(Validation.HasError), Source={x:Reference endDatePicker}}" Value="False"/> + </MultiDataTrigger.Conditions> + <Setter Property="IsEnabled" Value="True"/> + </MultiDataTrigger> + </Style.Triggers> + </Style> + </Button.Style> + </Button> </StackPanel> diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml.cs index d79d88281..bd97ed2bc 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/ChartsView.xaml.cs @@ -31,5 +31,44 @@ namespace Tango.MachineStudio.Statistics.Views var tooltip = ((chartPoint.ChartView as PieChart).DataTooltip as Tooltips.PieChartTooltipControl).Title; txtPieTitle.Text = tooltip; } + private void StartDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e) + { + DatePicker datePickerObj = sender as DatePicker; + if (datePickerObj != null && datePickerObj.SelectedDate != null && endDatePicker.SelectedDate != null) + { + if (datePickerObj.SelectedDate > endDatePicker.SelectedDate) + { + BindingExpression start_be = datePickerObj.GetBindingExpression(DatePicker.SelectedDateProperty); + ValidationError validationError = new ValidationError(StartDateExpiredRule, start_be); + validationError.ErrorContent = "The start time must be less than or equal to end time."; + Validation.MarkInvalid(start_be, validationError); + } + else if (Validation.GetHasError(endDatePicker)) + { + BindingExpression end_be = endDatePicker.GetBindingExpression(DatePicker.SelectedDateProperty); + Validation.ClearInvalid(end_be); + } + } + } + + private void EndDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e) + { + DatePicker datePickerObj = sender as DatePicker; + if (datePickerObj.SelectedDate != null && startdatePicker.SelectedDate != null) + { + if (datePickerObj != null && datePickerObj.SelectedDate < startdatePicker.SelectedDate) + { + BindingExpression end_be = datePickerObj.GetBindingExpression(DatePicker.SelectedDateProperty); + ValidationError validationError = new ValidationError(EndDateExpiredRule, end_be); + validationError.ErrorContent = "The end time must be greater than or equal to the start time."; + Validation.MarkInvalid(end_be, validationError); + } + else if (Validation.GetHasError(startdatePicker)) + { + BindingExpression start_be = startdatePicker.GetBindingExpression(DatePicker.SelectedDateProperty); + Validation.ClearInvalid(start_be); + } + } + } } } 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 6431d72fb..bc99c1bfa 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 @@ -6,14 +6,17 @@ xmlns:sharedConverters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:localConverters="clr-namespace:Tango.MachineStudio.Statistics.Converters" + xmlns:localrule="clr-namespace:Tango.MachineStudio.Statistics.ValidationRules" xmlns:mahapps="http://metro.mahapps.com/winfx/xaml/controls" xmlns:autoComplete="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete" xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" xmlns:tooltips="clr-namespace:Tango.MachineStudio.Statistics.Tooltips" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:enumerations="clr-namespace:Tango.BL.Enumerations;assembly=Tango.BL" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" xmlns:local="clr-namespace:Tango.MachineStudio.Statistics.Views" xmlns:model="clr-namespace:Tango.MachineStudio.Statistics.Models" + xmlns:vs="clr-namespace:Tango.MachineStudio.Statistics.ViewModels" xmlns:wellknowntypes="clr-namespace:Google.Protobuf.WellKnownTypes;assembly=Google.Protobuf" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="1800" Foreground="{StaticResource JobFieldForeground}"> @@ -30,6 +33,8 @@ <localConverters:MidTankLevelToElementHeightConverter x:Key="MidTankLevelToElementHeightConverter"/> <localConverters:JobLengthConverter x:Key="JobLengthConverter"/> <localConverters:NanoLiterToLiterFormatConverter x:Key="NanoLiterToLiterFormatConverter"/> + <localConverters:LiquidQuantityToFormatStringConverter x:Key="LiquidQuantityToFormatStringConverter"/> + <localConverters:TooltipLiquidQuantityFormatConverter x:Key="TooltipLiquidQuantityFormatConverter"/> <ResourceDictionary x:Key="SelectAllTextBoxResource"> <Style TargetType="TextBox"> @@ -38,6 +43,12 @@ </Style> </ResourceDictionary> + <ObjectDataProvider x:Key="HeadCleaning" MethodName="GetValues" ObjectType="{x:Type sys:Enum}"> + <ObjectDataProvider.MethodParameters> + <x:Type TypeName="vs:HeadCleaningSelectionEnum"/> + </ObjectDataProvider.MethodParameters> + </ObjectDataProvider> + <Style TargetType="{x:Type TextBlock}" x:Key="WrapText"> <Setter Property="TextWrapping" Value="Wrap"/> </Style> @@ -51,39 +62,23 @@ <Setter Property="Background" Value="Transparent"/> <Setter Property="LegendLocation" Value="None"/> </Style> - + <DataTemplate x:Key="PopUpDataTemplate"> - <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}"> + <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" Click="CheckBox_StayChecked" Tag="{Binding Path=ItemsSource, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}},Mode=OneWay}"> <CheckBox.Content> <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data}"></TextBlock> </CheckBox.Content> </CheckBox> </DataTemplate> - <DataTemplate x:Key="PopUpSNDataTemplate"> - <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" > - <CheckBox.Content> - <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data.SerialNumber}" ToolTip="{Binding Data.SerialNumber}" FontFamily="{StaticResource FontName}"></TextBlock> - </CheckBox.Content> - </CheckBox> - </DataTemplate> - <DataTemplate x:Key="PopupBoolDataTemplate"> - <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}"> + <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" Click="CheckBox_StayChecked" Tag="{Binding Path=ItemsSource, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}},Mode=OneWay}"> <CheckBox.Content> <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data, Converter={StaticResource BooleanToYesNoConverter}}"/> </CheckBox.Content> </CheckBox> </DataTemplate> - <DataTemplate x:Key="PopupThreadDataTemplate"> - <CheckBox VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected}" > - <CheckBox.Content> - <TextBlock Margin="5 0 5 0" VerticalAlignment="Center" Text="{Binding Data.Name}" ToolTip="{Binding Data.Name}" FontFamily="{StaticResource FontName}" FontSize="11"></TextBlock> - </CheckBox.Content> - </CheckBox> - </DataTemplate> - <Style x:Key="{x:Type ToolTip}" TargetType="{x:Type ToolTip}" BasedOn="{StaticResource MaterialDesignToolTip}"> <Setter Property="Background" Value="{StaticResource Logging.Background}" /> @@ -146,13 +141,18 @@ </DockPanel> </Border> <Popup AllowsTransparency="True" StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }"> - <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="#F6F6F6" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > + <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> - <ScrollViewer MaxHeight="600" Background="#F6F6F6" > - <ItemsControl ItemsSource="{Binding SelectedMachines}" Foreground="{StaticResource MainWindow.Foreground}" ItemTemplate="{StaticResource PopUpSNDataTemplate}"/> - </ScrollViewer> + <controls:AllSelectedCheckboxList Style="{StaticResource AllSelectedCheckBoxListStyle}" MaxHeight="600" ItemsSource="{Binding SelectedMachines}" Background="{StaticResource ComboBox.Floating.Background}" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionMode="Multiple" AllSelected="True" FontSize="11" FontFamily="{StaticResource FontName}"> + <controls:AllSelectedCheckboxList.ItemTemplate> + <DataTemplate > + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data.SerialNumber}" ToolTip="{Binding Data.SerialNumber}" FontFamily="{StaticResource FontName}" Background="{DynamicResource TransparentBackgroundBrush}" FontSize="11"></TextBlock> + + </DataTemplate> + </controls:AllSelectedCheckboxList.ItemTemplate> + </controls:AllSelectedCheckboxList> </Border> </Popup> </Grid> @@ -161,13 +161,30 @@ </ToggleButton> </StackPanel> - <StackPanel Margin="50 10 0 0" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" HorizontalAlignment="Center"> <TextBlock FontSize="11">Start Date:</TextBlock> - <DatePicker x:Name="startdatePicker" Margin="0 5 0 0" SelectedDate="{Binding StartSelectedDate}" materialDesign:HintAssist.Hint="Pick start date" Width="130" VerticalAlignment="Center" FontSize="11" /> + <DatePicker x:Name="startdatePicker" SelectedDateChanged="StartDatePicker_SelectedDateChanged" Margin="0 5 0 0" materialDesign:HintAssist.Hint="Pick start date" Width="130" VerticalAlignment="Center" FontSize="11" > + <DatePicker.SelectedDate> + <Binding Path="StartSelectedDate" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> + <Binding.ValidationRules> + <localrule:DateExpiredRule x:Name="StartDateExpiredRule"/> + </Binding.ValidationRules> + </Binding> + </DatePicker.SelectedDate> + </DatePicker> </StackPanel> - <StackPanel Margin="50 10 0 0" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" HorizontalAlignment="Center"> <TextBlock FontSize="11">End Date:</TextBlock> - <DatePicker x:Name="endDatePicker" Margin="0 5 0 0" SelectedDate="{Binding EndSelectedDate}" materialDesign:HintAssist.Hint="Pick end date" Width="130" VerticalAlignment="Center" FontSize="11" /> + <DatePicker x:Name="endDatePicker" Margin="0 5 0 0" materialDesign:HintAssist.Hint="Pick end date" Width="130" VerticalAlignment="Center" FontSize="11" SelectedDateChanged="EndDatePicker_SelectedDateChanged"> + <DatePicker.SelectedDate> + <Binding Path="EndSelectedDate" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True"> + <Binding.ValidationRules> + <localrule:DateExpiredRule x:Name="EndDateExpiredRule"/> + </Binding.ValidationRules> + </Binding> + </DatePicker.SelectedDate> + + </DatePicker> </StackPanel> </StackPanel> @@ -184,7 +201,7 @@ </autoComplete:AutoCompleteTextBox.ItemTemplate> </autoComplete:AutoCompleteTextBox> </StackPanel> - <StackPanel Margin="50 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> <TextBlock Text="Source:" VerticalAlignment="Center" FontSize="11"></TextBlock> <ToggleButton Width="130" Height="24" Margin="0 10 0 0" x:Name="selectJobRunSources" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> <ToggleButton.Template> @@ -199,7 +216,7 @@ </DockPanel> </Border> <Popup AllowsTransparency="True" StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }"> - <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="#F6F6F6" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > + <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="{StaticResource TransparentBackgroundBrush200}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> @@ -212,7 +229,7 @@ </ToggleButton.Template> </ToggleButton> </StackPanel> - <StackPanel Margin="50 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> <TextBlock Text="Gradient:" VerticalAlignment="Center" FontSize="11"></TextBlock> <ToggleButton Height="24" Width="130" Margin="0 10 0 0" x:Name="selectIsGradient" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> <ToggleButton.Template> @@ -224,12 +241,12 @@ <materialDesign:PackIcon Width="16" Height="16" Kind="ChevronDown" VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Right"/> </Button> <TextBlock VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" FontSize="11" Margin="5 0 2 0"> - <Run Text="{Binding IsGradientSelection.SynchedSource, Converter={StaticResource CollectionConverter}}"></Run> + <Run Text="{Binding IsGradientSelection.SynchedSource, Converter={StaticResource CollectionConverter}, ConverterParameter='No, Yes'}"></Run> </TextBlock> </DockPanel> </Border> <Popup AllowsTransparency="True" StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }"> - <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="#F6F6F6" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}"> + <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="{StaticResource TransparentBackgroundBrush200}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}"> <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> @@ -242,12 +259,12 @@ </ToggleButton.Template> </ToggleButton> </StackPanel> - <StackPanel Margin="40 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> <TextBlock Text="Length:" VerticalAlignment="Center" FontSize="11"></TextBlock> <Border BorderThickness="1" CornerRadius="3" BorderBrush="{StaticResource borderBrush}" Margin="0 10 0 0" Height="24" Padding="10 0"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding LengthLowerValue, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" FontSize="11" Width="30"></TextBlock> - <mahapps:RangeSlider Focusable="True" Height="40" Margin="5 5 5 5" Minimum="0" Maximum="5000" Width="140" ExtendedMode="True" + <mahapps:RangeSlider Focusable="True" Height="40" Margin="5 5 5 5" Minimum="0" Maximum="10000" Width="140" ExtendedMode="True" LowerValue="{Binding LengthLowerValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" UpperValue="{Binding LengthUpperValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" IsSnapToTickEnabled="True" FontSize="8"/> @@ -255,7 +272,7 @@ </StackPanel> </Border> </StackPanel> - <StackPanel Margin="40 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> <TextBlock Text="Status:" VerticalAlignment="Center" FontSize="11"></TextBlock> <ToggleButton Height="24" Width="170" Margin="0 10 0 0" x:Name="selectJobRunStatus" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> <ToggleButton.Template> @@ -270,7 +287,7 @@ </DockPanel> </Border> <Popup AllowsTransparency="True" StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }"> - <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="#F6F6F6" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > + <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="{StaticResource TransparentBackgroundBrush200}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}" > <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> @@ -282,9 +299,9 @@ </ToggleButton.Template> </ToggleButton> </StackPanel> - <StackPanel Margin="40 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> <TextBlock Text="Threads:" VerticalAlignment="Center" FontSize="11"></TextBlock> - <ToggleButton Width="140" Margin="0 10 0 0" x:Name="selectThreadsButton" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> + <ToggleButton Width="100" Margin="0 10 0 0" x:Name="selectThreadsButton" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> <ToggleButton.Template> <ControlTemplate> <Grid> @@ -313,10 +330,52 @@ <Border.Effect> <DropShadowEffect Opacity="0.2" /> </Border.Effect> - <ScrollViewer MaxHeight="600" Background="#F6F6F6"> - <ItemsControl ItemsSource="{Binding SelectedThreads}" Foreground="{StaticResource MainWindow.Foreground}" ItemTemplate="{StaticResource PopupThreadDataTemplate}"/> - - </ScrollViewer> + <controls:AllSelectedCheckboxList Style="{StaticResource AllSelectedCheckBoxListStyle}" MaxHeight="600" ItemsSource="{Binding SelectedThreads}" Background="{StaticResource ComboBox.Floating.Background}" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" SelectionMode="Multiple" AllSelected="True" FontSize="11" FontFamily="{StaticResource FontName}"> + <controls:AllSelectedCheckboxList.ItemTemplate> + <DataTemplate > + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Data.Name}" ToolTip="{Binding Data.Name}" FontFamily="{StaticResource FontName}"></TextBlock> + </DataTemplate> + </controls:AllSelectedCheckboxList.ItemTemplate> + </controls:AllSelectedCheckboxList> + </Border> + </Popup> + </Grid> + </ControlTemplate> + </ToggleButton.Template> + </ToggleButton> + </StackPanel> + <StackPanel Margin="30 10 0 0" Orientation="Vertical" HorizontalAlignment="Center"> + <TextBlock Text="HeadCleaning:" VerticalAlignment="Center" FontSize="11"></TextBlock> + <ToggleButton Height="24" Width="120" Margin="0 10 0 0" x:Name="isHeadCleaningToggleButton" HorizontalAlignment="Left" FontSize="16" VerticalAlignment="Center"> + <ToggleButton.Template> + <ControlTemplate> + <Grid> + <Border CornerRadius="3" BorderBrush="{StaticResource borderBrush}" BorderThickness="1" TextElement.Foreground="Black" > + <DockPanel> + <Button x:Name="IsHeadCleaningButton" Width="18" Padding="0" Height="16" DockPanel.Dock="Right" BorderBrush="{x:Null}" HorizontalAlignment="Left" Click="IsHeadCleaningButton_Click" Style="{StaticResource MaterialDesignFlatButton}" Foreground="{StaticResource MainWindow.Foreground}"> + <materialDesign:PackIcon Width="16" Height="16" Kind="ChevronDown" VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" HorizontalAlignment="Right"/> + </Button> + <TextBlock VerticalAlignment="Center" Foreground="{StaticResource MainWindow.Foreground}" FontSize="11" Margin="5 0 2 0" Text="{Binding HeadCleaningSelected, Converter={StaticResource EnumToDescriptionConverter}}"> + + </TextBlock> + </DockPanel> + </Border> + <Popup AllowsTransparency="True" StaysOpen="False" IsOpen="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=IsChecked }"> + <Border Padding="3" CornerRadius="0 0 3 3" MinWidth="{Binding RelativeSource={RelativeSource AncestorType=ToggleButton},Path=Width}" Margin="5" Background="{StaticResource TransparentBackgroundBrush200}" BorderBrush="{StaticResource AutoCompleteTextBox.Popup.BorderBrush}"> + <Border.Effect> + <DropShadowEffect Opacity="0.2" /> + </Border.Effect> + <ListBox x:Name="HeadCleaningListBoxItem" ItemsSource="{Binding Source={StaticResource HeadCleaning}}" Foreground="{StaticResource MainWindow.Foreground}" SelectedItem="{Binding HeadCleaningSelected, Mode=TwoWay}" SelectionMode="Single" > + <ListBox.ItemTemplate> + <DataTemplate> + <CheckBox x:Name="HeadCleaningCheckBox" Selector.IsSelected="True" VerticalAlignment="Center" FontSize="11" DockPanel.Dock="Left" IsChecked="{Binding IsSelected, Mode=TwoWay, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, UpdateSourceTrigger=PropertyChanged}" Click="CheckBox_PreventUndoCheck"> + <CheckBox.Content> + <TextBlock Margin="5 0 0 0" VerticalAlignment="Center" Text="{Binding Converter={StaticResource EnumToDescriptionConverter}}"/> + </CheckBox.Content> + </CheckBox> + </DataTemplate> + </ListBox.ItemTemplate> + </ListBox> </Border> </Popup> </Grid> @@ -326,7 +385,22 @@ </StackPanel> </StackPanel> </Grid> - <Button Grid.Column="1" HorizontalAlignment="Right" Command="{Binding LoadJobRunsCommand}" Margin="0 0 10 0" Padding="70 15" Height="Auto" VerticalAlignment="Center">ANALYZE</Button> + <Button Grid.Column="1" HorizontalAlignment="Right" Command="{Binding LoadJobRunsCommand}" Margin="0 0 10 0" Padding="30 15" Height="Auto" VerticalAlignment="Center" Content="ANALYZE"> + <Button.Style> + <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}"> + <Setter Property="IsEnabled" Value="False"/> + <Style.Triggers> + <MultiDataTrigger> + <MultiDataTrigger.Conditions> + <Condition Binding="{Binding Path=(Validation.HasError), Source={x:Reference startdatePicker}}" Value="False"/> + <Condition Binding="{Binding Path=(Validation.HasError), Source={x:Reference endDatePicker}}" Value="False"/> + </MultiDataTrigger.Conditions> + <Setter Property="IsEnabled" Value="True"/> + </MultiDataTrigger> + </Style.Triggers> + </Style> + </Button.Style> + </Button> </Grid> </Border> </Grid> @@ -419,7 +493,7 @@ </DataGridTemplateColumn> <DataGridTextColumn Header="ID" Binding="{Binding JobRun.ID}" Width="50" ElementStyle="{StaticResource WrapText}"/> <DataGridTextColumn Header="Machine" Binding="{Binding Machine.SerialNumber}" Width="100" ></DataGridTextColumn> - <DataGridTextColumn Header="User" Binding="{Binding User.Contact.FullName}" Width="100" ElementStyle="{StaticResource WrapText}" /> + <DataGridTextColumn Header="User" Binding="{Binding User.Contact.FullName,TargetNullValue='PPC',FallbackValue='PPC'}" Width="100" ElementStyle="{StaticResource WrapText}" /> <DataGridTextColumn Header="Job Name" Binding="{Binding JobRun.JobName}" Width="100" ElementStyle="{StaticResource WrapText}"/> <DataGridTextColumn Header="Thread" Binding="{Binding Rml.Name}" Width="80" ElementStyle="{StaticResource WrapText}"/> <DataGridTextColumn Header="Length" Binding="{Binding JobRun.JobLength, StringFormat={}{0:0.00}}" Width="60" /> @@ -484,11 +558,11 @@ </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> - <DockPanel ToolTip="{Binding Quantity}" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="10"> - <Grid DockPanel.Dock="Top" Height="40" Margin="0 5 8 0" Width="16"> - <Border x:Name="LiquidTypeBorder" BorderThickness="1" BorderBrush="{StaticResource borderBrush}" CornerRadius="2"> + <DockPanel ToolTip="{Binding Quantity, Converter={StaticResource TooltipLiquidQuantityFormatConverter}, ConverterParameter='#,#\\'}" ToolTipService.Placement="Center" ToolTipService.VerticalOffset="10"> + <Grid DockPanel.Dock="Top" Height="40" Margin="0 5 8 0" Width="16" > + <Border x:Name="LiquidTypeBorder" BorderThickness="1" BorderBrush="{StaticResource borderBrush}" CornerRadius="2" > <Canvas x:Name="LiquidCanvas" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="0" ClipToBounds="True" ToolTip="{Binding Quantity}" ToolTipService.Placement="Left" ToolTipService.VerticalOffset="10"> - <Border Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualHeight }" Width="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualWidth }"> + <Border Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualHeight }" Width="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualWidth }" > <Border.Background> <SolidColorBrush Color="{Binding LiquidType,Converter={StaticResource LiquidTypeToColorConverter}}" /> </Border.Background> @@ -505,6 +579,7 @@ </Style> </Border.Style> </Border> + <Border Background="Transparent" ToolTip="{Binding Quantity, Converter={StaticResource TooltipLiquidQuantityFormatConverter}, ConverterParameter='#,#\\'}" Height="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualHeight }" Width="{Binding RelativeSource={RelativeSource AncestorType=Canvas}, Path=ActualWidth }"></Border> </Canvas> </Border> </Grid> @@ -554,7 +629,7 @@ <StackPanel Orientation="Horizontal" Margin="0 3"> <TextBlock Text="{Binding Name}" FontWeight="SemiBold"/> <TextBlock Text=": "/> - <TextBlock Text="{Binding Value, StringFormat={}{0:#,0.##}}"/> + <TextBlock Text="{Binding Value, StringFormat={}{0:N2}}"/> <TextBlock Text="{Binding Unit}"/> </StackPanel> </DataTemplate> @@ -599,7 +674,7 @@ <StackPanel Orientation="Horizontal" Margin="2"> <TextBlock Margin="5 0 0 0" Text="{Binding Name}" FontWeight="SemiBold"/> <TextBlock Text=": "/> - <TextBlock Text="{Binding Value, StringFormat={}{0:0.0}}"/> + <TextBlock Text="{Binding Value, StringFormat={}{0:N0}}"/> <TextBlock Text="{Binding Unit}"/> </StackPanel> </DataTemplate> @@ -659,7 +734,8 @@ </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> - <StackPanel Orientation="Horizontal" Margin="4"> + <Border Background="Transparent" ToolTip="{Binding Quantity, Converter={StaticResource TooltipLiquidQuantityFormatConverter}, ConverterParameter='#,#\\'}"> + <StackPanel Orientation="Horizontal" Margin="4"> <Ellipse Width="30" Height="30"> <Ellipse.Fill> <SolidColorBrush Color="{Binding LiquidType,Converter={StaticResource LiquidTypeToColorConverter}}" /> @@ -668,17 +744,19 @@ <StackPanel Orientation="Vertical" Margin="4"> <TextBlock Text="{Binding LiquidType,Converter={StaticResource EnumToDescriptionConverter}}" FontWeight="SemiBold"></TextBlock> <TextBlock > - <Run Text="{Binding Quantity, Converter={StaticResource NanoLiterToLiterFormatConverter}}"></Run> + <Run Text="{Binding Quantity, Converter={StaticResource NanoLiterToLiterFormatConverter}, ConverterParameter='0.00'}"></Run> <Run Text=" liters"></Run> </TextBlock> </StackPanel> </StackPanel> + </Border> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> + <Border Background="Transparent" ToolTip="{Binding StatisticsValueCollection.TotalLiquidQuantities, Converter={StaticResource TooltipLiquidQuantityFormatConverter}, ConverterParameter='#,#\\'}"> <TextBlock DockPanel.Dock="Bottom" Margin="4 10 0 0 "> <Run Text="Total liquid quantities for all: " FontWeight="SemiBold"/> - <Run Text="{Binding StatisticsValueCollection.TotalLiquidQuantities, Converter={StaticResource NanoLiterToLiterFormatConverter}}"></Run> + <Run Text="{Binding StatisticsValueCollection.TotalLiquidQuantities, Converter={StaticResource NanoLiterToLiterFormatConverter}, ConverterParameter='0.00'}"></Run> <Run Text=" liters"></Run> <TextBlock.Style> <Style TargetType="TextBlock"> @@ -691,9 +769,19 @@ </Style> </TextBlock.Style> </TextBlock> + </Border> </DockPanel> </Border> </Grid> </Border> + <Grid Grid.Row="0" Grid.Column="1" Margin="20 0 20 0"> + <Border Padding="14 14 12 14" BorderBrush="DimGray" BorderThickness="0" Background="{StaticResource Logging.Background}" HorizontalAlignment="Stretch" CornerRadius="2" > + <Border.Effect> + <DropShadowEffect ShadowDepth="4" BlurRadius="10" Opacity="0.5"/> + </Border.Effect> + + <Button Grid.Column="1" HorizontalAlignment="Right" Command="{Binding ExportToExcelCommand}" Margin="0 0 10 0" Padding="10 15" Height="Auto" VerticalAlignment="Center" Width="Auto">EXPORT TO EXCEL</Button> + </Border> + </Grid> </Grid> </UserControl> 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 2b3ed79ca..961d7f691 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Statistics/Views/JobRunsView.xaml.cs @@ -1,7 +1,9 @@ using LiveCharts; using LiveCharts.Wpf; using System; +using System.Collections; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -14,6 +16,7 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using Tango.SharedUI.Components; namespace Tango.MachineStudio.Statistics.Views { @@ -28,6 +31,8 @@ namespace Tango.MachineStudio.Statistics.Views InitializeComponent(); _lastSelectedGridItemIndex = -1; } + + private void Button_Click(object sender, RoutedEventArgs e) { selectMachineButton.IsChecked = true; @@ -68,6 +73,12 @@ namespace Tango.MachineStudio.Statistics.Views e.Handled = true; } + private void IsHeadCleaningButton_Click(object sender, RoutedEventArgs e) + { + isHeadCleaningToggleButton.IsChecked = true; + e.Handled = true; + } + private void DataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) { DataGrid dataGrid = sender as DataGrid; @@ -81,6 +92,84 @@ namespace Tango.MachineStudio.Statistics.Views } } } + + private void StartDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e) + { + DatePicker datePickerObj = sender as DatePicker; + if(datePickerObj != null && datePickerObj.SelectedDate != null && endDatePicker.SelectedDate != null) + { + if(datePickerObj.SelectedDate> endDatePicker.SelectedDate) + { + BindingExpression start_be = datePickerObj.GetBindingExpression(DatePicker.SelectedDateProperty); + ValidationError validationError = new ValidationError(StartDateExpiredRule, start_be); + validationError.ErrorContent = "The start time must be less than or equal to end time."; + Validation.MarkInvalid(start_be, validationError); + } + else if (Validation.GetHasError(endDatePicker)) + { + BindingExpression end_be = endDatePicker.GetBindingExpression(DatePicker.SelectedDateProperty); + Validation.ClearInvalid(end_be); + } + } + } + + private void EndDatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e) + { + DatePicker datePickerObj = sender as DatePicker; + if (datePickerObj.SelectedDate != null && startdatePicker.SelectedDate != null ) + { + if(datePickerObj != null && datePickerObj.SelectedDate < startdatePicker.SelectedDate) + { + BindingExpression end_be = datePickerObj.GetBindingExpression(DatePicker.SelectedDateProperty); + ValidationError validationError = new ValidationError(EndDateExpiredRule, end_be); + validationError.ErrorContent = "The end time must be greater than or equal to the start time."; + Validation.MarkInvalid(end_be, validationError); + } + else if (Validation.GetHasError(startdatePicker)) + { + BindingExpression start_be = startdatePicker.GetBindingExpression(DatePicker.SelectedDateProperty); + Validation.ClearInvalid(start_be); + } + } + } + + private void CheckBox_PreventUndoCheck(object sender, RoutedEventArgs e) + { + if( sender is CheckBox) + { + CheckBox cb = sender as CheckBox; + if (cb.IsChecked == false) + { + cb.IsChecked = true; + e.Handled = true; + return; + } + } + e.Handled = false; + } + private void CheckBox_StayChecked(object sender, RoutedEventArgs e) + { + if (sender is CheckBox) + { + CheckBox cb = sender as CheckBox; + if (cb.IsChecked == false) + { + var col = cb.Tag; + Type type = col.GetType(); + if (col != null && col.GetType().GetGenericTypeDefinition() == typeof(SelectedObjectCollection<>)) + { + dynamic dSynchedSource = type.GetProperty("SynchedSource").GetValue(col); + if(dSynchedSource != null && dSynchedSource.GetType().GetGenericTypeDefinition() == typeof(ObservableCollection<>) && dSynchedSource.Count == 0) + { + cb.IsChecked = true; + e.Handled = true; + return; + } + } + } + } + e.Handled = false; + } } } |
