完全な例です。これはBackgroundWorkerを使用して作業を実行し、更新するためにUIに信号を送ります。また、データを集約します。 MSChartは多くの点を扱うことができず、2.私のディスプレイは1920ピクセルの幅しかないので、もっと表示しようとする必要はありません。この例では、5k(10M/2k)ポイントごとに1ポイントをプロットします。これはx:最新の時刻、y:平均値です。もしあなたが好きであれば、平均的な時間を取ることもできますが、これはきれいです。
情報が不足しているため、特定の変数が含まれていません。しかし、あなたはそれがどのように動作し、それがあなたの環境で動作するかを考えなければなりません。
Public Class Form1
Private worker As System.ComponentModel.BackgroundWorker
Private chartX As New List(Of Long)()
Private chartY As New List(Of Long)()
' settings for demo
Private count As Long = 10000000
Private numberOfGroups As Long = 2000
Private groupSize As Long = count/numberOfGroups
Private Sub doWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
' holds chunk of data to be grouped
Dim temp As New List(Of Tuple(Of Long, Long))()
For i As Long = 1 To count
' generate some scientific data!
temp.Add(New Tuple(Of Long, Long)(i, Convert.ToInt64(i * Math.Sin(Math.PI * i/count) * Math.Sin(i))))
' make this happen 10 times
If i Mod count/10 = 0 Then
' group the time and data into same groupings
Dim aggregate =
temp.
Select(Function(d, index) New Tuple(Of Integer, Tuple(Of Long, Long))(index, d)).
GroupBy(Function(d) Math.Floor(d.Item1/groupSize))
' take the latest time
Dim xAggregate =
aggregate.
Select(Function(a) a.Max(Function(b) b.Item2.Item1)).
ToArray()
' take the average data
Dim yAggregate =
aggregate.
Select(Function(a) Convert.ToInt64(a.Average(Function(b) b.Item2.Item2))).
ToArray()
' clear temp data
temp.Clear()
' -- calling resetChartData() here would make the chart display only the currently processed data
' -- might be useful if you were displaying data from an oscilloscope for instance
' resetChartData()
' add the aggregate data to the chart source data
chartX.AddRange(xAggregate)
chartY.AddRange(yAggregate)
' report progress (initiate charting)
DirectCast(sender, System.ComponentModel.BackgroundWorker).ReportProgress(Convert.ToInt32(100 * i/count))
End If
Next
End Sub
Private Sub progressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs)
' ui thread runs here.
' perform minimal ui operations as not to slow down ui thread
' added a progress bar, nice to see
ProgressBar1.Value = e.ProgressPercentage
' databind the data
Chart1.Series("Series1").Points.DataBindXY(chartX, chartY)
End Sub
Private Sub resetChartData()
chartX.Clear()
chartY.Clear()
End Sub
Private Sub runWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs)
Button1.Enabled = True
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' to prevent double clicks
Button1.Enabled = False
worker = New System.ComponentModel.BackgroundWorker()
AddHandler worker.DoWork, AddressOf doWork
AddHandler worker.ProgressChanged, AddressOf progressChanged
AddHandler worker.RunWorkerCompleted, AddressOf runWorkerCompleted
worker.WorkerReportsProgress = True
' do work on background thread
worker.RunWorkerAsync()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' set up chart
Chart1.Series.Add("Series1")
Chart1.Series.Single().MarkerStyle = DataVisualization.Charting.MarkerStyle.None
Chart1.Series.Single().ChartType = DataVisualization.Charting.SeriesChartType.FastLine
Chart1.Legends.Clear()
End Sub
End Class
出典
2017-09-07 20:16:36
djv
getArrayForGraphはどのくらいの頻度で呼び出されますか? – djv
ユーザーが更新ボタンをクリックすると、与えられた入力に対してグラフがリフレッシュされますので、一度言います – user1565283
主な問題は、MSChartが多くのデータポイントを処理できないことです。あなたはそれをまったくプロットすることはできますか?たとえばミリ秒単位でデータを集計し、各ミリ秒の平均データを最初の/平均/前回のミリ秒までプロットする必要があるかもしれません。 – djv