Public Class GraphTimePerDay
Private Days As List(Of Date)
Private [Step], Pixels As Single
Private DFont As New Font("Microsoft Sans Serif", 13, FontStyle.Regular)
Private Const BottomSpan As Int16 = 80
Private Const LeftSpan As Int16 = 50
Private Const DefaultWidth As Int16 = 650
Private Sub InitializeValues(ByVal Log As LogExplorer.Log)
Days = New List(Of Date)
For Each S As LogExplorer.Session In Log.Sessions
If Not Days.Contains(S.StartTime.Date) Then
Days.Add(S.StartTime.Date)
Hours.Add(S.StartTime.Date, S.ElapsedTime.TotalHours)
Else
Hours(S.StartTime.Date) += S.ElapsedTime.TotalHours
End If
Next
Days.Sort()
Pixels = 35 * (22 / Days.Count)
[Step] = Days.Count / 22
Me.Refresh()
End Sub
Sub New(ByVal Log As LogExplorer.Log)
Me.InitializeComponent()
Me.InitializeValues(Log)
End Sub
Private Function GetX(ByVal Index As Int16, ByVal PixelSpan As Single) As Single
Return LeftSpan + 17 + (Index) * PixelSpan
End Function
Private Sub GraphTimePerDay_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
Try
With e.Graphics
.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
.DrawLine(Pens.Black, 50, 0, 50, Me.Height)
.DrawLine(Pens.Black, 0, Me.Height - BottomSpan, Me.Width, Me.Height - BottomSpan)
Dim Index As Int16 = 0
Dim Prec, PrecStart As Int16
Dim Size As SizeF
Dim Pix As Single
Dim Points As New List(Of Point)
Dim Max As Single
If [Step] < 1 Then
Pix = Pixels * Me.Width / DefaultWidth
Else
Pix = 35 * Me.Width / DefaultWidth
End If
For Each V As Single In Hours.Values
If V > Max Then
Max = V
End If
Next
For I As Int16 = 0 To Days.Count - 1
If I Mod CInt(Math.Ceiling([Step])) = 0 Then
.DrawLine(Pens.Black, GetX(Index, Pix), Me.Height - BottomSpan, GetX(Index, Pix), Me.Height - BottomSpan + 3)
Size = .MeasureString(Days(I).Day, DFont)
.DrawString(Days(I).Day, DFont, Brushes.Black, GetX(Index, Pix) - Size.Width / 2, Me.Height - BottomSpan + 1)
Index += 1
End If
If Days(I).Month <> Prec Then
If PrecStart > 0 Then
Dim Month As String = New Date(2000, Prec, 1).ToString("MMMM")
Dim Y As Int16 = Me.Height - BottomSpan + 20
Dim ThisX As Int16 = GetX(Index - 1, Pix)
Dim Color As Color = Drawing.Color.Gray
Size = .MeasureString(Month, DFont)
If PrecStart + Size.Width > ThisX Then
Y += 30
Color = Drawing.Color.LightGray
Month = Month.Substring(0, 3)
Size = .MeasureString(Month, DFont)
End If
.FillRectangle(New SolidBrush(Color), PrecStart, Y, ThisX - PrecStart - 1, 25)
.DrawString(Month, DFont, Brushes.Black, PrecStart + (ThisX - PrecStart) / 2 - Size.Width / 2, Y)
End If
Prec = Days(I).Month
PrecStart = GetX(Index - 1, Pix)
End If
Next
If PrecStart > 0 Then
Dim Month As String = New Date(2000, Days(Days.Count - 1).Month, 1).ToString("MMMM")
Dim Y As Int16 = Me.Height - BottomSpan + 20
Dim Color As Color = Drawing.Color.Gray
Size = .MeasureString(Month, DFont)
.FillRectangle(New SolidBrush(Color), PrecStart, Y, Me.Width - PrecStart - 1, 25)
.DrawString(Month, DFont, Brushes.Black, PrecStart + (Me.Width - PrecStart) / 2 - Size.Width / 2, Y)
End If
For I As Int16 = 0 To Days.Count - 1
Points.Add(New Point(GetX(I, (Pix / Math.Ceiling([Step]))), Me.Height - BottomSpan - ((Me.Height - BottomSpan) * Hours(Days(I)) / Max)))
Next
For I As Int16 = 0 To 10
Size = .MeasureString(String.Format("{0:N2}", Max * I / 10), DFont)
.DrawLine(Pens.Black, LeftSpan - 3, CInt(Me.Height - BottomSpan - ((Me.Height - BottomSpan) * I / 10)), LeftSpan, CInt(Me.Height - BottomSpan - ((Me.Height - BottomSpan) * I / 10)))
.DrawString(String.Format("{0:N2}", Max * I / 10), DFont, Brushes.Black, 50 - Size.Width, CInt(Me.Height - BottomSpan - ((Me.Height - BottomSpan) * I / 10)))
Next
Dim IntPen As New Pen(Color.Blue)
Dim RealPen As New Pen(Color.Black)
IntPen.DashCap = Drawing2D.DashCap.Round
IntPen.DashStyle = Drawing2D.DashStyle.Dash
If btnLine.Text = "Interpolazione" Then
.DrawCurve(IntPen, Points.ToArray)
Else
.DrawLines(RealPen, Points.ToArray)
End If
End With
Catch Ex As Exception
RemoveHandler Me.Paint, AddressOf GraphTimePerDay_Paint
MessageBox.Show("Impossibile disegnare il grafico con questi dati!", "Errore grafico", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub btnLine_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLine.Click
If btnLine.Text = "Interpolazione" Then
btnLine.Text = "Normale"
Else
btnLine.Text = "Interpolazione"
End If
Me.Refresh()
End Sub
End Class