Colour tone of the record, for quantity

Asked

Viewed 79 times

2

I have a table with various records, and these have a field "date".

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

$dias = $data_hoje - $data_registro;

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

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

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

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

What I’d like to do is print the list, bringing the intensity of the colours, according to the days running in relation to the default value calculated. This intensity would be on the scale of the "gradient" of this color range.

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

I have to use decimal and then turn to hexa ? Or I can use hexa, or other form of colour ?

  • In JS you have this: https://answall.com/questions/97277/fun%C3%A7%C3%a3o-javascript-que-gera-cores-html

2 answers

2

Whoa, I think I can shed some light on your problem.

In the example below, I had a uniform gradient printed, but you can do your grading in any way necessary. You only need to keep in mind that you will need to calculate a rate of how close the date you want to color is to the final date, imagining that your initial date will be 0 and your final date will be 1. Then a date in the exact middle between these two will be 0.5.

Keeping this in mind, in the example will print the text AAA color related to this distance ratio of the initial and final colors.

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

?>
  • 1

    David, your answer worked, but Victor’s was simpler to implement by asking for an array. Even so, thank you very much. + 1

  • 1

    @RBZ For nothing, the intention is to help :D

2


First, let’s create a function that given a color that corresponds to the value 0, a color that corresponds to the value 1 and a value between 0 and 1, provide the corresponding color:

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

Colors should be shaped like #rrggbb where rr is the hexadecimal value of the red component, gg the green component and bb that of the blue component.

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

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 the point 0 and black the 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 exit is:

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

That is, on the way out gave these colors: 50 tons de cinza

Let’s try it with other colors. Red to 0 and green to 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 exit is:

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

That translates into those colors: vermelho verde

See here working on ideone.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.