Color of the record, referring to quantity

4

I have a table with multiple records , and these have a " data " field.

I generate a list of these records, I make the difference of days by comparing the " date " with the " current date ". Example:

$dias = $data_hoje - $data_registro;

I define 2 colors. Example: white, black , example:

$cor1 = '#FFF';
$cor2 = '#000';

Gero a default value of the oldest date of records with the " current date ". Example:

$data_padrão = $data_hoje - $data_primeiro_registro;
$data_final = $data_hoje;

What you would like to do is: print the list by bringing the intensity of the colors as the days elapsed from the calculated default value . This intensity would be in the "gradient" scale of this color range.

How do I generate this color with the intensity related to the registry the 3 variables I have (oldest date, today, date of registration)?

I have to use decimal and then transform to hexa ? Or can I use hexa , or another form of color?

    
asked by anonymous 04.05.2018 / 21:40

2 answers

2

First, let's create a function that gives a color that corresponds to the value 0, a color that corresponds to the value 1 and a value between 0 and 1,

function interpolar_cor($cor0, $cor1, $valor) {
    if ($valor <= 0) return $cor0;
    if ($valor >= 1) return $cor1;
    list($r0, $g0, $b0) = sscanf($cor0, "#%02x%02x%02x");
    list($r1, $g1, $b1) = sscanf($cor1, "#%02x%02x%02x");
    $rx = (int) ($valor * ($r1 - $r0) + $r0);
    $gx = (int) ($valor * ($g1 - $g0) + $g0);
    $bx = (int) ($valor * ($b1 - $b0) + $b0);
    return "#" . str_pad(dechex($rx * 256 * 256 + $gx * 256 + $bx), 6, "0", STR_PAD_LEFT);
}

The colors should be in the #rrggbb format where rr is the hexadecimal value of the red component, gg o of the green component, and bb o of the blue component.

Once this is done, we can create a function to interpolate dates and associate them with color:

function interpolar_cor_data($cor0, $data0, $cor1, $data1, $dataX) {
    $dias_max = $data1->diff($data0)->days;
    if ($dias_max <= 0) $dias_max = 1;
    $dias_t = $dataX->diff($data0)->days;
    return interpolar_cor($cor0, $cor1, $dias_t / (float) $dias_max);
}

Let's do a test. First let's set some dates:

$data_teste1 = new DateTime("2018-04-01");
$data_teste2 = new DateTime("2018-04-05");
$data_teste3 = new DateTime("2018-04-10");
$data_teste4 = new DateTime("2018-04-20");
$data_teste5 = new DateTime("2018-04-30");
$data_teste6 = new DateTime("2018-05-04");

$data_hoje = new DateTime("2018-05-04");
$data_inicio = new DateTime("2018-04-01");

And then test them with the white colors being point 0 and black point 1:

// Entre branco e preto:
$branco = "#ffffff";
$preto = "#000000";
echo interpolar_cor_data($branco, $data_inicio, $preto, $data_hoje, $data_teste1) . "\n";
echo interpolar_cor_data($branco, $data_inicio, $preto, $data_hoje, $data_teste2) . "\n";
echo interpolar_cor_data($branco, $data_inicio, $preto, $data_hoje, $data_teste3) . "\n";
echo interpolar_cor_data($branco, $data_inicio, $preto, $data_hoje, $data_teste4) . "\n";
echo interpolar_cor_data($branco, $data_inicio, $preto, $data_hoje, $data_teste5) . "\n";
echo interpolar_cor_data($branco, $data_inicio, $preto, $data_hoje, $data_teste6) . "\n";

The output is:

#ffffff
#e0e0e0
#b9b9b9
#6c6c6c
#1e1e1e
#000000

That is, the output gave these colors:

Let's try with other colors. Red for point 0 and green for point 1:

// Entre vermelho e verde:
$vermelho = "#ff0000";
$verde = "#00ff00";
echo interpolar_cor_data($vermelho, $data_inicio, $verde, $data_hoje, $data_teste1) . "\n";
echo interpolar_cor_data($vermelho, $data_inicio, $verde, $data_hoje, $data_teste2) . "\n";
echo interpolar_cor_data($vermelho, $data_inicio, $verde, $data_hoje, $data_teste3) . "\n";
echo interpolar_cor_data($vermelho, $data_inicio, $verde, $data_hoje, $data_teste4) . "\n";
echo interpolar_cor_data($vermelho, $data_inicio, $verde, $data_hoje, $data_teste5) . "\n";
echo interpolar_cor_data($vermelho, $data_inicio, $verde, $data_hoje, $data_teste6) . "\n";

The output is:

#ff0000
#e01e00
#b94500
#6c9200
#1ee000
#00ff00

This translates into these colors:

See here working on ideone.

    
04.05.2018 / 22:39
3

Oops, I think I can give you a light for your problem.

In the example below, I had a uniform gradient printed, but you can make your gradient the way you need it. You just need to keep in mind that you will need to calculate a rate of how close to the date you want to color is from the end date, imagining that your starting date will have value 0 and your end date will have value 1. Then a date in the exact middle between these two will be 0.5.

With this in mind, in the example will print the% color% color of the color relative to this initial and final color distance rate.

<?php
function getValorDaCor($color) {
    // Assumindo cores no formato #xxxxxx
    return array(
        hexdec(substr($color, 1, 2)),
        hexdec(substr($color, 3, 2)),
        hexdec(substr($color, 5, 2)),
    );
}

function getCorDoValor($array) {
    return sprintf('#%02x%02x%02x', $array[0], $array[1], $array[2]);
}

$cor_inicial = "#ff6347";
$cor_final = "#0066CC";
$valor_cor_inicial = getValorDaCor($cor_inicial); //array
$valor_cor_final = getValorDaCor($cor_final); //array

for( $i=0 ; $i<=1 ; $i+=0.05 ){
    $index = $i; // taxa de quão mais perto da cor final você está

    // Inicio das contas para calcular nova cor
    $novo_valor_1 = array();
    foreach ($valor_cor_inicial as $posicao => $valor) { 
        $novo_valor_1[$posicao] = $index * $valor;
    }

    $novo_valor_2 = array();
    foreach ($valor_cor_final as $posicao => $valor) { 
        $novo_valor_2[$posicao] = (1 - $index) * $valor;
    }

    $newval = array();
    foreach ($novo_valor_1 as $posicao => $valor) { 
        $newval[$posicao] = $valor + $novo_valor_2[$posicao];
    }
    // Fim das contas para calcular nova cor

    $nova_cor = getCorDoValor($newval);

    echo "<span style='color:".$nova_cor."'>AAA</span>";
}

?>
    
04.05.2018 / 22:38