【问题标题】:Calculating values from a C# windows form application graph从 C# windows 窗体应用程序图中计算值
【发布时间】:2020-11-13 20:05:02
【问题描述】:

我正在进行热测试,其中有 3 个设定点值(+/1C)我需要确认。 设定点是

  1. 37C
  2. 60℃
  3. 80℃

我创建了一个 Windows 窗体应用程序,我可以在其中从“CSV”文件上传数据并将其绘制在应用程序上。

如何计算每个设定点范围的平均值、最小值和最大值? (标记的红色框不是来自应用程序)

有没有办法确定每个设定点的中心点并在中间任一侧的 2.5 分钟内计算?

CSV 数据如下所示

非常感谢任何帮助我朝着正确方向前进的 cmets

很抱歉回复太晚了。 我已经用代码和指向 CSV 数据的链接更新了问题

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Windows.Forms.DataVisualization.Charting;
namespace TBE_Temperature_Contral_Test
{
    public partial class Form1 : Form
    {

    public Form1()
    {
        InitializeComponent();
        CHART_CH1.MouseWheel += CHART_CH1_MouseWheel;
        CHART_CH2.MouseWheel += CHART_CH2_MouseWheel;
    }

    private void BTN_Load_Click(object sender, EventArgs e)
    {
        OpenFileDialog openFileDialog1 = new OpenFileDialog
        {
            InitialDirectory = @"C:\temp",// object of file dialog  sent to open file to default c drive
            Title = "Browse txt File",// text to show on the bar

            CheckFileExists = true,// check whether file exit
            CheckPathExists = true,//check file path

            DefaultExt = "txt",// the file default extensio
            Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*",//filter by default to only txt files
            FilterIndex = 2,
            RestoreDirectory = true,

            ReadOnlyChecked = true,
            ShowReadOnly = true
        };//creation and inialization of open file dialog 
        if (openFileDialog1.ShowDialog() == DialogResult.OK)// prompt for a file dialog
        {
            string SourcePath = openFileDialog1.FileName;
            DataTable dt = new DataTable();
            dt.Columns.AddRange(new DataColumn[10] { new DataColumn("No."), new DataColumn("Data"), new DataColumn("Time"), new DataColumn("ID"), new DataColumn("CH1"), new DataColumn("Type_1"), new DataColumn("Unit_1"), new DataColumn("CH2"), new DataColumn("Type_2"), new DataColumn("Unit_2") });
            List<string> list = new List<string>();
            using (StreamReader sr = new StreamReader(SourcePath))
            {
                while (sr.Peek() >= 0)
                {
                    list.Add(sr.ReadLine());
                }
            }
            for (int i = 1; i < list.Count; i++)
            {
                string[] strlist = list[i].Split('\t');
                dt.Rows.Add(strlist[0], strlist[1], strlist[2], strlist[3], strlist[4], strlist[5], strlist[6], strlist[7], strlist[8], strlist[9]);
            }
            var filteredCH136 = dt.AsEnumerable()
             .Where(r => r.Field<string>("CH1").Contains("36"));
            //dt.DefaultView.RowFilter = "No. LIKE '%" + "36" + "%'";
            string FirstCH136 = (from DataRow dr in dt.Rows
                                where (string)dr["CH1"] == "36"
                                select (string)dr["No."]).FirstOrDefault();
            label1.Text = FirstCH136.ToString();

            var filteredCH138 = dt.AsEnumerable()
             .Where(r => r.Field<string>("CH1").Contains("38"));
            //dt.DefaultView.RowFilter = "No. LIKE '%" + "36" + "%'";
            string FirstCH138 = (from DataRow dr in dt.Rows
                              where (string)dr["CH1"] == "38"
                              select (string)dr["No."]).FirstOrDefault();
            label2.Text = FirstCH138.ToString();
            CHART_CH1.Series.Add("CH1_36_38");

            CHART_CH1.Series.Add("CH1");
            CHART_CH2.Series.Add("CH2");
            CHART_CH1.Series["CH1_36_38"].ChartType = SeriesChartType.Line;
            CHART_CH1.Series["CH1"].ChartType = SeriesChartType.Line;
            CHART_CH1.Series["CH1"].Color = Color.Orange;
            CHART_CH2.Series["CH2"].ChartType = SeriesChartType.Line;
            CHART_CH2.Series["CH2"].Color = Color.Blue;
            //CHART_CH1.Series["CH1_36_38"].Points.AddXY(float.Parse(FirstCH136), 36);
            //CHART_CH1.Series["CH1_36_38"].Points.AddXY(float.Parse(FirstCH138), 38);
            CHART_CH1.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
            CHART_CH1.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
            CHART_CH2.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
            CHART_CH2.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
            
            CHART_CH1.DataSource = dt;
            CHART_CH2.DataSource = dt;

            CHART_CH1.Series["CH1"].XValueMember ="No.";
            CHART_CH1.Series["CH1"].YValueMembers = "CH1";
            CHART_CH2.Series["CH2"].XValueMember = "No.";
            CHART_CH2.Series["CH2"].YValueMembers = "CH2";
            //databind
            CHART_CH1.DataBind();
            CHART_CH2.DataBind();
        }
    }

    private void CHART_CH1_MouseEnter(object sender, EventArgs e)
    {
        if (!CHART_CH1.Focused)
            CHART_CH1.Focus();
    }

    private void CHART_CH2_MouseEnter(object sender, EventArgs e)
    {
        if (!CHART_CH2.Focused)
            CHART_CH2.Focus();
    }

    private void CHART_CH1_MouseLeave(object sender, EventArgs e)
    {
        if (CHART_CH1.Focused)
            CHART_CH1.Parent.Focus();
    }

    private void CHART_CH2_MouseLeave(object sender, EventArgs e)
    {
        if (CHART_CH2.Focused)
            CHART_CH2.Parent.Focus();
    }

    private void CHART_CH1_MouseWheel(object sender, MouseEventArgs e)
    {
        var chart = (Chart)sender;
        var xAxis = chart.ChartAreas[0].AxisX;
        var yAxis = chart.ChartAreas[0].AxisY;

        try
        {
            if (e.Delta < 0) // Scrolled down.
            {
                xAxis.ScaleView.ZoomReset();
                yAxis.ScaleView.ZoomReset();
            }
            else if (e.Delta > 0) // Scrolled up.
            {
                var xMin = xAxis.ScaleView.ViewMinimum;
                var xMax = xAxis.ScaleView.ViewMaximum;
                var yMin = yAxis.ScaleView.ViewMinimum;
                var yMax = yAxis.ScaleView.ViewMaximum;

                var posXStart = xAxis.PixelPositionToValue(e.Location.X) - (xMax - xMin) / 4;
                var posXFinish = xAxis.PixelPositionToValue(e.Location.X) + (xMax - xMin) / 4;
                var posYStart = yAxis.PixelPositionToValue(e.Location.Y) - (yMax - yMin) / 4;
                var posYFinish = yAxis.PixelPositionToValue(e.Location.Y) + (yMax - yMin) / 4;

                xAxis.ScaleView.Zoom(posXStart, posXFinish);
                yAxis.ScaleView.Zoom(posYStart, posYFinish);
            }
        }
        catch { throw; }
    }

    private void CHART_CH2_MouseWheel(object sender, MouseEventArgs e)
    {
        var chart = (Chart)sender;
        var xAxis = chart.ChartAreas[0].AxisX;
        var yAxis = chart.ChartAreas[0].AxisY;

        try
        {
            if (e.Delta < 0) // Scrolled down.
            {
                xAxis.ScaleView.ZoomReset();
                yAxis.ScaleView.ZoomReset();
            }
            else if (e.Delta > 0) // Scrolled up.
            {
                var xMin = xAxis.ScaleView.ViewMinimum;
                var xMax = xAxis.ScaleView.ViewMaximum;
                var yMin = yAxis.ScaleView.ViewMinimum;
                var yMax = yAxis.ScaleView.ViewMaximum;

                var posXStart = xAxis.PixelPositionToValue(e.Location.X) - (xMax - xMin) / 4;
                var posXFinish = xAxis.PixelPositionToValue(e.Location.X) + (xMax - xMin) / 4;
                var posYStart = yAxis.PixelPositionToValue(e.Location.Y) - (yMax - yMin) / 4;
                var posYFinish = yAxis.PixelPositionToValue(e.Location.Y) + (yMax - yMin) / 4;

                xAxis.ScaleView.Zoom(posXStart, posXFinish);
                yAxis.ScaleView.Zoom(posYStart, posYFinish);
            }
        }
        catch { throw; }
    }
}

}

C# Winform 有两个 char 控件,因为 CSV 有两个临时数据通道。

CSV 数据保存在 Pastebin C# Temp Data

我想检查温度是否稳定在 3 个给定范围内。它应该稳定至少 5 分钟,公差为 +/1 度。我不能对整个列表使用 min-max 和 average

【问题讨论】:

  • :是否以列表的形式从CSV文件中加载数据?你能告诉我们你的代码吗?
  • 您是使用自定义代码手动绘制图形还是使用某种控件?您当前是否将这些日期和时间列解析为有效的 DateTime 实例?给我们一些代码...
  • 您知道设定点出现的时间范围(列表中的索引)吗?这个问题与 winforms 或 ms-chart 无关。它只是读取 csv 数据并运行数据统计。
  • 第三个设定点看起来不像是在 80C 的 1C 范围内。应该使用数据中的哪些内容来找到达到设定点的位置?
  • 这是一个很好的开始。我立即看到您只是将所有这些数据作为直接字符串添加到 DataTable 中。您可以告诉 DataTable 每列的DATA TYPE。在将这些值添加到新行之前,您需要解析数据并将其转换为每种适当的类型。完成后,您将能够使用 LINQ 样式查询来回答问题。

标签: c# .net winforms math statistics


【解决方案1】:

运行结果显示最高温度、最低温度、平均温度在设定值37度以内。

如果要测试温度60,可以把60换成37。(另外你的txt文件没有80度。)

我做以下代码示例。

using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace TBE_Temperature_Contral_Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            CHART_CH1.MouseWheel += CHART_CH1_MouseWheel;
            CHART_CH2.MouseWheel += CHART_CH2_MouseWheel;
        }

        private void BTN_Load_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog1 = new OpenFileDialog
            {
                InitialDirectory = @"D:\TestData",// object of file dialog  sent to open file to default c drive
                Title = "Browse txt File",// text to show on the bar

                CheckFileExists = true,// check whether file exit
                CheckPathExists = true,//check file path

                DefaultExt = "txt",// the file default extensio
                Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*",//filter by default to only txt files
                FilterIndex = 2,
                RestoreDirectory = true,

                ReadOnlyChecked = true,
                ShowReadOnly = true
            };//creation and inialization of open file dialog 
            if (openFileDialog1.ShowDialog() == DialogResult.OK)// prompt for a file dialog
            {
                string SourcePath = openFileDialog1.FileName;
                DataTable dt = new DataTable();
                dt.Columns.AddRange(new DataColumn[10] { new DataColumn("No."), new DataColumn("Data"), new DataColumn("Time"), new DataColumn("ID"), new DataColumn("CH1"), new DataColumn("Type_1"), new DataColumn("Unit_1"), new DataColumn("CH2"), new DataColumn("Type_2"), new DataColumn("Unit_2") });
                List<string> list = new List<string>();
                using (StreamReader sr = new StreamReader(SourcePath))
                {
                    while (sr.Peek() >= 0)
                    {
                        //MessageBox.Show(sr.ReadLine());
                        list.Add(sr.ReadLine());

                    }
                }            
                    for (int i = 1; i < list.Count; i++)
                    {
                    string[] strlist = list[i].Split(',');                  
                    dt.Rows.Add(strlist[0], strlist[1], strlist[2], strlist[3], strlist[4], strlist[5], strlist[6], strlist[7], strlist[8], strlist[9]);
                    }
                var filteredCH136 = dt.AsEnumerable()
                 .Where(r => r.Field<string>("CH1").Contains("36"));
                //dt.DefaultView.RowFilter = "No. LIKE '%" + "36" + "%'";
                string FirstCH136 = (from DataRow dr in dt.Rows
                                     where (string)dr["CH1"] == "36"
                                     select (string)dr["No."]).FirstOrDefault();
                               
                label1.Text = FirstCH136.ToString();
                var filteredCH138 = dt.AsEnumerable()
                 .Where(r => r.Field<string>("CH1").Contains("38"));
                //dt.DefaultView.RowFilter = "No. LIKE '%" + "36" + "%'";
                string FirstCH138 = (from DataRow dr in dt.Rows
                                     where (string)dr["CH1"] == "38"
                                     select (string)dr["No."]).FirstOrDefault();
                label2.Text = FirstCH138.ToString();
                CHART_CH1.Series.Add("CH1_36_38");


                string FirstCH137 = (from DataRow dr in dt.Rows
                                     where (string)dr["CH1"] == "37"
                                     select (string)dr["No."]).FirstOrDefault();

                string BefNO = (Convert.ToInt32(FirstCH137) - 150).ToString();//Two minutes is 150 seconds
                string AftNo = (Convert.ToInt32(FirstCH137) + 150).ToString();              
                int TmpNum = Convert.ToInt32(AftNo) - Convert.ToInt32(BefNO) +1;
                IEnumerable<double> tmp = (from DataRow dr in dt.Rows 
                                             where Convert.ToInt32(dr["No."]) >= Convert.ToInt32(BefNO) && Convert.ToInt32(dr["No."]) <= Convert.ToInt32(AftNo) 
                                             orderby Convert.ToDouble(dr["CH1"]) descending
                                             select Convert.ToDouble(dr["CH1"]));

                double min =tmp.FirstOrDefault();
                double max =tmp.LastOrDefault();               
                IEnumerable<double> TmpSum = (from DataRow dr in dt.Rows
                                              where Convert.ToInt32(dr["No."]) >= Convert.ToInt32(BefNO) && Convert.ToInt32(dr["No."]) <= Convert.ToInt32(AftNo)
                                              select Convert.ToDouble(dr["CH1"]));

                double sum = 0;
                foreach (var v in TmpSum) 
                {
                    sum += v;
                }
                label3.Text = string.Format("{0:F2}", sum / TmpNum);//Average value  
                label4.Text = min.ToString();//Max value
                label5.Text = max.ToString();//Min value


                CHART_CH1.Series.Add("CH1");
                CHART_CH2.Series.Add("CH2");
                CHART_CH1.Series["CH1_36_38"].ChartType = SeriesChartType.Line;
                CHART_CH1.Series["CH1"].ChartType = SeriesChartType.Line;
                CHART_CH1.Series["CH1"].Color = Color.Orange;
                CHART_CH2.Series["CH2"].ChartType = SeriesChartType.Line;
                CHART_CH2.Series["CH2"].Color = Color.Blue;
                //CHART_CH1.Series["CH1_36_38"].Points.AddXY(float.Parse(FirstCH136), 36);
                //CHART_CH1.Series["CH1_36_38"].Points.AddXY(float.Parse(FirstCH138), 38);
                CHART_CH1.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
                CHART_CH1.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
                CHART_CH2.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
                CHART_CH2.ChartAreas[0].AxisY.ScaleView.Zoomable = true;

                CHART_CH1.DataSource = dt;
                CHART_CH2.DataSource = dt;

                CHART_CH1.Series["CH1"].XValueMember = "No.";
                CHART_CH1.Series["CH1"].YValueMembers = "CH1";
                CHART_CH2.Series["CH2"].XValueMember = "No.";
                CHART_CH2.Series["CH2"].YValueMembers = "CH2";
                //databind
                CHART_CH1.DataBind();
                CHART_CH2.DataBind();
            }
        }

        private void CHART_CH1_MouseEnter(object sender, EventArgs e)
        {
            if (!CHART_CH1.Focused)
                CHART_CH1.Focus();
        }

        private void CHART_CH1_MouseLeave(object sender, EventArgs e)
        {
            if (CHART_CH1.Focused)
                CHART_CH1.Parent.Focus();
        }

        private void CHART_CH2_MouseEnter(object sender, EventArgs e)
        {
            if (!CHART_CH2.Focused)
                CHART_CH2.Focus();
        }

        private void CHART_CH2_MouseLeave(object sender, EventArgs e)
        {
            if (CHART_CH2.Focused)
                CHART_CH2.Parent.Focus();
        }

        private void CHART_CH1_MouseWheel(object sender, MouseEventArgs e)
        {
            var chart = (Chart)sender;
            var xAxis = chart.ChartAreas[0].AxisX;
            var yAxis = chart.ChartAreas[0].AxisY;

            try
            {
                if (e.Delta < 0) // Scrolled down.
                {
                    xAxis.ScaleView.ZoomReset();
                    yAxis.ScaleView.ZoomReset();
                }
                else if (e.Delta > 0) // Scrolled up.
                {
                    var xMin = xAxis.ScaleView.ViewMinimum;
                    var xMax = xAxis.ScaleView.ViewMaximum;
                    var yMin = yAxis.ScaleView.ViewMinimum;
                    var yMax = yAxis.ScaleView.ViewMaximum;

                    var posXStart = xAxis.PixelPositionToValue(e.Location.X) - (xMax - xMin) / 4;
                    var posXFinish = xAxis.PixelPositionToValue(e.Location.X) + (xMax - xMin) / 4;
                    var posYStart = yAxis.PixelPositionToValue(e.Location.Y) - (yMax - yMin) / 4;
                    var posYFinish = yAxis.PixelPositionToValue(e.Location.Y) + (yMax - yMin) / 4;

                    xAxis.ScaleView.Zoom(posXStart, posXFinish);
                    yAxis.ScaleView.Zoom(posYStart, posYFinish);
                }
            }
            catch { throw; }
        }

        private void CHART_CH2_MouseWheel(object sender, MouseEventArgs e)
        {
            var chart = (Chart)sender;
            var xAxis = chart.ChartAreas[0].AxisX;
            var yAxis = chart.ChartAreas[0].AxisY;

            try
            {
                if (e.Delta < 0) // Scrolled down.
                {
                    xAxis.ScaleView.ZoomReset();
                    yAxis.ScaleView.ZoomReset();
                }
                else if (e.Delta > 0) // Scrolled up.
                {
                    var xMin = xAxis.ScaleView.ViewMinimum;
                    var xMax = xAxis.ScaleView.ViewMaximum;
                    var yMin = yAxis.ScaleView.ViewMinimum;
                    var yMax = yAxis.ScaleView.ViewMaximum;

                    var posXStart = xAxis.PixelPositionToValue(e.Location.X) - (xMax - xMin) / 4;
                    var posXFinish = xAxis.PixelPositionToValue(e.Location.X) + (xMax - xMin) / 4;
                    var posYStart = yAxis.PixelPositionToValue(e.Location.Y) - (yMax - yMin) / 4;
                    var posYFinish = yAxis.PixelPositionToValue(e.Location.Y) + (yMax - yMin) / 4;

                    xAxis.ScaleView.Zoom(posXStart, posXFinish);
                    yAxis.ScaleView.Zoom(posYStart, posYFinish);
                }
            }
            catch { throw; }
        }
    }
}

测试结果:

【讨论】:

  • 嗨,@Jack 你的解决方案对我来说很有意义,谢谢。但是,当我编译时,代码行 IEnumerable tmp 出现错误 Ther Error is System.FormatException: 'Input string was not in a correct format.'我已经尝试对转换和解析方法进行多次更改,但到目前为止没有一个对我有用。可以分享你的完整代码吗?
  • @rellik,谢谢你的回复,我已经更新了我完成的代码。
  • 我用一个只有 36,60 和 80 的新数据集以及温度下降的尾端进行了测试。从技术上讲,这应该通过所有三个条件,但由于 LINQ 查询正在寻找 37,它正在计算它正在下降的尾端。即使在您的示例屏幕截图中,它也显示 44.57,59,36.4,因为它在尾端找到了 37,而不是在实际的 36 设定点区域中。我需要重新考虑这一点,因为我们不是在寻找 37。我想检查它通过的范围。仍然令人印象深刻,远远超出了我所能推动的范围。
  • 如果一个37C存在于一个急剧上升或下降的线上,它的36C到38C的时间会很短。在你的设置下,一个正确的37C,它在36C和38C之间的时间维持5个以上分钟。所以你可以根据这个条件找到正确的37C。首先,您可以找到所有 37C。如果 36C 和 38C 在其前后 100 秒内都可以找到,那么这一定是一个不正确的 37C。 100秒的设定值可根据线路的陡峭程度进行调整。
【解决方案2】:

我无法完全理解 Setpoint 的含义(如果可以,请添加一些解释)。

但是,执行列表的计算非常容易。

double minvalue = listname.Min();
double maxvalue = listname.Max();
double avgvalue = listname.Average();

【讨论】:

  • 抱歉,我没有使用正确的语言来解释我的问题。我想检查温度是否稳定在 3 个给定范围内。它应该稳定至少 5 分钟,公差为 +/1 度。我不能对整个列表使用 min-max 和 average 因为它总是会给我整个列表的最大值和最小值 - 即使是在测试时也是如此。与平均值相同。如何选择 3 个“区域”来单独计算这些属性。?
  • @rellik:看,你肯定不能根据图表的值进行计算。无论你做什么计算都应该直接通过列表来完成,这很容易。如果你能给我 3 个示例范围,我很容易帮助你!
  • 当然,您可以使用我原来问题中的数据范围和数据吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-20
  • 1970-01-01
  • 1970-01-01
  • 2017-10-12
相关资源
最近更新 更多