using OxyPlot; using OxyPlot.Annotations; using OxyPlot.Axes; using OxyPlot.Legends; using OxyPlot.Series; using Prism.Commands; using Prism.Events; using Prism.Ioc; using Prism.Mvvm; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using System.Windows.Documents; using TeamAAS_VP.Core; using TeamAAS_VP.Data; using TeamAAS_VP.Enums; using TeamAAS_VP.Events; using TeamAAS_VP.Interfaces; using TeamAAS_VP.Models; using TeamAAS_VP.Resources.Languages; using TeamAAS_VP.Services; using static MaterialDesignThemes.Wpf.Theme.ToolBar; namespace TeamAAS_VP.ViewModels.Statistics { public class ProductionStatementViewModel : BindableBase { IContainerProvider _container; ISystemDatabaseService _systemDatabaseService; IProductService _productService; IEventAggregator _eventAggregator; #region 属性 private Int64 _TotalCount; /// /// 总产能 /// public Int64 TotalCount { get { return _TotalCount; } set { SetProperty(ref _TotalCount,value); } } private Int64 _MonthCount; /// /// 月产能 /// public Int64 MonthCount { get { return _MonthCount; } set { SetProperty(ref _MonthCount, value); } } private Int64 _WeekCount; /// /// 周产能 /// public Int64 WeekCount { get { return _WeekCount; } set { SetProperty(ref _WeekCount, value); } } private Int64 _DayCount; /// /// 日产能 /// public Int64 DayCount { get { return _DayCount; } set { SetProperty(ref _DayCount, value); } } private PlotModel _YieldChartModel; /// /// 良率图表Model的mvvm属性,可通知UI更新 /// public PlotModel YieldChartModel { get { return _YieldChartModel; } set { SetProperty(ref _YieldChartModel, value); } } private PlotModel _MonthChartModel; /// /// 月产能 /// public PlotModel MonthChartModel { get { return _MonthChartModel; } set { SetProperty(ref _MonthChartModel, value); } } private PlotModel _WeekChartModel; /// /// 周产能 /// public PlotModel WeekChartModel { get { return _WeekChartModel; } set { SetProperty(ref _WeekChartModel, value); } } private PlotModel _DayChartModel; /// /// 日产能 /// public PlotModel DayChartModel { get { return _DayChartModel; } set { SetProperty(ref _DayChartModel, value); } } private string _NowYieldt; /// /// 实时良率 /// public string NowYieldt { get { return _NowYieldt; } set { SetProperty(ref _NowYieldt, value); } } private string _NowNumbers; /// /// 总检测数 /// public string NowNumbers { get { return _NowNumbers; } set { SetProperty(ref _NowNumbers, value); } } private string _NowOkNumbers; /// /// 合格数量 /// public string NowOkNumbers { get { return _NowOkNumbers; } set { SetProperty(ref _NowOkNumbers, value); } } private string _NowNgNumbers; /// /// 不良数量 /// public string NowNgNumbers { get { return _NowNgNumbers; } set { SetProperty(ref _NowNgNumbers, value); } } private string _UphNumber; /// /// uph合格数量 /// public string UphNumber { get { return _UphNumber; } set { SetProperty(ref _UphNumber, value); } } private string _HourNumber; /// /// uph连续小时数 /// public string HourNumber { get { return _HourNumber; } set { SetProperty(ref _HourNumber, value); } } #endregion #region 命令 private DelegateCommand _LoadedCommand; public DelegateCommand LoadedCommand => _LoadedCommand ?? (_LoadedCommand = new DelegateCommand(ExecuteLoadedCommand)); private DelegateCommand _SaveConfigCommand; public DelegateCommand SaveConfigCommand => _SaveConfigCommand ?? (_SaveConfigCommand = new DelegateCommand(SaveConfig)); #endregion #region 事件 #endregion public ProductionStatementViewModel(IContainerProvider container, ISystemDatabaseService systemDatabaseService, IProductService productService) { _container= container; _systemDatabaseService = systemDatabaseService; _productService = productService; } #region 方法 async void ExecuteLoadedCommand() { //var spcvlaue = Management.GetLatest20PressureSPCAsync(); var currentproduct = _productService.GetCurrentProduct(); if (currentproduct == null) return; await App.Current.Dispatcher.InvokeAsync(new Action(async () => { YieldChartModel = CreateYieldChartModel(await _systemDatabaseService.GetProductionByCategoriesAsync(currentproduct.Name)); TotalCount = await _systemDatabaseService.GetOverallProductionAsync(currentproduct.Name); MonthCount = await _systemDatabaseService.GetCurrentMonthProductionAsync(currentproduct.Name); WeekCount = await _systemDatabaseService.GetCurrentWeekProductionAsync(currentproduct.Name); DayCount = await _systemDatabaseService.GetTodayProductionAsync(currentproduct.Name); WeekChartModel = CreateAssemblyPressureSPC(await GetLatest20PressureSPCAsync()); MonthChartModel = CreateMonth(await _systemDatabaseService.GetMonthlyProductionByDayAndCategoryAsync(currentproduct.Name)); //WeekChartModel = CreateWeek(await _systemDatabaseService.GetWeeklyProductionByDayAndCategoryAsync(currentproduct.Name)); DayChartModel = CreateDay(await _systemDatabaseService.GetDailyProductionByHourAndCategoryAsync(currentproduct.Name)); await GetGapYieldStatisticsAsync(); await ReadUphAlarmConfig(); })); } // 保存配置方法 private void SaveConfig() { try { UPhAlarm data = new UPhAlarm { Hour = HourNumber, Number = UphNumber }; string path = @"..\Config\UphAlarm.cfg"; Directory.CreateDirectory(Path.GetDirectoryName(path)); FileHelper.WriteJsonFile(data, path); //_eventAggregator.GetEvent().Publish(new MessageParameter() { Msg = $"{Lang.成功}!", Duration = 0.4 }); } catch (Exception ex) { } } public Task ReadUphAlarmConfig() { try { string path = @"..\Config\UphAlarm.cfg"; if (File.Exists(path)) { // 读取JSON文件 var data = FileHelper.ReadJsonFile(path); if (data != null) { // 把配置值加载到属性 HourNumber = data.Hour; UphNumber = data.Number; Management.uphhour = int.Parse(HourNumber); Management.uphnumber = int.Parse(UphNumber); } } } catch (Exception ex) { Console.WriteLine($"读取配置失败:{ex.Message}"); } return Task.CompletedTask; } public class UPhAlarm { public string Hour { get; set; } public string Number { get; set; } } /// /// 实时监控 GAP 检测良率(最近20条生产拍照记录) /// /// 总数量、合格数、良率(%)、状态 public async Task GetGapYieldStatisticsAsync() { try { var currentproduct = _productService.GetCurrentProduct(); if (currentproduct == null) { return ; } var records = await _systemDatabaseService.GetLatest20AssemblyPressureAsync(1); if (records == null || records.Count == 0) return ; double min = currentproduct.GlobalParamEx.DownPressure.PressureDownLimit; double max = currentproduct.GlobalParamEx.DownPressure.PressureUpLimit; // 3. 统计良率 double total = records.Count; double okCount = records.Count(g =>Convert.ToDouble(g.Split('|')[0]) >= min && Convert.ToDouble(g.Split('|')[0]) <= max); double yieldRate = Math.Round((double)okCount / total * 100, 2); NowYieldt = yieldRate.ToString("F2")+"%";//良率 NowNumbers = total.ToString();//总数 NowOkNumbers = okCount.ToString();//OK数 NowNgNumbers=(total-okCount).ToString(); return ; } catch (Exception ex) { LogHelper.WriteLogError("GAP良率统计异常", ex); return ; } } /// /// 创建产量图表模型 /// /// private PlotModel CreateYieldChartModel(Dictionary Items) { List PieSlices = new List(); PieSlices = new List(); foreach (var item in Items) { PieSlices.Add(new PieSlice(item.Key, (double)item.Value)); } var model = new PlotModel { Title = Lang.产能统计 }; var series = new PieSeries { StrokeThickness = 1.0, InsideLabelPosition = 0.5, AngleSpan = 360, StartAngle = 0 }; foreach (var slice in PieSlices) { series.Slices.Add(slice); } model.Series.Add(series); return model; } /// /// 创建Spc压力控制图 /// /// /// private PlotModel CreateAssemblyPressureSPC(List spcPoints) { if (spcPoints == null || spcPoints.Count == 0) return new PlotModel { Title = "暂无数据" }; var model = new PlotModel { Title = "组装压力SPC控制图", TitleFontSize = 14 }; model.Legends.Add(new Legend { LegendPlacement = LegendPlacement.Outside, LegendPosition = LegendPosition.RightMiddle, LegendOrientation = LegendOrientation.Vertical, LegendBorderThickness = 0, LegendTextColor = OxyColors.LightGray }); double ucl = spcPoints.First().UCL; double cl = spcPoints.First().CL; double lcl = spcPoints.First().LCL; string sn = spcPoints.First().SN; double maxValue = spcPoints.Max(p => p.Value); double minValue = spcPoints.Min(p => p.Value); double yx = spcPoints.Count; double allMax = new[] { maxValue, ucl }.Max(); double allMin = new[] { minValue, lcl }.Min(); double yMax = allMax > 0 ? allMax * 1.05 : allMax * 0.95; double yMin = allMin < 0 ? allMin * 1.05 : allMin * 0.95; yMin = Math.Min(yMin, allMin - 3); yMax = Math.Max(yMax, allMax + 3); var xAxis = new LinearAxis { Key = "X", Title = "序号", Minimum = 0, Maximum = yx + 1, Position = AxisPosition.Bottom, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.Outside, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3") }; model.Axes.Add(xAxis); var yAxis = new LinearAxis { Key = "Y", Title = "压力值", Minimum = yMin, Maximum = yMax, Position = AxisPosition.Left, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.Outside, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3") }; model.Axes.Add(yAxis); var valueSeries = new LineSeries { Title = "实际压力", Color = OxyColors.Blue, MarkerType = MarkerType.Circle, MarkerSize = 4, MarkerStroke = OxyColors.Blue, MarkerFill = OxyColors.White, YAxisKey = "Y", XAxisKey = "X" }; var uclSeries = new LineSeries { Title = $"上限 = {ucl:F2}", Color = OxyColors.Red, LineStyle = LineStyle.Dash, YAxisKey = "Y", XAxisKey = "X" }; var clSeries = new LineSeries { Title = $"平均值 = {cl:F2}", Color = OxyColors.Green, LineStyle = LineStyle.Solid, YAxisKey = "Y", XAxisKey = "X" }; var lclSeries = new LineSeries { Title = $"下限 = {lcl:F2}", Color = OxyColors.Red, LineStyle = LineStyle.Dash, YAxisKey = "Y", XAxisKey = "X" }; foreach (var point in spcPoints) { valueSeries.Points.Add(new OxyPlot.DataPoint(point.Index, point.Value)); uclSeries.Points.Add(new OxyPlot.DataPoint(point.Index, point.UCL)); clSeries.Points.Add(new OxyPlot.DataPoint(point.Index, point.CL)); lclSeries.Points.Add(new OxyPlot.DataPoint(point.Index, point.LCL)); } var uclAnnotation = new LineAnnotation { Type = LineAnnotationType.Horizontal, Y = ucl, Text = $"UCL {ucl:F2}", TextColor = OxyColors.Red, Color = OxyColors.Red, LineStyle = LineStyle.None, TextPosition = new OxyPlot.DataPoint(20.5, ucl) }; var clAnnotation = new LineAnnotation { Type = LineAnnotationType.Horizontal, Y = cl, Text = $"CL {cl:F2}", TextColor = OxyColors.Green, Color = OxyColors.Green, LineStyle = LineStyle.None, TextPosition = new OxyPlot.DataPoint(20.5, cl) }; var lclAnnotation = new LineAnnotation { Type = LineAnnotationType.Horizontal, Y = lcl, Text = $"LCL {lcl:F2}", TextColor = OxyColors.Red, Color = OxyColors.Red, LineStyle = LineStyle.None, TextPosition = new OxyPlot.DataPoint(20.5, lcl) }; model.Annotations.Add(uclAnnotation); model.Annotations.Add(clAnnotation); model.Annotations.Add(lclAnnotation); model.Series.Add(valueSeries); model.Series.Add(uclSeries); model.Series.Add(clSeries); model.Series.Add(lclSeries); return model; } /// /// 创建月统计模型(总产能蓝色柱 + OK量绿色柱,Tooltip显示正确日期+标签) /// private PlotModel CreateMonth(Dictionary> Items) { var model = new PlotModel { Title = Lang.当前月产能统计 }; model.Legends.Add(new Legend { LegendPlacement = LegendPlacement.Outside, LegendPosition = LegendPosition.RightMiddle, LegendOrientation = LegendOrientation.Vertical, LegendBorderThickness = 0, LegendTextColor = OxyColors.LightGray }); var ay1 = new LinearAxis() { Key = "y1", Title = Lang.数量, TitlePosition = 1, Minimum = 0, Position = AxisPosition.Left, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.None, MinorTickSize = 0, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3"), }; DateTime minDate, maxDate; if (Items == null || Items.Count == 0) { var today = DateTime.Now.Date; minDate = today.AddDays(-0.5); maxDate = today.AddDays(0.5); } else { minDate = Items.Keys.First().AddDays(-0.5); maxDate = Items.Keys.Last().AddDays(0.5); } var ax = new DateTimeAxis() { Minimum = DateTimeAxis.ToDouble(minDate), Maximum = DateTimeAxis.ToDouble(maxDate), StringFormat = $"dd {Lang.日}", MajorStep = 1, Position = AxisPosition.Bottom, Angle = 45, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.None, MinorTickSize = 0, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3"), }; model.Axes.Add(ay1); model.Axes.Add(ax); // 1. 总产能(蓝色柱) var totalSeries = new LinearBarSeries { Title = "总产能", YAxisKey = "y1", BarWidth = 10, FillColor = OxyColors.SteelBlue, StrokeColor = OxyColors.SteelBlue, TrackerFormatString = "总产能\n{2:MM月dd日}: {4:0}" }; // 2. OK量(绿色柱) var okSeries = new LinearBarSeries { Title = "OK量", YAxisKey = "y1", BarWidth = 10, FillColor = OxyColors.Green, StrokeColor = OxyColors.Green, TrackerFormatString = "OK量\n{2:MM月dd日}: {4:0}" }; foreach (var item in Items) { double baseX = DateTimeAxis.ToDouble(item.Key); long totalCount = item.Value.Sum(kv => kv.Value); int okCount = item.Value.ContainsKey("OK") ? item.Value["OK"] : 0; totalSeries.Points.Add(new OxyPlot.DataPoint(baseX , totalCount)); okSeries.Points.Add(new OxyPlot.DataPoint(baseX + 0.2, okCount)); } model.Series.Add(totalSeries); model.Series.Add(okSeries); return model; } /// /// 创建月统计模型 /// /// /// private PlotModel CreateMonth2(Dictionary> Items) { var model = new PlotModel { Title = Lang.当前月产能统计 }; // 添加图例说明 model.Legends.Add(new Legend { LegendPlacement = LegendPlacement.Outside, LegendPosition = LegendPosition.RightMiddle, LegendOrientation = LegendOrientation.Vertical, LegendBorderThickness = 0, LegendTextColor = OxyColors.LightGray }); ; // 定义第一个Y轴y1,显示数量 var ay1 = new LinearAxis() { Key = "y1", Title= Lang.数量, TitlePosition=1, Minimum = 0, Position = AxisPosition.Left, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.None, MinorTickSize = 0, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3"), }; // 定义X轴为日期轴 var minValue = DateTimeAxis.ToDouble(Items.Keys.ElementAt(0)); var maxValue = DateTimeAxis.ToDouble(Items.Keys.ElementAt(Items.Keys.Count-1)); var ax = new DateTimeAxis() { Minimum = minValue, Maximum = maxValue, StringFormat = $"dd{Lang.日}", MajorStep = 1, Position = AxisPosition.Bottom, Angle = 45, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.None, MinorTickSize = 0, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3"), }; model.Axes.Add(ay1); model.Axes.Add(ax); foreach (var category in Items.First().Value.Keys) { var barSeries = new LinearBarSeries { Title = category }; barSeries.YAxisKey = "y1"; barSeries.BarWidth = 10; // 点击时弹出的label内容 barSeries.TrackerFormatString = $"{0}\r\n{2:dd}{Lang.日}: {4:0}"; foreach (var item in Items) { barSeries.Points.Add(new OxyPlot.DataPoint(DateTimeAxis.ToDouble(item.Key), (double)(item.Value[category]))); } model.Series.Add(barSeries); } var Series = new LineSeries { Title = Lang.总产量 }; Series.YAxisKey = "y1"; Series.TrackerFormatString = $"{0}\r\n{2:dd}{Lang.日}: {4:0}"; foreach (var item in Items) { Int64 count = 0; foreach (var item1 in item.Value) { count += item1.Value; } Series.Points.Add(new OxyPlot.DataPoint(DateTimeAxis.ToDouble(item.Key), (double)count)); } model.Series.Add(Series); return model; } /// /// 创建周统计模型 /// /// /// private PlotModel CreateWeek(Dictionary> Items) { var model = new PlotModel { Title = Lang.当前周产能统计 }; // 添加图例说明 model.Legends.Add(new Legend { LegendPlacement = LegendPlacement.Outside, LegendPosition = LegendPosition.RightMiddle, LegendOrientation = LegendOrientation.Vertical, LegendBorderThickness = 0, LegendTextColor = OxyColors.LightGray }); // 定义第一个Y轴y1,显示数量 var ay1 = new LinearAxis() { Key = "y1", Title = Lang.数量, Minimum = 0, Position = AxisPosition.Left, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.None, MinorTickSize = 0, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3"), }; // 定义X轴为日期轴 var ax = new LinearAxis() { Minimum = 0, Maximum = 7.5, MajorStep = 1, Position = AxisPosition.Bottom, StringFormat= $"{Lang.周} 0", Angle = 0, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.None, MinorTickSize = 0, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3"), }; model.Axes.Add(ay1); model.Axes.Add(ax); foreach (var category in Items.First().Value.Keys) { var barSeries = new LinearBarSeries { Title = category }; barSeries.YAxisKey = "y1"; barSeries.BarWidth = 10; // 点击时弹出的label内容 barSeries.TrackerFormatString = $"{0}\r\n{Lang.周}{2:0}: {4:0}"; foreach (var item in Items) { barSeries.Points.Add(new OxyPlot.DataPoint(LinearAxis.ToDouble(item.Key), (double)(item.Value[category]))); } model.Series.Add(barSeries); } var Series = new LineSeries { Title = Lang.当前周产能统计 }; Series.YAxisKey = "y1"; Series.TrackerFormatString = $"{0}\r\n{2:dd}{Lang.日}: {4:0}"; foreach (var item in Items) { Int64 count = 0; foreach (var item1 in item.Value) { count += item1.Value; } Series.Points.Add(new OxyPlot.DataPoint(DateTimeAxis.ToDouble(item.Key), (double)count)); } model.Series.Add(Series); return model; } /// /// 创建日统计模型(总产能蓝色柱 + OK量绿色柱) /// /// /// private PlotModel CreateDay(Dictionary> Items) { var model = new PlotModel { Title = Lang.当前日产能统计 }; // 添加图例说明 model.Legends.Add(new Legend { LegendPlacement = LegendPlacement.Outside, LegendPosition = LegendPosition.RightMiddle, LegendOrientation = LegendOrientation.Vertical, LegendBorderThickness = 0, LegendTextColor = OxyColors.LightGray }); // 定义第一个Y轴y1,显示数量 var ay1 = new LinearAxis() { Key = "y1", Title = $"{Lang.数量}", Minimum = 0, Position = AxisPosition.Left, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.None, MinorTickSize = 0, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3"), }; // 定义X轴为小时 var ax = new LinearAxis() { Minimum = 0, Maximum = 24.5, MajorStep = 1, StringFormat = "0 H", Position = AxisPosition.Bottom, Angle = 0, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.None, MinorTickSize = 0, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3"), }; model.Axes.Add(ay1); model.Axes.Add(ax); if (Items.Count == 0) { return model; } // 1. 总产能(蓝色柱) var totalSeries = new LinearBarSeries { Title = "总产能", YAxisKey = "y1", BarWidth = 10, FillColor = OxyColors.SteelBlue, StrokeColor = OxyColors.SteelBlue, TrackerFormatString = "总产能\n{2:0}时: {4:0}" }; // 2. OK量(绿色柱) var okSeries = new LinearBarSeries { Title = "OK量", YAxisKey = "y1", BarWidth = 10, FillColor = OxyColors.Green, StrokeColor = OxyColors.Green, TrackerFormatString = "OK量\n{2:0}时: {4:0}" }; // 遍历每小时数据 foreach (var item in Items) { double baseX = LinearAxis.ToDouble(item.Key); long totalCount = item.Value.Sum(kv => kv.Value); int okCount = item.Value.ContainsKey("OK") ? item.Value["OK"] : 0; totalSeries.Points.Add(new OxyPlot.DataPoint(baseX , totalCount)); okSeries.Points.Add(new OxyPlot.DataPoint(baseX + 0.2, okCount)); } model.Series.Add(totalSeries); model.Series.Add(okSeries); return model; } /// /// 创建日统计模型 /// /// /// private PlotModel CreateDay2(Dictionary> Items) { var model = new PlotModel { Title = Lang.当前日产能统计 }; // 添加图例说明 model.Legends.Add(new Legend { LegendPlacement = LegendPlacement.Outside, LegendPosition = LegendPosition.RightMiddle, LegendOrientation = LegendOrientation.Vertical, LegendBorderThickness = 0, LegendTextColor = OxyColors.LightGray }); // 定义第一个Y轴y1,显示数量 var ay1 = new LinearAxis() { Key = "y1", Title = $"{Lang.数量}", Minimum = 0, Position = AxisPosition.Left, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.None, MinorTickSize = 0, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3"), }; // 定义X轴为小时 var ax = new LinearAxis() { Minimum = 0, Maximum = 24.5, MajorStep = 1, StringFormat = "0 H", Position = AxisPosition.Bottom, Angle = 0, IsZoomEnabled = false, IsPanEnabled = false, TickStyle = TickStyle.None, MinorTickSize = 0, MajorGridlineStyle = LineStyle.Solid, MajorGridlineColor = OxyColor.Parse("#F3F3F3"), }; model.Axes.Add(ay1); model.Axes.Add(ax); if (Items.Count==0) { return model; } foreach (var category in Items.First().Value.Keys) { var barSeries = new LinearBarSeries { Title = category }; barSeries.YAxisKey = "y1"; barSeries.BarWidth = 10; // 点击时弹出的label内容 barSeries.TrackerFormatString = "{0}\r\n{2:0}Hours: {4:0}"; foreach (var item in Items) { barSeries.Points.Add(new OxyPlot.DataPoint(LinearAxis.ToDouble(item.Key), (double)(item.Value[category]))); } model.Series.Add(barSeries); } var Series = new LineSeries { Title = Lang.总产量 }; Series.YAxisKey = "y1"; Series.TrackerFormatString = $"{0}\r\n{2:dd}{Lang.小时}: {4:0}"; foreach (var item in Items) { Int64 count = 0; foreach (var item1 in item.Value) { count += item1.Value; } Series.Points.Add(new OxyPlot.DataPoint(DateTimeAxis.ToDouble(item.Key), (double)count)); } model.Series.Add(Series); return model; } #endregion #region Spc public async Task> GetLatest20PressureSPCAsync() { //var pressureList = await _systemDatabaseService.GetLatest20CameraResultAsync(); var pressureList1 = await _systemDatabaseService.GetLatest20AssemblyPressureAsync(1); return GenerateAssemblyPressureSPC(pressureList1); } /// /// 根据20条组装压力值 → 生成SPC控制图数据 /// public List GenerateAssemblyPressureSPC(List values) { // 获取当前产品 var currentProduct = _productService.GetCurrentProduct(); List spcList = new List(); if (values == null || values.Count == 0) return spcList; double UCL = currentProduct.GlobalParamEx.DownPressure.PressureUpLimit; double CL = (currentProduct.GlobalParamEx.DownPressure.PressureUpLimit + currentProduct.GlobalParamEx.DownPressure.PressureDownLimit) / 2; double LCL = currentProduct.GlobalParamEx.DownPressure.PressureDownLimit; // 生成每个点 for (int i = 0; i < values.Count; i++) { double val =Convert.ToDouble( values[i].Split('|')[0]); string sn = values[i].Split('|')[1]; spcList.Add(new SpcPoint { Index = i + 1, Value = val, UCL = UCL, CL = CL, LCL = LCL, SN =sn, IsOutOfControl = val > UCL || val < LCL }); } return spcList; } /// /// SPC 控制图点实体 /// public class SpcPoint { public string SN { get; set; } public int Index { get; set; } public double Value { get; set; } public double UCL { get; set; } public double CL { get; set; } public double LCL { get; set; } public bool IsOutOfControl { get; set; } } #endregion } }