It is currently April 25th, 2024, 4:58 pm

Feature Request - autoscale max variable for histogram/line

Report bugs with the Rainmeter application and suggest features.
TGonZo
Posts: 68
Joined: April 25th, 2015, 8:19 pm
Location: Virginia

Feature Request - autoscale max variable for histogram/line

Post by TGonZo »

I know I have asked for this on another post, but I am writing it here in the official Feature Suggestions section.

I think the Histogram meter and the Line meter would be more useful if they contained a variable that was readable containing the current max for that display when they are in autoscale mode.

With this variable, we could create another String Meter and display that current max value, and see it change as the autoscale changes.

Not sure if a new measure or a new variable would be the best way to implement this. Which ever way works is fine by me.

I think this feature would make the Histogram and Line meters much more effective when in autoscale mode. The data being display would have context as to their relative values.

What do you think? What happens from here? Will you post whether you accept or reject the Feature Request? Just wondering.

Thanks all.
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Feature Request - autoscale max variable for histogram/l

Post by jsmorley »

We really don't take requests and either approve or reject them. We certainly do welcome and take requests, and every one is given some thought, but what ends up being in or out of any future effort is not based on anything terribly organized.

Things just don't get put into a request queue, evaluated, accepted or rejected, given a priority and put on a development schedule. It's not even remotely that organized.

At least informally, we tend to attack things that seem to be causing pain to the most users, or additional functionality that we think really makes Rainmeter a better tool. These are just judgement calls made by the guys who do the coding, and is as much based on what interests them, and how much free time they have, as it is on anything else.

So having said that, your suggestion has been heard. I personally don't think it is a bad idea at all, perhaps with some new section variable that would more or less be [MeterName:MaxVisibleInMeter] or some such. There are issues with timing with this that are a bit scary, as you are asking to know and use a value during the same update cycle that the value is created. That might not be easy, or even possible.

But I have made sure the team has seen this post, and I'm sure that some thought will be given to it.
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Feature Request - autoscale max variable for histogram/l

Post by jsmorley »

To be clear:

Proper modern development process:

1) Receive bug report or change request
2) Put request in an initial queue based on when received
3) Project managers and coders evaluate request
4) Project managers determine desirability, feasibility, risk, cost/benefit of change
5) Project managers assign a relative priority based on that analysis
6) Project managers place request in a development schedule based on the priority
7) Coders make changes, other coders do "peer review"
8) Changed code passed to QA team for iterative functional and regression testing / fixes until QA signs off
9) Documentation team makes changes to beta documentation.
10) Final signed-off QA version used to create a beta version of the software with all changes made in that beta cycle

Rainmeter development process:

Guy 1: "Hey it would be cool if it did this... Some guy on the forum made a good point."
Guy 2: "Yeah, that wold be cool. Lemmie look at that."
Guy 2: "Here's a patch."
Guy 1: "Works great! Nice, people are going to love this. I'll do a beta."

Just slightly less organized, but a lot more fun, and really the only way it can work on a project as informal as Rainmeter, done in whatever spare time guys with serious drug and gambling addictions have.

So if you are looking for a "Change ID" that you can track in our online system and get text notifications of schedule, issues and progress, then... Well, uhm...

The best we can do, and we try hard, is to never "over-promise and under-deliver".
TGonZo
Posts: 68
Joined: April 25th, 2015, 8:19 pm
Location: Virginia

Re: Feature Request - autoscale max variable for histogram/l

Post by TGonZo »

haha, Thanks for the explanation. Just a, looks good, we'll see what we can do. That's all I really expected. The extra detail is good to know though. If I sounded more official, I guess a smiley would have been appropriate. :) Thanks again.
User avatar
SilverAzide
Rainmeter Sage
Posts: 2605
Joined: March 23rd, 2015, 5:26 pm

Re: Feature Request - autoscale max variable for histogram/l

Post by SilverAzide »

I think this is doable now with addition of a variable (to hold your max value). Just add an IfCondition to the measure that is bound to your Line/Histogram. For example, if you are tracking the maximum NetIn value:

[MeasureNetIn]
Measure=NetIn
Interface=0
IfConditionMode=1
IfCondition=MeasureNetIn > #MaxValue#
IfTrueAction=[!SetVariable MaxValue ([MeasureNetIn])]
DynamicVariables=1
Gadgets Wiki GitHub More Gadgets...
User avatar
jsmorley
Developer
Posts: 22629
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Feature Request - autoscale max variable for histogram/l

Post by jsmorley »

SilverAzide wrote:I think this is doable now with addition of a variable (to hold your max value). Just add an IfCondition to the measure that is bound to your Line/Histogram. For example, if you are tracking the maximum NetIn value:

[MeasureNetIn]
Measure=NetIn
Interface=0
IfConditionMode=1
IfCondition=MeasureNetIn > #MaxValue#
IfTrueAction=[!SetVariable MaxValue ([MeasureNetIn])]
DynamicVariables=1
Yes, but not really his point though. It's a bit subtle, but what he wants is to know is what value the meter is using as a "maximum" when it scales the meter with AutoScale. For meters like Line or Histogram, that is a moving target. In a sense the maximum used for scaling is the maximum value that is currently showing in the meter. That is difficult to get manually, as you would have to "keep track of" the last XX values the bound measure has, and the only way to know what XX should be is some calculation based on the width of the meter and the rate that the meter is being updated at. That would be very tricky to know even manually, and probably impossible in any generic way. It gets exponentially more complicated with LineWidth on a Line meter or when using images with a Histogram.

I presume the goal is to create a "grid" in front of a Line or Histogram meter, and have string "labels" on the Y coordinate of the grid showing the "scale" being used. That scale will change as the meter is AutoScaled, and so the labels (and maybe the lines creating the grid) would need to react. Not really possible today.

His, and my, point is that while "he" can't know how to get that in any reasonable way, Rainmeter must internally know it, as that is how it scales the meter. The question is whether we can expose that value in any useful way. Not entirely sure yet. Just getting the value into something like [MeterName:MaxScale] is probably not out of the question. The bigger issues have to do with timing, so you are not "one update behind" with it. That might take some serious changes to the Line and Histogram meters, and might have some limitations (or at least complexities) with how you use it that we initially fear a bit.

I personally think it would make both Line and Histogram meters more useful, but we always have to weigh how valuable a change really is to the broader Rainmeter community against the work required and backwards compatibility risks involved.
User avatar
SilverAzide
Rainmeter Sage
Posts: 2605
Joined: March 23rd, 2015, 5:26 pm

Re: Feature Request - autoscale max variable for histogram/l

Post by SilverAzide »

Oh, I see now... yes, that would be a moving target. Thanks for the clarification.
Gadgets Wiki GitHub More Gadgets...
TGonZo
Posts: 68
Joined: April 25th, 2015, 8:19 pm
Location: Virginia

Re: Feature Request - autoscale max variable for histogram/l

Post by TGonZo »

Hi all,

So, this was enough of a thorn in my side that I dug into Lua a bit more. I wrote a script that will figure out what the Histogram display scale should be. I looked through the Rainmeter code to find out what it was doing. I now know the Histogram always has a minimum scale of 2, and it just loops multiplying by 2 until it is larger than the max value in the Histogram.

In source file MeterHistogram.cpp variable m_MaxSecondaryValue is the Max display scale. I even downloaded and compiled the whole thing, and it ran. I know C pretty well, but C++ gets me lost with all the overloading of functions and operators. I was not able to figure out how to get the value to a readable variable usable in a ini file.

So, I have basically replicated that bit of code in this Lua script. So, as long as you point it at the same Measure the Histogram is using, and set the Width the same, it should calculate the same display max scale. It looks like it is working to me.

It's as clean of a kludge as I can make, and should work until the feature can be added into Rainmeter properly.
Please check it out, and let me know if anything is off.

Code: Select all

--
-- FindMaxHistValue.lua v1.0 by TGonZo
--
-- This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License.
--
-- History:
--
--
-- This script will keep track of the values that are within the Histogram display and calculate
-- the Max Scale of the Histogram that is running in AutoScale mode.
-- I set this up to run like a regular Measure so you can point it at the very same Measure that the
--  Histogram is using, and you can use AutoScale and other options with it in a Meter.
-- It needs to update every time the Histogram does to collect the values anyway, so this seemed the simplest way.
-- An example below shows a use case to help you understand how to use it.
--
-- Lua Script Options for FindMaxHistValue.lua when used in a Measure.
--
--     CurValue
--
--       The value of a measure that will be used in the Histogram.  Another Measure.
--
--     HistWidth
--
--       The width of the Histogram.  (How many values to store and remember.)
--
--
--
-- Example skin:
--
-- [Variables]
-- HistogramWidth=80
--
-- [MeasureDiskReadBytes1]
-- Measure=Plugin
-- Plugin=PerfMon
-- PerfMonObject=LogicalDisk
-- PerfMonCounter=Disk Read Bytes/sec
-- PerfMonInstance=C:
--
-- [measureDiskReadBytesMaxHist]
-- Measure=Script
-- ScriptFile=#@#/FindMaxHistValue.lua
-- CurValue=[MeasureDiskReadBytes1]
-- HistWidth=#HistogramWidth#
--
-- [MeterReadBytesHistogram1]
-- Meter=Histogram
-- MeasureName=MeasureDiskReadBytes1
-- X=28
-- Y=10
-- W=#HistogramWidth#
-- H=30
-- PrimaryColor=#colorBlue#
-- SolidColor=0,0,0,100
-- AntiAlias=1
-- AutoScale=1
--
-- [MeterDiskReadBytesMaxHistText]
-- Meter=String
-- MeasureName=measureDiskReadBytesMaxHist
-- StringAlign=Right
-- FontColor=#colorWhite#
-- X=80r
-- Y=0r
-- W=40
-- H=12
-- AutoScale=1
-- NumOfDecimals=0
-- Text=%1
--
--
----------------------------------------------------------------------------------------------------
--

function Initialize()
  --
  -- this function is called when the script measure is initialized or reloaded
  --

  -- initialize array for Histogram values just once when the skin is loaded
  --
  tValues = {}

  return
end

--
-----------------------
--

function Update()

  -- initialize local vars, the Histogram max scale is always a minimum of 2.
  local CurMax = 2
  local HistMax = 2
  local CurSize = 0

  -- get parameters from the Measure the script is called from.
  sInputValue = SELF:GetOption('CurValue', '0')
  sHistWidth = SELF:GetOption('HistWidth', '1')

  --
  -- validate input parameters
  --
  local nValue = tonumber(sInputValue)
  local nHistWidth = tonumber(sHistWidth)

  -- add new value to the list.
  table.insert(tValues, 1, nValue)
  CurSize = table.maxn(tValues)

  -- trim off oldest Value as it falls off the Histogram view.
  if CurSize > nHistWidth then
    table.remove(tValues, nHistWidth+1)
  end

  -- find the Max Value in the current Histogram view.
  CurSize = table.maxn(tValues)
  if CurSize >= 1 then
    i = 1
    while i <= CurSize do
      if CurMax < tValues[i] then
        CurMax = tValues[i]
      end
      i = i + 1
    end
  end

  -- find the current Histogram Max Scale.
  while CurMax > HistMax do
    HistMax = HistMax * 2
  end

  -- return a numeric value and not a string, so the autoscaler will work.
  return HistMax

end

--
----------------------------------------------------------------------------------------------------
--
TGonZo
Posts: 68
Joined: April 25th, 2015, 8:19 pm
Location: Virginia

Re: Feature Request - autoscale max variable for histogram/l

Post by TGonZo »

Not that it was bad, but I did make it a bit more efficient. A couple of IF statements and now it only scans all the values for a new max when it is needed. Which is probably less than 5% of the time. I don't like wasting CPU cycles if it only takes a little more code. It still works as advertised.

Code: Select all

--
-- FindMaxHistValue v1.1 by TGonZo
--
-- This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License.
--
-- History:
-- v1.0 - Initial release
-- v1.1 - Made it more efficient, only scans values for a new max when needed.
--        Moved a couple of assignments to the initialize function that only need to be done on startup.
--
-- This script will keep track of the values that are within the Histogram display and calculate
-- the Max Scale of the Histogram that is running in AutoScale mode.
-- I set this up to run like a regular Measure so you can point it at the very same Measure that the
--  Histogram is using, and you can use AutoScale and other options with it in a Meter.
-- It needs to update every time the Histogram does to collect the values anyway, so this seemed the simplest way.
-- An example below shows a use case to help you understand how to use it.
--
-- Lua Script Options for FindMaxHistValue.lua when used in a Measure.
--
--     CurValue
--
--       The value of a measure that will be used in the Histogram.  Another Measure.
--
--     HistWidth
--
--       The width of the Histogram.  (How many values to store and remember.)
--
--
--
-- Example skin:
--
-- [Variables]
-- HistogramWidth=80
--
-- [MeasureDiskReadBytes1]
-- Measure=Plugin
-- Plugin=PerfMon
-- PerfMonObject=LogicalDisk
-- PerfMonCounter=Disk Read Bytes/sec
-- PerfMonInstance=C:
--
-- [measureDiskReadBytesMaxHist]
-- Measure=Script
-- ScriptFile=#@#/FindMaxHistValue.lua
-- CurValue=[MeasureDiskReadBytes1]
-- HistWidth=#HistogramWidth#
--
-- [MeterReadBytesHistogram1]
-- Meter=Histogram
-- MeasureName=MeasureDiskReadBytes1
-- X=28
-- Y=10
-- W=#HistogramWidth#
-- H=30
-- PrimaryColor=#colorBlue#
-- SolidColor=0,0,0,100
-- AntiAlias=1
-- AutoScale=1
--
-- [MeterDiskReadBytesMaxHistText]
-- Meter=String
-- MeasureName=measureDiskReadBytesMaxHist
-- StringAlign=Right
-- FontColor=#colorWhite#
-- X=80r
-- Y=0r
-- W=40
-- H=12
-- AutoScale=1
-- NumOfDecimals=0
-- Text=%1
--
--
----------------------------------------------------------------------------------------------------
--

function Initialize()
  --
  -- this function is called when the script measure is initialized or reloaded
  --

  -- initialize array for Histogram values just once when the skin is loaded
  --
  tValues = {}
  PrevMax = 0
  PrevMaxIndex = 0

  sHistWidth = SELF:GetOption('HistWidth', '1')
  nHistWidth = tonumber(sHistWidth)

  return
end

--
-----------------------
--

function Update()

  -- initialize local vars, the Histogram max scale is always a minimum of 2.
  local CurMax = 2
  local HistMax = 2
  local CurSize = 0

  -- get parameters from the Measure the script is called from.
  sInputValue = SELF:GetOption('CurValue', '0')

  -- validate input parameters
  nValue = tonumber(sInputValue)

  -- add new value to the list.
  table.insert(tValues, 1, nValue)
  CurSize = table.maxn(tValues)

  -- trim off oldest Value as it falls off the Histogram view.
  if CurSize > nHistWidth then
    table.remove(tValues, nHistWidth+1)
  end
  PrevMaxIndex = PrevMaxIndex + 1


  -- if new value is the new max, no need to scan all values for a max.
  if nValue >= PrevMax then

    PrevMax = nValue
    PrevMaxIndex = 1

  -- when the old max ages out of the buffer, need to scan for a new max.
  elseif PrevMaxIndex > nHistWidth then

    -- find the Max Value in the current Histogram view.
    CurSize = table.maxn(tValues)
    if CurSize >= 1 then
      i = 1
      while i <= CurSize do
        if CurMax < tValues[i] then
          CurMax = tValues[i]
          PrevMaxIndex = i
        end
        i = i + 1
      end
    end
    PrevMax = CurMax

  end


  -- find the current Histogram Max Scale.
  while PrevMax > HistMax do
    HistMax = HistMax * 2
  end


  -- return a numeric value and not a string, so the autoscaler will work.
  return HistMax

end

--
----------------------------------------------------------------------------------------------------
--
TGonZo
Posts: 68
Joined: April 25th, 2015, 8:19 pm
Location: Virginia

Re: Feature Request - autoscale max variable for histogram/l

Post by TGonZo »

I've made it a bit more efficient. It only scans for a new max value when it is needed, and it only calculates the Histogram max when it is needed. So, most of the time it just hits an IF statement and returns. I think this is as good as gets for now.
I am using it on 11 Histograms at the moment, and I don't see any impact on my system.
Enjoy.

Code: Select all

--
-- FindMaxHistValue.lua v1.2 by TGonZo
--
-- This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 License.
--
-- History:
-- v1.0 - 2015-06-08 - Initial release
-- v1.1 - 2015-06-08 - Made it more efficient, only scans values for a new max when needed.
--        Moved a couple of assignments to the initialize function that only need to be done on startup.
-- v1.2 - 2015-06-16 - Made it more efficient, it no longer recalculates the max unless needed.
--
-- This script will keep track of the values that are within the Histogram display and calculates
--  the Max Scale of the Histogram that is running in AutoScale mode.
-- I set this up to run like a regular Measure so you can point it at the very same Measure that the
--  Histogram is using, and you can use AutoScale and other options with it in a Meter.
-- It needs to update every time the Histogram does to collect the values anyway, so this seemed the simplest way.
-- It should work with a Line meter in autoscale mode as well.
-- An example below is there to help you understand how to use it.
--
-- Lua Script Options for FindMaxHistValue.lua when used in a Measure.
--
--     CurValue
--
--       The value of the measure that will be used in the Histogram.  The measure name.
--
--     HistWidth
--
--       The width of the Histogram meter.  (How many values to store and remember.)
--
--
--
-- Example skin:
--
-- [Rainmeter]
-- Update=1000
-- SolidColor=0,0,0,100
-- BackgroundMode=2
-- BackgroundMargins=0,0,10,10
--
-- [Variables]
-- HistogramWidth=80
--
-- [MeasureDiskReadBytes1]
-- Measure=Plugin
-- Plugin=PerfMon
-- PerfMonObject=LogicalDisk
-- PerfMonCounter=Disk Read Bytes/sec
-- PerfMonInstance=C:
--
-- [measureDiskReadBytesMaxHist]
-- Measure=Script
-- ScriptFile=#@#/FindMaxHistValue.lua
-- CurValue=[MeasureDiskReadBytes1]
-- HistWidth=#HistogramWidth#
--
-- [MeterReadBytesHistogram1]
-- Meter=Histogram
-- MeasureName=MeasureDiskReadBytes1
-- X=10
-- Y=10
-- W=#HistogramWidth#
-- H=30
-- PrimaryColor=100,150,250,220
-- SolidColor=0,0,0,100
-- AntiAlias=1
-- AutoScale=1
--
-- [MeterDiskReadBytesMaxHistText]
-- Meter=String
-- MeasureName=measureDiskReadBytesMaxHist
-- StringAlign=Left
-- FontSize=8
-- FontColor=255,255,255,220
-- X=0r
-- Y=0r
-- W=40
-- H=12
-- AutoScale=1
-- NumOfDecimals=0
-- Text=%1
--
--
----------------------------------------------------------------------------------------------------
--

function Initialize()
  --
  -- this function is called when the script measure is initialized or reloaded
  --

  -- initialize array and vars for Histogram values just once when the skin is loaded
  tValues = {}
  PrevMax = 0
  PrevMaxIndex = 0
  HistMaxPrev = 0

  sHistWidth = SELF:GetOption('HistWidth', '1')
  nHistWidth = tonumber(sHistWidth)

  return
end

--
-----------------------
--

function Update()

  -- initialize local vars, the Histogram max scale is always a minimum of 2.
  local CurMax = 2
  local HistMax = 2
  local CurSize = 0

  -- get parameters from the Measure the script is called from.
  sInputValue = SELF:GetOption('CurValue', '0')

  -- validate input parameters
  nValue = tonumber(sInputValue)

  -- add new value to the list.
  table.insert(tValues, 1, nValue)
  CurSize = table.maxn(tValues)

  -- trim off oldest Value as it falls off the Histogram view.
  if CurSize > nHistWidth then
    table.remove(tValues, nHistWidth+1)
  end
  PrevMaxIndex = PrevMaxIndex + 1


  -- if new value is the new max, no need to scan all values for a max.
  if nValue >= PrevMax then

    PrevMax = nValue
    PrevMaxIndex = 1

  -- when the old max ages out of the buffer, need to scan for a new max.
  elseif PrevMaxIndex > nHistWidth then

    -- find the Max Value in the current Histogram view.
    CurSize = table.maxn(tValues)
    if CurSize >= 1 then
      i = 1
      while i <= CurSize do
        if CurMax < tValues[i] then
          CurMax = tValues[i]
          PrevMaxIndex = i
        end
        i = i + 1
      end
    end
    PrevMax = CurMax

  else

    -- if no reason to rescan for a new max, return the previous max.
    return HistMaxPrev

  end


  -- find the current Histogram Max Scale based on the new max value.
  while PrevMax > HistMax do
    HistMax = HistMax * 2
  end
  HistMaxPrev = HistMax

  -- return a numeric value and not a string, so the autoscaler will work.
  return HistMax

end

--
----------------------------------------------------------------------------------------------------
--