It is currently August 10th, 2020, 3:12 pm

Quantization value for histograms

Report bugs with the Rainmeter application and suggest features.
User avatar
Yincognito
Posts: 2223
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Quantization value for histograms

Post by Yincognito »

balala wrote:
July 6th, 2020, 2:06 pm
I'm curious and wait for it.
Final version of the code. I merged [MeasureInitialHistogramPath] and [MeasureHistogramPath] into one measure, and tricked Rainmeter to not consume resources with the substitutions while the initial string was automatically (and recursively) built by setting the initial RegExpSubstitute to 0. After the initial string is built, the normal substitutions take place, triggered from the "histogrammed" measure ([MeasureCPU] in this case), and because an UpdateDivider of -1 is set on [MeasureHistogramPath], a duplicate update of it is avoided (not that it would affect the result, but just to be efficient with resources).

The code:

Code: Select all

[Variables]
Values=100
Padding=5
W=3
H=100
HistogramColor=255,255,255,255
HistogramBGCol=0,0,0,100
PathSegment="LineTo (#W#*([MeasureLastValueIndex]-1-(0+0))),(#H#-(0/100)*#H#) | LineTo (#W#*([MeasureLastValueIndex]-(0+0))),(#H#-(0/100)*#H#) | "

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1

---Histogram Path Measures---

[MeasureFirstValueIndex]
Measure=Calc
Formula=(MeasureFirstValueIndex+1)

[MeasureLastValueIndex]
Group=InitialGroup
Measure=Calc
Formula=(MeasureLastValueIndex+1)

[MeasureHistogramPath]
Group=InitialGroup
Measure=String
String=
UpdateDivider=-1
RegExpSubstitute=0
Substitute="(?siU)^(?:LineTo .* \| LineTo .* \| ){1}((?:LineTo .* \| LineTo .* \| ){#Values#})$":"\1","-\(\d+\+":"-([MeasureFirstValueIndex]+"
IfCondition=(MeasureLastValueIndex<=#Values#)
IfTrueAction=[!SetOption #CURRENTSECTION# String "[#CURRENTSECTION#]#PathSegment#"][!UpdateMeasureGroup InitialGroup]
IfFalseAction=[!SetOption #CURRENTSECTION# RegExpSubstitute 1]
IfConditionMode=1
DynamicVariables=1

---Actual Histogram Measures---

[MeasureCPU]
Measure=CPU
OnUpdateAction=[!SetOption MeasureHistogramPath String "[MeasureHistogramPath]LineTo (#W#*([MeasureLastValueIndex]-(0+1))),(#H#-([#CURRENTSECTION#]/100)*#H#) | LineTo (#W#*([MeasureLastValueIndex]+1-(0+1))),(#H#-([#CURRENTSECTION#]/100)*#H#) | "][!UpdateMeasure MeasureHistogramPath]
DynamicVariables=1

---Meters---

[MeterCPUBackgroundImage]
Meter=Image
SolidColor=24,102,10
X=0
Y=0
W=(#Values#+#W#*#Values#+#Padding#*3)
H=(#H#+#Padding#*2)

[MeterCPUHistogram]
Meter=Histogram
MeasureName=MeasureCPU
X=#Padding#
Y=#Padding#
W=#Values#
H=#H#
PrimaryColor=#HistogramColor#
SolidColor=#HistogramBGCol#
AntiAlias=1

[MeterImageGap]
Meter=Image
X=0R
Y=0r
W=#Padding#
H=#H#
SolidColor=0,0,0,0
AntiAlias=1

[MeterCPUShapeHistogram]
Meter=Shape
X=0R
Y=0r
Shape=Rectangle 0,0,(#W#*#Values#),#H# | StrokeWidth 0 | Stroke Color #HistogramBGCol# | Fill Color #HistogramBGCol#
Shape2=Path HistogramPath | StrokeWidth 0 | Stroke Color #HistogramColor# | Fill Color #HistogramColor#
HistogramPath=0,#H# | [MeasureHistogramPath]LineTo (#W#*#Values#),#H# | SetNoStroke 1 | ClosePath 1
DynamicVariables=1

[MeterCPUText]
Meter=String
MeasureName=MeasureCPU
X=((#Values#+#W#*#Values#+#Padding#*3)/2)
Y=(#Padding#*2)R
FontSize=8
FontColor=255,255,255,255
StringAlign=Center
AntiAlias=1
Text=%1%
So, only 3 additional measures and 1 meter to achieve what the OP wanted. Sure, it's not as easy as a common option added to the Histogram meter itself, but still easy enough for anyone to be able to do it with minimal effort. ;-)
User avatar
balala
Rainmeter Sage
Posts: 11191
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Quantization value for histograms

Post by balala »

Yincognito wrote:
July 6th, 2020, 7:43 pm
So far, my mission is complete, as the code works, no additional measures or meters are needed, every parameter of the Path histogram simulation is adjustable (and only for convenience linked to the equivalent parameter in the actual histogram, so one can notice the similarity). The commented lines write the Path strings to a Test.inc file in the skin's folder - I used those to verify if the results were appropriate.
Interesting code, will have to study it a little bit.
User avatar
Yincognito
Posts: 2223
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Quantization value for histograms

Post by Yincognito »

balala wrote:
July 7th, 2020, 12:26 pm
Interesting code, will have to study it a little bit.
Go for the code where [MeasureInitialHistogramPath] and [MeasureHistogramPath] are separated, as it's easier to understand due to the separation.

All in all, the principle is not complicated at all:
- in the "initial phase", I automatically and recursively (i.e. by self-updating [MeasureInitialHistogramPath], along with the index of the currently last value point in the histogram) add "path segments" to the initially empty (i.e. "") measure value, in order to build the full path string (which will in effect be just a number of 0 value points, really)
- in the "operating phase", I remove the first (i.e. the leftmost) path segment string from the beginning of the full path string and add the last (i.e. the rightmost) path segment string at the end of the full path string, in effect creating the "timeline motion" of the path histogram simulation from right to left

While the format of a path segment string is a bit complicated by the "(0+...)"-like parts (which I had to use in order for the substitutions to work in both the initial phase and the operating phase), its base format and idea is not at all complicated, it's just a LineTo followed by a LineTo, basically constructing a (or , if value decreases) segment in the histogram. This would look like a:

                                          ┏
                       ┏
      ┏
 Segment 1   Segment 2   Segment 3

structure, which translates to a

Code: Select all

"LineTo (#W#*(<lastindex>-<firstindex>)),(#H#-([MeasureCPU]/100)*#H#) | LineTo (#W#*(<lastindex>+1-<firstindex>)),(#H#-([MeasureCPU]/100)*#H#) | "
segment string, where, of course, the path segments "touch" each other, and W = the width of a value point visually, H = the height of the path histogram, <firstindex> = the index of the visually leftmost value point and <lastindex> = the index of the currently last value point (or the currently drawn value point, if you like). Then, in the Shape2 from the [MeterCPUShapeHistogram], I add the origin point (i.e. 0,#H#) and the end LineTo (i.e. LineTo (#W#*#Values#),#H#) of the path and close the shape so it can be filled.

In other words, I subtract ([MeasureCPU]/100)*#H# from #H# to set the LineTo's "Y", and subtract <firstindex> from <lastindex> (the difference multiplied by #W#, of course) to set the LineTo's "X". So, if a histogram has 20 visible value points in its "viewport" and its first 6 value points off the viewport to the left, it means <firstindex> is 7 (since it's the first visible or the leftmost value point in the "viewport") and <lastindex> would iterate from value point indexes 7 to 27 (i.e. 7+20). Because of the subtraction used to set the LineTo's "X" and <lastindex> iteration according to the currently drawn segment, in reality the first "X" would be <lastindexiteration1>-<firstindex>=7-7=0, the second "X" would be <lastindexiteration2>-<firstindex>=8-7=1 and so on. The regex substitutions just make sure the default "-(0+...)" (or whatever past number may be there instead of 0) is "updated" to "-(<firstindex>+...)", so that the current <firstindex> is always subtracted from whatever <lastindex> is there, in a dynamic way.

That's pretty much it, if you really wanted to "study" and understand what's going on. Not a big deal, but obviously it becomes a bit more difficult to understand if one isn't the "author" writing the code - I've been there as well, so I get it.
User avatar
eclectic-tech
Rainmeter Sage
Posts: 4072
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Quantization value for histograms

Post by eclectic-tech »

Very nice work using the Shape meter Yincognito! :thumbup:

As an alternate demonstration, using TransformationMatrix is also pretty straightforward and (in my opinion) a simpler process.

To expand the histogram, increase the first matrix value by the amount of scaling, reduce the histogram width by same factor, and adjust the second-last matrix value by the negative 'space' to place the transformation at the same starting point.

Code showing normal histogram, and stretched 2x, 3x, 4x, and 5x below.

Code: Select all

[Rainmeter]

[Variables]
GraphWidth=200

[MeasureCPU]
Measure=Cpu

[MeterBG]
Meter=Shape
Shape=Rectangle 0,0,210,280 | StrokeWidth 0 | Fill Color 60,220,40,100 

; Normal Width
[MeterHistogram1]
Meter=Histogram
X=5
Y=5
W=(#GraphWidth#/1)
H=50
MeasureName=MeasureCPU
TransformationMatrix=1; 0; 0; 1; 0; 0
PrimaryColor=255,255,255
SolidColor=0,0,0,100

; 2 Times normal width
[MeterHistogram2]
Meter=Histogram
X=r
Y=5R
W=(#GraphWidth#/2)
H=50
MeasureName=MeasureCPU
TransformationMatrix=2; 0; 0; 1; -5; 0
PrimaryColor=255,255,255
SolidColor=0,0,0,100

; 3 Times normal width
[MeterHistogram3]
Meter=Histogram
X=r
Y=5R
W=(#GraphWidth#/3)
H=50
MeasureName=MeasureCPU
TransformationMatrix=3; 0; 0; 1; -10; 0
PrimaryColor=255,255,255
SolidColor=0,0,0,100

; 4 Times normal width
[MeterHistogram4]
Meter=Histogram
X=r
Y=5R
W=(#GraphWidth#/4)
H=50
MeasureName=MeasureCPU
TransformationMatrix=4; 0; 0; 1; -15; 0
PrimaryColor=255,255,255
SolidColor=0,0,0,100

; 5 Times normal width
[MeterHistogram5]
Meter=Histogram
X=r
Y=5R
W=(#GraphWidth#/5)
H=50
MeasureName=MeasureCPU
TransformationMatrix=5; 0; 0; 1; -20; 0
PrimaryColor=255,255,255
SolidColor=0,0,0,100

You do not have the required permissions to view the files attached to this post.
User avatar
Yincognito
Posts: 2223
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Quantization value for histograms

Post by Yincognito »

eclectic-tech wrote:
July 7th, 2020, 3:24 pm
Very nice work using the Shape meter Yincognito! :thumbup:

As an alternate demonstration, using TransformationMatrix is also pretty straightforward and (in my opinion) a simpler process.
Yes, those are probably the right parameters for the TransformationMatrix indeed - didn't want to abuse balala to write a working code for something that the OP probably lost interest in the meantime, so I went for alternative methods (the bar meter one, the path one) to show that it can be done in various ways, with the path one the most "user friendly" of my approaches.

The TransformationMatrix method is indeed the simplest of them all, and while I can't speak for balala, I have to admit I didn't thought of "cropping" the histogram by dividing the meter width itself accordingly, while still applying the matrix to the meter (i.e. the equivalent of decreasing the Values variable in my Path approach), so I was living under the impression that widening the visible part of the histogram would be unavoidable. Well done! :thumbup:

Regarding my work using the Path variant of the Shape meter, you're actually the one I have to thank for that, since a while ago you helped me with my idea of designing a custom bevel width using path Shapes and opened my eyes on the possibilities... :rosegift:
Last edited by Yincognito on July 7th, 2020, 4:04 pm, edited 1 time in total.
User avatar
balala
Rainmeter Sage
Posts: 11191
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Quantization value for histograms

Post by balala »

eclectic-tech wrote:
July 7th, 2020, 3:24 pm
As an alternate demonstration, using TransformationMatrix is also pretty straightforward and (in my opinion) a simpler process.
Yes, definitely much simpler solution then any other using Shape or Bar meters. I say again: even if not simple, the TransformationMatrix is an extremely powerful option (additionally I love it).
User avatar
Yincognito
Posts: 2223
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Quantization value for histograms

Post by Yincognito »

balala wrote:
July 7th, 2020, 4:02 pm
Yes, definitely much simpler solution then any other using Shape or Bar meters. I say again: even if not simple, the TransformationMatrix is an extremely powerful option (additionally I love it).
I love it as well. JsMorley doesn't though, for some unknown reason... :lol:
User avatar
balala
Rainmeter Sage
Posts: 11191
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Quantization value for histograms

Post by balala »

Yincognito wrote:
July 7th, 2020, 4:01 pm
didn't want to abuse balala to write a working code for something that the OP probably lost interest in the meantime,
Yes, my bad, I promised I'm gonna take a look to fix the errors of my last such code (using the TransformationMatrix), but in meantime I started dealing with something else and finally forgot. Sorry...
Now eclectic-tech did what I should have to.
User avatar
Yincognito
Posts: 2223
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Quantization value for histograms

Post by Yincognito »

balala wrote:
July 7th, 2020, 4:06 pm
Yes, my bad, I promised I'm gonna take a look to fix the errors of my last such code (using the TransformationMatrix), but in meantime I started dealing with something else and finally forgot. Sorry...
Now eclectic-tech did what I should have to.
Don't worry, it's ok - as I said, you didn't need to convince me, I was already in agreement with you on it. ;-) Anyway, it's very nice to have so many options / implementations to choose from, it just shows that for everything there are at least two possibilities of achieving it.
User avatar
jsmorley
Developer
Posts: 21236
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Quantization value for histograms

Post by jsmorley »

Yincognito wrote:
July 7th, 2020, 4:06 pm
I love it as well. JsMorley doesn't though, for some unknown reason... :lol:
Aside from the relative complexity, which is really neither here nor there, my biggest concern with TransformationMatrix is that it is very hard to get it right with any mouse actions, since the transformation of the objects in the meter don't change the meter itself, which mouse actions are dependent on (aside from the Shape meter that is).