Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


Tip of the Day
Language: Java
Expertise: Beginner
Mar 8, 1999

Generating a Series of Unique Colors

Graphs, charts, and maps often use color to help the user tell data points apart. For instance, a line graph comparing processor benchmarks might show the Motorola processor in red, the Intel processor in blue, the Sun processor in green, and so on. For small, fixed data sets (about 10 or less), there's no problem in specifying the color coding at compile time in order to get the right look and to ensure that the colors are unique. But what if the data sets are neither small nor fixed? For instance, let's say you could have anywhere from 2 to 50 data sets, and you won't know exactly how many sets there will be until the program actually runs. Surely there exists some algorithm that could choose the color coding for you--at run time--and choose it in such a way that the colors are as unique and easy to distinguish as possible.

I pondered this problem and wasted a few hours trying to figure out how to iterate through red, green, and blue values to get an even distribution of unique colors. Then, as I was playing around with the Color Chooser component of the Swing framework, I happened to notice that the HSB panel (hue, saturation, and brightness) of the chooser displayed exactly what I was trying to create: a rainbow of colors. It showed a brightly colored bar that gradually changed from red, to yellow, to green, to cyan, to blue, and to violet. Upon closer inspection, I realized that the bar had not been generated through some complex algorithm, but merely by iterating through the range of possible values for the hue.

With this information in hand, I was able to create a color generation algorithm. This algorithm creates an array of unique, evenly distributed colors by keeping the saturation and brightness levels constant while sliding the hue level. On each iteration of the loop, it passes these values to the Color.getHSBColor() method which returns a standard java.awt.Color object representing those levels. Notice that although the true range of the hue level goes from 0.0 to 1.0, I have adjusted the range in the algorithm to go from 0.0 to 0.85. This eliminates the problem of similar colors due to the wrapping of the color spectrum. Also, because the spectrum of hue levels gives extra space to red, blue, and green values, I have hacked the algorithm to alternate between light and dark versions of the same hue, producing a more fully distributed range of colors. For these reasons, the algorithm isn't perfect, but it works well enough for most purposes.

 
/**
Generates a series of colors such that the
distribution of the colors is (fairly) evenly spaced
throughout the color spectrum. This is especially
useful for generating unique color codes to be used
in a legend or on a graph.

@param numColors the number of colors to generate
@return an array of Color objects representing the
colors in the table
*/
private Color[] createColorCodeTable(int numColors)
{
   Color[] table = new Color[numColors];

   if (numColors == 1)
   {
      // Special case for only one color
      table[0] = Color.red;
   }
   else
   {
      float hueMax = (float) 0.85;
      float sat = (float) 0.8;

      for (int i = 0; i < numColors; i++)
      {
         float hue = hueMax * i / (numColors-1);

         // Here we interleave light colors and dark colors
         // to get a wider distribution of colors.
         if (i % 2 == 0)
            table[i] = Color.getHSBColor(hue, sat, (float)0.9);
         else
            table[i] = Color.getHSBColor(hue, sat, (float)0.7);
      }
   }

   return table;
}
Trevor Harmon
 
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date