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
{
    /// <summary>
    /// 称重分析页面：查询称重记录，查看曲线点位和最终重量取值依据。
    /// </summary>
    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 ToolTip tip_Point = new ToolTip();

        private readonly List<decimal> _points = new List<decimal>();
        private PointF[] _chartPoints = new PointF[0];
        private int _finalStartSeq;
        private int _finalEndSeq;
        private decimal? _finalWeight;
        private int _sampleIntervalMs;
        private int _lastTipSeq;

        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();
            pnl_Chart.MouseMove += pnl_Chart_MouseMove;
            pnl_Chart.MouseLeave += (s, e) => HidePointTip();
        }

        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();
            HidePointTip();
            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();
            HidePointTip();
            _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)
            {
                _chartPoints = new PointF[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);

            _chartPoints = BuildPointLocations(padL, padT, chartW, chartH, minVal, maxVal);
            DrawHighlightWindow(g, _chartPoints, padT, chartH);
            DrawCurve(g, _chartPoints);
            DrawPoints(g, _chartPoints);
            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 pnl_Chart_MouseMove(object sender, MouseEventArgs e)
        {
            int index = FindNearestPointIndex(e.Location);
            if (index < 0)
            {
                HidePointTip();
                return;
            }

            int seq = index + 1;
            if (seq == _lastTipSeq) return;

            _lastTipSeq = seq;
            string finalText = IsInFinalWindow(seq) ? "\r\n取值依据：最终采用区间内" : "";
            string tipText = $"第 {seq} 点\r\n重量：{_points[index]:F3} kg\r\n时间：{FormatElapsedTime(seq)}{finalText}";
            tip_Point.Show(tipText, pnl_Chart, e.Location.X + 16, e.Location.Y + 16, 3000);
        }

        private int FindNearestPointIndex(Point mouse)
        {
            if (_chartPoints.Length == 0 || _points.Count == 0) return -1;

            int nearestIndex = -1;
            double nearestDistance = double.MaxValue;
            for (int i = 0; i < _chartPoints.Length; i++)
            {
                double dx = _chartPoints[i].X - mouse.X;
                double dy = _chartPoints[i].Y - mouse.Y;
                double distance = dx * dx + dy * dy;
                if (distance < nearestDistance)
                {
                    nearestDistance = distance;
                    nearestIndex = i;
                }
            }

            return nearestDistance <= 144 ? nearestIndex : -1; // 鼠标离点 12px 内才显示，避免误触。
        }

        private string FormatElapsedTime(int seq)
        {
            int interval = _sampleIntervalMs > 0 ? _sampleIntervalMs : 200;
            int totalMs = Math.Max(0, seq - 1) * interval; // 第1点按采集起点0ms估算。
            int seconds = totalMs / 1000;
            int milliseconds = totalMs % 1000;
            return $"{seconds}秒{milliseconds:D3}毫秒";
        }

        private void HidePointTip()
        {
            _lastTipSeq = 0;
            tip_Point.Hide(pnl_Chart);
        }

        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);
            }
        }
    }
}
