计算热图颜色

时间:2013-07-23 22:04:02

标签: c# hex rgb heatmap

我正在制作一个由HTML表组成的热图。此表包含 n 单元格,并具有最低值和最高值(最高值始终高于最低值)。每个单元格都有一个单元格值。所有这些值都是整数。

具有最低值的细胞意味着是浅蓝色,缩放到具有最高值的细胞是深红色的点。请参阅下面的渐变以获得理想范围:

enter image description here

要计算每个单元格的十六进制颜色值,我会查看表格中最低最高值以及单元格总计 value,将它们传递给返回RGB十六进制的方法,准备与HTML的 background-color 样式一起使用。

到目前为止,这是方法:

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

最低值为0且最高值为235时,此方法返回下表(单元格值在单元格中)。

enter image description here

示例案例:如果最低为20,最高为400且 cell 为60,我希望该方法返回RGB hex颜色大约是梯度的15.8%。

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

我知道这个公式不太准确,但这也是我在这里寻求帮助的部分原因。

我已经做到这一点,但我真的不确定如何继续。非常感谢任何帮助!

2 个答案:

答案 0 :(得分:4)

今天我已经开始寻找一些关于他的问题的帮助,但没有回答我找到答案正是这个问题。

“热图”不是原始值%到Hue转换,它可以用7,5或更少颜色构建(例如:红色到黄色),可以是线性或对数等。

enter image description here

我编写并分享了一个C#.Net 4.6.1代码,它可以成为构建ValueToColorOnHeatMap转换器的坚实基础: (注意:这是经过验证和测试的)

using System.Windows.Media;// for WPF
// for WindowsForms using System.Drawing
using System;
using System.Collections.Generic;
public class ColorHeatMap
{
    public ColorHeatMap()
    {
        initColorsBlocks();
    }
    public ColorHeatMap(byte alpha)
    {
        this.Alpha = alpha;
        initColorsBlocks();
    }
    private void initColorsBlocks()
    {
        ColorsOfMap.AddRange(new Color[]{
            Color.FromArgb(Alpha, 0, 0, 0) ,//Black
            Color.FromArgb(Alpha, 0, 0, 0xFF) ,//Blue
            Color.FromArgb(Alpha, 0, 0xFF, 0xFF) ,//Cyan
            Color.FromArgb(Alpha, 0, 0xFF, 0) ,//Green
            Color.FromArgb(Alpha, 0xFF, 0xFF, 0) ,//Yellow
            Color.FromArgb(Alpha, 0xFF, 0, 0) ,//Red
            Color.FromArgb(Alpha, 0xFF, 0xFF, 0xFF) // White
        });
    }
    public Color GetColorForValue(double val, double maxVal)
    {
        double valPerc = val / maxVal;// value%
        double colorPerc = 1d / (ColorsOfMap.Count-1);// % of each block of color. the last is the "100% Color"
        double blockOfColor = valPerc / colorPerc;// the integer part repersents how many block to skip
        int blockIdx = (int)Math.Truncate(blockOfColor);// Idx of 
        double valPercResidual = valPerc - (blockIdx*colorPerc);//remove the part represented of block 
        double percOfColor = valPercResidual / colorPerc;// % of color of this block that will be filled

        Color cTarget = ColorsOfMap[blockIdx];
        Color cNext = cNext = ColorsOfMap[blockIdx + 1]; 

        var deltaR =cNext.R - cTarget.R;
        var deltaG =cNext.G - cTarget.G;
        var deltaB =cNext.B - cTarget.B;

        var R = cTarget.R + (deltaR * percOfColor);
        var G = cTarget.G + (deltaG * percOfColor);
        var B = cTarget.B + (deltaB * percOfColor);

        Color c = ColorsOfMap[0];
        try
        {
            c = Color.FromArgb(Alpha, (byte)R, (byte)G, (byte)B);
        }
        catch (Exception ex)
        {
        }
        return c;
    }
    public byte Alpha = 0xff;
    public List<Color> ColorsOfMap = new List<Color>();
}

要使用更少或个性化的颜色,请使用ColorsOfMap列表。 该类使用比例,线性,重复表示,在blocOfColor上工作以改变线性度。

我希望这会帮助一些人节省时间:)。

感谢所有与社区分享他们的答案/解决方案的人。

要使用更少或个性化的颜色,请使用ColorsOfMap列表。 该类使用比例,线性,重复表示,在blocOfColor上工作以改变线性度。

我希望这会帮助一些人节省时间:)。

感谢所有与社区分享他们的答案/解决方案的人。

答案 1 :(得分:3)

你真正想要的是HSV颜色,因为Hue(H值)是周期性的。如果色调介于0和1之间,那么它表示您希望颜色渐变的距离。在这种情况下,饱和度和值组件始终为1。

在此处按照HSV转换为RGB转换代码: 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");
}

如果您知道可以定位支持它的浏览器(CSS3),则可以直接渲染hsv值。