From 8784a5a98239732989ab95a72addcab2c3ffbc79 Mon Sep 17 00:00:00 2001 From: XingCheng3 <1773407212@qq.com> Date: Wed, 13 May 2026 01:22:00 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=B0=E9=87=8D=E5=88=86=E6=9E=90=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E6=96=B0=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SCADA/MAIN_PAGE.cs | 46 ++- SCADA/Pages/UC_Weighing.cs | 2 +- SCADA/Pages/UC_WeighingAnalysis.cs | 483 +++++++++++++++++++++++++++++ SCADA/WC_GKJ_OIL.csproj | 17 +- 4 files changed, 539 insertions(+), 9 deletions(-) create mode 100644 SCADA/Pages/UC_WeighingAnalysis.cs diff --git a/SCADA/MAIN_PAGE.cs b/SCADA/MAIN_PAGE.cs index c6361a4..29aff2f 100644 --- a/SCADA/MAIN_PAGE.cs +++ b/SCADA/MAIN_PAGE.cs @@ -27,6 +27,7 @@ namespace MesWork OnStart(); InitializeComponent(); + InsertWeighingAnalysisNav(); CheckForIllegalCrossThreadCalls = false; IsMdiContainer = false; @@ -161,7 +162,13 @@ namespace MesWork string pageKey = ""; UserControl uc = null; - if (navTag.Contains("称重")) + if (navTag.Contains("称重分析")) + { + pageKey = "weighing_analysis"; + if (!_pageCache.ContainsKey(pageKey)) + _pageCache[pageKey] = new Pages.UC_WeighingAnalysis(); + } + else if (navTag.Contains("称重")) { pageKey = "weighing"; if (!_pageCache.ContainsKey(pageKey)) @@ -228,6 +235,43 @@ namespace MesWork } } + /// + /// 在统计分析后插入称重分析入口,减少对设计器文件的手工改动。 + /// + private void InsertWeighingAnalysisNav() + { + var pnlNav = new Panel + { + BackColor = Color.FromArgb(30, 58, 95), + Cursor = Cursors.Hand, + Location = new Point(1, 470), + Name = "pnl_NavWeighingAnalysis", + Size = new Size(78, 64), + Tag = "📈\n称重分析" + }; + var lblNav = new Label + { + AutoSize = false, + Cursor = Cursors.Hand, + Dock = DockStyle.Fill, + Font = new Font("微软雅黑", 9F), + ForeColor = Color.FromArgb(148, 163, 184), + Text = "📈\n称重分析", + TextAlign = ContentAlignment.MiddleCenter + }; + + pnlNav.Controls.Add(lblNav); + pnlNav.Click += Nav_Click; + lblNav.Click += Nav_Click; + + pnl_NavSettings.Top += 66; // 称重分析占用一个导航位,后续菜单整体下移。 + pnl_NavLog.Top += 66; + pnl_NavPLC.Top += 66; + pnl_SidebarScroll.Controls.Add(pnlNav); + pnlNav.BringToFront(); + pnl_NavActiveIndicator.BringToFront(); + } + // ==================================================================== // Timer Events // ==================================================================== diff --git a/SCADA/Pages/UC_Weighing.cs b/SCADA/Pages/UC_Weighing.cs index 05cfe4d..828cf60 100644 --- a/SCADA/Pages/UC_Weighing.cs +++ b/SCADA/Pages/UC_Weighing.cs @@ -382,7 +382,7 @@ namespace MesWork.Pages valueLabel.BackColor = panel.BackColor; valueLabel.Font = new System.Drawing.Font("微软雅黑", valueFontSize, System.Drawing.FontStyle.Bold); valueLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(30)))), ((int)(((byte)(58)))), ((int)(((byte)(95))))); - int unitWidth = unit == "KG/L" ? 66 : (unit == "ppm" ? 58 : 38); + int unitWidth = unit == "KG/L" ? 66 : (unit == "ppm" ? 76 : 38); int valueRightPadding = unitLabel == null ? 16 : unitWidth + 24; valueLabel.Location = new System.Drawing.Point(20, height >= 100 ? 24 : 20); valueLabel.Size = new System.Drawing.Size(Math.Max(72, width - 20 - valueRightPadding), height >= 100 ? height - 40 : height - 24); diff --git a/SCADA/Pages/UC_WeighingAnalysis.cs b/SCADA/Pages/UC_WeighingAnalysis.cs new file mode 100644 index 0000000..b1183d2 --- /dev/null +++ b/SCADA/Pages/UC_WeighingAnalysis.cs @@ -0,0 +1,483 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Globalization; +using System.Linq; +using System.Windows.Forms; +using MesWork; + +namespace MesWork.Pages +{ + /// + /// 称重分析页面:查询称重记录,查看曲线点位和最终重量取值依据。 + /// + public class UC_WeighingAnalysis : UserControl + { + private readonly Panel pnl_QueryBar = new Panel(); + private readonly DateTimePicker dtp_Start = new DateTimePicker(); + private readonly DateTimePicker dtp_End = new DateTimePicker(); + private readonly TextBox txt_ProductNo = new TextBox(); + private readonly TextBox txt_ModelNo = new TextBox(); + private readonly TextBox txt_OrderNo = new TextBox(); + private readonly Button btn_Query = new Button(); + private readonly SplitContainer split_Main = new SplitContainer(); + private readonly Panel pnl_Chart = new Panel(); + private readonly Panel pnl_Info = new Panel(); + private readonly DataGridView dgv_Data = new DataGridView(); + + private readonly Label lbl_Title = new Label(); + private readonly Label lbl_FinalWeight = new Label(); + private readonly Label lbl_Window = new Label(); + private readonly Label lbl_Method = new Label(); + private readonly Label lbl_Product = new Label(); + private readonly Label lbl_Sample = new Label(); + private readonly Label lbl_Status = new Label(); + + private readonly List _points = new List(); + private int _finalStartSeq; + private int _finalEndSeq; + private decimal? _finalWeight; + private int _sampleIntervalMs; + + private static readonly Color ClrPrimary = Color.FromArgb(74, 144, 217); + private static readonly Color ClrPrimaryDark = Color.FromArgb(30, 58, 95); + private static readonly Color ClrAccent = Color.FromArgb(245, 158, 11); + private static readonly Color ClrGood = Color.FromArgb(5, 150, 105); + private static readonly Color ClrGrid = Color.FromArgb(229, 231, 235); + private static readonly Color ClrText = Color.FromArgb(55, 65, 81); + private static readonly Color ClrMuted = Color.FromArgb(107, 114, 128); + + public UC_WeighingAnalysis() + { + InitializeLayout(); + InitGrid(); + dtp_Start.Value = DateTime.Today.AddDays(-30); + dtp_End.Value = DateTime.Today; + SetHint(txt_ProductNo, "产品编号..."); + SetHint(txt_ModelNo, "机型号..."); + SetHint(txt_OrderNo, "工单号..."); + pnl_Chart.Paint += pnl_Chart_Paint; + pnl_Chart.Resize += (s, e) => pnl_Chart.Invalidate(); + } + + private void InitializeLayout() + { + BackColor = Color.FromArgb(245, 247, 250); + Dock = DockStyle.Fill; + + pnl_QueryBar.BackColor = Color.White; + pnl_QueryBar.Dock = DockStyle.Top; + pnl_QueryBar.Height = 56; + pnl_QueryBar.Padding = new Padding(16, 0, 16, 0); + Controls.Add(split_Main); + Controls.Add(pnl_QueryBar); + + AddQueryLabel("从", 16); + InitDatePicker(dtp_Start, 40); + AddQueryLabel("到", 180); + InitDatePicker(dtp_End, 204); + InitTextBox(txt_ProductNo, 365, 150); + InitTextBox(txt_ModelNo, 525, 130); + InitTextBox(txt_OrderNo, 665, 150); + InitButton(); + + split_Main.Dock = DockStyle.Fill; + split_Main.Orientation = Orientation.Horizontal; + split_Main.SplitterDistance = 430; + split_Main.SplitterWidth = 6; + split_Main.Panel1.Padding = new Padding(12, 8, 12, 4); + split_Main.Panel2.Padding = new Padding(12, 4, 12, 12); + split_Main.Panel1.Controls.Add(pnl_Chart); + split_Main.Panel1.Controls.Add(pnl_Info); + split_Main.Panel2.Controls.Add(dgv_Data); + + pnl_Info.BackColor = Color.FromArgb(248, 250, 252); + pnl_Info.Dock = DockStyle.Right; + pnl_Info.Width = 340; + pnl_Info.Padding = new Padding(20, 12, 20, 12); + pnl_Info.Controls.Add(lbl_Status); + pnl_Info.Controls.Add(lbl_Sample); + pnl_Info.Controls.Add(lbl_Product); + pnl_Info.Controls.Add(lbl_Method); + pnl_Info.Controls.Add(lbl_Window); + pnl_Info.Controls.Add(lbl_FinalWeight); + + InitInfoLabel(lbl_FinalWeight, 18, FontStyle.Bold, ClrGood, 18); + InitInfoLabel(lbl_Window, 11, FontStyle.Bold, ClrPrimaryDark, 78); + InitInfoLabel(lbl_Method, 10, FontStyle.Regular, ClrText, 124); + InitInfoLabel(lbl_Product, 10, FontStyle.Regular, ClrText, 210); + InitInfoLabel(lbl_Sample, 10, FontStyle.Regular, ClrText, 246); + InitInfoLabel(lbl_Status, 10, FontStyle.Regular, ClrMuted, 282); + + pnl_Chart.BackColor = Color.White; + pnl_Chart.Dock = DockStyle.Fill; + pnl_Chart.Padding = new Padding(18, 8, 18, 8); + pnl_Chart.Controls.Add(lbl_Title); + + lbl_Title.Dock = DockStyle.Top; + lbl_Title.Height = 34; + lbl_Title.Font = new Font("微软雅黑", 12F, FontStyle.Bold); + lbl_Title.ForeColor = ClrPrimaryDark; + lbl_Title.Text = "称重曲线与最终取值依据"; + lbl_Title.TextAlign = ContentAlignment.MiddleLeft; + } + + private void AddQueryLabel(string text, int x) + { + var label = new Label + { + AutoSize = true, + Font = new Font("微软雅黑", 10F), + ForeColor = ClrText, + Location = new Point(x, 18), + Text = text + }; + pnl_QueryBar.Controls.Add(label); + } + + private void InitDatePicker(DateTimePicker picker, int x) + { + picker.Font = new Font("微软雅黑", 10F); + picker.Format = DateTimePickerFormat.Short; + picker.Location = new Point(x, 13); + picker.Size = new Size(130, 25); + pnl_QueryBar.Controls.Add(picker); + } + + private void InitTextBox(TextBox textBox, int x, int width) + { + textBox.BorderStyle = BorderStyle.FixedSingle; + textBox.Font = new Font("微软雅黑", 10F); + textBox.Location = new Point(x, 13); + textBox.Size = new Size(width, 27); + pnl_QueryBar.Controls.Add(textBox); + } + + private void InitButton() + { + btn_Query.BackColor = ClrPrimary; + btn_Query.Cursor = Cursors.Hand; + btn_Query.FlatAppearance.BorderSize = 0; + btn_Query.FlatStyle = FlatStyle.Flat; + btn_Query.Font = new Font("微软雅黑", 10F, FontStyle.Bold); + btn_Query.ForeColor = Color.White; + btn_Query.Location = new Point(830, 12); + btn_Query.Size = new Size(110, 30); + btn_Query.Text = "查询分析"; + btn_Query.UseVisualStyleBackColor = false; + btn_Query.Click += btn_Query_Click; + pnl_QueryBar.Controls.Add(btn_Query); + } + + private void InitInfoLabel(Label label, float fontSize, FontStyle style, Color color, int y) + { + label.Font = new Font("微软雅黑", fontSize, style); + label.ForeColor = color; + label.Location = new Point(20, y); + label.Size = new Size(300, y == 124 ? 72 : 32); + label.TextAlign = ContentAlignment.MiddleLeft; + } + + private void InitGrid() + { + dgv_Data.AllowUserToAddRows = false; + dgv_Data.AllowUserToDeleteRows = false; + dgv_Data.AllowUserToResizeRows = false; + dgv_Data.AutoGenerateColumns = false; + dgv_Data.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; + dgv_Data.BackgroundColor = Color.White; + dgv_Data.BorderStyle = BorderStyle.None; + dgv_Data.CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal; + dgv_Data.ColumnHeadersHeight = 40; + dgv_Data.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; + dgv_Data.ColumnHeadersDefaultCellStyle.BackColor = Color.FromArgb(232, 237, 242); + dgv_Data.ColumnHeadersDefaultCellStyle.ForeColor = ClrPrimaryDark; + dgv_Data.ColumnHeadersDefaultCellStyle.Font = new Font("微软雅黑", 10F, FontStyle.Bold); + dgv_Data.DefaultCellStyle.Font = new Font("微软雅黑", 10F); + dgv_Data.DefaultCellStyle.ForeColor = Color.FromArgb(31, 41, 55); + dgv_Data.DefaultCellStyle.SelectionBackColor = Color.FromArgb(219, 234, 254); + dgv_Data.DefaultCellStyle.SelectionForeColor = ClrPrimaryDark; + dgv_Data.DefaultCellStyle.Padding = new Padding(6, 0, 6, 0); + dgv_Data.AlternatingRowsDefaultCellStyle.BackColor = Color.FromArgb(248, 250, 252); + dgv_Data.Dock = DockStyle.Fill; + dgv_Data.EnableHeadersVisualStyles = false; + dgv_Data.GridColor = ClrGrid; + dgv_Data.MultiSelect = false; + dgv_Data.ReadOnly = true; + dgv_Data.RowHeadersVisible = false; + dgv_Data.RowTemplate.Height = 36; + dgv_Data.SelectionMode = DataGridViewSelectionMode.FullRowSelect; + dgv_Data.SelectionChanged += dgv_Data_SelectionChanged; + + dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = "检测时间", DataPropertyName = "测试时间", FillWeight = 95 }); + dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = "产品编号", DataPropertyName = "发动机号", FillWeight = 110 }); + dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = "工单号", DataPropertyName = "订单号", FillWeight = 95 }); + dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = "机型号", DataPropertyName = "机型号", FillWeight = 65 }); + dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = "称重类型", DataPropertyName = "称重类型", FillWeight = 70 }); + dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = "工位号", DataPropertyName = "设备编号", FillWeight = 60 }); + dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = "最终重量", DataPropertyName = "最终重量", FillWeight = 70, DefaultCellStyle = new DataGridViewCellStyle { Format = "F3" } }); + dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = "取点区间", DataPropertyName = "取点区间", FillWeight = 70 }); + dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = "采样点数", DataPropertyName = "采样点数", FillWeight = 60 }); + dgv_Data.Columns.Add(new DataGridViewTextBoxColumn { HeaderText = "操作员", DataPropertyName = "操作员", FillWeight = 60 }); + } + + private void SetHint(TextBox txt, string hint) + { + txt.Tag = hint; + txt.Text = hint; + txt.ForeColor = Color.FromArgb(156, 163, 175); + txt.GotFocus += (s, e) => { if (txt.Text == hint) { txt.Text = ""; txt.ForeColor = ClrPrimaryDark; } }; + txt.LostFocus += (s, e) => { if (string.IsNullOrWhiteSpace(txt.Text)) { txt.Text = hint; txt.ForeColor = Color.FromArgb(156, 163, 175); } }; + } + + private string GetHintValue(TextBox txt) + { + return txt.Text == txt.Tag?.ToString() ? "" : txt.Text.Trim(); + } + + private void btn_Query_Click(object sender, EventArgs e) + { + QueryData(); + } + + private void QueryData() + { + try + { + var parms = new SqlParameter[] + { + new SqlParameter("@发动机号", GetHintValue(txt_ProductNo)), + new SqlParameter("@机型号", GetHintValue(txt_ModelNo)), + new SqlParameter("@工单号", GetHintValue(txt_OrderNo)), + new SqlParameter("@开始时间", dtp_Start.Value.ToString("yyyy-MM-dd")), + new SqlParameter("@结束时间", dtp_End.Value.AddDays(1).ToString("yyyy-MM-dd")) + }; + SqlOperation.ExecuteStoredProcedure("称重分析_查询", parms, out DataTable dt, out string err); + if (!string.IsNullOrWhiteSpace(err)) + throw new Exception(err); + + dgv_Data.DataSource = dt; + if (dt == null || dt.Rows.Count == 0) + { + ClearCurve("查询范围内无曲线数据"); + MessageBox.Show("查询范围内无称重曲线记录", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + catch (Exception ex) + { + MessageBox.Show($"查询失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void dgv_Data_SelectionChanged(object sender, EventArgs e) + { + if (dgv_Data.CurrentRow?.DataBoundItem is DataRowView rowView) + { + LoadCurve(rowView.Row); + } + } + + private void LoadCurve(DataRow row) + { + _points.Clear(); + string pointValues = row.Table.Columns.Contains("点位值") ? row["点位值"]?.ToString() : ""; + foreach (string item in (pointValues ?? "").Split('|')) + { + if (decimal.TryParse(item, NumberStyles.Number, CultureInfo.InvariantCulture, out decimal value)) + _points.Add(value); + } + + _finalStartSeq = ToInt(row, "最终取点开始序号"); + _finalEndSeq = ToInt(row, "最终取点结束序号"); + _sampleIntervalMs = ToInt(row, "采样间隔ms"); + _finalWeight = ToNullableDecimal(row, "最终重量"); + + string productNo = GetText(row, "发动机号"); + string stationNo = GetText(row, "设备编号"); + lbl_FinalWeight.Text = _finalWeight.HasValue ? $"最终重量 {_finalWeight.Value:F3} kg" : "最终重量 —"; + lbl_Window.Text = _finalStartSeq > 0 && _finalEndSeq > 0 + ? $"依据点位 第 {_finalStartSeq} - {_finalEndSeq} 点" + : "依据点位 未记录"; + lbl_Method.Text = "计算方式 取连续20点中极差最小的一段,去掉一个最大值和一个最小值,剩余18点求平均。"; + lbl_Product.Text = $"产品编号 {productNo}"; + lbl_Sample.Text = $"工位号 {stationNo} 采样点数 {_points.Count} 间隔 {_sampleIntervalMs}ms"; + lbl_Status.Text = _points.Count > 0 ? "曲线状态 已加载,可追溯最终取值区间" : "曲线状态 无点位数据"; + pnl_Chart.Invalidate(); + } + + private void ClearCurve(string msg) + { + _points.Clear(); + _finalWeight = null; + _finalStartSeq = 0; + _finalEndSeq = 0; + lbl_FinalWeight.Text = "最终重量 —"; + lbl_Window.Text = "依据点位 —"; + lbl_Method.Text = "计算方式 —"; + lbl_Product.Text = ""; + lbl_Sample.Text = ""; + lbl_Status.Text = msg; + pnl_Chart.Invalidate(); + } + + private int ToInt(DataRow row, string column) + { + if (!row.Table.Columns.Contains(column) || row[column] == DBNull.Value) return 0; + int.TryParse(row[column].ToString(), out int value); + return value; + } + + private decimal? ToNullableDecimal(DataRow row, string column) + { + if (!row.Table.Columns.Contains(column) || row[column] == DBNull.Value) return null; + return decimal.TryParse(row[column].ToString(), out decimal value) ? value : (decimal?)null; + } + + private string GetText(DataRow row, string column) + { + return row.Table.Columns.Contains(column) && row[column] != DBNull.Value ? row[column].ToString() : ""; + } + + private void pnl_Chart_Paint(object sender, PaintEventArgs e) + { + Graphics g = e.Graphics; + g.SmoothingMode = SmoothingMode.AntiAlias; + g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; + Rectangle rect = pnl_Chart.ClientRectangle; + using (var bg = new SolidBrush(Color.White)) + g.FillRectangle(bg, rect); + + int padL = 70, padR = 36, padT = 54, padB = 54; + int chartW = rect.Width - padL - padR; + int chartH = rect.Height - padT - padB; + if (chartW < 80 || chartH < 80) return; + + if (_points.Count == 0) + { + DrawCenterText(g, rect, "选择一条称重记录后显示曲线"); + return; + } + + decimal minDec = _points.Min(); + decimal maxDec = _points.Max(); + double minVal = (double)minDec; + double maxVal = (double)maxDec; + double range = maxVal - minVal; + if (range < 0.001) range = Math.Max(Math.Abs(maxVal) * 0.1, 1); + minVal -= range * 0.15; + maxVal += range * 0.15; + + DrawGrid(g, padL, padT, chartW, chartH, minVal, maxVal); + + PointF[] points = BuildPointLocations(padL, padT, chartW, chartH, minVal, maxVal); + DrawHighlightWindow(g, points, padT, chartH); + DrawCurve(g, points); + DrawPoints(g, points); + DrawFinalLine(g, padL, padT, chartW, chartH, minVal, maxVal); + } + + private void DrawGrid(Graphics g, int padL, int padT, int chartW, int chartH, double minVal, double maxVal) + { + using (var axisPen = new Pen(Color.FromArgb(200, 210, 220), 1)) + using (var gridPen = new Pen(ClrGrid, 1) { DashStyle = DashStyle.Dot }) + using (var font = new Font("微软雅黑", 9F)) + using (var brush = new SolidBrush(ClrMuted)) + { + g.DrawLine(axisPen, padL, padT, padL, padT + chartH); + g.DrawLine(axisPen, padL, padT + chartH, padL + chartW, padT + chartH); + for (int i = 0; i <= 5; i++) + { + int y = padT + chartH - (int)(chartH * i / 5.0); + if (i > 0) g.DrawLine(gridPen, padL + 1, y, padL + chartW, y); + string text = (minVal + (maxVal - minVal) * i / 5.0).ToString("F2"); + SizeF size = g.MeasureString(text, font); + g.DrawString(text, font, brush, padL - size.Width - 6, y - size.Height / 2); + } + } + } + + private PointF[] BuildPointLocations(int padL, int padT, int chartW, int chartH, double minVal, double maxVal) + { + var points = new PointF[_points.Count]; + for (int i = 0; i < _points.Count; i++) + { + float x = _points.Count == 1 ? padL + chartW / 2f : padL + chartW * i / (float)(_points.Count - 1); + float y = padT + chartH - (float)(chartH * (((double)_points[i] - minVal) / (maxVal - minVal))); + points[i] = new PointF(x, y); + } + return points; + } + + private void DrawHighlightWindow(Graphics g, PointF[] points, int padT, int chartH) + { + if (_finalStartSeq <= 0 || _finalEndSeq <= 0 || _finalStartSeq > points.Length) return; + int startIndex = Math.Max(0, _finalStartSeq - 1); + int endIndex = Math.Min(points.Length - 1, _finalEndSeq - 1); + float x1 = points[startIndex].X; + float x2 = points[endIndex].X; + using (var brush = new SolidBrush(Color.FromArgb(46, 245, 158, 11))) + g.FillRectangle(brush, x1, padT, Math.Max(2, x2 - x1), chartH); + using (var pen = new Pen(ClrAccent, 1.6f) { DashStyle = DashStyle.Dash }) + { + g.DrawLine(pen, x1, padT, x1, padT + chartH); + g.DrawLine(pen, x2, padT, x2, padT + chartH); + } + } + + private void DrawCurve(Graphics g, PointF[] points) + { + if (points.Length < 2) return; + using (var shadow = new Pen(Color.FromArgb(34, 74, 144, 217), 5f) { LineJoin = LineJoin.Round }) + using (var line = new Pen(ClrPrimary, 2.2f) { LineJoin = LineJoin.Round }) + { + g.DrawLines(shadow, points); + g.DrawLines(line, points); + } + } + + private void DrawPoints(Graphics g, PointF[] points) + { + int step = Math.Max(1, points.Length / 120); + for (int i = 0; i < points.Length; i += step) + { + Brush brush = IsInFinalWindow(i + 1) ? new SolidBrush(ClrAccent) : new SolidBrush(ClrPrimary); + using (brush) + g.FillEllipse(brush, points[i].X - 3, points[i].Y - 3, 6, 6); + } + } + + private void DrawFinalLine(Graphics g, int padL, int padT, int chartW, int chartH, double minVal, double maxVal) + { + if (!_finalWeight.HasValue) return; + float y = padT + chartH - (float)(chartH * (((double)_finalWeight.Value - minVal) / (maxVal - minVal))); + if (y < padT || y > padT + chartH) return; + using (var pen = new Pen(ClrGood, 1.8f) { DashStyle = DashStyle.Dash }) + using (var font = new Font("微软雅黑", 9F, FontStyle.Bold)) + using (var brush = new SolidBrush(ClrGood)) + { + g.DrawLine(pen, padL, y, padL + chartW, y); + string text = $"最终 {_finalWeight.Value:F3} kg"; + SizeF size = g.MeasureString(text, font); + g.DrawString(text, font, brush, padL + chartW - size.Width - 4, y - size.Height - 4); + } + } + + private bool IsInFinalWindow(int seq) + { + return _finalStartSeq > 0 && _finalEndSeq > 0 && seq >= _finalStartSeq && seq <= _finalEndSeq; + } + + private void DrawCenterText(Graphics g, Rectangle rect, string text) + { + using (var font = new Font("微软雅黑", 14F)) + using (var brush = new SolidBrush(Color.FromArgb(156, 163, 175))) + { + SizeF size = g.MeasureString(text, font); + g.DrawString(text, font, brush, (rect.Width - size.Width) / 2, (rect.Height - size.Height) / 2); + } + } + } +} diff --git a/SCADA/WC_GKJ_OIL.csproj b/SCADA/WC_GKJ_OIL.csproj index faf92e4..8f02134 100644 --- a/SCADA/WC_GKJ_OIL.csproj +++ b/SCADA/WC_GKJ_OIL.csproj @@ -249,12 +249,15 @@ UC_StationRecord.cs - - UserControl - - - UC_Statistics.cs - + + UserControl + + + UserControl + + + UC_Statistics.cs + @@ -364,4 +367,4 @@ - \ No newline at end of file +