初始化提交
This commit is contained in:
@@ -0,0 +1,473 @@
|
||||
using JinYuan.Helper;
|
||||
using JinYuan.Models;
|
||||
using JinYuan.VirtualDataLibrary;
|
||||
using Language;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Text;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Forms.DataVisualization.Charting;
|
||||
|
||||
namespace LargeSquareOne
|
||||
{
|
||||
|
||||
|
||||
public partial class FrmMonitor : MultiLanguageForm
|
||||
{
|
||||
private static readonly object uiLock = new object();
|
||||
private static FrmMonitor _instance;
|
||||
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
||||
private readonly PrivateFontCollection _font = new PrivateFontCollection();
|
||||
private Font _myFont;
|
||||
|
||||
public static FrmMonitor Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (uiLock)
|
||||
{
|
||||
return _instance ??= new FrmMonitor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FrmMonitor()
|
||||
{
|
||||
InitializeComponent();
|
||||
InitializeFormSettings();
|
||||
//LoadCustomFont();
|
||||
|
||||
this.FormClosing += FrmMonitor_FormClosing;
|
||||
}
|
||||
|
||||
private void InitializeFormSettings()
|
||||
{
|
||||
this.SetStyle(ControlStyles.AllPaintingInWmPaint |
|
||||
ControlStyles.DoubleBuffer |
|
||||
ControlStyles.ResizeRedraw |
|
||||
ControlStyles.Selectable |
|
||||
ControlStyles.SupportsTransparentBackColor, true);
|
||||
}
|
||||
|
||||
private void LoadCustomFont()
|
||||
{
|
||||
try
|
||||
{
|
||||
var fontPath = Path.Combine(Environment.CurrentDirectory, "Assts", "Fonts", "FZY4JW.ttf");
|
||||
_font.AddFontFile(fontPath);
|
||||
var myFontFamily = new FontFamily(_font.Families[0].Name, _font);
|
||||
_myFont = new Font(myFontFamily, 20, FontStyle.Bold);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CommonMethods.AddLog(true, "加载字体异常".Translated() + $":{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void FrmMonitor_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
_cts.Cancel();
|
||||
_font?.Dispose();
|
||||
_myFont?.Dispose();
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
if (m.Msg == 0x0014) return; // 禁掉清除背景消息
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
private async void FrmMonitor_Load(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
SetChart();
|
||||
await RefreshAllDataAsync();
|
||||
await StartPeriodicRefreshAsync(_cts.Token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CommonMethods.AddLog(true, "窗体加载异常".Translated() + $":{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void SetChart()
|
||||
{
|
||||
try
|
||||
{
|
||||
#region 24小时统计
|
||||
Chart12HourTotal.Series.Clear();
|
||||
Chart12HourTotal.ChartAreas[0].AxisY.Minimum = 0;
|
||||
Chart12HourTotal.ChartAreas[0].AxisY.Maximum = 2000;
|
||||
|
||||
ChartHelper.AddSeries(Chart12HourTotal, "投入".Translated(), SeriesChartType.Column,
|
||||
ChartValueType.Auto, MarkerStyle.Diamond, 8, Color.DarkTurquoise,
|
||||
Color.Aqua, "", false, true);
|
||||
|
||||
ChartHelper.AddSeries(Chart12HourTotal, "产出".Translated(), SeriesChartType.Column,
|
||||
ChartValueType.Auto, MarkerStyle.Diamond, 8, Color.PaleGoldenrod,
|
||||
Color.PaleGoldenrod, "", false, true);
|
||||
|
||||
ChartHelper.AddSeries(Chart12HourTotal, "优率".Translated(), SeriesChartType.Spline,
|
||||
ChartValueType.String, MarkerStyle.Circle, 8, Color.Lime,
|
||||
Color.Lime, "#VAL{P}", true, true);
|
||||
|
||||
ChartHelper.SetStyle(Chart12HourTotal, Color.Transparent, Color.White);
|
||||
ChartHelper.SetLegend(Chart12HourTotal, Docking.Left, StringAlignment.Center,
|
||||
Color.Transparent, Color.White);
|
||||
ChartHelper.SetXY(Chart12HourTotal, "时间".Translated(), "数值".Translated(), -45, StringAlignment.Center,
|
||||
Color.White, Color.White, AxisArrowStyle.None, 1, true);
|
||||
ChartHelper.SetMajorGrid(Chart12HourTotal, Color.Transparent, 20, 2);
|
||||
#endregion
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CommonMethods.AddLog(true, "图表初始化异常".Translated() + $":{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StartPeriodicRefreshAsync(CancellationToken ct)
|
||||
{
|
||||
while (!ct.IsCancellationRequested)
|
||||
{
|
||||
try
|
||||
{
|
||||
await RefreshAllDataAsync();
|
||||
await Task.Delay(2000, ct);
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
break;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CommonMethods.AddLog(true, "定时刷新异常".Translated() + $":{ex.Message}");
|
||||
await Task.Delay(1000, ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshAllDataAsync()
|
||||
{
|
||||
var tasks = new[]
|
||||
{
|
||||
Refish12ProdQtyAsync(),
|
||||
RefreshXiaoLvDataAsync(),
|
||||
RefreshChatTop10AlarmDataAsync(),
|
||||
RefreshChatNGDataAsync()
|
||||
};
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
private async Task Refish12ProdQtyAsync()
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (IsDisposed) return;
|
||||
|
||||
this.InvokeIfRequired(() =>
|
||||
{
|
||||
var data = CommonMethods.Lst_Prod12HourData; // CommonMethods.Lst_Prod12HourData?.Count > 0 ? CommonMethods.Lst_Prod12HourData : MockDataGenerator.Generate12HourData();
|
||||
|
||||
UpdateChart12HourData(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateChart12HourData(List<Chart12HourData> data)
|
||||
{
|
||||
try
|
||||
{
|
||||
var maxValue = data.Max(x => x.ProdIn);
|
||||
Chart12HourTotal.ChartAreas[0].AxisY.Minimum = 0;
|
||||
Chart12HourTotal.ChartAreas[0].AxisY.Maximum = (int)maxValue + 1500;
|
||||
|
||||
// 直接使用数据,不需要额外排序
|
||||
var x1 = data.Select(c => c.DisplayTime).ToList();
|
||||
var y1 = data.Select(c => c.ProdIn).ToList();
|
||||
var y2 = data.Select(c => c.ProdOut).ToList();
|
||||
var y3 = data.Select(c => c.OKRatio).ToList();
|
||||
|
||||
Chart12HourTotal.Series[0].Points.DataBindXY(x1, y1);
|
||||
Chart12HourTotal.Series[1].Points.DataBindXY(x1, y2);
|
||||
Chart12HourTotal.Series[2].Points.DataBindXY(x1, y3);
|
||||
|
||||
// 设置X轴标签的角度,提高可读性
|
||||
Chart12HourTotal.ChartAreas[0].AxisX.LabelStyle.Angle = 0;
|
||||
// 确保显示所有标签
|
||||
Chart12HourTotal.ChartAreas[0].AxisX.Interval = 1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CommonMethods.AddLog(true, "更新12小时数据异常".Translated() + $":{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 效率数据也可以添加模拟数据
|
||||
private async Task RefreshXiaoLvDataAsync()
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (IsDisposed) return;
|
||||
|
||||
// 使用实际数据或模拟数据
|
||||
var utilizationRate = Convert.ToDouble(CommonMethods.JiaDL) * 100; // CommonMethods.JiaDL >= 0
|
||||
//? Convert.ToDouble(CommonMethods.JiaDL) * 100
|
||||
//: MockDataGenerator._random.Next(60, 95);
|
||||
|
||||
var totalQty = CommonMethods.TotalQty;
|
||||
//CommonMethods.TotalQty >= 0
|
||||
// ? CommonMethods.TotalQty
|
||||
// : MockDataGenerator._random.Next(1000, 5000);
|
||||
|
||||
var okQty = CommonMethods.ProOKQty;
|
||||
//CommonMethods.ProOKQty >= 0
|
||||
// ? CommonMethods.ProOKQty
|
||||
// : MockDataGenerator._random.Next(900, (int)totalQty);
|
||||
|
||||
var yieldRate = totalQty == 0 ? 0 :
|
||||
Convert.ToDouble((Convert.ToDouble(okQty) /
|
||||
Convert.ToDouble(totalQty) * 100.0)
|
||||
.ToString("f2"));
|
||||
|
||||
this.InvokeIfRequired(() =>
|
||||
{
|
||||
UpdateEfficiencyControls(utilizationRate, yieldRate, (int)totalQty, (int)okQty);
|
||||
UpdateTimeDisplay();
|
||||
UpdateEnergyDisplay();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private double CalculateYieldRate()
|
||||
{
|
||||
if (CommonMethods.TotalQty == 0) return 0;
|
||||
|
||||
return Convert.ToDouble((Convert.ToDouble(CommonMethods.ProOKQty) /
|
||||
Convert.ToDouble(CommonMethods.TotalQty) * 100.0)
|
||||
.ToString("f2"));
|
||||
}
|
||||
|
||||
private void UpdateEfficiencyControls(double utilizationRate, double yieldRate, int totalQty, int okQty)
|
||||
{
|
||||
try
|
||||
{
|
||||
titleModeName.Title = CommonMethods.mesConfig.ModelName ?? "测试型号";
|
||||
titleFactory_code.Title = CommonMethods.mesConfig.siteCode ?? "TEST001";
|
||||
titleLine_No.Title = CommonMethods.mesConfig.lineCode ?? "LINE01";
|
||||
titleEqp_code.Title = CommonMethods.mesConfig.equipNum ?? "EQP001";
|
||||
proUtilizationRate.FloatValue = (float)utilizationRate;
|
||||
proPPM.IntValue = (int)CommonMethods.Ppm; // (CommonMethods.Ppm > 0 ? CommonMethods.Ppm : MockDataGenerator._random.Next(100, 1000));
|
||||
proOKQty.IntValue = okQty;
|
||||
proOKRatio.Value = yieldRate;
|
||||
proTotalQty.TotalValue = totalQty;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CommonMethods.AddLog(true, "更新效率控件异常".Translated() + $":{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTimeDisplay()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (CommonMethods.PlcOpenAndRunTime?.Count > 0)
|
||||
{
|
||||
titleStartTime.Title = $"{CommonMethods.PlcOpenAndRunTime[0]}:" +
|
||||
$"{CommonMethods.PlcOpenAndRunTime[1]}:" +
|
||||
$"{CommonMethods.PlcOpenAndRunTime[2]}";
|
||||
|
||||
titleRunTime.Title = $"{CommonMethods.PlcOpenAndRunTime[3]}:" +
|
||||
$"{CommonMethods.PlcOpenAndRunTime[4]}:" +
|
||||
$"{CommonMethods.PlcOpenAndRunTime[5]}";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CommonMethods.AddLog(true, "更新时间显示异常".Translated() + $":{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateEnergyDisplay()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (CommonMethods.listElectricEnergy?.Count > 0)
|
||||
{
|
||||
EyMaterH1.ElectricEnergy = CommonMethods.listElectricEnergy[0];
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CommonMethods.AddLog(true, "更新能源显示异常".Translated() + $":{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshChatTop10AlarmDataAsync()
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (IsDisposed) return;
|
||||
|
||||
this.InvokeIfRequired(() =>
|
||||
{
|
||||
UpdateAlarmChart();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateAlarmChart()
|
||||
{
|
||||
try
|
||||
{
|
||||
var alarmData = CommonMethods.Lst_AlarmTop10_Qty;
|
||||
// CommonMethods.Lst_AlarmTop10_Qty?.Count > 0
|
||||
//? CommonMethods.Lst_AlarmTop10_Qty
|
||||
//: MockDataGenerator.GenerateAlarmTop10Data();
|
||||
|
||||
if (alarmData?.Count > 0)
|
||||
{
|
||||
chartAlarmData.Series.Clear();
|
||||
chartAlarmData.Titles.Clear();
|
||||
|
||||
var maxValue = alarmData.Max(x => x.DataCount);
|
||||
chartAlarmData.ChartAreas[0].AxisY.Minimum = 0;
|
||||
chartAlarmData.ChartAreas[0].AxisY.Maximum = (int)maxValue + 20;
|
||||
|
||||
foreach (var item in alarmData)
|
||||
{
|
||||
ChartHelper.AddSeries(chartAlarmData, item.DataType,
|
||||
SeriesChartType.Column, ChartValueType.Auto,
|
||||
MarkerStyle.Diamond, 4, Color.DarkTurquoise,
|
||||
Color.White, "", false, true);
|
||||
}
|
||||
|
||||
ConfigureAlarmChart();
|
||||
|
||||
var xData = alarmData.Select(c => c.DataType).ToList();
|
||||
var yData = alarmData.Select(c => c.DataCount).ToList();
|
||||
chartAlarmData.Series[0].Points.DataBindXY(xData, yData);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CommonMethods.AddLog(true, "更新报警图表异常".Translated() + $":{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureAlarmChart()
|
||||
{
|
||||
ChartHelper.SetTitle(chartAlarmData, "报警TOP10".Translated(),
|
||||
new Font("微软雅黑", 12), Docking.Top, Color.White);
|
||||
ChartHelper.SetStyle(chartAlarmData, Color.Transparent, Color.White);
|
||||
ChartHelper.SetLegend(chartAlarmData, Docking.Top,
|
||||
StringAlignment.Center, Color.Transparent, Color.White);
|
||||
ChartHelper.SetXY(chartAlarmData, "报警项".Translated(), "次数".Translated(), -45,
|
||||
StringAlignment.Center, Color.White, Color.White,
|
||||
AxisArrowStyle.None, 1, false);
|
||||
ChartHelper.SetMajorGrid(chartAlarmData, Color.Transparent, 20, 2);
|
||||
}
|
||||
|
||||
private void BindAlarmChartData()
|
||||
{
|
||||
var xData = CommonMethods.Lst_AlarmTop10_Qty.Select(c => c.DataType).ToList();
|
||||
var yData = CommonMethods.Lst_AlarmTop10_Qty.Select(c => c.DataCount).ToList();
|
||||
chartAlarmData.Series[0].Points.DataBindXY(xData, yData);
|
||||
}
|
||||
|
||||
private async Task RefreshChatNGDataAsync()
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
if (IsDisposed) return;
|
||||
|
||||
this.InvokeIfRequired(() =>
|
||||
{
|
||||
UpdateNGChart();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void UpdateNGChart()
|
||||
{
|
||||
try
|
||||
{
|
||||
var ngData = CommonMethods.Lst_DefectTypeQty;
|
||||
//CommonMethods.Lst_DefectTypeQty?.Count > 0
|
||||
// ? CommonMethods.Lst_DefectTypeQty
|
||||
// : MockDataGenerator.GenerateNGData();
|
||||
|
||||
if (ngData?.Count > 0)
|
||||
{
|
||||
chartNgShow.Series.Clear();
|
||||
chartNgShow.Titles.Clear();
|
||||
|
||||
var maxValue = ngData.Max(x => x.DataCount);
|
||||
chartNgShow.ChartAreas[0].AxisY.Minimum = 0;
|
||||
chartNgShow.ChartAreas[0].AxisY.Maximum = (int)maxValue + 100;
|
||||
|
||||
foreach (var item in ngData)
|
||||
{
|
||||
ChartHelper.AddSeries(chartNgShow, item.DataType,
|
||||
SeriesChartType.Column, ChartValueType.Auto,
|
||||
MarkerStyle.Diamond, 4, Color.Red,
|
||||
Color.White, "", false, true);
|
||||
}
|
||||
|
||||
ConfigureNGChart();
|
||||
|
||||
var xData = ngData.Select(c => c.DataType).ToList();
|
||||
var yData = ngData.Select(c => c.DataCount).ToList();
|
||||
chartNgShow.Series[0].Points.DataBindXY(xData, yData);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CommonMethods.AddLog(true, "更新不良图表异常".Translated() + $":{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void ConfigureNGChart()
|
||||
{
|
||||
ChartHelper.SetTitle(chartNgShow, "各不良项".Translated(),
|
||||
new Font("微软雅黑", 12), Docking.Top, Color.White);
|
||||
ChartHelper.SetStyle(chartNgShow, Color.Transparent, Color.White);
|
||||
ChartHelper.SetLegend(chartNgShow, Docking.Top,
|
||||
StringAlignment.Center, Color.Transparent, Color.White);
|
||||
ChartHelper.SetXY(chartNgShow, "项名".Translated(), "数值".Translated(), 0,
|
||||
StringAlignment.Center, Color.White, Color.White,
|
||||
AxisArrowStyle.None, 1, false);
|
||||
ChartHelper.SetMajorGrid(chartNgShow, Color.Transparent, 1, 1);
|
||||
}
|
||||
|
||||
private void BindNGChartData()
|
||||
{
|
||||
var xData = CommonMethods.Lst_DefectTypeQty.Select(c => c.DataType).ToList();
|
||||
var yData = CommonMethods.Lst_DefectTypeQty.Select(c => c.DataCount).ToList();
|
||||
chartNgShow.Series[0].Points.DataBindXY(xData, yData);
|
||||
}
|
||||
}
|
||||
|
||||
// 扩展方法
|
||||
public static class ControlExtensions
|
||||
{
|
||||
public static void InvokeIfRequired(this Control control, Action action)
|
||||
{
|
||||
if (control.IsDisposed) return;
|
||||
|
||||
if (control.InvokeRequired)
|
||||
control.BeginInvoke(action);
|
||||
else
|
||||
action();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user