Search code examples
c#hexrgbheatmap

Calculating heat map colours


I'm working on a heat map made up of an HTML table. This table contains n cells and has a lowest value and a highest value (highest is always higher than lowest). Each cell has a cell value. All these values are ints.

Cells with the lowest value are meant to be a light blue, scaling across to the point where the cells with the highest value are a deep red. See gradient below for an ideal range:

enter image description here

To calculate the hex colour value of each individual cell, I look at the lowest and highest values from the table and the cell's total value, passing them into a method that returns the RGB hex, ready to be used with HTML's background-color style.

Here is the method so far:

public string ConvertTotalToRgb(int low, int high, int cell)
{
    int range = high - low;

    int main = 255 * cell/ range;
    string hexR = main.ToString("X2");
    int flip = 255 * (1 - (cell/ range));
    string hexB = flip.ToString("X2");

    return hexR + "00" + hexB;
}

With a lowest value of 0 and a highest value of 235, this method returns the following table (cell values are in the cells).

enter image description here

Example case: If lowest was 20, highest was 400 and cell was 60, I would want the method returning the RGB hex of the colour about 15.8% of the way along the gradient.

400 - 20 = 380
380 / 60 = 6.33
100 / 6.33 = 15.8

I'm aware that this formula isn't quite accurate but that's partially why I'm asking for help here.

I've made it this far but I'm really not sure how to proceed. Any help is hugely appreciated!


Solution

  • What you really want is an HSV color, because the Hue (H value) is cyclical. if the hue is between 0 and 1, then it indicates how far along your color gradient you want to be. The saturation and value components are always 1 in this case.

    Follow the HSV to RGB conversion code here: HSV to RGB Stops at yellow C#

    public string ConvertTotalToRgb(int low, int high, int cell)
    {
        int range = high - low;
        float h= cell/ (float)range;
        rgb = HSVtoRGB(h,1.0f,1.0f);
        return "#" + rgb.R.ToString("X2") + rgb.G.ToString("X2") + rgb.B.ToString("X2");
    }
    

    If you know you can target browsers that support it (CSS3), you can just render the hsv value directly.