PHP红色到绿色RGB颜色热图

时间:2016-03-07 15:49:27

标签: php math heatmap

我似乎无法理解这一点。我有一组缩放值(0 ... 1),我需要将颜色与之关联起来。最高(1)为红色,最低(0)为绿色。

我似乎无法找到如何在红色和绿色之间获得介于0和1之间的RGB颜色。

这是我将用于缩放值的缩放功能:

set_in_transform

我认为将它们从0缩放到1将使下一部分我更容易挣扎。

这是一个非常糟糕的尝试,我想出了这个,失败得非常糟糕。

function scale_value($value, $srcmin, $srcmax, $destmin = 0, $destmax = 1)
{
    # How Far In Source Range Are We
    $pos = (($value - $srcmin) / ($srcmax - $srcmin));
    return ($pos * ($destmax - $destmin)) + $destmin;
}

有没有人使用PHP来确定用于介于1和0之间的值的颜色?

3 个答案:

答案 0 :(得分:3)

找到一个解决方案,将JS实现的解决方案posted here转换为PHP并将红色转换为绿色极性,因此Red为高,Green为低。

看起来像这样:

/**
 * @param $value
 * @param integer|float $min
 * @param integer|float $max
 * @return string
 */
function make_color($value, $min = 0, $max = .5)
{
    $ratio = $value;
    if ($min > 0 || $max < 1) {
        if ($value < $min) {
            $ratio = 1;
        } else if ($value > $max) {
            $ratio = 0;
        } else {
            $range = $min - $max;
            $ratio = ($value - $max) / $range;
        }
    }

    $hue = ($ratio * 1.2) / 3.60;
    $rgb = hsl_to_rgb($hue, 1, .5);

    $r = round($rgb['r'], 0);
    $g = round($rgb['g'], 0);
    $b = round($rgb['b'], 0);

    return "rgb($r,$g,$b)";
}

这也依赖于HSL到RGB的翻译器,我发现on this post。这最终给了我一个非常好的结果:

Red to green heatmap using PHP

感谢您的帮助。

答案 1 :(得分:1)

感谢Matthew Brown提供了他的来源链接。和JF中使用JSFiddle的那个链接。但是Matthew的版本包含了一个在我的PHP中失败的函数,因此我转换了JSFiddle,包括所有函数,结果是:

<html>
    <head>
        <style>
    li {
    display: block;
    float: left;
    width: 50px;
    height: 50px;
    margin: 2px;
}
hr {
    clear: both;
}
</style>
<title>hi</title>
    </head>
    <body>
        <?PHP 

function hslToRgb($h, $s, $l){
#    var r, g, b;
    if($s == 0){
        $r = $g = $b = $l; // achromatic
    }else{
        if($l < 0.5){
            $q =$l * (1 + $s);
        } else {
            $q =$l + $s - $l * $s;
        }
        $p = 2 * $l - $q;
        $r = hue2rgb($p, $q, $h + 1/3);
        $g = hue2rgb($p, $q, $h);
        $b = hue2rgb($p, $q, $h - 1/3);
    }
    $return=array(floor($r * 255), floor($g * 255), floor($b * 255));
    return $return;
}

function hue2rgb($p, $q, $t){
    if($t < 0) { $t++; }
    if($t > 1) { $t--; }
    if($t < 1/6) { return $p + ($q - $p) * 6 * $t; }
    if($t < 1/2) { return $q; }
    if($t < 2/3) { return $p + ($q - $p) * (2/3 - $t) * 6; }
    return $p;
}
/**
 * Convert a number to a color using hsl, with range definition.
 * Example: if min/max are 0/1, and i is 0.75, the color is closer to green.
 * Example: if min/max are 0.5/1, and i is 0.75, the color is in the middle between red and green.
 * @param i (floating point, range 0 to 1)
 * param min (floating point, range 0 to 1, all i at and below this is red)
 * param max (floating point, range 0 to 1, all i at and above this is green)
 */
function numberToColorHsl($i, $min, $max) {
    $ratio = $i;
    if ($min> 0 || $max < 1) {
        if ($i < $min) {
            $ratio = 0;
        } elseif ($i > $max) {
            $ratio = 1;
        } else {
            $range = $max - $min;
            $ratio = ($i-$min) / $range;
        }
    }
    // as the function expects a value between 0 and 1, and red = 0° and green = 120°
    // we convert the input to the appropriate hue value
    $hue = $ratio * 1.2 / 3.60;
    //if (minMaxFactor!=1) hue /= minMaxFactor;
    //console.log(hue);

    // we convert hsl to rgb (saturation 100%, lightness 50%)
    $rgb = hslToRgb($hue, 1, .5);
    // we format to css value and return
    return 'rgb('.$rgb[0].','.$rgb[1].','.$rgb[2].')'; 
}

// build the color sample lists
for ($i=0; $i<=100; $i++) {
    $list1.='<li style="background-color:'. numberToColorHsl($i/100, 0, 1) .'">'.$i."</li>\n";
    $list2.='<li style="background-color:'. numberToColorHsl($i/100, 0.5, 1). '">'.$i."</li>\n";
    $list3.='<li style="background-color:'. numberToColorHsl($i/100, 0, 0.6).'">' . $i . "</li>\n";
    $list4.='<li style="background-color:'. numberToColorHsl($i/100, 0.3, 0.8).'">' . $i . "</li>\n";
}
echo "<br><hr>\n\n"; ?>
<hr>
full range
<ul id='list-1'></ul>
    <?PHP echo $list1; ?>
<hr>
all below 0.5 is bad
<ul id='list-2'></ul>
<?PHP echo $list2; ?>
<hr>
all above 0.6 is ok
<ul id='list-3'></ul>
<?PHP echo $list3; ?>
<hr>
all below 0.3 is red, all above 0.8 is green
<ul id='list-4'></ul>
<?PHP echo $list4; 

JMeter Chrome Extension

答案 2 :(得分:0)

这将允许您选择自己的颜色渐变比例。

enter image description here

function Gradient($HexFrom, $HexTo, $ColorSteps) {
    // credit: Hailwood (stackoverflow)
    $FromRGB['r'] = hexdec(substr($HexFrom, 0, 2));
    $FromRGB['g'] = hexdec(substr($HexFrom, 2, 2));
    $FromRGB['b'] = hexdec(substr($HexFrom, 4, 2));

    $ToRGB['r'] = hexdec(substr($HexTo, 0, 2));
    $ToRGB['g'] = hexdec(substr($HexTo, 2, 2));
    $ToRGB['b'] = hexdec(substr($HexTo, 4, 2));

    $StepRGB['r'] = ($FromRGB['r'] - $ToRGB['r']) / ($ColorSteps - 1);
    $StepRGB['g'] = ($FromRGB['g'] - $ToRGB['g']) / ($ColorSteps - 1);
    $StepRGB['b'] = ($FromRGB['b'] - $ToRGB['b']) / ($ColorSteps - 1);

    $GradientColors = array();

    for($i = 0; $i <= $ColorSteps; $i++) {
        $RGB['r'] = floor($FromRGB['r'] - ($StepRGB['r'] * $i));
        $RGB['g'] = floor($FromRGB['g'] - ($StepRGB['g'] * $i));
        $RGB['b'] = floor($FromRGB['b'] - ($StepRGB['b'] * $i));

        $HexRGB['r'] = sprintf('%02x', ($RGB['r']));
        $HexRGB['g'] = sprintf('%02x', ($RGB['g']));
        $HexRGB['b'] = sprintf('%02x', ($RGB['b']));

        $GradientColors[] = implode(NULL, $HexRGB);
    }
    $GradientColors = array_filter($GradientColors, function($val){
        return (strlen($val) == 6 ? true : false );
    });
    return $GradientColors;
}

function ColorFromGradient($n, $min, $max, $colors)
{
    $tablecolors = [];
    $prevcolor = array_shift($colors);
    foreach ($colors as $color) {
        $tablecolors = array_merge($tablecolors, Gradient($prevcolor, $color, 10));
        $prevcolor = $color;
    }
    $max = $max-$min;
    $n-= $min;
    if ($n > $max) $n = $max;
    
    $ncolor = round(count($tablecolors)/$max * $n)-1;
    
    return $tablecolors[$ncolor];
}


// USAGE: Generate the Gradient Table
echo ColorFromGradient(25, 0, 100, ['FFFFFF', 'FFFF00', 'FF0000']); // WHITE -> YELLOW -> RED