How can I update Chart by thread timer. I not use invoke like this code.
Chart1.BeginInvoke(New MethodInvoker(Sub()
Showdatatimer()
End Sub))
Because it freeze UI not difference from no thread.
So I try to use System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False Code like this
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
When Series less than 10 not a problem but serie more than I got error
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
I try to use with dotnetcharting 500 series it work but dotnetcharting no StackedBar
Reason of 100 series.I will implement to show timeline status of machine yellow,green,red,blue. Anyone have other way suggest me please.
this code:
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
I try another way to reduce series if can add in one series but different color.I try this code but same color.
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()
Solve Stack Bar not change color add most value to first point and reduce value like this code. I will try to new algorithm add last value to first value.
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
CheckForIllegalCrossThreadCalls
toFalse
, so you should just go ahead and remove that again. The only way to access the UI from a background thread is to invoke. If doing so causes your UI to freeze then yourShowdatatimer()
method is doing some long-running work it shouldn't do. You never showed us in what context you are performing the invoke. – Visual VincentSystem.Windows.Forms.Timer
? (which runs on the UI thread) – Visual Vincent