Ответ 1
Самый простой способ - использовать String.Format
и использовать шестнадцатеричный формат для аргумента.
var random = new Random();
var color = String.Format("#{0:X6}", random.Next(0x1000000)); // = "#A197B9"
Я создаю несколько диаграмм, которым нужна шестнадцатеричная строка для цветов.
Пример:
<dataseries name="ford" color="FF00FF" />
Я создаю эти динамически, поэтому я хотел бы генерировать шестнадцатеричный код для каждого dataseries случайным образом.
Каков наилучший способ сделать это?
Самый простой способ - использовать String.Format
и использовать шестнадцатеричный формат для аргумента.
var random = new Random();
var color = String.Format("#{0:X6}", random.Next(0x1000000)); // = "#A197B9"
IMO, чисто случайные цвета могут быть не предпочтительными, так как вам нужны цвета, которые могут быть различимы в глазах человека.
Как предустановить несколько цветов и выбрать их случайно?
Возможно, вы найдете лучшие ответы в некоторых библиотеках с открытым исходным кодом.
Ответ Samuel - лучший способ сделать это, просто убедитесь, что если вы генерируете цвета внутри цикла, вы каждый раз не создаете новый объект 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)));
}
Хорошим способом создания красивого набора цветов является определение их с использованием фиксированного насыщения и яркости и изменение оттенка.
Это дает вам приятный набор цветов, которые выглядят так, как будто они пришли из одного и того же "набора" - все пастели, или все интенсивные, или все не совсем белые. И это довольно легко кодировать, если у вас есть 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);
Я заметил, что вы (Рахким) прокомментировали сообщение Грега, что вы хотите, чтобы вы могли поместить его идею (сохраняя насыщенность и значение постоянным, и только меняя оттенок... хорошая идея) в код. Ты можешь! Или, скорее, у кого-то уже есть для вас!
Я нашел этот пост в блоге Преобразование цвета HSV в RGB с использованием С#, и я уверен, что там больше. Вы, вероятно, в конечном итоге получите более красивый набор цветов, чем путем выбора их в случайном порядке.
Кроме того, конечно, этот метод упрощает получение красивого набора цветов... поскольку Hue идет от 0-359, вы могли бы сделать что-то вроде того, как настроить свой оттенок примерно так:
Hue = (PreviousHue + 50) % 360;
(я выбрал 50, так как он не переходит в 360 равномерно, поэтому, если вы выходите за пределы 360, вы не будете начинать повторять оттенки мгновенно. Вам придется поиграть со значением, чтобы получить идеальное разделение в зависимости от того, как много разных цветов, которые вы ожидаете.)
Таким образом, вам не нужно беспокоиться о том, когда код случайно выбирает два цвета, которые очень близки друг к другу, когда еще есть много неиспользуемого пространства оттенков.