2013-07-23 4 views
3

Я работаю над тепловой картой, состоящей из таблицы HTML. Эта таблица содержит n и имеет самое низкое значение и значение наивысшее значение (самое высокое всегда выше, чем самое низкое). Каждая ячейка имеет ячейку . Все эти значения являются ints.Вычисление цветов тепловой карты

Клетки с наименьшим значением должны быть светло-голубыми, масштабирующимися до точки, где ячейки с самым высоким значением являются темно-красными. См градиента ниже для идеального диапазона:

enter image description here

Для вычисления значения шестнадцатеричного цвета каждой отдельной клетки, я смотрю на низких и высших значений из таблицы и общей значения ячейки , передавая их в метод, который возвращает шестнадцатеричный RGB, готовый для использования с фоном HTML-стиля.

Вот метод до сих пор:

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 и клеток было 60, я хотел бы метод, возвращая RGB гекс цвета около 15,8% пути по градиент.

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

Я знаю, что эта формула не совсем точна, но отчасти поэтому я прошу о помощи здесь.

Я сделал это так далеко, но я действительно не уверен, как действовать дальше. Любая помощь очень ценится!

+0

Ваш вопрос действительно запутан. Что выглядит таблица HTML? – Sayse

+0

Я буквально положил изображение таблицы в вопрос, прямо внизу:/ – Djentleman

+0

Я неправильно понял тогда .. откуда взялись значения? – Sayse

ответ

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), вы можете просто визуализировать значение ВПГ напрямую.

+0

Это, похоже, не сработало - это отображает все в таблице выше как красное. – Djentleman

+0

Хорошо, я понял вопрос. Цветовой оттенок был крошечным десятичным, что означало, что он едва перемещал цвет по спектру. Когда он был умножен на 240 (положение чистого синего на спектре HSV), он работал, как ожидалось. Спасибо за помощь! – Djentleman

3

Сегодня я искал, чтобы найти какую-то помощь в его вопросе, но ответа я не нашел точно.

«Тепловая карта» не является исходным значением преобразования% to Hue, оно может быть построено с 7, 5 или менее цветами (например, от красного до желтого), может быть линейным или логарифмическим и т. Д.

enter image description here

я написал, и обмен я, C# .Net 4.6.1 код, который может быть прочной базой для построения ValueToColorOnHeatMap нейтрализатор: (Примечание: это debuged и испытанный)

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

Как написано, этот код вылетает с исключением из исключения исключений, когда GetColorForValue вызывается с val == maxval. Простое исправление будет «double valPerc = val/(maxval + 1)» –

+0

BTW, это был лучший пример кода цветового сопоставления, который я нашел после нескольких часов поиска. Использование (maxval + 1) для сохранения valPerc ниже 1.0 отлично работало в моей среде, но вам может потребоваться другой подход в зависимости от диапазона ваших значений. –

+2

Я также использовал эту реализацию, это хорошо. Вы можете настроить собственные цвета в градиенте и т. Д. Но я изменил некоторые строки. Ваша реализация предполагает, что minVal равно 0, но что, если это не так? Поэтому я использовал 'double valPerc = (val-minVal)/(maxVal-minVal);' Также изменил @ Craig.Feied обработку case 'val == maxVal' таким образом' Цвет cNext = val == maxVal? ColorGradient [blockIdx]: ColorGradient [blockIdx + 1]; 'Потому что, когда вы используете' double valPerc = val/(maxval + 1) ', вы никогда не достигнете максимального цвета, который в этом случае будет красным. – Gondil

Смежные вопросы