The example here uses the jsdeliver service which obviously requires your device to have internet access.
Special thanks to cicciocb without whom I would never have been able to get the web page and Annex to talk to each other.
Hope this little snippet is of use to someone.
Code: [Local Link Removed for Guests]
'****************************************************************************************
'* *
'* Example of Chart.js persistant time graph with variable data sets *
'* V1.0.0 16/06/2023 © BeanieBots. *
'* Thanks to cicciocb for the help with html & jarva bits. *
'* For more information on the use of Chart.js, please see https://www.chartjs.org/ *
'* Tested on ESP8266 FW 1.44.2 & ESP32 FW BLE CAN 1.48.22 *
'* *
'****************************************************************************************
RAMspare = 60000 'The amount of RAM left spare after creating the datasets.
'Determines how long data will be stored before deleting.
'The ESP8266 can be as low 32000 but the ESP32 requires at
'least 60000 to be reliable.
NumSets = 3 'The number of EXTRA datasets to be plotted.
Dim Value(NumSets) 'Create an array to hold the new values.
Dim DataSet$(NumSets) 'Create a string array to hold each dataset.
Angle = 0 'Starting value for dummy data
TimeStamp$ = "" 'Declare empty timestamp.
'-----------------------------------------------------------------------------------------
OnHtmlReload ReLoadPage'Re-Load page for new connections.
'-----------------------------------------------------------------------------------------
Gosub LoadPage 'Load initial page
Timer0 3000, NextData 'Do not set < 2000
wait
'-----------------------------------------------------------------------------------------
NextData:
Gosub GetTimeStamp 'Each piece of data requires a timestamp in string format
Gosub GetValue 'Generate some example data.
Gosub UpdateChart 'Send data to page and update
while ramfree < RAMspare 'When low on RAM start removing old data from the left.
For Set = 0 to NumSets 'Remove data from the left
DataSet$(Set) = right$(DataSet$(Set),(len(DataSet$(Set))-instr(DataSet$(Set),"}")-1))
Next Set
'An alternative (especially if datasets have different frame rates) would be to set
'a maximun string length (possibly for each set individualy) and then trim accordingly.
wend
Return
'-----------------------------------------------------------------------------------------
GetTimeStamp: '-1 hour (60*60*1000) for GB time.
TimeStamp = (dateUNIX(date$)+timeunix(time$))*1000-(60*60*1000)
Timestamp$ = str$(TimeStamp,"%0.0f")
Return
'-----------------------------------------------------------------------------------------
UpdateChart:
For Set = 0 to NumSets 'Add the new data to the existing string for each dataset.
DataSet$(Set) = DataSet$(Set) + "{x:"+TimeStamp$+",y:"+str$(Value(Set))+"},"
jscall "mychart.data.datasets[" + str$(Set )+ "].data = [" + DataSet$(Set) + "];"
Pause 100 'wait for data to load
Next Set
jscall "mychart.update();" 'now update the chart.
Return
'-----------------------------------------------------------------------------------------
GetValue: 'Create some dummy data for each dataset.
angle = angle+2*pi/47
if angle > 2*pi then 'limit angle to between 0 & 2.pi radians.
angle = angle-(2*pi)
endif
For N = 0 to NumSets
Value(N) = sin(angle+(N*(2*pi/12))) 'each set is 30 degrees ahead of the previous one
Next N
Return
'-----------------------------------------------------------------------------------------
LoadPage:
cls
jsexternal "https://cdn.jsdelivr.net/npm/chart.js@4.3.0/dist/chart.umd.min.js"
pause 500 'wait a little bit for the library to load
jsexternal "https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"
'Required for 'time' scale plots.
pause 100 'wait a little bit for the library to load
cls
A$=""
A$ = |<h> Time Graph </h>|
A$ = A$ + |<div>|
A$ = A$ + | <canvas id="myChart"></canvas>|
A$ = A$ + |<style> body {background-color: #cce;}</style>|
A$ = A$ + |</div>|
html a$
'Generate the chart
A$ = ||
A$ = A$ + |ctx = document.getElementById('myChart');|
A$ = A$ + ||
A$ = A$ + | mychart = new Chart(ctx, {|
A$ = A$ + | type: 'line',|
A$ = A$ + | data: {|
'Add the first dataset
A$ = A$ + | datasets: [{|
A$ = A$ + | label: 'Data0',|
A$ = A$ + | data: [],|
'Add subsequent datasets (if any)
For Set = 1 to NumSets
Title$ = "Data" + Str$(Set)
A$ = A$ + | },{|
A$ = A$ + | label: '|+Title$+|',|
A$ = A$ + | data: [],|
Next Set
'Close off the datasets, set scales and add any options.
A$ = A$ + | },]|
A$ = A$ + | },|
A$ = A$ + | options: {|
A$ = A$ + | scales: {|
A$ = A$ + | x: {|
A$ = A$ + | type: 'time',|
A$ = A$ + | time: {unit: 'minute'},|
A$ = A$ + | }|
A$ = A$ + | }|
A$ = A$ + | }|
A$ = A$ + | });|
jscript A$
A$ = ""
Pause 100
Return
'-----------------------------------------------------------------------------------------
ReLoadPage:
Gosub LoadPage
If TimeStamp$ <> "" then 'Don't update an empty graph.
Gosub UpdateChart
endif
Return
'-----------------------------------------------------------------------------------------
End
An ESP32 can maintain 10 data sets samples every 3 seconds for about 8 minutes.
If anyone ever tries it on one of the large S3 devices, I'd be curious to know how much it can handle.