Jump to content

Generate interactive line graphics, pie charts and much more with IE and chart.js


qsek
 Share

Recommended Posts

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

 

grafik.thumb.png.282b216468da9517c476c8b0ed7b7a61.png

 

#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 by qsek
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

  • 3 years later...

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...