Сделайте простую гистограмму в C#
В этом примере показана гистограмма, показывающая распределение случайных значений, которые моделируют прокатку двух 6-сторонних кубиков.
Во время разработки я дал форме программы две группы элементов Label в нижней части формы. В нижней группе отображаются метки для баров, которые в этом случае равны 2, 3, 4, ..., 12.
Вторая группа ярлыков формирует цветные полосы. Эти метки называются lbl2, lbl3 и т. д.
Когда программа запускается, она использует следующий код для генерации некоторых случайных данных.
// Сделайте некоторые данные.
private void Form1_Load(object sender, EventArgs e)
{
// Сделать массив для хранения значений для значений
// между 2 и 12 с индексами от 0 до 10.
int[] counts = new int[11];
// Сделайте значения.
Random rand = new Random();
for (int i = 0; i < 1000; i++)
{
// Сверните две 6-сторонние кости.
int new_value = rand.Next(1, 7) + rand.Next(1, 7);
int index = new_value - 2;
counts[index]++;
}
// Сделайте простую гистограмму.
Label[] labels = { lbl2, lbl3, lbl4, lbl5, lbl6,
lbl7, lbl8, lbl9, lbl10, lbl11, lbl12 };
MakeHistogram(labels, counts);
}
Эта программа имитирует сканирование двух 6-сторонних кубиков для генерации значений между 2 и 12. В нем хранится количество раз, которое генерируется значением в массиве counts с индексами от 0 до 11. Например, когда данные закончены, значение counts [0] содержит количество раз, когда было создано значение 2.
Программа сначала создает массив counts, чтобы удерживать подсчеты. Затем он вводит цикл, который устанавливает new_value равный двум случайным числам между 1 и 6. Затем он увеличивает соответствующую запись counts.
После завершения создания значений код вызывает следующий метод MakeHistogram для отображения гистограммы.
// Отображение значений.
private void MakeHistogram(Label[] labels, int[] values)
{
// Вычислим масштаб, чтобы наибольший
// значение прекрасно вписывается в форму.
int available_height = labels[0].Bottom - 5;
int max = values.Max();
float scale = available_height / (float)max;
for (int i = 0; i < labels.Length; i++)
{
int height = (int)(scale * values[i]);
labels[i].Top = labels[i].Bottom - height;
labels[i].Height = height;
}
}
Этот метод сначала получает доступную высоту и наибольшее значение в массиве values. Из них он вычисляет масштабный коэффициент, который он может использовать для обеспечения того, чтобы наибольшее значение находилось в доступном пространстве.
Далее код перебирает значения. Для каждого значения метод вычисляет соответствующую высоту. Затем он устанавливает соответствующее свойство Label управления Top в положение, которое оно должно иметь, чтобы сохранить его нижнее положение в своем текущем положении, когда оно имеет новую высоту. Затем он устанавливает высоту элемента управления. (Как вы думаете, если вы установите Height перед установкой Top?)

