问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C# 如何解决chart控件显示数据量过大时的卡顿问题

创作时间:
作者:
@小白创作中心

C# 如何解决chart控件显示数据量过大时的卡顿问题

引用
CSDN
1.
https://blog.csdn.net/qq_41848097/article/details/106119181

前言

Winform中自带的曲线显示控件Chart,在显示数据量过大时会出现卡顿的情况,导致用户体验不好。
针对这种情况本文通过数据分段的方法解决此类问题。

几个重要的属性

在介绍实现方法前需要先了解chart控件的几个属性

  1. ChartAreas :绘图区域,当数据量大时只要一个绘图区域。
  2. AxisX:X轴。(Y轴一致,此文进介绍X轴)。
  3. AxisX.ScrollBar:X轴滚动条。
  4. AxisX.ScaleView.Position:X轴显示的起始值。
  5. AxisX.ScaleView.Size:X轴显示数据的数量


图中
AxisX.ScaleView.Position = 941
AxisX.ScaleView.Size = 1941-941+1

实现思路

  1. 将数据分段每段10000到50000之间(以50000为例)。
  2. 给chart控件添加滚动条,
  3. 将第一个数据段的数据绑定到chart数据源上,给chart添加鼠标滚动事件。
  4. 滚动滚轮可以更改AxisX.ScaleView.Position的值,当显示完最后一个数值时,更改chart的数据源将第二段数据绑定在chart数据源上。
  5. 依次循环就可以实现所有数据的显示

代码实现

  1. 数据分段
double[] data = new double[2000*1000]{...};//需要显示的数据 长度为200万。
public List<double[]> DataPanel = new List<double[]>();
for(int m =0;m<40;m++)
{
  double [] smallArray = new double [50000]; 
  for(int n = 0;n<50000;n++)
  {
      smallArray [n] = data [m*50000+n];
  }
  DataPanel.Add(smallArray);
}
  1. 给chart控件添加滚动条
private void ChartScrollbarStyle()
 {        
    chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = true;
    chart1.ChartAreas[0].AxisX.ScaleView.Position = 1;
    chart1.ChartAreas[0].AxisX.ScaleView.Size = 300;
    chart1.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
    chart1.ChartAreas[0].AxisX.ScrollBar.ButtonColor = Color.Silver;
    chart1.ChartAreas[0].AxisX.ScrollBar.LineColor = Color.Black;
    chart1.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = false;
}
  1. 将数据绑定在chart数据源上,更改DataCount,就更改了数据源。
int DataCount = 0;
chart1.Series[0].Points.DataBindY(DataPanel[DataCount]);
  1. 给chart控件添加鼠标滚轮事件
//该事件需要注册在方法中,最好可以放在构造方法中。
chart1.MouseWheel += Chart1_MouseWheel;
private void Chart1_MouseWheel(object sender, MouseEventArgs e)
{
    int position = Convert.ToInt32(chart1.ChartAreas[0].AxisX.ScaleView.Position);
   int WindowSize = (int)chart1.ChartAreas[0].AxisX.ScaleView.Size;
   if (e.Delta < 0)
   {
       position += 200;//滚轮动一下,移动多少数据
       if (position >= chart1.ChartAreas[0].AxisX.Maximum - WindowSize)//一段数据显示完毕
       {
           DataCount++;
           if (DataCount >= DataPanel.Count)
           {
               MessageBox.Show("所有数据已经全部显示完毕", "提示");
               DataCount = DataPanel.Count - 1;
               return;
           }
           chart1.Series[0].Points.DataBindY(DataPanel[DataCount]);
           position = 1;//新的一段数据开始时 滚动条移动到最左侧
       }
   }
   else
   {
       position -= 200;
       if (position < 1)
       {
           if (DataCount == 0)
           {
               position = 1;
               MessageBox.Show("已经是第一个数据", "提示");
           }
           else
           {
               DataCount--;
           }
           chart1.Series[0].Points.DataBindY(DataPanel[DataCount]);
           position = Convert.ToInt32(chart1.ChartAreas[0].AxisX.Maximum - WindowSize);
       }
   }
   chart1.ChartAreas[0].AxisX.ScaleView.Position = position;
}
  1. 到此处,基本上就已经完成了。理论上讲可显示的数据量为无限大。并且该方法本人已经应用于超1000万数据显示的项目中,但是因为本文的代码是经过删减整理的,可能会有一些问题。取用时要自行验证。
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号