我正在生成一些需要颜色十六进制字符串的图表。
例子:
<dataseries name="ford" color="FF00FF" />
我正在动态创建这些,所以我想为每个数据序列随机生成十六进制代码。
做这个的最好方式是什么?
最简单的方法是使用String.Format
和使用十六进制格式的参数。
var random = new Random();
var color = String.Format("#{0:X6}", random.Next(0x1000000)); // = "#A197B9"
塞缪尔的回答是做到这一点的最佳方法,只要确保如果您在循环内生成颜色,您不会Random
每次都实例化新对象,因为new Random()
使用系统时钟为生成器播种。您的循环运行速度将超过时钟的滴答速度,因此您最终会一遍又一遍地生成几种相同的颜色,因为random
正在播种相同的值。
它应该看起来像这样:
int numColors = 10;
var colors = new List<string>();
var random = new Random(); // Make sure this is out of the loop!
for (int i = 0; i < numColors; i++)
{
colors.Add(String.Format("#{0:X6}", random.Next(0x1000000)));
}
代替:
int numColors = 10;
var colors = new List<string>();
for (int i = 0; i < numColors; i++)
{
var random = new Random(); // Don't put this here!
colors.Add(String.Format("#{0:X6}", random.Next(0x1000000)));
}
IMO,纯粹的随机颜色可能并不可取,因为您需要在人眼中可区分的颜色。
预设多种颜色并随机选择它们怎么样?
也许您可以在一些开源图表库中找到更好的答案。
生成一组漂亮颜色的一个好方法是使用固定的饱和度和亮度来定义它们并改变色调。
这为您提供了一组漂亮的颜色,它们看起来都来自同一个“集合”——全是柔和的,或全是强烈的,或全是灰白色的,等等。如果你有 Color.FromHSV(),那么它很容易编码。
但是,一旦您获得太多颜色,它可能会停止工作,它们将无法区分。但无论如何,你可能会遇到这个问题。
在伪代码中:
Sat = 0.5 * 255 //assuming we want range 0-255...
Brightness = 0.9 * 255
NumberOfColours = 7
HueSeparation = 360 / 7
Colors = []
for (i = 0 ; i< NumberOfColours; i++)
Colors.Add(Color.FromHSV(HueSeparation * i, Sat, Brightness)
或者
n = 7
Colors = [Color.FromHSV(x*360/n, 128, 230) for x in range(n)]
(我确实喜欢列表推导......)
Random rand = new Random(); // specify a seed
int r = rand.Next(0x1000000);
Console.WriteLine("#{0:X6}", r);
我注意到您(Rahkim)对 Greg 的帖子发表评论说您希望您可以将他的想法(保持饱和度和值不变,并且只是改变色调......一个好主意)放入代码中。你可以!或者,更确切地说,有人已经为你准备好了!
我发现这篇关于使用 C# 将 HSV 转换为 RGB 颜色的博客文章,我相信还有更多内容。与完全随机选择它们相比,您可能会以这种方式获得更好的颜色套件。
此外,当然,这种方法可以很容易地获得一组漂亮的颜色......因为色调从 0 到 359,你可以做一些像这样设置你的色调的事情:
Hue = (PreviousHue + 50) % 360;
(我选择了 50,因为它不会均匀地进入 360,所以如果你超过 360,你不会立即开始重复色调。你必须根据不同颜色的数量来调整这个值以获得理想的分离你期待。)
这样您就不必担心当仍有大量未使用的“色调”空间时代码会随机选择两种非常接近的颜色。