首先进行Chart控件的初始化,以我记录力传感器的为例
#region 曲线初始化 public void IntiCHure() { this.chart1.ChartAreas.Clear(); ChartArea chartArea1 = new ChartArea("C1"); chartArea1.BackColor = System.Drawing.SystemColors.Control; this.chart1.ChartAreas.Add(chartArea1); //定义存储和显示点的容器 this.chart1.Series.Clear(); Series series1 = new Series("s1"); Series series2 = new Series("s2"); Series series3 = new Series("s3"); Series series4 = new Series("s4"); Series series5 = new Series("s5"); Series series6 = new Series("s6"); series1.ChartArea = "C1"; series2.ChartArea = "C1"; series3.ChartArea = "C1"; this.chart1.Series.Add(series1); this.chart1.Series.Add(series2); this.chart1.Series.Add(series3); this.chart1.Series.Add(series4); this.chart1.Series.Add(series5); this.chart1.Series.Add(series6); //设置图表显示样式 this.chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = System.Drawing.Color.Silver; this.chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = System.Drawing.Color.Silver; //设置标题 this.chart1.Titles.Clear(); this.chart1.Titles.Add("S01"); this.chart1.Titles[0].Text = "力值显示"; this.chart1.Titles[0].Alignment = System.Drawing.ContentAlignment.MiddleLeft; this.chart1.Titles[0].ForeColor = Color.RoyalBlue; this.chart1.Titles[0].Font = new System.Drawing.Font("Microsoft Sans Serif", 12F); this.chart1.Series[0].ChartType = SeriesChartType.Line; this.chart1.Series[1].ChartType = SeriesChartType.Line; this.chart1.Series[2].ChartType = SeriesChartType.Line; this.chart1.Series[3].ChartType = SeriesChartType.Line; this.chart1.Series[4].ChartType = SeriesChartType.Line; this.chart1.Series[5].ChartType = SeriesChartType.Line; //设置图表显示样式 this.chart1.Series[0].Color = Color.Orange; this.chart1.Series[1].Color = Color.Green; this.chart1.Series[2].Color = Color.Red; this.chart1.Series[3].Color = Color.Blue; this.chart1.Series[4].Color = Color.DarkViolet; this.chart1.Series[5].Color = Color.Brown; //this.chart1.ChartAreas[0].AxisY.Title = "力值"; this.chart1.ChartAreas[0].AxisY.IsStartedFromZero = false; this.chart1.Series[0].Points.Clear(); } #endregion
初始化后再进行数据的绑定
public void ForceDataShow(Queue<Double> Force, string RD, int index,CheckBox Cbx) { if (Force.Count > CountNum)//当组中的数据大于曲线的长度时,剔除最前面一个值 { for (int i = 0; i < num; i++)//Num为组一次更新的点数 { Force.Dequeue(); } } for (int i = 0; i < num; i++) { Force.Enqueue(Convert.ToDouble(RD));//下图为增加点数到组的最后面一个值 } if (Cbx.Checked == true) { this.BeginInvoke(new MethodInvoker(() => { //this.chart1.Series[index].Points.Clear(); //for (int J = 0; J < Force.Count; J++) //{ // this.chart1.Series[index].Points.AddXY(TE.ElementAt(J).ToString("0.00"), Force.ElementAt(J)); //} this.chart1.Series[index].Points.DataBindY(Force); //绑定值到对应曲线中 })); }
然后是刷新的方法,尝试过Timer和Task两种刷新方法,发现用Timer的刷新频率过高时会出现界面卡顿的现象,而Task不会出现卡顿问题;
private void timer1_Tick(object sender, EventArgs e) { if (Interlocked.Exchange(ref inTimer, 1) == 0) { ForceList = DisposeForce(RobotData.RobotValue.Value.ToString()); ForceDataShow(ForceXData,ForceList[0], 0, cbx_Fx); ForceDataShow(ForceYData,ForceList[1], 1, cbx_Fy); ForceDataShow(ForceZData,ForceList[2], 2, cbx_Fz); Interlocked.Exchange(ref inTimer, 0); } }
推荐使用Task
private void MainForm1_Load(object sender, EventArgs e) { task2 = new System.Threading.Tasks.Task(async () => { while (true) { if (token.IsCancellationRequested) { return; } // 初始化为true时执行WaitOne不阻塞 resetEvent.WaitOne(); ForceList = DisposeForce(RobotData.RobotValue.Value.ToString()); ForceDataShow(ForceXData, ForceList[0], 0, cbx_Fx); ForceDataShow(ForceYData, ForceList[1], 1, cbx_Fy); ForceDataShow(ForceZData, ForceList[2], 2, cbx_Fz); Interlocked.Exchange(ref inTimer, 0); await System.Threading.Tasks.Task.Delay(10); } }); }