Question

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?

Was it helpful?

Solution 2

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;

OTHER TIPS

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

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

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top