首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C#实现MS图中的时间序列

用C#实现MS图中的时间序列
EN

Stack Overflow用户
提问于 2014-09-10 18:09:20
回答 1查看 3.3K关注 0票数 0

我使用绘制时间序列中的点,如下所示

代码语言:javascript
复制
chart1.Series[0].Points.AddXY(time, voltage);  

我得到了大量的数据(1点/ 100毫秒),所以在一天结束时,程序绘制新数据的速度非常慢。因此,我希望能够在一定时间后自动滚动图表的x轴,例如30分钟左右.我想保持数据绘制,但用户不能直接看到,但隐藏在图表的左边。

,我该怎么做?

EN

回答 1

Stack Overflow用户

发布于 2014-09-10 18:49:02

编辑:看到我的编辑在结束沿着一个解决方案,在您的集合缩放。

您应该只绘制可见的内容,而不是其他的.

要么将旧值保存在内存中,要么将它们保存到磁盘中,并根据需要加载它们。

这里有一个例子:

我有1000,000分,在内存中,我可以无缝滚动和绘图立即发生。

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public List<int> Values { get; private set; }

        public int ValuesToShow
        {
            get { return 20; }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Values = new List<int>();
            var random = new Random();
            for (int i = 0; i < 1000000; i++)
            {
                int next = random.Next(10, 50);
                Values.Add(next);
            }

            hScrollBar1.Maximum = (Values.Count - 1) - ValuesToShow;
        }

        private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            var hScrollBar = (HScrollBar) sender;
            int value = hScrollBar.Value;
            IEnumerable<int> enumerable = Values.Skip(value).Take(ValuesToShow);

            chart1.Series.Clear();
            var series = new Series();

            foreach (int i in enumerable)
            {
                series.Points.Add((double) i);
            }

            chart1.Series.Add(series);
        }
    }
}

结果:

备注:

1天的值= 86M点,乘以4(一个float的大小),你就可以得到350 of的数据。

我想你可以根据今天的个人电脑规格将这些数据保存在内存中,如果不是定期保存的话。

使用BinaryReader从文件中读取特定位置的值应该非常容易,我将其留给您作为练习;另外,在将它们保存到HDD之前,队列可能会帮助您暂时存储它们。

编辑

我试图使用带有缩放功能的官方方法,但我遇到了一些问题:

  • 即使是1M点也太慢了
  • 减少修复点的数量,但您无法访问以前和未来的点。
  • 试图攻击AxisViewChanging事件是没有结论的,比如当我们在滚动条->中的某个位置添加/删除更多的点时,滚动条将改变它的位置,即不对用户友好。(我刚在这个过程中停了下来,因为它太烦人/不可靠,海事组织)
  • 添加“加载前一组/下一组”按钮显然比这一攻击更好,但它更不友好,您可能会点击他们大量的时间。

我的最后结论是:

要获得缩放,添加两个按钮将改变ValuesToShow的值。

显然,您失去了使用矩形选择点的能力,但是您几乎可以立即进入数据集中的任何部分。

代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public List<int> Values { get; private set; }

        public int ValuesToShow { get; set; }

        private void Form1_Load(object sender, EventArgs e)
        {
            ValuesToShow = 20;

            Values = new List<int>();
            var random = new Random();
            for (int i = 0; i < 1000000; i++)
            {
                int next = random.Next(10, 50);
                Values.Add(next);
            }

            hScrollBar1.Maximum = (Values.Count - 1) - ValuesToShow;

            RefreshChart();
        }

        private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            RefreshChart();
        }

        private IEnumerable<int> GetCurrentValues(int value)
        {
            return Values.Skip(value).Take(ValuesToShow);
        }

        private int GetCurrentPosition()
        {
            return hScrollBar1.Value;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            ValuesToShow /= 2;
            RefreshChart();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            ValuesToShow *= 2;
            RefreshChart();
        }

        private void RefreshChart()
        {
            int value = GetCurrentPosition();
            IEnumerable<int> enumerable = GetCurrentValues(value);

            chart1.Series.Clear();
            var series = new Series();

            foreach (int i in enumerable)
            {
                series.Points.Add((double) i);
            }

            chart1.Series.Add(series);
        }
    }
}

最后注记:

1M点似乎是合理的(20分钟的数据),更多,它开始放缓,我也尝试了8400万,但这是不切实际的。

为了使用户更加友好,您可能可以缩放,而用户使用鼠标轮。

如果您能够负担得起其他解决方案,您可能会获得良好的性能,与WPF和/或商业解决方案,如DevExpress,但你将不得不支付.在这里,我为您提供了一个0美元的解决方案,它只缺少一个选择矩形,但它总是快速的:D

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25772228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档