qsek Posted February 16, 2021 Share Posted February 16, 2021 (edited) Just wanted to share a quick proof of concept with some performance testing. GraphGDIPlus lacked performance and interactivity for me so i searched new way to generate graphs. Potential is huge especially when you consider using d3.js instead of chart.js expandcollapse popup#include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <Array.au3> #include <File.au3> #include <Date.au3> #include <IE.au3> Opt("GuiOnEventMode", 1) $oIE = ObjCreate("Shell.Explorer.2") $Form1 = GUICreate("Embedded Web control Test", 1140, 380, _ (@DesktopWidth - 1140) / 2, (@DesktopHeight - 380) / 2, _ $WS_OVERLAPPEDWINDOW + $WS_CLIPSIBLINGS + $WS_CLIPCHILDREN) GUICtrlCreateObj($oIE, 10, 10, 1120, 360) GUICtrlSetResizing ( -1, 1 ) GUISetOnEvent(-3, "_MyExit", $Form1) GUISetState() Func _MyExit() Exit EndFunc ConsoleWrite("generating dataset..." & @CRLF) ; generate a 5k line dataset ; string $datastr = "" For $i = 0 To 2000 $date = _DateAdd("n", $i, "2021/02/14 00:00:00") $datastr &= $date&","&Random(1,500,1)& @CRLF next $datastr = StringTrimRight($datastr, 2) ; array Dim $dataarr[0][2] _ArrayAdd ( $dataarr, $datastr, 0, ",", @CRLF) ConsoleWrite("finished." & @CRLF& @CRLF) $oIE.navigate( "about:blank") $html = "" Sethtml() _IEDocWriteHTML($oIE, $html) _IEAction ( $oIE, "refresh" ) _IELoadWait($oIE) ;~ ; watch your variable/function case with that notation! $ohJS = $oIE.document.parentwindow.JSglobal ;~ ; need to eval [0], javascript arrays are not compatible with autoit arrays or object collections $dset = $ohJS.eval("myChart.data.datasets[0]") $dset.label = "Test1: init dataset with jsvariable.push()" $ohJS.myChart.update() ConsoleWrite("Test1: init dataset with jsvariable.push()"& @CRLF) $ti = TimerInit() ; Test1 $glabels = $ohJS.myChart.data.labels For $i = 0 To UBound($dataarr)-1 If Mod($i,1000) = 0 then ConsoleWrite($i & @CRLF) $glabels.push($dataarr[$i][0]) $dset.data.push($dataarr[$i][1]) next $ohJS.myChart.update() ConsoleWrite("Test1: "&Round(TimerDiff($ti),1)&" ms"& @CRLF) Sleep(2000) $ohJS.GraphClearData() Sleep(1000) ConsoleWrite("Test2: init dataset with passing datastring to js function"& @CRLF) $ti = TimerInit() ; Test2 $ohJS.InitGraphWithData($datastr) $ohJS.myChart.update() ConsoleWrite("Test2: "&Round(TimerDiff($ti),1)&" ms"& @CRLF) Sleep(2000) $ohJS.GraphClearData() $dset.label = "Test3: add data with jsvariable.push()" $ohJS.myChart.update() ConsoleWrite("Test3: add data with jsvariable.push()"& @CRLF) $ti = TimerInit() ; Test3 $glabels = $ohJS.myChart.data.labels For $i = 0 To 500 If Mod($i,100) = 0 then $dset.label = "Test3: add data with jsvariable.push() ("&$i&"/500)" $date = _DateAdd("n", $i, "2021/02/14 00:00:00") $glabels.push($date) $dset.data.push(Random(1,500+$i,1)) $ohJS.myChart.update() Next ConsoleWrite("Test3: "&Round(TimerDiff($ti),1)&" ms"& @CRLF) $ohJS.GraphClearData() ConsoleWrite("Test4: add data with passing datastring to js function" & @CRLF) $ti = TimerInit() ; Test4 For $i = 0 To 500 If Mod($i,100) = 0 then $dset.label = "Test4: add data with passing datastring to js function ("&$i&"/500)" $date = _DateAdd("n", $i, "2021/02/14 00:00:00") $ohJS.GraphAddData($date&","&Random(1,500+$i,1)) If Mod($i,100) = 0 then $dset.label = "Test4: add data with passing datastring to js function ("&$i&"/500)" Next ConsoleWrite("Test4: "&Round(TimerDiff($ti),1)&" ms"& @CRLF) ConsoleWrite("testing ended" & @CRLF) $dset.label = "You can click on points" $ohJS.myChart.update() While 1 For $i = 0 To $ohJS.clickedPoints.length -1 $label = $ohJS.eval("myChart.data.labels[clickedPoints["&$i&"]._index].format('YYYY/MM/DD hh:mm:ss');") $value = $ohJS.eval("myChart.data.datasets[clickedPoints["&$i&"]._datasetIndex].data[clickedPoints["&$i&"]._index];") ConsoleWrite("You clicked at " & $label & ", "&$value & @CRLF) Next $ohJS.clickedPoints = "" Sleep(10) WEnd exit Func Sethtml() $html = "<!DOCTYPE html>" & @CRLF & _ "<html lang='en'>" & @CRLF & _ "" & @CRLF & _ "<head>" & @CRLF & _ " <meta charset='UTF-8'>" & @CRLF & _ " <meta http-equiv='X-UA-Compatible' content='IE=edge' >" & @CRLF & _ " <script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script>" & @CRLF & _ " <script src='https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js'></script>" & @CRLF & _ " <script src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js'></script>" & @CRLF & _ " <title>My Chart</title>" & @CRLF & _ "</head>" & @CRLF & _ "" & @CRLF & _ "<body>" & @CRLF & _ " <div class='container'> <canvas id='myChart' width='100' height='30'></canvas></div>" & @CRLF & _ "" & @CRLF & _ " <script>" & @CRLF & _ " var JSglobal = (1,eval)('this');" & @CRLF & _ " var au3data = ['test','123'];" & @CRLF & _ " var clickedPoints = '';" & @CRLF & _ " Chart.defaults.global.animation.duration = 0;" & @CRLF & _ " Chart.defaults.global.hover.animationDuration = 0;" & @CRLF & _ " Chart.defaults.global.animation.easing = 'linear';" & @CRLF & _ " Chart.defaults.global.elements.line.tension = 0;" & @CRLF & _ " Chart.defaults.global.elements.line.backgroundColor = 'rgba(255, 99, 132, 0.2)';" & @CRLF & _ " Chart.defaults.global.elements.line.borderColor = 'rgba(255, 99, 132, 1)';" & @CRLF & _ "" & @CRLF & _ " Chart.defaults.global.responsiveAnimationDuration = 0;" & @CRLF & _ " //Chart.defaults.line.showLines = false;" & @CRLF & _ " Chart.defaults.line.spanGaps = false;" & @CRLF & _ "" & @CRLF & _ " function GraphClearData() {" & @CRLF & _ " myChart.data.datasets[0].data = [];" & @CRLF & _ " myChart.data.labels = [];" & @CRLF & _ " myChart.update(0);" & @CRLF & _ " }" & @CRLF & _ "" & @CRLF & _ " function InitGraphWithData(datastring, rowdelim, coldelim) {" & @CRLF & _ " rowdelim = typeof rowdelim !== 'undefined' ? rowdelim : '\n';" & @CRLF & _ " coldelim = typeof coldelim !== 'undefined' ? coldelim : ',';" & @CRLF & _ " GraphClearData();" & @CRLF & _ "" & @CRLF & _ " var allLinesArray = datastring.split('\n');" & @CRLF & _ " if (allLinesArray.length > 0) {" & @CRLF & _ " for (var i = 0; i < allLinesArray.length; i++) {" & @CRLF & _ " var rowData = allLinesArray[i].split(',');" & @CRLF & _ " if (rowData[0] != '') {" & @CRLF & _ " myChart.data.labels.push(moment(rowData[0], 'YYYY/MM/DD hh:mm:ss'));" & @CRLF & _ " myChart.data.datasets[0].data.push(rowData[1]);" & @CRLF & _ " }" & @CRLF & _ " }" & @CRLF & _ " }" & @CRLF & _ " myChart.update();" & @CRLF & _ " }" & @CRLF & _ "" & @CRLF & _ "" & @CRLF & _ " function GraphAddData(datastring, rowdelim, coldelim) {" & @CRLF & _ " rowdelim = typeof rowdelim !== 'undefined' ? rowdelim : '\n';" & @CRLF & _ " coldelim = typeof coldelim !== 'undefined' ? coldelim : ',';" & @CRLF & _ "" & @CRLF & _ " var allLinesArray = datastring.split('\n');" & @CRLF & _ " if (allLinesArray.length > 0) {" & @CRLF & _ " for (var i = 0; i < allLinesArray.length; i++) {" & @CRLF & _ " var rowData = allLinesArray[i].split(',');" & @CRLF & _ " if (rowData[0] != '') {" & @CRLF & _ " //alert('adding '+rowData[0]+', '+rowData[1]);" & @CRLF & _ " myChart.data.labels.push(moment(rowData[0], 'YYYY/MM/DD hh:mm:ss'));" & @CRLF & _ " myChart.data.datasets[0].data.push(rowData[1]);" & @CRLF & _ " }" & @CRLF & _ " }" & @CRLF & _ " }" & @CRLF & _ " myChart.update();" & @CRLF & _ " }" & @CRLF & _ "" & @CRLF & _ " var ctx = document.getElementById('myChart').getContext('2d');" & @CRLF & _ "" & @CRLF & _ " document.getElementById('myChart').onclick = function(evt) {" & @CRLF & _ " clickedPoints = myChart.getElementsAtEvent(evt);" & @CRLF & _ " };" & @CRLF & _ "" & @CRLF & _ " var myChart = new Chart(ctx, {" & @CRLF & _ " type: 'line'," & @CRLF & _ " data: {" & @CRLF & _ " datasets: [{" & @CRLF & _ " label: ''," & @CRLF & _ " }]" & @CRLF & _ " }," & @CRLF & _ " options: {" & @CRLF & _ " responsive: 'true'," & @CRLF & _ " scales: {" & @CRLF & _ " xAxes: [{" & @CRLF & _ " type: 'time'," & @CRLF & _ " time: {" & @CRLF & _ " displayFormats: {" & @CRLF & _ " minute: 'DD.MMM H:m'" & @CRLF & _ " }" & @CRLF & _ " }," & @CRLF & _ " distribution: 'linear'," & @CRLF & _ " ticks: {" & @CRLF & _ " source: 'auto'" & @CRLF & _ " }," & @CRLF & _ " bounds: 'bounds'" & @CRLF & _ " }]" & @CRLF & _ " }" & @CRLF & _ " }" & @CRLF & _ " });" & @CRLF & _ "" & @CRLF & _ " myChart.update();" & @CRLF & _ "" & @CRLF & _ " <!-- setInterval(function() { -->" & @CRLF & _ " <!-- updateChart() -->" & @CRLF & _ " <!-- }, 5000); -->" & @CRLF & _ " </script>" & @CRLF & _ "</body>" & @CRLF & _ "" & @CRLF & _ "</html>" & @CRLF EndFunc Edited February 17, 2021 by qsek Gianni, mLipok and argumentum 2 1 Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite Link to comment Share on other sites More sharing options...
Burgs Posted August 27 Share Posted August 27 Greetings, I realize this post is a few years old, however I wanted to thank you for posting it. I find this interesting and it got me to thinking a bit. I attempted to modify this code to create a financial 'candlestick' chart using either Chart.js or D3.js (as you had mentioned) however I was frustrated by the inability to render the chart and the candlestick elements within. I believe this is because IE is outdated and no longer supported so the IE commands within AutoIt are unable to handle modern JavaScript code and SVG graphics, at the very least. Not sure if there is any workaround...I thought WebDriver might be feasible, however as I understand it the browser renders as a separate window and cannot be embedded into an AutoIt GUI as I would like, although I could certainly be mistaken. Anyway thank you again for your interesting concept. Regards Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now