' FORM1 with ' Chart1 ' CoboBox1 with 12 hours, 7 days, Month ' TextBox1 for StepSize ' Button1 to GO ' DataGridView1 for display of raw ' data if needed ' Needs the data file in a Folder named ' Data in same place as executable Option Strict On Option Explicit On Imports System.IO Imports System.Windows.Forms.DataVisualization.Charting Public Class Form1 Dim path As String = IO.Path.Combine(Application.StartupPath, "Data", "Agriculture_Humidity_Log.csv") Dim dt As New DataTable("Freddy") Dim LogData() As String Dim WithEvents FSW As FileSystemWatcher Dim max As Double = 0.0 Dim min As Double = 9999.9 Dim r As New Random Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load ' this will OVERWRITE existing data ' file with random data make sure ' you have a copy. ' frequency of 90 seconds used, ' 42000 data points (approx 44 days) ' uncomment with care ' =============================== ' OverWriteDataFile() ' =============================== If Not Directory.Exists(Directory.GetParent(path).FullName) Then MessageBox.Show("Need to have the datafile in a folder named 'Data' alongside the executable file", "ERROR") Directory.CreateDirectory(Directory.GetParent(path).FullName) End If If File.Exists(path) Then FSW = New FileSystemWatcher() With FSW .Path = Directory.GetParent(path).FullName .EnableRaisingEvents = False .NotifyFilter = NotifyFilters.LastWrite .Filter = "*.csv" End With End If With dt .Columns.Add("ID", GetType(Integer)) .Columns.Add("DateTime", GetType(DateTime)) .Columns.Add("Humidity", GetType(Double)) End With With ComboBox1 .Items.AddRange({"12 hours", "7 days", "Month", "All"}) .SelectedIndex = 0 End With With Chart1 .Series(0).ChartType = SeriesChartType.Spline .Series(0).XValueType = ChartValueType.Time .ChartAreas(0).AxisX.IntervalType = DataVisualization.Charting.DateTimeIntervalType.Hours End With ReadLogData() End Sub Sub ShowDGV() With DataGridView1 .DataSource = dt .SelectionMode = DataGridViewSelectionMode.FullRowSelect .Columns("ID").AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells .Columns("DateTime").DefaultCellStyle.Format = "ddd, dd MMM yyyy HH:mm:ss" .Columns("DateTime").AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill .Columns("Humidity").DefaultCellStyle.Format = "0.0" End With End Sub Sub ReadLogData() LogData = ReadData() If LogData Is Nothing Then MessageBox.Show("Data file not found can not continue .......", "ERROR") End End If dt.Clear() With dt Dim id As Integer = 1 For Each s As String In LogData Dim a() As String = s.Split(","c) If a(0) = "Date" Then Continue For Dim comb As DateTime = CDate(String.Join(","c, a(0), a(1))) .Rows.Add(id, comb, a(2)) id += 1 Next End With FSW.EnableRaisingEvents = True With DateTimePicker1 .Value = CDate(dt(0)(1)) .MinDate = CDate(dt(0)(1)) .MaxDate = CDate(dt.Compute("MAX(DateTime)", "")) End With End Sub Function ReadData() As String() Dim s() As String = Nothing If File.Exists(path) Then s = File.ReadAllLines(path) End If Return s End Function Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click max = 0 : min = 9999 Cursor = Cursors.WaitCursor Select Case ComboBox1.SelectedItem.ToString Case "12 hours" MakeGraph(12, 60) Case "7 days" MakeGraph(7 * 24, 7 * 60) Case "Month" ' 28 day month MakeGraph(28 * 24, 28 * 90) Case "All" MakeGraph(500 * 24, 28 * 150) End Select With Chart1 With .ChartAreas(0).AxisY .Maximum = CInt(max + 1) .Minimum = CInt(min - 1) .Interval = CInt((max - min) / 10) End With .ResetAutoValues() End With Cursor = Cursors.Default End Sub Sub MakeGraph(added As Integer, gap As Integer) Dim start As DateTime If CheckBox1.Checked Then start = DateTimePicker1.Value Else start = CDate(dt(0)(1)) End If Dim ending As DateTime = start.AddHours(added) If dt.Rows.Count < 1 Then Exit Sub Dim stepsize As Integer Integer.TryParse(TextBox1.Text, stepsize) If stepsize < 1 Then Exit Sub With Chart1 .Series(0).Points.Clear() .ChartAreas(0).AxisX.Interval = gap End With For i As Integer = 0 To dt.Rows.Count - 1 Step stepsize If CDate(dt(i)(1)) < start Then Continue For If CDate(dt(i)(1)) > ending Then Exit Sub With Chart1.Series(0).Points Dim v As Double = CDbl(dt(i)(2)) .AddXY((dt(i)(1)).ToString, v) If v > max Then max = v If v < min Then min = v End With Next End Sub Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged ReadLogData() Button1.PerformClick() End Sub Private Sub FSW_Changed(sender As Object, e As FileSystemEventArgs) Handles FSW.Changed FSW.EnableRaisingEvents = False Threading.Thread.Sleep(200) ReadLogData() Invoke(Sub() Button1.PerformClick()) End Sub Dim fillDGV As Boolean = False Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click fillDGV = Not fillDGV If Not fillDGV Then DataGridView1.DataSource = Nothing Else Cursor = Cursors.WaitCursor ShowDGV() Cursor = Cursors.Default End If End Sub Sub OverWriteDataFile() ' ONLY TO CREATE RANDOM DATA FILE ' OVERWRITE EXISTING FILE SO MAKE A ' COPY Dim inc() As Double = {-0.1, -0.07, -0.04, -0.01, 0, 0.04, 0.07, 0.1} Dim dd As DateTime = New Date(2022, 9, 9, 8, 45, 56) Dim st As Double = 60.0 Using sw As New StreamWriter(path) For i As Integer = 1 To 42000 Dim rr As Double = inc(r.Next(inc.Length)) Dim mm As Integer = r.Next(-1, 1) If mm = 0 Then st += rr Else st -= rr End If sw.Write(dd.Date.ToString("yyyy-MM-dd") & ", " & dd.TimeOfDay.ToString & ", " & st.ToString("0.00") & vbCrLf) dd = dd.AddSeconds(90) Next End Using End Sub End Class