几个重要的属性
在介绍实现方法前需要先了解chart控件的几个属性
- ChartAreas :绘图区域,当数据量大时只要一个绘图区域。
- AxisX:X轴。(Y轴一致,此文进介绍X轴)。
- AxisX.ScrollBar:X轴滚动条。
- AxisX.ScaleView.Position:X轴显示的起始值。
- AxisX.ScaleView.Size:X轴显示数据的数量
图中
AxisX.ScaleView.Position = 941
AxisX.ScaleView.Size = 1941-941+1
实现思路
- 将数据分段每段10000到50000之间(以50000为例)。
- 给chart控件添加滚动条,
- 将第一个数据段的数据绑定到chart数据源上,给chart添加鼠标滚动事件。
- 滚动滚轮可以更改AxisX.ScaleView.Position的值,当显示完最后一个数值时,更改chart的数据源将第二段数据绑定在chart数据源上。
- 依次循环就可以实现所有数据的显示
代码实现
1.数据分段
1 2 3 4 5 6 7 8 9 10 11 12
| double[] data = new double[2000*1000]{...}; 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 [i*50000+n]; } DataPanel .add(smallArray); }
|
2.给chart控件添加滚动条
1 2 3 4 5 6 7 8 9 10 11
| private void ChartScrollbarStyle() { chartAmend.ChartAreas[0].AxisX.ScrollBar.Enabled = true; chartAmend.ChartAreas[0].AxisX.ScaleView.Position = 1; chartAmend.ChartAreas[0].AxisX.ScaleView.Size = 300; chartAmend.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll; chartAmend.ChartAreas[0].AxisX.ScrollBar.ButtonColor = Color.Silver; chartAmend.ChartAreas[0].AxisX.ScrollBar.LineColor = Color.Black; chartAmend.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = false; }
|
3.将数据绑定在chart数据源上,更改DataCount,就更改了数据源。
1 2 3
| int DataCount = 0; chart1.Series[0].Points.DataBindY(DataPanel[DataCount]);
|
4.给chart控件添加鼠标滚轮事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| chart1.MouseWheel += Chart1_MouseWheel; private void Chart1_MouseWheel(object sender, MouseEventArgs e) { int position = Convert.ToInt32(chart1.ChartAreas[0].AxisX.ScaleView.Position); int WindowSize = chart1.ChartAreas[0].AxisX.ScaleView.Size; if (e.Delta < 0) { position += 200; if (position >= chartAmend.ChartAreas[0].AxisX.Maximum - WindowSize) { DataCount++; if (DataCount >= DataPanel.Count) { MessageBox.Show("所有数据已经全部显示完毕","提示"); DataCount = DataPanel.Count-1; return; } chart1.Series[0].Points.DataBindY(Overall.DataPanel[DataCount]); position = 1; } } else { position -= 200; if (position < 1) { if (DataCount == 0) { position = 1; MessageBox.Show("已经是第一个数据", "提示"); } else { DataCount--; } chart1.Series[0].Points.DataBindY(Overall.DataPanel[DataCount]); position = Convert.ToInt32(chart1.ChartAreas[0].AxisX.Maximum - WindowSize); } } chart1.ChartAreas[0].AxisX.ScaleView.Position = position; }
|
到此处,基本上就已经完成了。理论上讲可显示的数据量为无限大。并且该方法本人已经应用于超1000万数据显示的项目中,但是因为本文的代码是经过删减整理的,可能会有一些问题。取用时要自行验证。
精彩评论收集
评论一:帅气转身而过
- (问)你好,滚轮事件有问题!我这样写有错!
- (答)能具体点吗?可以把错误提示说一下吗?
- (问)chart1.MouseWheel += Chart1_MouseWheel; 说不清,鼠标的事件中我找不到对于chart1.MouseWheel的注册,你这样写,我那边是无效的,红色的波浪线
- (答)“chart1.MouseWheel +=“ 输入完毕后会后提示显示,最好按照提示输入,可能是你的大小写有问题。这个我在项目中用过很多次了不可能有问题的,还有控件中是不包含MouseWheel事件的,只能通过代码实现。
评论二:椰壳里的海
- 楼主,你只能每帧显示50000个数据,我这里可以任意范围平滑显示,看看我的帖子吧。
- 是一屏显示50000,这也基本上是chart控件的极限了。你说的任意范围平滑显示,那你试过单次显示500万数据吗?
其他
用fastline样式就行,30w以下数据基本不卡
确实 spline最卡,我实时刷新125ms一个点,1000个点就开始卡
那怎么保全全部的数据呢,我看还是同时搞两个chart控件方便,一个后台运行保存全部数据,一个看当前时区的变动数据。需要查看全部的数据了再点开看。就不存在卡的现象了。即保存了全部数据,又不影响当前可变的数据。
相关链接(侵删)
- C# 如何解决chart控件显示数据量过大时的卡顿问题
- echarts绘制大数量折线图太卡,绘制很慢
- echartsjs大数据绘图
=================我是分割线=================
欢迎到公众号来唠嗑: