2017-06-29 5 views
1

私はVisual Studio 2017を使用しており、C#とwinformを使用して散布図でリアルタイム値を表示するプログラムを作成しようとしています。コンピュータのリソースを節約して散布図に50,000を超える値をプロットするにはどうすればよいですか?

以下のソースコードでは、イベントが発生したときに新しい値(1秒あたり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点以上のチャートをロードすることはほとんどありません。 視覚情報を失うことなく、元のポイントの一部を使用してデータを提示することができます。ここでは250ポイント(0.25%)にまで10万ポイントをフィルタリングサンプルです:

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; 
     } 
    } 
} 

私はあなたが動的にポイントを追加している理解し、あなたはそれにいくつかのロジックを追加する必要があります。しかし、私のポイントはまだ立っている:あなたあなたのデータをフィルタする必要があります。また、より洗練されたフィルタを使用することもできます。

関連する問題