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
+