Mapping Actions over Time
Mapping Actions over Time
I'm thinking about making a simple example of using a gui to create graphs for this thread viewtopic.php?f=6&t=94961&p=421828#p421828
I don't really have much that I can think of to graph, so I have decided to go with showing a graph of cps / time.
ATM I'm struggling trying to come up with a good structure to use to record / hold the data.
The main idea is to use a hotkey LButton to record something like A_Sec and get that into an array.
Then once every 1-10 seconds (SetTimer) I use the new data and a bit of the old to populate an array of cps over the last 1-3 mins
Once I have the data I can create the graphics to display / update in a graph.
Any ideas on a good structure for this?
I don't really have much that I can think of to graph, so I have decided to go with showing a graph of cps / time.
ATM I'm struggling trying to come up with a good structure to use to record / hold the data.
The main idea is to use a hotkey LButton to record something like A_Sec and get that into an array.
Then once every 1-10 seconds (SetTimer) I use the new data and a bit of the old to populate an array of cps over the last 1-3 mins
Once I have the data I can create the graphics to display / update in a graph.
Any ideas on a good structure for this?
Re: Mapping Actions over Time
This is what I have been able to come up with so far.
That should work? for recoding clicks, the only issue is being able to take the different arrays and combine them together into an array that is used for the graph and toss out the expired bits.
This now comes down to manipulating time which is something I have to say is not a skill I have spent much time developing.
Thoughts?
that joke was unintentional, but this one is : )
Ideally I should end up with an array with between 60 and 180 values in it.
Code: Select all
#If ( Active )
;Clicks := [] up top
~$*LButton::
if( CurrentMin != A_Min ){
CurrentMin := A_Min
Clicks[ CurrentMin ] := []
}
Clicks[ CurrentMin ].Push( A_Sec )
return
#If
This now comes down to manipulating time which is something I have to say is not a skill I have spent much time developing.
Thoughts?
that joke was unintentional, but this one is : )
Ideally I should end up with an array with between 60 and 180 values in it.
Re: Mapping Actions over Time
Code: Select all
minutes := 3, clik := []
~*LButton::
clik.Push(dif := A_Now), clik := purge(clik, minutes)
dif -= clik.1, S ; Seconds since the first time in the measurement interval
ToolTip, % Max(1, Round(clik.Count() / dif)) " cps`nClicks: " clik.Count()
Return
purge(arr, min) { ; Remove invalid times from array
start := A_Now, n := 0
start += -min, M ; Starting time of the measurement interval
For index, time in arr
n := time < start ? index : n ; Find the latest time outside the interval
arr.RemoveAt(1, n) ; Remove all invalid times
Return arr
}
Re: Mapping Actions over Time
@mikeyww
Thanks for that, it looks good. Took me a min to figure out what var += -var2 , var3 was lol
Would I be right in assuming that I can take this out
and only call it when I plan on updating the graphics?
***EDIT*** On second inspection, I am not really sure how this is supposed to work.
It looks like I need to still do the split into an array that can be displayed in a line or bar graph?
Thanks for that, it looks good. Took me a min to figure out what var += -var2 , var3 was lol
Would I be right in assuming that I can take this out
Code: Select all
clik := purge(clik, minutes)
***EDIT*** On second inspection, I am not really sure how this is supposed to work.
It looks like I need to still do the split into an array that can be displayed in a line or bar graph?
Last edited by Hellbent on 23 Sep 2021, 21:24, edited 1 time in total.
Re: Mapping Actions over Time
Yes, but instead of getting cps over the last 3 minutes, you will just get the cumulative cps. Nonetheless, since you would have all values, you could then compute the cps for any interval that you like.
To build a longitudinal record, you could either store all values and then compute cps for particular intervals, or you could add a timestamped cps for each new value along the way.
The way I remember += and -= for times:
1. If you want to subtract a time and return a difference, use -=.
2. If you want to add a difference and return a time, use +=.
To build a longitudinal record, you could either store all values and then compute cps for particular intervals, or you could add a timestamped cps for each new value along the way.
Code: Select all
minutes := 3, record := {}, clik := [], n := 0, text := ""
SetTimer, Record, 500
~*LButton::clik.Push(A_Now)
Record:
record[now := A_Now] := cps(clik := purge(clik, minutes)), text .= "`n" now ": " record[now]
ToolTip, % record[now] " cps`nClicks: " clik.Count()
If (n++ < 10)
Return
SetTimer,, Off
ToolTip
MsgBox, 64, Time and CPS, % text := SubStr(text, 2)
Return
purge(arr, min) { ; Remove invalid times from array
start := A_Now, n := 0
start += -min, M ; Starting time of the measurement interval
For index, time in arr
n := time < start ? index : n ; Find the latest time outside the interval
arr.RemoveAt(1, n) ; Remove all invalid times
Return arr
}
cps(clik) {
dif := A_Now
dif -= clik.1, S ; Seconds since the first time in the measurement interval
Return clik.Count() ? Max(1, Round(clik.Count() / dif)) : 0
}
1. If you want to subtract a time and return a difference, use -=.
2. If you want to add a difference and return a time, use +=.
Last edited by mikeyww on 23 Sep 2021, 21:45, edited 1 time in total.
Re: Mapping Actions over Time
That is a last min update to my last post.***EDIT*** On second inspection, I am not really sure how this is supposed to work.
It looks like I need to still do the split into an array that can be displayed in a line or bar graph?
I think that my intentions are unclear or I misunderstand what you mean.
give me a few mins and i'll try to paint a better picture. (in a new post)
The gist is,
Record when a click was made and then every 1-10 seconds update a running graph ( has up to 180 points ) one point for every for every second in the last (up to 180) seconds.
The idea with the points is the newest entry's would start on the left or right side of the graph and then as time passes the point would move towards the far side where it eventually gets discarded to free the memory.
If you have any questions about that let me know.
Thanks I was talking about the (what looked like) , var at the end of it, but I assume the -=/+= plays a part in looking for the ,
Re: Mapping Actions over Time
Code: Select all
minutes := 3, record := [], clik := []
Gui, +AlwaysOnTop
Loop, 10
Gui, Add, Progress, x+m yp w15 h110 cBlue Vertical Range0-10 vp%A_Index%
Gui, Show, w280 NoActivate, CPS
SetTimer, Record, 1000
~*LButton::clik.Push(A_Now)
Record:
SoundBeep, 1500
record[now := A_Now] := cps(clik := purge(clik, minutes)), n := 0
For time, cps in record
If (A_Index > record.Count() - 10)
GuiControl,, % "p" ++n := Mod(0 n, 10), %cps%
Return
GuiClose:
GuiEscape:
ExitApp
purge(arr, min) { ; Remove invalid times from array
start := A_Now, n := 0
start += -min, M ; Starting time of the measurement interval
For index, time in arr
n := time < start ? index : n ; Find the latest time outside the interval
arr.RemoveAt(1, n) ; Remove all invalid times
Return arr
}
cps(clik) {
dif := A_Now
dif -= clik.1, S ; Seconds since the first time in the measurement interval
Return clik.Count() ? Max(1, Round(clik.Count() / dif)) : 0
}
Code: Select all
Record:
SoundBeep, 1500
record.Push(cps(clik := purge(clik, minutes)))
If record.Count() > 10
record.RemoveAt(1)
For each, cps in record
GuiControl,, p%each%, %cps%
Return
Re: Mapping Actions over Time
Hi @mikeyww. I just noticed you edited your last post so I haven't checked out your new code yet.
I have gone over your last code and it looks like it may have a bug. It seems to start off ok, but then sort of slowly counts down and becomes a bit unresponsive to clicks for awhile and then seems to read the clicks for a bit before going into countdown again.
This is my exact test code, Besides the extra bit of script setup and shutdown code I only altered the Record routine, I don't see anything in my alterations that should change the codes function.
And thank you for your help so far.
I have gone over your last code and it looks like it may have a bug. It seems to start off ok, but then sort of slowly counts down and becomes a bit unresponsive to clicks for awhile and then seems to read the clicks for a bit before going into countdown again.
This is my exact test code, Besides the extra bit of script setup and shutdown code I only altered the Record routine, I don't see anything in my alterations that should change the codes function.
Code: Select all
#SingleInstance, Force
#NoEnv
SetBatchLines, -1
minutes := 3, record := {}, clik := [], n := 0, text := ""
SetTimer, Record, 500
return
GuiClose:
GuiContextMenu:
*ESC::
ExitApp
~*LButton::clik.Push(A_Now)
Record:
record[now := A_Now] := cps(clik := purge(clik, minutes)), text .= "`n" now ": " record[now]
;ToolTip, % record[now] " cps`nClicks: " clik.Count()
If (n++ > 30 && !n := 0 )
text := ""
;Return
;SetTimer,, Off
;ToolTip
ToolTip, % text ;:= SubStr(text, 2)
Return
purge(arr, min) { ; Remove invalid times from array
start := A_Now, n := 0
start += -min, M ; Starting time of the measurement interval
For index, time in arr
n := time < start ? index : n ; Find the latest time outside the interval
arr.RemoveAt(1, n) ; Remove all invalid times
Return arr
}
cps(clik) {
dif := A_Now
dif -= clik.1, S ; Seconds since the first time in the measurement interval
Return clik.Count() ? Max(1, Round(clik.Count() / dif)) : 0
}
Re: Mapping Actions over Time
You could be right! Do some testing.
With minutes=3, it means that you are seeing the cps during that entire period, so as more time elapses up to that number of minutes, the influence of new clicks will diminish. You can decrease the minutes to see greater relative influences. You can try minutes=0.1, for example. To understand how that works, you can add lines (line 34 here) that display the number of clicks and the number of seconds elapsed.
With minutes=3, it means that you are seeing the cps during that entire period, so as more time elapses up to that number of minutes, the influence of new clicks will diminish. You can decrease the minutes to see greater relative influences. You can try minutes=0.1, for example. To understand how that works, you can add lines (line 34 here) that display the number of clicks and the number of seconds elapsed.
Code: Select all
minutes := 3, record := [], clik := []
Gui, +AlwaysOnTop
Loop, 10
Gui, Add, Progress, x+m yp w15 h110 cBlue Vertical Range0-10 vp%A_Index%
Gui, Show, w280 NoActivate, CPS
SetTimer, Record, 1000
~*LButton::clik.Push(A_Now)
Record:
SoundBeep, 1500
record[A_Now] := cps(clik := purge(clik, minutes)), n := 0
For time, cps in record
If (A_Index > record.Count() - 10)
GuiControl,, % "p" ++n, %cps%
Return
GuiClose:
GuiEscape:
ExitApp
purge(arr, min) { ; Remove invalid times from array
start := A_Now, n := 0
start += -min, M ; Starting time of the measurement interval
For index, time in arr
n := time < start ? index : n ; Find the latest time outside the interval
arr.RemoveAt(1, n) ; Remove all invalid times
Return arr
}
cps(clik) {
dif := A_Now
dif -= clik.1, S ; Seconds since the first time in the measurement interval
ToolTip, % Round(clik.Count() / dif) " cps`nClicks: " clik.Count() "`nSeconds: " dif
Return Round(clik.Count() / dif)
}
Re: Mapping Actions over Time
Thank You @mikeyww that gui helped a lot.
Your method of displaying a rolling average? isn't quite what I had in mind. That said, I was looking for data to graph and this does give me data to graph so it's a win on that front.
However... 2 things.
I would still like to be able to graph the actual clicks in any given second, as it is now I normally have to go to web sites to get cps data and they can be very unreliable.
This is a mockup I made an hour or so ago but didn't post because I was still working through your examples.
The other thing is that although your code seems to work pretty well with short time spans minutes := 1/30, there seems to be a flaw in the methodology that shows up when times such as the 3 mins are used. (the changing divisor)
p.s no I don't mean what you think I mean, I mean it (the time interval) doesn't change linearly like you would expect it to. It can jump around if you feed it a few random clicks here and there, that puts big gaps in the time stamps. (which causes the divisor to jump around wildly)
Funny enough though, it still gives me data to plot so another win lol
Oh yeah, it's really nice to see that I'm not the only one who has off days every now and then
And thank you so much for your help so far.
Your method of displaying a rolling average? isn't quite what I had in mind. That said, I was looking for data to graph and this does give me data to graph so it's a win on that front.
However... 2 things.
I would still like to be able to graph the actual clicks in any given second, as it is now I normally have to go to web sites to get cps data and they can be very unreliable.
This is a mockup I made an hour or so ago but didn't post because I was still working through your examples.
The other thing is that although your code seems to work pretty well with short time spans minutes := 1/30, there seems to be a flaw in the methodology that shows up when times such as the 3 mins are used. (the changing divisor)
p.s no I don't mean what you think I mean, I mean it (the time interval) doesn't change linearly like you would expect it to. It can jump around if you feed it a few random clicks here and there, that puts big gaps in the time stamps. (which causes the divisor to jump around wildly)
Funny enough though, it still gives me data to plot so another win lol
Oh yeah, it's really nice to see that I'm not the only one who has off days every now and then
Code: Select all
For time, cps in record
If (A_Index > record.Count() - 10)
GuiControl,, % "p" ++n, %cps%
Re: Mapping Actions over Time
Well,... it does exactly what I programmed it to do. What it does: "use a hotkey LButton to record something like A_Sec and get that into an array. Then once every 1-10 seconds (SetTimer) I use the new data and a bit of the old to populate an array of cps over the last 1-3 mins. Once I have the data I can create the graphics to display / update in a graph."
There are lots of ways to skin the cat, so feel free to adjust to meet your needs. As noted, you can change the minutes variable to get computations over different intervals. You are correct that in this script, the denominator may vary according to the clicking times, but the cps are still the output. You can change that, if needed, simply by using a fixed denominator instead of a computed denominator.
In my script, the denominator, dif, is computed on line 33, and then used on lines 34 and 35. Instead of seconds since the first actual click time, you could a fixed interval of your choosing. A variation is to use the computed denominator until the elapsed time exceeds the "minutes", and then use a fixed denominator.
Of course, one can also modify the script so that it generates any additional actions upon each click of the button.
There are lots of ways to skin the cat, so feel free to adjust to meet your needs. As noted, you can change the minutes variable to get computations over different intervals. You are correct that in this script, the denominator may vary according to the clicking times, but the cps are still the output. You can change that, if needed, simply by using a fixed denominator instead of a computed denominator.
In my script, the denominator, dif, is computed on line 33, and then used on lines 34 and 35. Instead of seconds since the first actual click time, you could a fixed interval of your choosing. A variation is to use the computed denominator until the elapsed time exceeds the "minutes", and then use a fixed denominator.
Of course, one can also modify the script so that it generates any additional actions upon each click of the button.
Re: Mapping Actions over Time
I had actually had put some thought into the path started in my second post. There is just one or two things that I am having a bit of trouble working out in my head.
Code: Select all
#If ( Active )
~*LButton::
if( CurrentMin != A_Min ){
CurrentMin := A_Min
Clicks[ CurrentMin ] := []
}
Clicks[ CurrentMin ].Push( A_Sec )
return
#If
Code: Select all
ClickDisplay := {}
loop, 180
ClickDisplay[ A_Index ] := 0
Code: Select all
Loop, % Click[ TheCorrectMin ].Length()
ClickDisplay[ Click[ TheCorrectMin ][ A_Index ] ]++ ;1: 3 , 2: 0 , 3: 11 , 4: 9001 , 5: 3 ;;;; 61: 0 , 62: 1 ... ;;; 121: 7, 122: 2 ... 180: 5
This is where I have my first hurdle, I can't simply look at min 01 and then simply subtract 2 to get the two other min arrays needed to populate the graph. I think I may be able to figure out how to use that sysget? to get the right ones.
On second thought, I don't think this is a real issue, i'll just start with the second second. I also realized it is 3 or 4 arrays that are required to fill out a 180 second display.
The last thing I think is another time manipulation problem, and that is knowing when a Click[ A_Min ] can get disposed of.
And once again I may be able to solve with that sysget bit.
Re: Mapping Actions over Time
OK. You are using one-second "bins" to count the clicks in each bin. This idea is captured below.
This may need some adjustment to handle what happens when the bin number is advanced.
Code: Select all
clik := []
nBins := 10 ; Use this number of bins to record click counts
Gosub, Advance
SetTimer, Advance, 1000
~*LButton::
clik[bin]++
Gosub, Update
Return
Advance: ; Advance to the next bin
SoundBeep, 1700
clik[++bin := Mod(0 bin, nBins)] := 0
Update:
ToolTip, % cps(clik) " cps`nBin: " bin " has clicks = " clik[bin]
Return
cps(clik) {
count := 0
For each, bin in clik
count += bin
Return Round(count / clik.Count())
}
Re: Mapping Actions over Time
I understand how it could be interpreted differently. I think my last post also fits the description pretty well too.mikeyww wrote: ↑24 Sep 2021, 05:03Well,... it does exactly what I programmed it to do. What it does: "use a hotkey LButton to record something like A_Sec and get that into an array. Then once every 1-10 seconds (SetTimer) I use the new data and a bit of the old to populate an array of cps over the last 1-3 mins. Once I have the data I can create the graphics to display / update in a graph."
That would likely be the best bet in this case. Although it would always give a correct cps with the way it is now, the sudden change in time frames makes the data spike in unexpected ways. You could be clicking at a steady 10 cps and then hit a few of the gaps in a row and it would look like you started clicking like crazy. (haven't tested but I think that would be the outcome?)You can change that, if needed, simply by using a fixed denominator instead of a computed denominator.
lmao thanks for the denominator.. I had even looked up what I should call it...
That was my thought too. I think that 3 mins is probably not sensitive enough to changes so a shorter cycle would be better,In my script, the denominator, dif, is computed on line 33, and then used on lines 34 and 35. Instead of seconds since the first actual click time, you could a fixed interval of your choosing. A variation is to use the computed denominator until the elapsed time exceeds the "minutes", and then use a fixed denominator.
Re: Mapping Actions over Time
Either approach can work, depending on what you want to show. My last post is more of a mirror to your original method. It provides a running average of the bin counts. The main issue that I saw is that as soon as the bin is advanced and reset, the new zero contributes to the average. I think you'd want a zero to contribute to the average only if the empty bin is not the current bin, or something like that. You can always change that if needed.
As far as I know, "denominator" and "divisor" refer to the same thing. I think of the former in more of an applied setting.
As far as I know, "denominator" and "divisor" refer to the same thing. I think of the former in more of an applied setting.
Re: Mapping Actions over Time
Thank you @mikeyww I'll have good look at after some rest.
One thing that I did notice that may be a issue (if I'm seeing it right).
It looks like every click causes every click stored over the display period (up to 180 seconds) to be looped over. So if you had an average of 20cps it would be doing 3k+ loops 20 times every second. The script can likely keep up no problem, but that seems like an awful lot of calculations to do this task, my whole idea of using the mouse to simply push onto an array and then at reasonable intervals do the work of looping and sorting etc. was to keep the load down. Like I said though I haven't worked my way through the code yet, so I could be wrong about what I said.
Thanks again.
One thing that I did notice that may be a issue (if I'm seeing it right).
It looks like every click causes every click stored over the display period (up to 180 seconds) to be looped over. So if you had an average of 20cps it would be doing 3k+ loops 20 times every second. The script can likely keep up no problem, but that seems like an awful lot of calculations to do this task, my whole idea of using the mouse to simply push onto an array and then at reasonable intervals do the work of looping and sorting etc. was to keep the load down. Like I said though I haven't worked my way through the code yet, so I could be wrong about what I said.
Thanks again.
Re: Mapping Actions over Time
In my last script, the number of bins never exceeds 10. If you run the script, you will see it in the tooltip. You could change the number to 180 if needed. With a slow loop frequency of 1 second, AHK can easily add 180 numbers in each iteration. Each click adds one to the current bin. I was never able to exceed about 10 cps with manual button clicks on my mouse, but you might have better luck, and even if you could press your button 100 times in one second, I don't think it would have any noticeable impact on the script's performance.
Last edited by mikeyww on 24 Sep 2021, 07:20, edited 1 time in total.
Re: Mapping Actions over Time
Perhaps I'm over thinking my need for so many bins, I could likely just... well I have an idea to go off of so I'll test in a few hours.
Re: Mapping Actions over Time
Code: Select all
clik := [] ; This script computes mean cps, using 1-second intervals
nBins := 180 ; Use this number of bins to record click counts
Gosub, Advance ; Set up the first bin
SetTimer, Advance, 1000 ; Each bin represents 1 second of click activity
~*LButton:: ; Each click adds one to the current bin
clik[bin]++ ; The bin's value contains a cps
Gosub, Update ; Show a tooltip
Return
Advance:
SoundBeep, 1800
clik[++bin := Mod(0 bin, nBins)] := 0 ; Advance to the next bin, and reset it
Update:
ToolTip, % cps(clik, bin) " cps`nBin: " bin " has clicks = " clik[bin]
Return
cps(clik, currentBin) { ; Compute the cps across bins
bins := sum := 0
For binNum, cps in clik ; Loop through each bin
If (cps || binNum != currentBin) ; Skip current bin if it has no clicks yet
sum += cps, bins++ ; Compute a sum of cps across bins
Return Round(sum / bins) ; Divide sum by the number of bins; return the mean cps
}
Re: Mapping Actions over Time
Hi @mikeyww.
I have had a chance to play around with your latest code and have it up and functioning in a default gui.
. .
Your bin system works a bit different than mine did, your bins are time increments filled with the click counts, and mine were positions along the x axis and they contained the value to display at that time.
Your bin system is also the starting place for the data and mine was the end point in the process.
Because of that I was still left with the same problem of getting my active data to the display controls, but with your bin system I didn't need to worry about tracking time so connecting the raw data to the display controls was easy.
Since I was going with your bin system I decided to reassess what I needed from it, and as It turns out I don't need 180 bins, I only need 1. In fact, as I'm writing this I can see that it likely doesn't need a bin at all. The bin would only really be needed if I was tracking clicks in time and not in increments of time.
That last thing brings up a good point though, and it is that if this is to be done right it probably should ultimately use time so that it can update at any rate and use different time spans like clicks per min and clicks per hour. However, time might not be needed to for some of that (I still have a bit of optimizing to do to the code so I'll find out at that point if they work or not without a time element ).
I have had a chance to play around with your latest code and have it up and functioning in a default gui.
. .
Your bin system works a bit different than mine did, your bins are time increments filled with the click counts, and mine were positions along the x axis and they contained the value to display at that time.
Your bin system is also the starting place for the data and mine was the end point in the process.
Because of that I was still left with the same problem of getting my active data to the display controls, but with your bin system I didn't need to worry about tracking time so connecting the raw data to the display controls was easy.
Since I was going with your bin system I decided to reassess what I needed from it, and as It turns out I don't need 180 bins, I only need 1. In fact, as I'm writing this I can see that it likely doesn't need a bin at all. The bin would only really be needed if I was tracking clicks in time and not in increments of time.
That last thing brings up a good point though, and it is that if this is to be done right it probably should ultimately use time so that it can update at any rate and use different time spans like clicks per min and clicks per hour. However, time might not be needed to for some of that (I still have a bit of optimizing to do to the code so I'll find out at that point if they work or not without a time element ).
Code: Select all
#SingleInstance, Force
SetBatchlines, -1
gosub, AddGui ; Create the display gui
clik := [] ; This script computes mean cps, using 1-second intervals
nBins := 1 ; Use this number of bins to record click counts
Gosub, Advance ; Set up the first bin
SetTimer, Advance, 1000 ; Each bin represents 1 second of click activity
SetTimer, DrawGui, 1000 ; Each bin represents 1 second of click activity
return
GuiClose:
GuiContextMenu:
*ESC::ExitApp
~$*LButton:: ; Each click adds one to the current bin
clik[bin]++ ; The bin's value contains a cps
Gosub, Update ; Show a tooltip
Return
Advance:
Display.Insert( 1, clik[ bin ] ) ;Insert the current bin to the begining of the display array
Display.Pop() ;Remove the last item from the display array
clik[++bin := Mod(0 bin, nBins)] := 0 ; Advance to the next bin, and reset it
Update:
cps(clik, bin)
Return
DrawGui:
Loop, % Bars.Length(){ ;loop over every data point being graphed
if( Bars[ A_Index ].Value != Display[ A_Index ] ){ ;Check to see if the value for this bar has changed
Bars[ A_Index ].Value := Display[ A_Index ] ;Update the value for the test next time
GuiControl, % "1:MoveDraw", % Bars[ A_Index ].Hwnd , % "y" YFloor - ( ( mag * Bars[ A_Index ].Value ) ) " h" mag * Bars[ A_Index ].Value ;Resize the progress control to it's new height
}
GuiControl, 1:, % texthwnd, % "CPS: " Display[1] ;Update the windows text (CPS:)
}
return
cps(clik, currentBin) { ; Compute the cps across bins
bins := sum := 0
For binNum, cps in clik ; Loop through each bin
If (cps || binNum != currentBin) ; Skip current bin if it has no clicks yet
sum += cps, bins++ ; Compute a sum of cps across bins
Return Round(sum / bins) ; Divide sum by the number of bins; return the mean cps
}
AddGui:
Gui, 1:New, +AlwaysOnTop -DPIScale +E0x02000000 +E0x00080000
Gui, 1:Color, 22262a
Display := [] ; Array used to cycle the data forward.
YFloor := 200 ; The bottom position ( Y ) for the bars
Bars := [] ; Array of objects used to hold the bars control data ( hwnd, value )
x := "m" ; Sets the first control to start at the x-margin
mag := 20 ; The height in pixels to draw each increament in value ( 1 cps ? draw the bar mag * 1 pixels tall )
Loop, 180 { ;Loop once for every data point to display
Display[A_Index] := 0 ; Preload the display array with its starting values
Gui, 1:Add, Progress, % "x" x " y" YFloor - ( mag * Display[ A_Index ] ) " w" 3 " h" mag * Display[ A_Index ] " hwndhwnd BackgroundTeal"
x := "+2" ;after the first control is added change the positions for every other control to have a 2px gap between them
Bars[ A_Index ] := { Hwnd: hwnd, Value: Display[ A_Index ] } ;Assign the controls object (Progress bar) its values
}
Gui, 1:Font, cTeal s26 ,sitka small
Gui, 1:Add, Text, xm ym w300 h100 BackgroundTrans Center 0x200 hwndtexthwnd, CPS: 0
Gui, 1:Show,,Demo
return
Random( min := 1 , max := 10 ){ ; RNG
local Out
Random, out, min, max
return out
}
Who is online
Users browsing this forum: No registered users and 226 guests