首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在不调用线程的情况下更新图表

如何在不调用线程的情况下更新图表
EN

Stack Overflow用户
提问于 2019-07-28 16:45:31
回答 1查看 223关注 0票数 0

如何通过线程计时器更新图表。我不会像下面这样使用invoke。

代码语言:javascript
复制
  Chart1.BeginInvoke(New MethodInvoker(Sub()
        Showdatatimer()
        End Sub))

因为它冻结了UI,与没有线程没有区别。

所以我尝试使用System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False代码,如下所示

代码语言:javascript
复制
 Private Sub Barfrmvb_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False

        Dim TDS1 As TimerCallback = AddressOf Showdatatimer
        Timer_LoadData = New Threading.Timer(TDS1, Nothing, 0, 3000)
  End Sub
Sub Showdatatimer()
        Timer_LoadData.Change(Timeout.Infinite, Timeout.Infinite)
        Try
          Dim s As SeriesCollection
            s = Chart1.Series

            For i = 0 To 100
                Dim s1 As New Series
                s1.ChartType = SeriesChartType.StackedBar
                s1.Points.AddXY(1, Now.Second + i)
                s.Add(s1)
            Next
        Catch ex As Exception
        Finally
            Timer_LoadData.Change(1000, 1000)
        End Try

当级数小于10没有问题,但级数大于我得到的错误

代码语言:javascript
复制
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.DataVisualization.dll

Additional information: Collection was modified; enumeration operation may not execute.

I think 
1.Thread1 Showdatatimer Complete
2.UI Chart render from Thread1  not complete
3.Thread2 Showdatatimer Complete
4.UI Chart render Collection was modified

我尝试使用dotnetcharting 500系列,但dotnetcharting没有StackedBar

100系列的原因。我将实现显示机器的黄,绿,红,蓝的时间线状态。任何人有其他方式请建议我。

这段代码:

代码语言:javascript
复制
Public Sub Showdata(UserDT As DataTable, fromtime As DateTime, totime As DateTime)
 Chart1.Series.Clear()
            Chart1.ChartAreas("ChartArea1").Position.X = 0
            Chart1.ChartAreas("ChartArea1").Position.Width = 100
            Chart1.ChartAreas("ChartArea1").AxisY.Minimum = fromtime.ToOADate
            Chart1.ChartAreas("ChartArea1").AxisY.Maximum = totime.ToOADate
                Dim nexttime As DateTime
                For i = 0 To UserDT.Rows.Count - 2
                    Dim dr As DataRow
                    dr = UserDT.Rows(i)
                    Dim sname As String = i
                    nexttime = UserDT.Rows(i + 1)("rectime")
                    Dim befUsetime As TimeSpan
                    If i = 0 Then
                        dr("usetime") = nexttime.ToString("yyyy-MM-dd HH:mm:ss")
                    Else
                        dr("usetime") = nexttime.Subtract(CDate(dr("rectime")))

                    End If

                    If Chart1.Series.IndexOf(sname) = -1 Then
                        Chart1.Series.Add(New Series(sname))
                    End If

                    Chart1.Series(sname).YValueType = ChartValueType.DateTime


                    If dr("s").ToString = "R" Then
                        Chart1.Series(sname).Color = Color.Red
                    ElseIf dr("s").ToString = "Y" Then
                        Chart1.Series(sname).Color = Color.Yellow
                    ElseIf dr("s").ToString = "G" Then
                        Chart1.Series(sname).Color = Color.LimeGreen
                    ElseIf dr("s").ToString = "idle" Then
                        Chart1.Series(sname).Color = Color.White
                    ElseIf dr("s").ToString = "Beaktime_Start" Then
                        Chart1.Series(sname).Color = Color.Blue
                    Else
                        Chart1.Series(sname).Color = Color.Gray
                    End If

                    Chart1.Series(sname).ChartType = SeriesChartType.StackedBar
                    Dim x As String
                    Dim y As Double
                    x = dr("username").ToString
                    If i = 0 Then
                        y = CDate(dr("usetime")).ToOADate
                        Chart1.Series(sname).Points.AddXY(x, y)
                    Else
                        Dim t As TimeSpan = TimeSpan.Parse(dr("usetime"))
                        Chart1.Series(sname).Points.AddXY(x, New DateTime(t.Ticks).ToOADate)
                    End If

                Next
    End sub

我尝试另一种方法来减少系列,如果可以添加一个系列,但不同的颜色。我尝试此代码,但相同的颜色。

代码语言:javascript
复制
 Chart1.SuspendLayout()
                                                 Chart1.Series.Clear()


                                                 Dim s As SeriesCollection
                                                 s = Chart1.Series
        Dim s1 As New Series
        For i = 0 To 500

            s1.ChartType = SeriesChartType.StackedBar
            Dim p As New DataPoint

            p.XValue = 1
            p.YValues = {Now.Second + i}
            If i Mod 2 = 0 Then
                p.Color = Color.Aqua
            ElseIf i Mod 3 = 0 Then
                p.Color = Color.White
            Else
                p.Color = Color.Red
            End If

            s1.Points.Add(p)

        Next
        s.Add(s1)
        Chart1.ResumeLayout()

解算Stack Bar不改变颜色,将大多数值添加到第一个点并减少值,如下面的代码所示。我将尝试新的算法将最后一个值添加到第一个值。

代码语言:javascript
复制
 For i = 0 To 500

            s1.ChartType = SeriesChartType.StackedBar
            Dim p As New DataPoint

            p.XValue = 1
            p.YValues = {500 - i}
            If i Mod 2 = 0 Then
                p.Color = Color.Aqua
            ElseIf i Mod 3 = 0 Then
                p.Color = Color.White
            Else
                p.Color = Color.Red
            End If

            s1.Points.Add(p)

        Next

结果:

EN

回答 1

Stack Overflow用户

发布于 2019-07-28 23:49:30

我尝试实现一个系列的代码,它与独立的线程和UI线程一起工作,不会冻结。这减少了,并且比旧的代码非常简单。

代码语言:javascript
复制
 Public Sub Showdata(UserDT As DataTable, fromtime As DateTime, totime As DateTime)



        Try
            Chart1.Series.Clear()
            Chart1.ChartAreas("ChartArea1").Position.X = 0
            Chart1.ChartAreas("ChartArea1").Position.Width = 100

            Chart1.ChartAreas("ChartArea1").AxisY.Minimum = fromtime.ToOADate
            Chart1.ChartAreas("ChartArea1").AxisY.Maximum = totime.ToOADate
            Chart1.SuspendLayout()

            Dim s As New Series
            s.YValueType = ChartValueType.DateTime
            s.ChartType = SeriesChartType.StackedBar

            For i = UserDT.Rows.Count - 1 To 1 Step -1

                Dim p As New DataPoint

                Dim dr, nextdr As DataRow
                dr = UserDT.Rows(i)
                nextdr = UserDT.Rows(i - 1)

                If nextdr("s").ToString = "R" Then
                    p.Color = Color.Red
                ElseIf nextdr("s").ToString = "Y" Then
                    p.Color = Color.Yellow
                ElseIf nextdr("s").ToString = "G" Then
                    p.Color = Color.LimeGreen
                ElseIf nextdr("s").ToString = "idle" Then
                    p.Color = Color.White
                ElseIf nextdr("s").ToString = "Beaktime_Start" Then
                    p.Color = Color.Blue
                Else
                    p.Color = Color.Gray
                End If


                Dim y As Double

                y = CDate(dr("rectime")).ToOADate
                p.XValue = 1
                p.YValues = {y}
                s.Points.Add(p)

            Next
            Chart1.Series.Add(s)
            Chart1.ResumeLayout()
        Catch ex As Exception

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

https://stackoverflow.com/questions/57239277

复制
相关文章

相似问题

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