Mapping Actions over Time

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Mapping Actions over Time

Post by Hellbent » 23 Sep 2021, 19:13

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?

User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Mapping Actions over Time

Post by Hellbent » 23 Sep 2021, 19:29

This is what I have been able to come up with so far.

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
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.

User avatar
mikeyww
Posts: 26602
Joined: 09 Sep 2014, 18:38

Re: Mapping Actions over Time

Post by mikeyww » 23 Sep 2021, 20:31

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
}

User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Mapping Actions over Time

Post by Hellbent » 23 Sep 2021, 21:14

@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

Code: Select all

clik := purge(clik, minutes)
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?
Last edited by Hellbent on 23 Sep 2021, 21:24, edited 1 time in total.

User avatar
mikeyww
Posts: 26602
Joined: 09 Sep 2014, 18:38

Re: Mapping Actions over Time

Post by mikeyww » 23 Sep 2021, 21:16

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.

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
}
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 +=.
Last edited by mikeyww on 23 Sep 2021, 21:45, edited 1 time in total.

User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Mapping Actions over Time

Post by Hellbent » 23 Sep 2021, 21:40

***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?
That is a last min update to my last post.

mikeyww wrote:
23 Sep 2021, 21:16
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.
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.
mikeyww wrote:
23 Sep 2021, 21:16
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 +=.
Thanks :thumbup: 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 ,

User avatar
mikeyww
Posts: 26602
Joined: 09 Sep 2014, 18:38

Re: Mapping Actions over Time

Post by mikeyww » 23 Sep 2021, 21:48

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
}
Alternative subroutine:

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

User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Mapping Actions over Time

Post by Hellbent » 23 Sep 2021, 23:25

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.

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
}
And thank you for your help so far.

User avatar
mikeyww
Posts: 26602
Joined: 09 Sep 2014, 18:38

Re: Mapping Actions over Time

Post by mikeyww » 23 Sep 2021, 23:29

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.

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)
}

User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Mapping Actions over Time

Post by Hellbent » 24 Sep 2021, 01:53

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.
20210924010014.png
20210924010014.png (12.1 KiB) Viewed 915 times
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%
And thank you so much for your help so far.

User avatar
mikeyww
Posts: 26602
Joined: 09 Sep 2014, 18:38

Re: Mapping Actions over Time

Post by mikeyww » 24 Sep 2021, 05:03

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.

User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Mapping Actions over Time

Post by Hellbent » 24 Sep 2021, 05:41

mikeyww wrote:
24 Sep 2021, 05:03
Well,... it does exactly what I programmed it to do. :)
:D


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
With that I can take an associative array that is prepopulated with the keys 1-180

Code: Select all

ClickDisplay := {}
loop, 180	
	ClickDisplay[ A_Index ] := 0
and then use the correct Click[ A_Min ] to increment the values ( offset by the minute position * 60 )

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

I can keep track of my starting time array with the var CurrentMin

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.

Another issue is one that I would find out in testing, but if it doesn't work the way I need it to, I may have to go back a few steps to work out another approach. The issue is whether or not I want to start with the current second, or start with the last second to be "completed".
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.

User avatar
mikeyww
Posts: 26602
Joined: 09 Sep 2014, 18:38

Re: Mapping Actions over Time

Post by mikeyww » 24 Sep 2021, 06:05

OK. You are using one-second "bins" to count the clicks in each bin. This idea is captured below.

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())
}
This may need some adjustment to handle what happens when the bin number is advanced.

User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Mapping Actions over Time

Post by Hellbent » 24 Sep 2021, 06:20

mikeyww wrote:
24 Sep 2021, 05:03
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."
I understand how it could be interpreted differently. I think my last post also fits the description pretty well too.

You can change that, if needed, simply by using a fixed denominator instead of a computed denominator.
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?)

lmao thanks for the denominator.. I had even looked up what I should call it...
20210924065644.png
20210924065644.png (23.02 KiB) Viewed 850 times
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.
That was my thought too. I think that 3 mins is probably not sensitive enough to changes so a shorter cycle would be better, but then unless the display was also made shorter, the display would have strange waves in it of equal size but different intensity . I picture something like this, but on it's side } that's wrong. It would give a nice curve.

User avatar
mikeyww
Posts: 26602
Joined: 09 Sep 2014, 18:38

Re: Mapping Actions over Time

Post by mikeyww » 24 Sep 2021, 06:26

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.

User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Mapping Actions over Time

Post by Hellbent » 24 Sep 2021, 06:52

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.

User avatar
mikeyww
Posts: 26602
Joined: 09 Sep 2014, 18:38

Re: Mapping Actions over Time

Post by mikeyww » 24 Sep 2021, 07:15

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.

User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Mapping Actions over Time

Post by Hellbent » 24 Sep 2021, 07:19

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.

User avatar
mikeyww
Posts: 26602
Joined: 09 Sep 2014, 18:38

Re: Mapping Actions over Time

Post by mikeyww » 24 Sep 2021, 08:01

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
}

User avatar
Hellbent
Posts: 2103
Joined: 23 Sep 2017, 13:34

Re: Mapping Actions over Time

Post by Hellbent » 24 Sep 2021, 17:12

Hi @mikeyww.

I have had a chance to play around with your latest code and have it up and functioning in a default gui.

.
Temp (1).gif
Temp (1).gif (66.07 KiB) Viewed 743 times
.

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
}

Post Reply

Return to “Ask for Help (v1)”