C# 借助mschart组件提高绘制大量点的性能

C# 借助mschart组件提高绘制大量点的性能,c#,winforms,performance,plot,mschart,C#,Winforms,Performance,Plot,Mschart,我目前正在开发一个包含多个模块的windows窗体应用程序。其中一个负责绘制生成的仿真数据。绘图的想法其实很简单,但我正在努力高效地渲染数据 因此,我的问题是: 绘制如此大量数据的最佳方法是什么 在位图上绘图是正确的选项吗 我是否缺少提供此功能的基本.net框架 要绘制的点以(时间、位置)的形式作为列表点提供,即我们有两个轴 我尝试了以下方法: 我尝试一次绘制所有电梯的点-->是资源密集型的,整个绘图将在调整大小事件时重新绘制。进行了两次测试: 在预定义的视口中绘制整个绘图,但这不是一个好主意,

我目前正在开发一个包含多个模块的windows窗体应用程序。其中一个负责绘制生成的仿真数据。绘图的想法其实很简单,但我正在努力高效地渲染数据

因此,我的问题是:
  • 绘制如此大量数据的最佳方法是什么
  • 在位图上绘图是正确的选项吗
  • 我是否缺少提供此功能的基本.net框架
  • 要绘制的点以(时间、位置)的形式作为列表点提供,即我们有两个轴

    我尝试了以下方法: 我尝试一次绘制所有电梯的点-->是资源密集型的,整个绘图将在调整大小事件时重新绘制。进行了两次测试:

  • 在预定义的视口中绘制整个绘图,但这不是一个好主意,因为图形会变得凌乱
  • 定义时间和位置的像素数(例如,1秒=1像素),并使面板(其中的picturebox)可滚动。这比第一个选项工作得更好,但如果数据太大,会导致outofmemory异常
  • 其他可能的办法: 为图形定义一个范围(例如,时间范围=10分钟),并仅绘制该范围。我认为滚动会有问题,因为当用户滚动时,我必须重新定义绘图的起点(起始点的范围)

    我将非常感谢您的帮助和任何建议、想法、评论……等等

    编辑: 我尝试了Patrick和TaW关于使用MS图表的建议。事实上,这是一个更好更容易的选择,因为它是更好的编程作为我的版本到目前为止。尽管如此,我提供了几个系列的数据,但仍然存在性能问题。也就是说,我有以下问题:

  • 绘制数据大约需要一分钟
  • 放大时(通过启用相应的属性,显示和找到提示),滚动会变慢。如果它能流动,那就太好了
  • 我不能或不知道如何缩小 参考TaW(见下文)关于我对大数据的意思的缺失信息的评论-要绘制的模拟数据表示一个小时(例如2-3小时)的时间段,并且应以60秒的间隔查看数据。

    我的主要问题是图表的性能

    一些可能有帮助的诊断数据(使用秒表测量绘图方法,包括其内部步骤):

    • chart1.Series.Clear()时间:00:00:00
    • 填充图表1.Series.Add(…数据…)花费时间:00:00:03.8230000
    • 配置图表1需要:00:00:03.8240000
    • 绘图视图。绘图图(点)拍摄时间:00:00:03.8290000
    这告诉我,图表模块中的绘图需要很长时间


    感谢您的帮助和时间。

    是的,您缺少一个.net组件,在winforms中,您可以使用图表组件,只需设置一个系列(您可以从一系列图表类型中进行选择,包括我认为您需要的点类型)他们只插入一次数据点,让.net为您处理工作

    只显示所需的部分,这无疑是花费最少资源和时间的选项。当然,在显示的winodw数据点大小的某个地方有一个盈亏平衡点,但我猜在多达数百个点的情况下,这将是最好的解决方案

    您可以尝试以下方法:

    DataPoint[] data60k1 = new DataPoint[60000];
    int windowSize = 60;
    HScrollBar scroller = new HScrollBar();
    
    private void button14_Click(object sender, EventArgs e)
    {
        // creating a few test data..
        for (int i = 0; i < data60k1.Length; i++) data60k1[i] = 
                                                  new DataPoint(i, 3 + Math.Sin(i / 100f));
    
        // set up a HScrollBar:
        chart1.Controls.Add(scroller);
        scroller.Dock = DockStyle.Bottom;
        scroller.Maximum = data60k1.Length - windowSize;
        scroller.LargeChange = windowSize ;
        scroller.Scroll += scroller_Scroll;
        // show first portion..
        scroller_Scroll(null, null);
    }
    
    void scroller_Scroll(object sender, ScrollEventArgs e)
    {
        chart1.Series[0].Points.Clear();
        for (int i = scroller.Value; i < scroller.Value + windowSize; i++) 
                     chart1.Series[0].Points.Add(data60k1[i]);
    }
    
    DataPoint[]data60k1=新数据点[60000];
    int windowSize=60;
    HScrollBar scroller=新的HScrollBar();
    私有无效按钮14_单击(对象发送者,事件参数e)
    {
    //创建一些测试数据。。
    对于(int i=0;i

    您可以更改
    windowSize
    以控制放大和缩小。。您可以将
    SmallChange
    设置为
    windowSize

    的一部分。我使用托管DirectX库渲染了100000个点。一点也不坏。在做这件事之前,我尝试了WPF,花了很长时间。我使用这个库是为了精确:

    在向图表添加x、y点时,您可以每添加10个点。而不是阵列中的所有22000个数据

           int TakeEveryNthPoint = 10;  
           double[] = new double[22000] {}; // your data
    
            for (int i = 0; i < data.Length; i++)
            {
                if (i % TakeEveryNthPoint != 0)
                    continue;
    
                chart1.Series[0].Points.AddXY(i, data[i]);
            }
    
    int TakeEveryNthPoint=10;
    double[]=新的double[22000]{};//你的数据
    for(int i=0;i
    或者:

    如果您不需要一些低于阈值水平平均值的值,您可以不添加它们

    但请确保threadshold值消除了许多不必要的值,这样您就可以看到性能的改进

           double[] data = new double[22000] {}; // your data
           int thresholdValue= 10; 
    
           // get top 25%  of points
           int thresholdValueAuto= (data.Avg() + data.Max())/2; 
    
            for (int i = 0; i < data.Length; i++)
            {
                if (data[i] < thresholdValueAuto )
                    continue;
    
                chart1.Series[0].Points.AddXY(i, data[i]);
            }
    
    double[]data=newdouble[22000]{};//你的数据
    int thresholdValue=10;
    //获得前25%的积分
    int thresholdValueAuto=(data.Avg()+data.Max())/2;
    for(int i=0;i