2017-06-29 32 views
1

我正在使用Visual Studio 2017,并试图使用C#和winform来制作一个在散点图中显示实时值的程序。如何在散点图中绘制超过50,000个值,节省计算机资源?

使用下面的源代码,无论何时发生事件并获得新值(每秒3〜5次),我都能够显示实时值。

valueArray通过GetRealTimeData函数不断获取新值,图表显示数组中的所有元素。

 valueArray[valueArray.Length - 1] = Convert.ToDouble(GetRealTimeData().Trim()); 

     Array.Copy(valueArray, 1, valueArray, 0, valueArray.Length - 1); 

     this.chart1.Series["Series1"].Points.Clear(); 
     this.chart1.Series["Series1"].Points.DataBindY(valueArray); 

不过,我有使用这个程序,这是它消耗大量计算机资源,即使它显示在图表中3000个值的问题。

我打算让图表代表50,000到100,000个值,但我认为它会耗尽太多的资源复制并在每次获得新值时显示旧值。

我想知道是否有任何功能或方法来做这种工作。如果我能得到一些建议或想法,我将不胜感激。

+0

你为什么要将valueArray复制到valueArray中?那是什么spanArray,你为什么还需要复制自己呢? –

+0

@Camilo Terevinto感谢您的评论。 valueArray现在可以包含3000个元素。我希望它在每次添加新值时显示其每个元素,因为如果它获得了超过3000个元素,它将删除最新的元素 - 这就是为什么我使用Array.Copy方法的原因。 spanArray是绘制另一个图表的另一个数组。当我第一次发布它时,我忘了忽略它。对不起! – maynull

+0

这可能是最可怕的方式(性能明智)做到这一点。阵列不能很好地工作,你需要另一个数据结构 –

回答

2

我几乎没有任何理由可以加载任何有100,000点以上的图表。您可以使用原始分数的一小部分来呈现您的数据,而不会损失视觉信息。这里的过滤100,000点下降到250点(0.25%)的样本:

enter image description here

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

    private void Form1_Load(object sender, EventArgs e) 
    { 
     double percent = 0.0025; 

     List<DataPoint> original = GetData(); 
     List<DataPoint> filtered = Filter(original, percent); 

     foreach (DataPoint dp in original) 
      chart1.Series[0].Points.Add(dp); 

     foreach (DataPoint dp in filtered) 
      chart1.Series[1].Points.Add(dp); 

     chart1.ChartAreas[0].AxisY.Maximum = original.Max(dp => dp.YValues[0]); 
     chart1.ChartAreas[0].AxisY.Minimum = original.Min(dp => dp.YValues[0]); 
     chart1.ChartAreas[0].AxisX.Minimum = 0; 

     Text = string.Format("original = {0:0,0} points, filtered = {1:0,0} points, percent = {2:P2}", original.Count, filtered.Count, percent); 
    } 

    private List<DataPoint> Filter(List<DataPoint> orig, double percent) 
    { 
     Random r = new Random(DateTime.Now.Millisecond); 

     List<DataPoint> filt = new List<DataPoint>(orig.ToArray()); 
     double total = filt.Count; 

     while (filt.Count/total > percent) 
      filt.RemoveAt(r.Next(1, filt.Count - 1)); 

     return filt; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     if (chart1.Series[0].Enabled) 
     { 
      chart1.Series[0].Enabled = false; 
      chart1.Series[1].Enabled = true; 
     } 
     else 
     { 
      chart1.Series[0].Enabled = true; 
      chart1.Series[1].Enabled = false; 
     } 
    } 
} 

我明白你动态地添加点,所以你必须要一些逻辑添加到它。但是我的观点仍然存在:您必须必须过滤您的数据。另外,如果你能想出一个,你可以使用更复杂的过滤器。