CSV数据异步刷新到UI(DataGridView),zedGraph绘制曲线

步骤:

1、选择文件夹,读取文件夹。

2、通过线程遍历文件以及解析csv文件,将csv的一行行数据保存到Queue 队列。

  csv文件数据模式:0.1668056,-0.569,-0.598

3、异步委托调用队列中的数据

  后台解析与UI界面不干扰,这样就解决了数据太多页面卡死的问题了,不影响用户使用。

  队列真的很神奇,再也不怕重复数据的读取,定位啥的,用一个少一个......

4、绘制曲线,自动累计,动态画图

  使用zedGraph控件,比vs自带控件chart功能强大,需要自行下载 zedGraph.dll 文件,拖拽至工具箱即可

5、展示DataGridView行号

灵感来源:使用多线程加载多个Xml文件到TreeView控件

例子:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using System.Collections;
 10 using System.IO;
 11 using System.Threading;
 12 using ZedGraph;
 13 
 14 namespace ThreadsOpenCsvFilesTwo
 15 {
 16     public partial class Form1 : Form
 17     {
 18         private Thread QueueFileThread;//定义一个线程,用来监视读取的文件队列 
 19         private delegate void csvDelegate(string instr);
 20         private Queue QueueFile = new Queue();//放置要加载的数据,数据模式:0.1668056,-0.569,-0.598
 21 
 22         public Form1()
 23         {
 24             InitializeComponent();
 25             
 26         }
 27 
 28         /// <summary>
 29         /// 委托的实现方法
 30         /// </summary>
 31         /// <param name="strLine"></param>
 32         private void csvDel(string strLine)
 33         {
 34             string[] aryLine = strLine.Split(',');
 35             dataGridView1.Rows.Add(aryLine);
 36             dataGridView1.Refresh();
 37         }
 38                 
 39         /// <summary>
 40         /// QueueFileThread 线程调用的方法 
 41         /// </summary>
 42         /// <param name="obj"></param>
 43         private void analysis(object obj)
 44         {
 45             string path = obj.ToString();// 文件
 46             DirectoryInfo theFolder = new DirectoryInfo(path);
 47             //遍历文件
 48             foreach (FileInfo NextFile in theFolder.GetFiles())
 49             {
 50                 string fileName = NextFile.Name;//获取到的只是文件的名字,不是路径
 51                 string stype = fileName.Substring(fileName.LastIndexOf("."));
 52                 if (stype == ".csv")
 53                 {
 54                     string filepPath = NextFile.FullName;
 55                     FileStream fs = new FileStream(filepPath, FileMode.Open);
 56                     StreamReader sr = new StreamReader(fs, Encoding.UTF8);
 57                     bool IsFirst = false;//是否读取第一行
 58                     string strLine = "";
 59                     //逐行读取CSV中的数据
 60                     while ((strLine = sr.ReadLine()) != null)
 61                     {
 62                         if (IsFirst == false)
 63                         {
 64                             IsFirst = true;
 65                         }
 66                         else
 67                         {
 68                             QueueFile.Enqueue(strLine);
 69                         }
 70                     }
 71                 }
 72             }
 73             
 74         }
 75 
 76         
 77 
 78         private void timer1_Tick(object sender, EventArgs e)
 79         {
 80             csvDelegate cd = new csvDelegate(csvDel);
 81             if (QueueFile.Count > 0)
 82             {
 83                 this.BeginInvoke(cd, QueueFile.Dequeue());// UI线程异步委托
 84 
 85             }
 86 
 87             this.zedGraphControl1.GraphPane.CurveList.Clear();//清空之前画的图
 88             this.zedGraphControl1.GraphPane.AxisChange();// 更新
 89             GraphPane myPane = this.zedGraphControl1.GraphPane;
 90             this.zedGraphControl1.GraphPane.Title.Text = "折线图";
 91             myPane.XAxis.Title.Text = "Sequence";// 顺序
 92             myPane.YAxis.Title.Text = "Time";
 93             myPane.Y2Axis.Title.Text = "Front, Back";
 94             myPane.Y2Axis.IsVisible = true;//显示第二个y轴
 95 
 96             // 数据
 97             List<double> column1 = new List<double>();// y
 98             List<double> column2 = new List<double>();// y2
 99             List<double> column3 = new List<double>();// y3
100             List<double> column4 = new List<double>();// x
101 
102             for (int i = 0; i < this.dataGridView1.Rows.Count - 1; i++)
103             {
104                 DataGridViewRow row = new DataGridViewRow();
105                 row = dataGridView1.Rows[i];
106                 column1.Add(double.Parse(row.Cells["Time"].Value.ToString()));
107                 column2.Add(double.Parse(row.Cells["Front"].Value.ToString()));
108                 column3.Add(double.Parse(row.Cells["Back"].Value.ToString()));
109                 column4.Add(i + 1);
110             }
111 
112             double[] y = column1.ToArray();
113             double[] y2 = column2.ToArray();
114             double[] y3 = column3.ToArray();
115             double[] x = column4.ToArray();
116 
117             // Fill the axis background with a color gradient
118             myPane.Chart.Fill = new Fill(Color.FromArgb(255, 255, 245), Color.FromArgb(255, 255, 190), 90F);
119 
120             // 生成曲线
121             LineItem myCurve = myPane.AddCurve("Time", x, y, Color.Blue, SymbolType.None);
122             LineItem myCurve2 = myPane.AddCurve("Front", x, y2, Color.Orange, SymbolType.None);
123             myCurve2.IsY2Axis = true;  //手动改为按【Y2Axis】的刻度描画 
124             LineItem myCurve3 = myPane.AddCurve("Back", x, y3, Color.Red, SymbolType.None);
125             myCurve3.IsY2Axis = true;
126 
127             // 手动设置x y y2 轴的范围
128             myPane.XAxis.Scale.Min = 0;
129             myPane.YAxis.Scale.Min = 0;
130             myPane.YAxis.Scale.Max = 200;
131             myPane.Y2Axis.Scale.Min = -1;
132             myPane.Y2Axis.Scale.Max = 2;
133 
134             // 显示Y轴网格线
135             myPane.YAxis.MajorGrid.IsVisible = true;
136             myPane.YAxis.MinorGrid.IsVisible = true;
137             myPane.Y2Axis.MajorGrid.IsVisible = true;
138             myPane.Y2Axis.MinorGrid.IsVisible = true;
139 
140             zedGraphControl1.AxisChange();
141             zedGraphControl1.Invalidate();  
142         }
143 
144         
145         private void dataGridView1_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
146         {
147             e.Row.HeaderCell.Value = string.Format("{0}", e.Row.Index + 1); //dataGridView显示行号
148         }
149 
150         private void button1_Click_1(object sender, EventArgs e)
151         {
152             dataGridView1.Rows.Clear();
153             FolderBrowserDialog dialog = new FolderBrowserDialog();
154             dialog.Description = "请选择CSV所在文件夹";
155             if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
156             {
157                 if (string.IsNullOrEmpty(dialog.SelectedPath))
158                 {
159                     MessageBox.Show(this, "文件夹路径不能为空", "提示");
160                     return;
161                 }
162                 string path = dialog.SelectedPath;
163                 textBox1.Text = path;
164                 QueueFileThread = new Thread(new ParameterizedThreadStart(this.analysis));
165                 QueueFileThread.IsBackground = true;// 设置为后台线程
166                 QueueFileThread.Start(path);
167 
168                 timer1.Start();
169             }
170         }
171     }
172 }
View Code

展示结果:

原文地址:https://www.cnblogs.com/shelly0307/p/7552884.html