I have an application monitoring a number of data points and I'm performing colouring based on the linear percentage fading between green, yellow and red. This however doesn't accurately visualise the problem as the higher the number the exponentially worse it is. The range is 0 -> 30000, how can I generate what I think would be termed a logarithmic percentage value rather than a linear one?
问题:
回答1:
Use a function of the following form.
f(x) = s bx / 30000 + t
We know that 0 should map to 0% and 30000 should map to 100%.
f(0) = 0
f(30000) = 100
These imply the following system of equations.
s + t = 0
s b + t = 100
The solution (with respect to b) is the following.
s = 100 / (b - 1)
t = -100 / (b - 1)
Pick a particular b > 1 value (say b = 10). Then you get the following solution.
s = 100 / 9
t = -100 / 9
That is, the function f(x) is the following.
f(x) = (100 10x / 30000 - 100) / 9
You can see a plot of this function here: Wolfram Alpha
In C# this will look like the following.
double x = ...;
double b = 10.0;
double s = 100.0 / (b - 1);
double t = -100.0 / (b - 1);
double f = s * Math.Pow(b, x / 30000.0) + t;
回答2:
I assume by "logarithmic percentage" you want to map your data to the range [0, 100] on a logarithmic basis. You can try something like this:
double Scale(int val)
{
if (val <= 1)
return 0; // log is undefined for 0, log(1) = 0
return 100 * Math.Log(val) / Math.Log(30000);
}
回答3:
Improving on bmm6o's answer:
public static double Scale(long value, long maxInputValue, long maxOutputValue)
{
if (value <= 1)
return 0; // log is undefined for 0, log(1) = 0
return maxOutputValue * Math.Log(value) / Math.Log(maxInputValue);
}
if you're looking for something between linear and logarithmic, the following might help:
public static double Scale(long value, long maxInputValue, long maxOutputValue, double scaleFactor)
{
if (value <= 1)
return 0; // log is undefined for 0, log(1) = 0
return maxOutputValue * Math.Pow(Math.Log(value), scaleFactor) / Math.Pow(Math.Log(maxInputValue), scaleFactor);
}
回答4:
Use Math.Log(double)
(or Math.Log(double, double)
if you want to play around with the base) to get the logarithm of your value, which you can than map to a color value.