2011-07-25 25 views
19

¿Cuál es la mejor manera de elegir los colores al azar de un gráfico de barras/histograma de tal manera que cada color es diferente de la otra .. y, posiblemente, en contrastecolores Crear únicos usando javascript

los más hablado de forma es

'#'+(Math.random()*0xFFFFFF<<0).toString(16); 

pero esto puede generar colores similares .. ya veces distinguiéndolos puede ser un problema .. Ejemplo enter image description here

+1

Cualquier método para elegir colores aleatorios a veces va a generar colores similares. Si nunca desea que sean similares, prepare una lista de colores adecuados y selecciónela (al azar si lo desea). –

+2

La razón más importante por la que no desea utilizar el método sugerido es que lo que las personas perciben visualmente como el espectro de color no es linealmente proporcional al espectro de color hexadecimal. Es por eso que los ["colores web seguros"] (http://www.w3schools.com/html/html_colors.asp) no se parecen en nada a un arcoiris. – Nicole

+1

http://phrogz.net/tmp/24colors.html – Phrogz

Respuesta

8

La mejor manera es convertir de HSV values. Puede dividir el valor máximo de "Tono" por la cantidad de colores que necesita y luego aumentar este resultado.

Para un mejor contraste, también puede alternar entre valores de luminosidad altos y bajos.

+3

Sin embargo, como dice @Renesis, dividir el tono de forma pareja no es lo mismo que elegir colores visualmente distintos: somos mucho menos sensibles a las variaciones de verde en comparación con nuestro sensibilidad a rojo y (en menor medida) azul. Diferenciar hierbas y hojas es menos importante que ver el fuego. – Phrogz

+0

Buen punto, este método solo es válido si necesita una pequeña cantidad de colores diferentes. – slaphappy

3
'#'+(Math.random()*0xFFFFFF<<0).toString(16); 

no es el mejor método a utilizar, ya que puede generar valores como #4567 que le falta dos dígitos en lugar de generar # 004567

Es mejor recoger cada personaje individualmente como:

'#'+Math.floor(Math.random()*16).toString(16)+ 
    Math.floor(Math.random()*16).toString(16)+ 
    Math.floor(Math.random()*16).toString(16)+ 
    Math.floor(Math.random()*16).toString(16)+ 
    Math.floor(Math.random()*16).toString(16)+ 
    Math.floor(Math.random()*16).toString(16); 

Pero eso se puede reducir fácilmente a elegir tres números ya que los colores hexadecimales pueden acortarse. ES DECIR. #457 == #445577

Entonces, si desea reducir el número de posibilidades y ensanchar la brecha entre ellos se puede utilizar:

'#'+(5*Math.floor(Math.random()*4)).toString(16)+ 
    (5*Math.floor(Math.random()*4)).toString(16)+ 
    (5*Math.floor(Math.random()*4)).toString(16); 

que divide el número de opciones para cada color por 5, y luego iguala la distribución por igual.

+0

Consulte mi comentario sobre la pregunta para obtener una explicación más larga, pero esto es malo, porque [colores seguros para la red] (http://www.w3schools.com/html/html_colors.asp) (colores divididos uniformemente entre los valores RGB) son feos . – Nicole

23

Generaría colores usando HSV (tono, saturación, valor) en lugar de RGB. En HSV, el color está definido por el matiz, que va de 0-360. Por lo tanto, si lo desea, p. 6 diferentes colores, puede simplemente dividir 360 por 5 (porque queremos incluir 0) y obtener 72, por lo que cada color debe incrementarse con 72. Use una función como this one para convertir el color HSV generado a RGB.

La siguiente función devuelve una matriz de total colores diferentes en formato RGB. Tenga en cuenta que los colores no serán "aleatorios" en este ejemplo, ya que siempre van desde el rojo al rosa.

function randomColors(total) 
{ 
    var i = 360/(total - 1); // distribute the colors evenly on the hue range 
    var r = []; // hold the generated colors 
    for (var x=0; x<total; x++) 
    { 
     r.push(hsvToRgb(i * x, 100, 100)); // you can also alternate the saturation and value for even more contrast between the colors 
    } 
    return r; 
} 
+2

+1, pero no soy seguidor del nombre de la función, como dices, no hay asignación aleatoria. – UpTheCreek

+1

Aquí hay un [JSFiddle mostrando la implementación] (https://jsfiddle.net/aldass/9f0yadfy/) arriba. He hecho algunas pequeñas modificaciones. –

1

Secundo lo kbok y Harpyon dicen sobre su trabajo en el espacio de color HSV, y this little library hace que sea muy fácil de cambiar entre RGB y HSV - y otros.

2

Me gusta usar valores de hsl para especificar el color de esta manera.

Así

"color: hsl(" + getRandomArbitary(0, 360) + ", 50%, 50%)"; 

le daría resultados aleatorios, pero que no le dará sus distintas separaciones. Así que lo basaría en el valor i de un ciclo.Algo como,

for (var i = 0; i < whateverYourValue; i += 1) { 
    color = "color: hsl(" + i * 10 + ", 50%, 50%)"; 

    // set your colour on whatever 
} 

obviamente, lo anterior es indicativo, y no es un código válido por sí mismo.

¿Quieres más información sobre hsl? Comprueba http://mothereffinghsl.com/ porque, ya sabes, es divertido.

4

Las respuestas existentes que mencionan el tono, la saturación, la representación del valor de los colores son muy elegantes, están más cerca de cómo los humanos perciben el color, y probablemente sea mejor seguir sus consejos. También crear una larga lista precalculada de colores y elegir subconjuntos de ellos según sea necesario es rápido y confiable.

Sin embargo, aquí hay un código que responde a su pregunta directamente: generará colores aleatorios en RGB que son lo suficientemente diferentes. Hay dos inconvenientes en esta técnica que puedo ver. En primer lugar, estos colores son realmente aleatorios y pueden parecer bastante burdos, y segundo, puede llevar un tiempo que el código tropiece con los colores que funcionan, dependiendo de cuán "lejanos" requiera que sean los colores.

function hex2rgb(h) { 
    return [(h & (255 << 16)) >> 16, (h & (255 << 8)) >> 8, h & 255]; 
} 
function distance(a, b) { 
    var d = [a[0] - b[0], a[1] - b[1], a[2] - b[2]]; 
    return Math.sqrt((d[0]*d[0]) + (d[1]*d[1]) + (d[2]*d[2])); 
} 
function freshColor(sofar, d) { 
    var n, ok; 
    while(true) { 
     ok = true; 
     n = Math.random()*0xFFFFFF<<0; 
     for(var c in sofar) { 
      if(distance(hex2rgb(sofar[c]), hex2rgb(n)) < d) { 
       ok = false; 
       break; 
      } 
     } 
     if(ok) { return n; } 
    } 
} 
function getColors(n, d) { 
    var a = []; 
    for(; n > 0; n--) { 
     a.push(freshColor(a, d)); 
    } 
    return a; 
} 

La distancia entre los colores es la Euclidean distance medida por los componentes B R, G, y. Por lo tanto, lo más lejos que pueden estar dos colores (blanco y negro) es aproximadamente 441.67.

Para usar este código, llame al getColors donde el primer parámetro es el número de colores, y el segundo es la distancia mínima entre dos de ellos. Devolverá una matriz de valores RGB numéricos.

Cuestiones relacionadas