为条形图/直方图选择随机颜色的最佳方法是什么,这样每种颜色都与其他颜色不同......并且可能具有对比度
最受关注的方式是
'#'+(Math.random()*0xFFFFFF<<0).toString(16);
但这可以生成相似的颜色..有时区分它们可能是一个问题..
例子
我会使用
HSV
(色调、饱和度、值)而不是 RGB 来生成颜色。在 HSV 中,颜色由色调定义,范围为 0-360。因此,如果您想要例如6
不同的颜色,您可以简单地将360
除以5
(因为我们要包括0
)并得到72
,因此每种颜色都应以72
递增。使用像 this one 这样的函数将生成的 HSV 颜色转换为 RGB。
以下函数返回 RGB 格式的
total
不同颜色的数组。请注意,在此示例中,颜色不会是“随机”的,因为它们的范围始终从红色到粉色。
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;
}
最好的方法是从 HSV 值进行转换。您可以将“色调”的最大值除以您需要的颜色数量,然后按此结果递增。
为了提高对比度,您还可以在高亮度值和低亮度值之间交替。
提到颜色的色相、饱和度、值表示的现有答案非常优雅,更接近人类感知颜色的方式,最好遵循他们的建议。此外,创建一个长的预先计算的颜色列表并根据需要选择它们的子集是快速且可靠的。
但是,这里有一些代码可以直接回答您的问题:它将生成足够不同的 RGB 随机颜色。我发现这种技术有两个缺点。首先,这些颜色确实是随机的,放在一起可能看起来有点恶心,其次,代码可能需要一段时间才能找到有效的颜色,具体取决于您需要颜色的“距离”。
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;
}
颜色之间的距离是通过 R、G 和 B 分量测量的欧几里得距离。因此,两种颜色(黑色和白色)的最远距离约为 441.67。
要使用此代码,请调用
getColors
,其中第一个参数是颜色数量,第二个参数是任意两个颜色之间的最小距离。它将返回一个 RGB 数值数组。
我喜欢使用 hsl 值以这种方式指定颜色。
那么
"color: hsl(" + getRandomArbitary(0, 360) + ", 50%, 50%)";
会给你随机结果,但这不会给你你独特的分离。所以我将其基于循环的 i 值。比如,
for (var i = 0; i < whateverYourValue; i += 1) {
color = "color: hsl(" + i * 10 + ", 50%, 50%)";
// set your colour on whatever
}
显然上述内容是指示性的,其本身并不是有效的代码。
想了解更多关于 hsl 的信息吗?检查 http://mothereffinghsl.com/ 因为,你知道,这很有趣。
'#'+(Math.random()*0xFFFFFF<<0).toString(16);
这不是最好的方法,因为它可以生成像
#4567
这样缺少两位数字的值,而不是生成 #004567
最好单独选择每个角色,例如:
'#'+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);
但是,由于可以缩短十六进制颜色,因此可以轻松减少为选择三个数字。 IE。
#457
==#445577
然后,如果您想减少可能性的数量并扩大它们之间的差距,您可以使用:
'#'+(5*Math.floor(Math.random()*4)).toString(16)+
(5*Math.floor(Math.random()*4)).toString(16)+
(5*Math.floor(Math.random()*4)).toString(16);
将每种颜色的选择数量除以 5,然后均匀分布。
我赞同 kbok 和 Harpyon 关于在 HSV 色彩空间中工作的说法,并且 这个小库使得在 RGB 和 HSV 以及其他颜色空间之间切换变得非常容易。
常量颜色 =
rgb(${(e.key.charCodeAt(0))}, ${(e.key.charCodeAt(0))}, ${(e.key.charCodeAt(0))})
;