automatic color codes from red to green

Greetings,
I have to plot a bunch of dots on a chart.

Each dot can have a standard html color.
Each dot has a number assigned to it.

I do not know how many dots there will be until the search is complete.

What I want is to have the dot with the highest number be red, avg be yellow, and lowest be blue.  

how do I calculate the color codes to span between red to yellow to blue divided by the number of dots?

Thanks much.
LVL 9
Evan CutlerVolunteer Chief Information OfficerAsked:
Who is Participating?
 
Ray PaseurCommented:
The color values are as follows:
Red = rgb 255, 0, 0 = #FF 00 00
Yellow = rgb 255,255,0 = #FF FF 00
Blue = rgb 0,0,255 = #00 00 FF

The color blending is problematic because as you blend arithmetically from yellow to blue, the RGB values take you through gray.  Thud. This is not the way we think about colors (we think spectrally, that green is between yellow and blue).  If you make the color scheme red-yellow-green the blending works better visually, I think.
Numeric color belnding from red, through yellow, to blueTo get a distribution you might use some code like this, which distributes the data into thirds (to get quartiles, change the URL to n=4, to get stanines, change the URL to n=9, etc).  To choose a color, or a blend of colors, you might consider the position of each data element along the distribution.
http://www.laprbass.com/RAY_quantiles.php?n=3

Hope this helps you consolidate your thinking about how to build the application.  If you have any questions, please post back and I'll try to help.  Best regards, ~Ray

<?php // RAY_quantiles.php
error_reporting(E_ALL);
echo "<pre>";


// DEMONSTRATION SCRIPT FOR "QUANTILES": QUARTILES, QUINTILES, DECILES, PERCENTILES, ETC.


// MAN PAGE REFERENCES
// http://bmj.bmjjournals.com/cgi/content/full/309/6960/996
// http://cancerweb.ncl.ac.uk/cgi-bin/omd?query=quantile&action=Search+OMD
// http://en.wikipedia.org/wiki/Quantiles
// RELATED: http://en.wikipedia.org/wiki/Stanine

// ALGORITHM:
//    CREATE A DATA MODEL - ASSOCIATIVE ARRAY OF KEYS AND VALUES
//    SORT ORDERED FROM HIGHEST TO LOWEST
//    COUNT THE ARRAY
//    DIVIDE BY QUANTILE NUMBER GIVING THE ELEMENTS PER GROUP IN EACH QUANTILE
//    WALK THE ARRAY, MARKING THE FIRST QUANTILE WITH A "1", THE SECOND QUANTILE WITH A "2", ETC
//    FIND THE ARRAY ELEMENT WITH THE INDICATED KEY
//    DISPLAY THE NUMBER THAT INDICATES ITS QUANTILE

// OUR TEST DATA MODEL MIGHT COME FROM A DATA BASE
$raw_data = array();
$raw_data['A'] = 1;
$raw_data['B'] = 2;
$raw_data['C'] = -3;
$raw_data['D'] = 4;
$raw_data['E'] = 5;
$raw_data['F'] = -6;
$raw_data['G'] = 7;
$raw_data['H'] = 8;
$raw_data['I'] = -9;
$raw_data['J'] = 10;
$raw_data['K'] = 11;
$raw_data['L'] = -12;
$raw_data['M'] = 13;
$raw_data['N'] = 14;
$raw_data['O'] = -15;
$raw_data['P'] = 16;
$raw_data['Q'] = 17;
$raw_data['R'] = -18;
$raw_data['S'] = 19;
$raw_data['T'] = 20;
$raw_data['U'] = 21;
$raw_data['V'] = 22;
$raw_data['W'] = 23;
$raw_data['X'] = 24;
$raw_data['Y'] = 25;
$raw_data['Z'] = 6;

// USE THE URL ARGUMENT OR CHOOSE A RANDOM LETTER
if (isset($_GET["q"]))
{
    $element = trim(strtoupper($_GET["q"]));
}
else
{
    $x = range('A', 'Z');
    shuffle($x);
    $element = current($x);
}

// USE THE URL ARGUMENT OR CHOOSE QUARTILES
$num = (isset($_GET["n"])) ? $_GET["n"] : 4;

// SORT THE DATA
arsort($raw_data);

// COUNT THE DATA
$kount = count($raw_data);
$tiles = intval(ceil($kount / $num));

// COPY THE ARRAY INSERTING THE QUANTILES
$quantiles = array();
$my_tile   = 1;
$my_tiles  = $tiles;
$negs = $pozs = 0;
foreach ($raw_data as $key => $val)
{
    if ($val < 0) $negs++;
    if ($val > 0) $pozs++;
    $quantiles[$key] = $my_tile;
    $my_tiles--;
    if ($my_tiles == 0)
    {
        $my_tiles = $tiles;
        $my_tile++;
    }
}

// REPORT THE STATISTICS

echo PHP_EOL . "COUNT OF ELEMENTS IN OUR DATA MODEL = $kount";
echo PHP_EOL . "COUNT OF NEGATIVE VALUES = $negs";
echo PHP_EOL . "COUNT OF POSITIVE VALUES = $pozs";
echo PHP_EOL . "NUMBER OF SUBSETS = $num";
echo PHP_EOL . "ELEMENTS PER SUBSET = $tiles";

echo PHP_EOL . "THE QUANTILE FOR $element IS {$quantiles[$element]}";
echo PHP_EOL;

// VISUALIZE THE GROUPED DATA
$n = 1;
foreach ($raw_data as $key => $val)
{
    if ($quantiles[$key] > $n)
    {
        $n = $quantiles[$key];
        echo PHP_EOL;
    }
    echo PHP_EOL . "$key $quantiles[$key] $val";
}

Open in new window

0
 
Ray PaseurCommented:
The general design pattern is to "normalize" the values of the dots.  It might be helpful to see how you have numbered the dots.  Can you please post a representative list of dots along with the data that the dot represents?  Once we can see the data continuum we may be able to help.  Also if you have written any code toward the solution, please post that, too.

This would be a bit easier if you were using the red-green-blue scheme instead of red-yellow-blue.  Just a thought in case you have some ability to affect the design pattern.
0
 
Evan CutlerVolunteer Chief Information OfficerAuthor Commented:
Hi Ray,
I wont' know that.

What I have is an audit log that I am querying.  It his locations visited, who visited it, and when.

When I query this table.  i will submit a location (or series of them), and two dates to go between.

The output will look something like:

Hospital               Doctor              Visits
===============================
1                              24                    1
1                             123                   2
2                              22                    1
2                              152                  3

And so on.

Using a MySQL query from PHP, I can order by Number of visits, and then determine how many by the NUM_AFFECTED_ROWS from the query.

THis is where I need to derive my colors.

If the query results in 1, 10, 150 returns...that's when I'll know.

Thanks for looking into this.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
Dushan De SilvaTechnology ArchitectCommented:
Lets say highest number is 900.
Example thresholds like:
900-600   : red
 600-300  : yellow
 300-0      : blue

y =255/(900-600) = 255/(600-300) =255/(300-0)

if(number>900)
then color=rgb((y*number) , (255 - y*number) , (255 - y*number)

if(number<600 && number>300)
then color=rgb((255 - y*number) , (y*number)  , (y*number) )

if(number<300)
then color=rgb(255 - y*number) , (255 - y*number)  , (y*number) )
0
 
Evan CutlerVolunteer Chief Information OfficerAuthor Commented:
awesome...
can you do that in html colors?
0
 
Dushan De SilvaTechnology ArchitectCommented:
0
 
Dushan De SilvaTechnology ArchitectCommented:
Sorry it should correct as
-------------------------------------------------------------------------------------------------------------------------------------------
y =255/(900-600) = 255/(600-300) =255/(300-0)

if(number<=900  && number>600)
then color=rgb((y*(number-600)) , (255 - y*(number-600)) , (255 - y*(number-600)))

if(number<=600 && number>300)
then color=rgb((255 - y*(number-300)) , (y*(number-300))  , (y*(number-300)) )

if(number<=300)
then color=rgb(255 - y*number) , (255 - y*number)  , (y*number) )
-------------------------------------------------------------------------------------------------------------------------------------------
0
 
Evan CutlerVolunteer Chief Information OfficerAuthor Commented:
Thanks guys...<br />This definately helped.<br /><br />Both solutions are great.<br />Most appreciated.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.