场景

Winforn中设置ZedGraph曲线图的属性、坐标轴属性、刻度属性:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100112573

需求是在曲线图上进行滚轮或者鼠标划区域缩放时重新加载数据。

效果如下

注:

博客主页:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

在包含ZedGraph曲线图的窗体中的load方法中进行图形的初始化。

//初始化ZedGraph
Common.DataChart.DataChartHelper.InitGraphPane(this.zedGraphControl1);

在初始化方法中进行滚轮缩放事件的绑定

zgc.ZoomEvent -= zgc_ZoomEvent;                     //滚轮缩放事件
zgc.ZoomEvent += zgc_ZoomEvent;                     //滚轮缩放事件

然后在滚轮缩放事件中

private static void zgc_ZoomEvent(ZedGraphControl sender, ZoomState oldState, ZoomState newState)
        {
            try
            {


                ReFillBeginIndex = (int)sender.GraphPane.XAxis.Scale.Min;      //缩放后的开始索引点
                ReFillEndIndex = (int)sender.GraphPane.XAxis.Scale.Max;        //缩放后的结束索引点

                #region 重新填充数据


                    if (ReFillBeginIndex < 0) ReFillBeginIndex = 0;
                    if (ReFillEndIndex >= Global.Instance.VirtualData.RecordDataFilter.Count) ReFillEndIndex = Global.Instance.VirtualData.RecordDataFilter.Count - 1;
                    if (ReFillEndIndex < 0) ReFillEndIndex = 0;
                    if (ReFillBeginIndex > ReFillEndIndex) ReFillBeginIndex = ReFillEndIndex;



                    int beginDataPoint = Global.Instance.VirtualData.RecordDataFilter[ReFillBeginIndex].DataPoint;      //保存开始记录的DataPoint值
                    int endDataPoint = Global.Instance.VirtualData.RecordDataFilter[ReFillEndIndex].DataPoint;          //保存结束记录的DataPoint值
                    List<Wongoing.Entity.Record> newFilterData = new List<Entity.Record>();         //保存新过滤的数据

                    #region 开启一个后台线程,用于重新计算过滤数据,计算完毕刷新曲线

                    Stopwatch sw = new Stopwatch();
                    sw.Restart();
                    using (System.ComponentModel.BackgroundWorker bgWorker = new System.ComponentModel.BackgroundWorker())
                    {
                        bgWorker.WorkerReportsProgress = true;          //允许报告进度
                        bgWorker.DoWork += delegate(object senderObj, System.ComponentModel.DoWorkEventArgs dwea)
                        {
                            IEnumerable<Entity.Record> records = Global.Instance.VirtualData.RecordDataList.Where(p => p.DataPoint >= beginDataPoint && p.DataPoint <= endDataPoint);
                            Entity.Record[] newRecords = records.ToArray<Entity.Record>();
                            bgWorker.ReportProgress(10);

                            if (records != null)
                            {
                                int count = newRecords.Length;
                                sw.Stop();

                                sw.Restart();
                                if (count > Global.AppConfig.ShowPointCount)
                                {
                                    int progressValue = 10;
                                    int interval = (count - (count % Global.AppConfig.ShowPointCount)) / Global.AppConfig.ShowPointCount;
                                    int w = 0;
                                    for (int k = 0; k < Global.AppConfig.ShowPointCount; k++)
                                    {
                                        newFilterData.Add(newRecords[w]);
                                        w += interval;
                                        if (progressValue != 10 + (int)(k * 90 / Global.AppConfig.ShowPointCount))
                                        {
                                            progressValue = 10 + (int)(k * 90 / Global.AppConfig.ShowPointCount);
                                            bgWorker.ReportProgress(progressValue);
                                        }
                                    }
                                }
                                else
                                {
                                    newFilterData.AddRange(newRecords);
                                }
                                sw.Stop();

                            }

                            bgWorker.ReportProgress(100);
                        };

                        //进度变化时改变进度对话框中的进度值
                        bgWorker.ProgressChanged += delegate(object senderObj, System.ComponentModel.ProgressChangedEventArgs pcea)
                        {
                            if (pcea.ProgressPercentage >= 0 && pcea.ProgressPercentage <= 100)
                            {
                                Dialog.FrmProgressBar.Instance.ProgressValue = pcea.ProgressPercentage;
                            }
                        };

                        //后台重新计算过滤数据完成
                        bgWorker.RunWorkerCompleted += delegate(object senderObj, System.ComponentModel.RunWorkerCompletedEventArgs rwcea)
                        {
                            Dialog.FrmProgressBar.Instance.Dispose();               //关闭进度对话框
                            RefreshPane(sender, newFilterData, null, null);        //重新刷新曲线
                        };
                        bgWorker.RunWorkerAsync();      //启动后台计算过滤数据的线程
                        Dialog.FrmProgressBar.Instance.ShowDialog();        //显示进度对话框
                    }

                    #endregion


                #endregion
            }
            catch(Exception ex)
            {
                ICSharpCode.Core.LoggingService<DataChartHelper>.Error("zgc_ZoomEvent is Exception :" + ex.Message, ex);
            }
        }

注:

1.首先通过ReFillBeginIndex =(int)sender.GraphPane.XAxis.Scale.Min和ReFillEndIndex =(int)sender.GraphPane.XAxis.Scale.Max;获取

缩放后的开始与结束的索引。

2.然后判断开始索引是否小于0,小于0则赋值为0,结束索引是否大于数据的总个数,大于则为总个数减一。

3.然后根据缩放后的开始和结束的索引获取缩放后要填充的数据。

4.中间又夹杂着进度条的显示和是否大于设置的要显示的总个数。

5.最终将过滤后的数据重新保存,并以此去刷新曲线图。

01-06 23:12