Categories
technical

Concerning Color Algorithms

Long ago I worked on an interface for a reporting system that displayed transaction volume data as a large table; days on one axis and hours on the other.  To improve the readability of this densely packed data we wrote a coloring algorithm to change the background color of the table cell.  The algorithm colored each cell in relation to every other cell using the minimum and maximum values of the displayed data.  The effect was quite good.  Users could instantly see patterns in the data without having to read the actual number in the cells.  This data display, though simple was one of the main selling points of the system.  End-users like the sexy packaging, the unseen technology that actually makes the system a wonder is only of interest to the developers—unless of course it does not work.

I spent a lot of time improving the UI of the system as a project once, and when my CTO asked me what I was going one day I said “optimizing the color algorithm”—that was a mistake.  I didn’t sleep for the next 6 months as I was assigned the new, high priority, has-to-be-done-now project.  For a new technology, that I had no idea how it worked.  It was fun, but that’s a story for another day. The reason I raise this here is that I never finished the intended work on the color algorithm. One of the major goals that I never got to was to fix the color range. The algorithm as implemented ended up with colors that transitioned from purple to yellow. I wanted to improve the algorithm to output colors that transitioned from red through yellow to green. Never got done.

Recently I was working on a project that required some visual UI work. One of the elements was a bar chart that displayed volume over time. So I used the same-old, same-old color algorithm (in PHP):

/*
* getColor()
* $max := the highest value in the set to be colored.
* $min := the lowest value in the set to be colored.
* $c := the current item's value.
*
* Returns a string; the HEX representation of an RGB color.
*/
function getColor( $max, $min, $c) {
   $j=0;
   $r=0;
   $g=0;
   $b=0;

   $j = $max != $min ? ( $c - $min ) * 20 / ( $max - $min) : 0;
   $j = $j > 20 ? 20 : $j;

   $r = 5 + $j;
   $r = $r > 15 ? 15 : $r;

   $g = 5 + $j/2;
   $g = $g > 15 ? 15 : $g;

   $b = 10 - $j/2;
   $b = $b > 0 ? 0 : $b;

   return sprintf( "%01x%01x%01x%01x%01x%01x", $r,$r,$g,0,$b,0 );
}
Old getColor output

Simple right? Well using that you end up with this:

So I started scratching my itch to fix the colors.

My first thought was to just ask a question over at StackOverflow [stackoverflow.com]. As I was typing in my question the system suggested existing questions… and since it’s an SO faux pas to repeat questions I started looking at them. It didn’t take long before I found two questions that seemed to be pointing me in the right direction: 1. Generate colors between red and green for a power meter [stackoverflow.com] and 2. Color scaling function [stackoverflow.com].

Reading the answers to those questions it took about 30 minutes to do this:

/*
* getColor()
*
* $max := the highest value in the set to be colored.
* $min := the lowest value in the set to be colored.
* $c := the current item's value.
*
* Returns a string; the RGB representation of a color (eg. "rgb(255, 255, 255)").
*/
function getColor( $max, $min, $c) {
   $h = (.33 / ($max - $min)) * ($c - $min);
   $s = .8;
   $v = 1;

   $rgb = hsv2rgb($h, $s, $v);

   return(sprintf("rgb(%d,%d,%d)", $rgb['r'], $rgb['g'], $rgb['b']));
}

/*
* hsv2rgb()
*
* $h := the hue, normalized to 0-1.
* $s := the saturation, normalized to 0-1.
* $v := the value, normalized to 0-1.
*
* Returns an associative array containing the red ('r'), green ('g') and blue ('b') values in the range 0-255.
*/
function hsv2rgb ($h, $s, $v){
   $rgb = array();

   if($s == 0){
      $r = $g = $b = $v * 255;
   } else {
      $var_h = $h * 6;
      $var_i = floor( $var_h );
      $var_1 = $v * ( 1 - $s );
      $var_2 = $v * ( 1 - $s * ( $var_h - $var_i ) );
      $var_3 = $v * ( 1 - $s * (1 - ( $var_h - $var_i ) ) );

      if ($var_i == 0) { $var_r = $v ; $var_g = $var_3 ; $var_b = $var_1 ; }
      else if ($var_i == 1) { $var_r = $var_2 ; $var_g = $v ; $var_b = $var_1 ; }
      else if ($var_i == 2) { $var_r = $var_1 ; $var_g = $v ; $var_b = $var_3 ; }
      else if ($var_i == 3) { $var_r = $var_1 ; $var_g = $var_2 ; $var_b = $v ; }
      else if ($var_i == 4) { $var_r = $var_3 ; $var_g = $var_1 ; $var_b = $v ; }
      else { $var_r = $v ; $var_g = $var_1 ; $var_b = $var_2 ; }

      $r = $var_r * 255;
      $g = $var_g * 255;
      $b = $var_b * 255;
   }

   $rgb['r'] = $r;
   $rgb['g'] = $g;
   $rgb['b'] = $b;

   return $rgb;
}

And…. voila:

New getColor output

That’s great! Now maybe I’ll play with the hue bounds, the saturation and the value, but it looks fairly good on my first try.

Moral of the story: this is what StackOverflow is for; getting an answer to a question without even asking it… Because you are not re-inventing the wheel, someone had your problem before, and maybe someone found the answer already. SO, thanks to Paul Dixon [stackoverflow.com] (also here [blog.dixo.net]) and ΤΖΩΤΖΙΟΥ [stackoverflow.com] for their answers!

Categories
ranting

Published 2

I’ve been published; [confusion.cc] again… This time by the Norwegians:

Delte Meninger

I don’t read Norwegian but judging from the website [deltemeninger.no], it’s something to do with ‘the social web’. My photo (here on Flickr [flickr.com]) appears on page 37. Funny that neither this photo nor the one chosen for the cover of Vocabulaire du chinois contemporain 1 are ones I would consider to be among my best [flickr.com].

Interesting that the published cover above (scanned from the book I got) differs from the cover distributed with the ebook in HTML format here [f9.no].

Categories
ranting

One small step

Buzz Aldran's boot print on the moon.

It’s not Armstrong’s [wikipedia.org] “one small step” footprint, it’s a later footprint by Buzz Aldrin [wikipedia.org] but it is from the Apollo 11 mission.

That was 40 years ago today… shouldn’t I be able to make one by now?

Categories
ranting

The sidewalk incident

This is another rant on the lack of common courtesy in the world, in general and in Singapore in particular… so if you are tired of listening to me complain about how fucked up most people are… move along and ponder the rainbow puking panda of explore… [flickr.com].

Still with me?

Good.  Let me set the stage… Candice and I took Victoria for a walk last night, we do this most nights—well maybe not most but a lot.  On our walk we traverse a long sidewalk along a plot of undeveloped land that is quite old and not very wide.  Two people can walk side by side comfortably but no extra room.  Additionally it has been quite wet in Singapore recently, raining often so the ground, while not muddy was wet.

Now for some visual help in explaining this particular fuck-headed rude behavior, yes I’m a geek I made a picture to help explain…:

The sidewalk incident as it happened.

As Candice, Victoria and I walked along said sidewalk another couple, a teenage girl and guy, approached us headed in the opposite direction.  This can be seen in step 1 of the figure above.  Nothing wrong with this, both the guy and I are walking next to our respective partners.  This makes conversation easier.  In this case the couple approaching us was even walking to their left—the appropriate orientation when walking in Singapore another oft-ignored guideline.

In step 2 you can see that both the guy and I have moved to our lefts.  I have moved further but he has begun to move left to allow for Candice, Victoria and I to pass on the right.  Great.

The problem, shown in step 3, is that he did not continue his move to the left.  Rather than getting behind the girl (or in front) for 30 seconds to allow us to pass easily, he was so obsessed with standing next to his girl that he managed to take up most of the sidewalk, thus forcing Candice and I to stop and wait or move off the sidewalk or… I don’t even know what he expected… But this is what he go:

“Get the fuck to the left you dip shit.  Have some fucking common courtesy and let other people use the sidewalk”

He kind of stared at me like a fish out of water… mouth opening slowly and eyes unable to focus.  We walked on.

The girl said something rude a few second later so I yelled back “shut the fuck up.”

As a side note my asshole attitude in cases like this has been developed after 4+ years in Singapore dealing with people who are so programmed by the nanny state in so many aspects of their life that they can’t think on their own and have therefore lost all common courtesy and common sense.  I used to be much nicer about things like this —I’ve always complained about dip shits but now I’m like a Manhattanite…  Cussing at them releases my frustration and they are so brain dead it can’t hurt them.

The sidewalk incident as it should have happened

Anyway, in the interest of public service this is how it should have happened:

See?  Now we can pass each other with nary-a-problem, birds sing, babies laugh and the soft light of the sun shines down and a happy ending.

Maybe I’ll diagram the proper way to not-be-that-asshole-trying-to-shove-their-way-on-the-train-before-people-can-get-off for everyone’s benefit.  And what about the I-can’t-be-bothered-to-watch-where-I-am-going-because-I-am-too-busy-(playing a game on my DS/PSP or texting or watching something on my PMP) issue that seems to be so in vogue?  Well, I’m not saying there is a problem with this behavior but let’s take all the manhole covers off and see if the problem fixes itself [telegraph.co.uk].

Categories
ranting

Going Digital…

So, I got an email today from Amazon… The Economist [economist.com] is now available as a digital subscription on the Kindle [amazon.com]… Too bad it only works the US. If it worked outside the US, even it it was only sold in the US but worked on WiFi or GSM I would buy one. Actually I might have already bought one, but the savings on my Economist subscription would be enough to justify the purchase for me.

I might still buy one when my current Economist subscription is up for renewal at the end of the year. Hopefully the Kindle goes global by then, or better yet Apple [apple.com] releases a 7″ or 10″ iPod Touch (and Amazon releases the Kindle software on for it like they did for the iPhone.)

As much as I like having physical books and magazines I don’t have the space to have the library I would like. And the idea of moving to an all, or mostly, digital existence, at least with regards to music, movies, books and magazines, appeals to me for several reasons. One the the biggest concerns I have had with most e-book readers is the inability to highlight and makes notes, the Kindle has solved this. If only there was a way to digitize my existing library as I have done with my CDs. This is a problem waiting to be solved. Trade-ins maybe?

Now if only Mother Jones [motherjones.com] was available on the Kindle, I’d buy one tomorrow!

2009/07/07 – Update: Then again… maybe I should stay away from Amazon’s stuff.  Within a week of posting this they have done two things that make me think that maybe I don’t want to give them my money, not if they continue down this [slashdot.org] path [gizmodo.com] at least.