Home > OS >  Getting Multiple Distinct Colors
Getting Multiple Distinct Colors

Time:12-20

I have a line chart that allows multiple lines to appear on the same chart depending on the items. However, the amount of items is different as it is based on individuals. Therefore, I would need to have get distinct colors for all the items. The users can pick which items to be visible on the chart. Therefore, the amount of colors needed will be increased when the user picking more items to be visible. As the amount of colors increases, each color should be distinct and distinguishable at first but gradually become similar to each other. Would like to know whether there is a library or segment of code to achieve the objective above?

CodePudding user response:

One method I thought of:

If you go around the HSV color wheel at equal intervals then you get distinct colors. HSV are in the range of [0,1]. Set Saturation and Value to 1 unless you need more than a few dozen colors.

HSV color cylinder

Method to create an array of the amount of colors you would like:

const colorCount = 24;
const dh = 1 / colorCount;
let colors = [];
for(let i=0;i<colorCount;i  ) {
     let rgb = HSVtoRGB(dh*i,1,1);
     colors.push(rgb);
}

// And our helper function:

/* accepts parameters
 * h  Object = {h:x, s:y, v:z}
 * OR 
 * h, s, v
*/
function HSVtoRGB(h, s, v) {
    var r, g, b, i, f, p, q, t;
    if (arguments.length === 1) {
        s = h.s, v = h.v, h = h.h;
    }
    i = Math.floor(h * 6);
    f = h * 6 - i;
    p = v * (1 - s);
    q = v * (1 - f * s);
    t = v * (1 - (1 - f) * s);
    switch (i % 6) {
        case 0: r = v, g = t, b = p; break;
        case 1: r = q, g = v, b = p; break;
        case 2: r = p, g = v, b = t; break;
        case 3: r = p, g = q, b = v; break;
        case 4: r = t, g = p, b = v; break;
        case 5: r = v, g = p, b = q; break;
    }
    return {
        r: Math.round(r * 255),
        g: Math.round(g * 255),
        b: Math.round(b * 255)
    };
}

Sources: Javascript convert HSB/HSV color to RGB accurately

CodePudding user response:

Try something like this:

Method 1: returns a random colour represented by an rgb() colour value. Downside with this method: because the colours are random, you can get very different colours but also very similar ones. If you want a more strict way of generating colours which are equally spaced on the colour wheel, see Method 2.

function randomColour() {
    return `rgb(${Math.round(Math.random() * 255)}, ${Math.round(Math.random() * 255)}, ${Math.round(Math.random() * 255)})`;
}

use:

let colOne = randomColour();
// colOne = "rbg(236, 174, 254)"

let colTwo = randomColour();
// colTwo = "rbg(47, 83, 164)"

let colThree = randomColour();
// colThree = "rbg(145, 214, 39)"

Method 2

function generateColours(quantity) {
    let colours = [];
    for (let i = 0; i < quantity; i  ) {
        colours.push(`hsl(${(360/quantity)*(quantity-i)}, 80%, 50%)`);
    }
    return colours;
}

use

let coloursArr = generateColours(5);

// coloursArr = [
//     'hsl(360, 80%, 50%)', 
//     'hsl(288, 80%, 50%)', 
//     'hsl(216, 80%, 50%)', 
//     'hsl(144, 80%, 50%)', 
//     'hsl(72, 80%, 50%)'
// ]

Colours are equally distinguishable.

  • Related