|
|
@@ -1,16 +1,22 @@
|
|
|
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;
|
|
|
@@ -24,6 +30,7 @@ namespace TeamAAS_VP.ViewModels.Statistics
|
|
|
IContainerProvider _container;
|
|
|
ISystemDatabaseService _systemDatabaseService;
|
|
|
IProductService _productService;
|
|
|
+ IEventAggregator _eventAggregator;
|
|
|
|
|
|
#region 属性
|
|
|
private Int64 _TotalCount;
|
|
|
@@ -105,6 +112,67 @@ namespace TeamAAS_VP.ViewModels.Statistics
|
|
|
get { return _DayChartModel; }
|
|
|
set { SetProperty(ref _DayChartModel, value); }
|
|
|
}
|
|
|
+
|
|
|
+ private string _NowYieldt;
|
|
|
+ /// <summary>
|
|
|
+ /// 实时良率
|
|
|
+ /// </summary>
|
|
|
+ public string NowYieldt
|
|
|
+ {
|
|
|
+ get { return _NowYieldt; }
|
|
|
+ set { SetProperty(ref _NowYieldt, value); }
|
|
|
+ }
|
|
|
+
|
|
|
+ private string _NowNumbers;
|
|
|
+ /// <summary>
|
|
|
+ /// 总检测数
|
|
|
+ /// </summary>
|
|
|
+ public string NowNumbers
|
|
|
+ {
|
|
|
+ get { return _NowNumbers; }
|
|
|
+ set { SetProperty(ref _NowNumbers, value); }
|
|
|
+ }
|
|
|
+
|
|
|
+ private string _NowOkNumbers;
|
|
|
+ /// <summary>
|
|
|
+ /// 合格数量
|
|
|
+ /// </summary>
|
|
|
+ public string NowOkNumbers
|
|
|
+ {
|
|
|
+ get { return _NowOkNumbers; }
|
|
|
+ set { SetProperty(ref _NowOkNumbers, value); }
|
|
|
+ }
|
|
|
+
|
|
|
+ private string _NowNgNumbers;
|
|
|
+ /// <summary>
|
|
|
+ /// 不良数量
|
|
|
+ /// </summary>
|
|
|
+ public string NowNgNumbers
|
|
|
+ {
|
|
|
+ get { return _NowNgNumbers; }
|
|
|
+ set { SetProperty(ref _NowNgNumbers, value); }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private string _UphNumber;
|
|
|
+ /// <summary>
|
|
|
+ /// uph合格数量
|
|
|
+ /// </summary>
|
|
|
+ public string UphNumber
|
|
|
+ {
|
|
|
+ get { return _UphNumber; }
|
|
|
+ set { SetProperty(ref _UphNumber, value); }
|
|
|
+ }
|
|
|
+
|
|
|
+ private string _HourNumber;
|
|
|
+ /// <summary>
|
|
|
+ /// uph连续小时数
|
|
|
+ /// </summary>
|
|
|
+ public string HourNumber
|
|
|
+ {
|
|
|
+ get { return _HourNumber; }
|
|
|
+ set { SetProperty(ref _HourNumber, value); }
|
|
|
+ }
|
|
|
#endregion
|
|
|
|
|
|
#region 命令
|
|
|
@@ -112,7 +180,9 @@ namespace TeamAAS_VP.ViewModels.Statistics
|
|
|
public DelegateCommand LoadedCommand =>
|
|
|
_LoadedCommand ?? (_LoadedCommand = new DelegateCommand(ExecuteLoadedCommand));
|
|
|
|
|
|
-
|
|
|
+ private DelegateCommand _SaveConfigCommand;
|
|
|
+ public DelegateCommand SaveConfigCommand =>
|
|
|
+ _SaveConfigCommand ?? (_SaveConfigCommand = new DelegateCommand(SaveConfig));
|
|
|
#endregion
|
|
|
|
|
|
#region 事件
|
|
|
@@ -129,6 +199,7 @@ namespace TeamAAS_VP.ViewModels.Statistics
|
|
|
#region 方法
|
|
|
async void ExecuteLoadedCommand()
|
|
|
{
|
|
|
+ //var spcvlaue = Management.GetLatest20PressureSPCAsync();
|
|
|
var currentproduct = _productService.GetCurrentProduct();
|
|
|
if (currentproduct == null) return;
|
|
|
await App.Current.Dispatcher.InvokeAsync(new Action(async () => {
|
|
|
@@ -137,13 +208,106 @@ namespace TeamAAS_VP.ViewModels.Statistics
|
|
|
MonthCount = await _systemDatabaseService.GetCurrentMonthProductionAsync(currentproduct.Name);
|
|
|
WeekCount = await _systemDatabaseService.GetCurrentWeekProductionAsync(currentproduct.Name);
|
|
|
DayCount = await _systemDatabaseService.GetTodayProductionAsync(currentproduct.Name);
|
|
|
- MonthChartModel = CreateMonth(await _systemDatabaseService.GetMonthlyProductionByDayAndCategoryAsync(currentproduct.Name));
|
|
|
- WeekChartModel = CreateWeek(await _systemDatabaseService.GetWeeklyProductionByDayAndCategoryAsync(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<SnackbarMessageNotification>().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<UPhAlarm>(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; }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 实时监控 GAP 检测良率(最近20条生产拍照记录)
|
|
|
+ /// </summary>
|
|
|
+ /// <returns>总数量、合格数、良率(%)、状态</returns>
|
|
|
+ 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 ;
|
|
|
+ }
|
|
|
+ }
|
|
|
/// <summary>
|
|
|
/// 创建产量图表模型
|
|
|
/// </summary>
|
|
|
@@ -175,13 +339,280 @@ namespace TeamAAS_VP.ViewModels.Statistics
|
|
|
|
|
|
return model;
|
|
|
}
|
|
|
+ /// <summary>
|
|
|
+ /// 创建Spc压力控制图
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="spcPoints"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ private PlotModel CreateAssemblyPressureSPC(List<SpcPoint> 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 创建月统计模型(总产能蓝色柱 + OK量绿色柱,Tooltip显示正确日期+标签)
|
|
|
+ /// </summary>
|
|
|
+ private PlotModel CreateMonth(Dictionary<DateTime, Dictionary<string, int>> 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;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
|
|
|
/// <summary>
|
|
|
/// 创建月统计模型
|
|
|
/// </summary>
|
|
|
/// <param name="Items"></param>
|
|
|
/// <returns></returns>
|
|
|
- private PlotModel CreateMonth(Dictionary<DateTime, Dictionary<string, int>> Items)
|
|
|
+ private PlotModel CreateMonth2(Dictionary<DateTime, Dictionary<string, int>> Items)
|
|
|
{
|
|
|
var model = new PlotModel { Title = Lang.当前月产能统计 };
|
|
|
|
|
|
@@ -352,8 +783,9 @@ namespace TeamAAS_VP.ViewModels.Statistics
|
|
|
return model;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/// <summary>
|
|
|
- /// 创建日统计模型
|
|
|
+ /// 创建日统计模型(总产能蓝色柱 + OK量绿色柱)
|
|
|
/// </summary>
|
|
|
/// <param name="Items"></param>
|
|
|
/// <returns></returns>
|
|
|
@@ -403,6 +835,104 @@ namespace TeamAAS_VP.ViewModels.Statistics
|
|
|
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;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 创建日统计模型
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="Items"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ private PlotModel CreateDay2(Dictionary<int, Dictionary<string, int>> 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)
|
|
|
@@ -443,5 +973,62 @@ namespace TeamAAS_VP.ViewModels.Statistics
|
|
|
return model;
|
|
|
}
|
|
|
#endregion
|
|
|
+ #region Spc
|
|
|
+ public async Task<List<SpcPoint>> GetLatest20PressureSPCAsync()
|
|
|
+ {
|
|
|
+ //var pressureList = await _systemDatabaseService.GetLatest20CameraResultAsync();
|
|
|
+ var pressureList1 = await _systemDatabaseService.GetLatest20AssemblyPressureAsync(1);
|
|
|
+ return GenerateAssemblyPressureSPC(pressureList1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 根据20条组装压力值 → 生成SPC控制图数据
|
|
|
+ /// </summary>
|
|
|
+ public List<SpcPoint> GenerateAssemblyPressureSPC(List<string> values)
|
|
|
+ {
|
|
|
+ // 获取当前产品
|
|
|
+ var currentProduct = _productService.GetCurrentProduct();
|
|
|
+ List<SpcPoint> spcList = new List<SpcPoint>();
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// SPC 控制图点实体
|
|
|
+ /// </summary>
|
|
|
+ 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
|
|
|
}
|
|
|
}
|