using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Linq; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; using JY.DAL; using JY.Model; using JY.Utility; using MetroFramework.Forms; namespace JY.Inspection.Frm { public partial class FrmStatistics : MetroForm { /// /// 数据库访问接口 /// private IDbHelper dbHelper = new OpSqlDataBase(); /// /// 读取成功 /// public bool isReadOK = true; /// /// Timer是否运行 /// public bool isEnabled = false; /// /// chart图表Y轴的上限值 /// int iChartHeight = 5000; /// /// 读取 /// public System.Timers.Timer timerStatistics1; /// /// 读取24小时产能统计 /// public System.Timers.Timer timer_HourProd; /// /// 投入产出饼状图显示委托 /// /// /// private delegate void UpdateDataChart2(List xData, List yData); /// /// 各不良统计NG显示委托 /// /// private delegate void UpdateDataChart3(List xData, List yData); /// /// 不良统计项目 /// List NGList = new List(); /// /// 生产统计项目 /// List ProductionList = new List(); public FrmStatistics() { InitializeComponent(); } /// /// 窗体实例 /// private static FrmStatistics _instance; internal static FrmStatistics Instance { get { if (_instance == null) _instance = new FrmStatistics(); return _instance; } } private void FrmStatistics_Load(object sender, EventArgs e) { //SetProductionList(); //OrgChart(); //GetValue(); //InitTimer(); } /// /// 初始化Timer控件 /// internal void InitTimer() { OrgChart(); SetProductionList(); isEnabled = true; } /// ///定义饼图和右上角柱状图显示类型 /// /// internal void SetProductionList() { //不良统计项目 NGList.Add(new ChartDataType() { DataType = "线扫扫码NG" }); NGList.Add(new ChartDataType() { DataType = "分档扫码NG" }); NGList.Add(new ChartDataType() { DataType = "侧面不良" }); NGList.Add(new ChartDataType() { DataType = "正极不良" }); NGList.Add(new ChartDataType() { DataType = "负极不良" }); //生产统计项目 ProductionList.Add(new ChartDataType() { DataType = "生产总数" }); ProductionList.Add(new ChartDataType() { DataType = "良品数" }); ProductionList.Add(new ChartDataType() { DataType = "不良数" }); } /// /// Chart控件初始化 /// internal void OrgChart() { #region 24小时统计 chart1.Series.Clear(); chart1.Titles.Clear(); chart1.ChartAreas[0].AxisY.Minimum = 0; chart1.ChartAreas[0].AxisY.Maximum = iChartHeight + 500; ChartHelper.AddSeries(chart1, "投入", SeriesChartType.Column, Color.DodgerBlue, Color.Red, true); ChartHelper.AddSeries(chart1, "产出", SeriesChartType.Column, Color.Lime, Color.Red, true); ChartHelper.AddSeries(chart1, "优率", SeriesChartType.Spline, Color.Red, Color.Red); ChartHelper.SetTitle(chart1, "当日每2小时投入与产出", new Font("微软雅黑", 18), Docking.Top, Color.Black); ChartHelper.SetStyle(chart1, Color.White, Color.Black); ChartHelper.SetLegend(chart1, Docking.Top, StringAlignment.Center, Color.White, Color.Black); ChartHelper.SetXY(chart1, "时间", "数值", StringAlignment.Far, Color.Black, Color.Black, AxisArrowStyle.None, 1, 2); ChartHelper.SetMajorGrid(chart1, Color.White, 20, 2); #endregion #region 数据统计 chartNgShow.Series.Clear(); chartNgShow.Titles.Clear(); chartNgShow.ChartAreas[0].AxisY.Minimum = 0; chartNgShow.ChartAreas[0].AxisY.Maximum = iChartHeight + 500; foreach (var item in NGList) { ChartHelper.AddSeries(chartNgShow, item.DataType, SeriesChartType.Column, Color.Red, Color.Red, true); } ChartHelper.SetTitle(chartNgShow, "各不良项", new Font("微软雅黑", 22), Docking.Top, Color.Black); ChartHelper.SetStyle(chartNgShow, Color.White, Color.Black); ChartHelper.SetLegend(chartNgShow, Docking.Top, StringAlignment.Center, Color.White, Color.Black); ChartHelper.SetXY(chartNgShow, "不良项", "数值", StringAlignment.Far, Color.Black, Color.Black, AxisArrowStyle.None, 1, 2); ChartHelper.SetMajorGrid(chartNgShow, Color.White, 20, 2); #endregion //投入产出统计 ChartHelper.SetTitle(chartToalShow, "投入产出", new Font("微软雅黑", 22), Docking.Top, Color.Black); chartToalShow.Series[0].ChartType = SeriesChartType.Pie;//设置图表类型为饼图 //chart2.Series[0].CustomProperties="PieLabel"+"PieSize = 50";//设置饼图参数 chartToalShow.Series[0].CustomProperties = "DoughnutRadius=60, PieLabelStyle=Disabled, PieDrawingStyle=SoftEdge"; chartToalShow.Series[0]["PieLabelStyle"] = "Inside";//将文字移到外侧 chartToalShow.Series[0].XValueType = ChartValueType.String; } /// /// 读取PLC产能统计 /// /// /// private void TimerUpGetData() { if (!HomeForm.startup) { return; } if (isReadOK) { isReadOK = false; GetValue(); } } /// /// 获取图表数据 /// public void GetValue() { try { if (isEnabled) { int ProdAllQty = HomeForm.omronPLCCom.lstMcUI[0].ReadIntDReg("HMI.生产总数"); int ProdOKQty = HomeForm.omronPLCCom.lstMcUI[0].ReadIntDReg("HMI.OK总数"); int ProdNGQty= HomeForm.omronPLCCom.lstMcUI[0].ReadIntDReg("HMI.NG总数"); int ProdSanNgQty = 123;//扫码NG int ProdVolNgQty = 145;//电压NG //從PLC讀取數據賦值給到NGList ProductionList.Where(p => p.DataType == "生产总数").FirstOrDefault().DataCount = ProdAllQty; ProductionList.Where(p => p.DataType == "良品数").FirstOrDefault().DataCount = ProdOKQty; ProductionList.Where(p => p.DataType == "不良数").FirstOrDefault().DataCount = ProdNGQty; //從PLC讀取數據賦值給到NGList NGList.Where(p => p.DataType == "线扫扫码NG").FirstOrDefault().DataCount = ProdSanNgQty; NGList.Where(p => p.DataType == "分档扫码NG").FirstOrDefault().DataCount = ProdSanNgQty; NGList.Where(p => p.DataType == "侧面不良").FirstOrDefault().DataCount = ProdVolNgQty; NGList.Where(p => p.DataType == "正极不良").FirstOrDefault().DataCount = ProdVolNgQty; NGList.Where(p => p.DataType == "负极不良").FirstOrDefault().DataCount = ProdSanNgQty; ShowChartData(); //------------------------------每小时产能------------------------------------------ string strErr = ""; DateTime dateTime = DateTime.Now; string strDate = dateTime.ToString("yyyy-MM-dd"); int Hour = dateTime.Hour; //读取PLC投入总数 int ProdCurrAllQty = GetToDayHourQty(Hour, true); //读取PLC产出数 int ProdCurrOKQty = GetToDayHourQty(Hour, false); HourprodEntity mh = new HourprodEntity(); mh.FDate = strDate; mh.FHour = Hour; mh.ProdIn = ProdCurrAllQty; mh.ProdOut = ProdCurrOKQty; mh.TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); var iResult = dbHelper.UpdateHourprodData(mh); if (iResult <= 0) { MessageBox.Show("存储每小时产能失败" + strErr, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Hand); LogHelper.Error("存储每小时产能失败" + strErr, new Exception("异常信息")); } isReadOK = true; } } catch (Exception ex) { LogHelper.Error(ex.Message, new Exception("异常信息")); timerStatistics1.Enabled = false; isReadOK = true; } } /// /// 每小时产能读取处理 /// /// /// /// private int GetToDayHourQty(int hour, bool flag) { try { string strAddr = ""; if (hour == 0) { hour = 24; } //else //{ // hour = hour - 1; //} if (flag)//产出 { strAddr = "W" + (1040 + hour); } else//良品数 { strAddr = "W" + (1070 + hour); } int ProdNGQty = HomeForm.omronPLCCom.lstMcUI[0].ReadIntDReg(strAddr);//生产NG数量 return ProdNGQty; } catch (Exception ex) { LogHelper.Error(ex.Message, new Exception("异常信息")); MessageBox.Show(ex.Message, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Hand); } return 0; } /// /// 刷新饼图生产统计信息;刷新生产不良统计信息 /// public void ShowChartData() { try { //不良类型统计 List xData = NGList.Select(c => c.DataType).ToList(); List yData = NGList.Select(c => c.DataCount).ToList(); ShowNGChart(xData, yData); //生产总数统计 var xlist = ProductionList.Select(c => c.DataType).ToList(); var ylist = ProductionList.Select(c => c.DataCount).ToList(); ShowChartToal(xlist, ylist); } catch (Exception ex) { LogHelper.Error(ex.Message, new Exception("异常信息")); MessageBox.Show(ex.Message, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Hand); } } /// /// 投入产出饼状图显示 /// /// /// private void ShowChartToal(List xData, List yData) { if (chartToalShow.InvokeRequired) { UpdateDataChart2 c = new UpdateDataChart2(ShowChartToal); this.Invoke(c, new object[] { xData, yData }); } else { chartToalShow.Series[0].Points.DataBindXY(xData, yData); } } /// /// 不良数统计显示 /// /// private void ShowNGChart(List xData, List yData) { if (chartNgShow.InvokeRequired) { UpdateDataChart3 c = new UpdateDataChart3(ShowNGChart); this.Invoke(c, new object[] { xData, yData }); } else { chartNgShow.Series[0].Points.DataBindXY(xData, yData); } } /// /// 读取产入产出 /// /// /// /// private void TimerUpHourProd() { try { if (isEnabled) { List chart24Hours = new List(); DateTime dtTime = DateTime.Now; string strDate = dtTime.ToString("yyyy-MM-dd"); int Hour = dtTime.Hour; var listTotal = dbHelper.GetProdTotal(strDate, 0);// 查询稼动率表中total数据 if (listTotal != null && listTotal.Count > 0) { for (int i = 1; i <= 12; i++) { if (!isEnabled) { break; } int j = i * 2; int m = j - 2; int n = j - 1; //当前时段第一个小时 var hour1 = listTotal.Where(p => p.FHour == m).FirstOrDefault(); //当前时段第二个小时 var hour2 = listTotal.Where(p => p.FHour == n).FirstOrDefault(); int ProdALLQty = 0; int ProdOKQty = 0; int ProdNGQty = 0; string strOkRatio = "0"; if (hour1 != null) { ProdALLQty += hour1.ProdIn; ProdOKQty += hour1.ProdOut; } if (hour2 != null) { ProdALLQty += hour2.ProdIn; ProdOKQty += hour2.ProdOut; } ProdNGQty = ProdALLQty - ProdOKQty; if (ProdNGQty > 0) { strOkRatio = Math.Round((ProdOKQty * 1.0 / ProdALLQty) * 100, 2) + "%"; } chart24Hours.Add(new Chart24HourData() { DisplayTime = m + ":00~" + n + ":59", ProdIn = ProdALLQty, ProdOut = ProdOKQty, ProdNg = ProdNGQty, OKRatio = strOkRatio }); } } else { Random rand = new Random(); for (int i = 1; i < 13; i++) { if (!isEnabled) { break; } int j = i * 2; int m = j - 2; int n = j - 1; int ranOK = rand.Next(1000, 3000); int ranNG = rand.Next(400, 1200); int total = ranOK + ranNG; chart24Hours.Add(new Chart24HourData() { DisplayTime = m + ":00~" + n + ":59", ProdIn = ranOK + ranNG, ProdOut = ranOK, ProdNg = ranNG, OKRatio = Math.Round((ranOK * 1.0 / total) * 100, 2) + "%" }); } } if (!isEnabled) { return; } UpdateGV(chart24Hours); BindChart(chart24Hours); } } catch (Exception ex) { LogHelper.Error(ex.Message, new Exception("异常信息")); MessageBox.Show(ex.Message, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Hand); timer_HourProd.Enabled = false; } } /// /// 更新24小时产能 /// /// private void UpdateGV(List list) { if (this.InvokeRequired) { this.BeginInvoke(new EventHandler(delegate { DataTable dtsShow = new DataTable(); for (int i = 1; i <= 13; i++) { dtsShow.Columns.Add("Col" + i); } dtsShow.Rows.Add(new object[] { "优率", list[0].OKRatio, list[1].OKRatio, list[2].OKRatio, list[3].OKRatio, list[4].OKRatio, list[5].OKRatio ,list[6].OKRatio, list[7].OKRatio, list[8].OKRatio, list[9].OKRatio, list[10].OKRatio, list[11].OKRatio }); dtsShow.Rows.Add(new object[] { "产出" , list[0].ProdOut, list[1].ProdOut, list[2].ProdOut, list[3].ProdOut, list[4].ProdOut, list[5].ProdOut ,list[6].ProdOut, list[7].ProdOut, list[8].ProdOut, list[9].ProdOut, list[10].ProdOut, list[11].ProdOut }); dtsShow.Rows.Add(new object[] { "投入", list[0].ProdIn, list[1].ProdIn, list[2].ProdIn, list[3].ProdIn, list[4].ProdIn, list[5].ProdIn ,list[6].ProdIn, list[7].ProdIn, list[8].ProdIn, list[9].ProdIn, list[10].ProdIn, list[11].ProdIn}); dtsShow.Rows.Add(new object[] { "时间" , list[0].DisplayTime, list[1].DisplayTime, list[2].DisplayTime, list[3].DisplayTime, list[4].DisplayTime, list[5].DisplayTime ,list[6].DisplayTime, list[7].DisplayTime, list[8].DisplayTime, list[9].DisplayTime, list[10].DisplayTime, list[11].DisplayTime }); dgvHShow.DataSource = dtsShow; dgvHShow.Refresh(); })); } } /// /// 更新24小时产能Chart柱状图显示 /// /// public void BindChart(List list) { if (this.InvokeRequired) { this.BeginInvoke(new EventHandler(delegate { var x1 = list.Select(c => c.DisplayTime).ToList(); var y1 = list.Select(c => c.ProdIn).ToList(); var y2 = list.Select(c => c.ProdOut).ToList(); chart1.Series[0].Points.DataBindXY(x1, y1); chart1.Series[1].Points.DataBindXY(x1, y2); chart1.Series[2].Points.DataBindXY(x1, y2); })); } } /// /// 窗口渐变透明 /// /// /// private void timerOpacity_Tick(object sender, EventArgs e) { this.Opacity += 0.1; if (this.Opacity == 1.0) { timerOpacity.Stop(); } } /// /// 关闭界面 /// /// /// public void FrmStatistics_FormClosing(object sender, FormClosingEventArgs e) { this.Visible = false; e.Cancel = true; } public void timerStatistics_Tick(object sender, EventArgs e) { TimerUpGetData(); } public void timer_HourProd2_Tick(object sender, EventArgs e) { TimerUpHourProd(); } } }