50 Shades of Hue

I was just reading a post called A Quick ‘n Dirty Color Sequence from an Apple developer named Peter Ammon over at blog called ridiculousfish.com.  It was an interesting way to get distinguishable color sequences for things like bar graphs.  He explains bisecting the regions of the color wheel to determine distinct distant colors.  This doesn’t take into other considerations like colorblindness, print-friendly, and photo-copy-able.  For those color selections, you’re best bet is to check out  Color Brewers for maps.

The code was designed to calculate Nth hues on a color circle (saturation and light disregarded).  I thought it would be interesting to see how to use this for anything besides the example he had on this page. So, I took his code and just adjusted it.

var DistinctColorManager = function (options) {
    var saturation = "100%",
        lightness = "60%",
        next_hue = 0,
        degrees = 0.6,
        pctRegex = /^(100|([1-9]?[0-9]{1}))%$/,
        degressRegex = /^d+$/,
        me = this;

    options = options || {};
    lightness = options.lightness || lightness;
    saturation = options.saturation || lightness;

    function validatePercentage(val) {
        return pctRegex.test(val);
    }

    function get_hue(idx) {

        /* Here we use 31 bit numbers because JavaScript doesn't have a 32 bit unsigned type, and so the conversion to float would produce a negative value. */
        var bitcount = 31;

        /* Reverse the bits of idx into ridx */
        var ridx = 0,
            i = 0;
        for (i = 0; i < bitcount; i++) {
            ridx = (ridx << 1) | (idx & 1);
            idx >>>= 1;
        }

        /* Divide by 2**bitcount */
        var hue = ridx / Math.pow(2, bitcount);

        /* Start at .6 (216 degrees) */
        return (hue + degrees) % 1;
    }
    return {
        resetHueIndex: function () {
            next_hue = 0;
        },
        setHueIndex: function (val) {
            next_hue = (typeof val === 'undefined' || parseInt(val,10) === NaN) ? next_hue : parseInt(val, 10);
        },
        setSaturation: function (val) {
            if (pctRegex.test(val)) {
                saturation = val;
            }
        },
        setDegrees: function (val) {
            if (degressRegex.test(val)) {
                degrees = (parseInt(val, 10) / 350);
            }
        },
        setLightness: function (val) {
            if (pctRegex.test(val)) {
                lightness = val;
            }
        },
        getCurrentHueIndex: function () {
            return next_hue;
        },
        getHSL: function () {
            var hue = Math.round(get_hue(next_hue++) * 360);
            hsl = 'hsl(' + hue + ',' + saturation + ',' + lightness + ')';
            return hsl;
        }

    };
};

The above code is a class that allows controll over the hue, saturation, and light. I also added a set property for changing the degrees starting point (the default is 0). To set parameters, you can pass in an object literal for the options like:


var oDCM = DistinctColorManager({saturation: '20%',lightness:'60%'}); 

The following is a usage example:

The color distinction is great for separation of data points.