动态更新数组的vb.net图表

时间:2017-09-06 08:32:02

标签: vb.net charts

我有一个子计算图形的数组,另一个子图形图。 有两个线程用于计算(getArrayForGraph()),另一个用于绘制图形。

现在我希望图形沿着侧面阵列更新功能绘制,因为阵列非常长(10 000 000),使整个过程非常慢。

如果图表可用点,我将如何开始更新图表。或哪种解决性能问题的最佳方法。

@Test
public void test(){
    Map<String, Integer> a = new HashMap<>();
    a.put("x", new Integer(0)); // Store Integer(0)
    Integer i = a.get("x");     // Get it
    a.put("x", i++);            // Unbox it, rebox it, store it again (still 0); increment it afterward
    i = a.get("x");             // Same again
    a.put("x", i++);            // ...
    i = a.get("x");             // ...
    a.put("x", i++);            // Unbox it, rebox it, store it again (still 0); increment it afterward 
    System.err.println(i);      // Show it; contains the *incremented* value
}

1 个答案:

答案 0 :(得分:0)

这是一个完整的例子。它使用BackgroundWorker来执行工作,该工作向UI发送信号以进行更新。它还汇总了数据。我选择只显示2000点因为1. 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