Нарисуйте простую гистограмму в C#
Когда программа загружается, следующий код генерирует некоторые случайные данные.
private const int MIN_VALUE = 0; private const int MAX_VALUE = 100; private float[] DataValues = new float[10]; // Сделайте некоторые случайные данные. private void Form1_Load(object sender, EventArgs e) { Random rnd = new Random(); // Создание данных. for (int i = 0; i < DataValues.Length; i++) DataValues[i] = rnd.Next(MIN_VALUE + 5, MAX_VALUE - 5); }
Этот код создает новый объект Random и использует его для заполнения массива DataValues со случайными значениями.
Обработчик события Paint в форме вызывает метод DrawHistogram, который выполняет всю интересную работу.
// Нарисуем гистограмму. private void picHisto_Paint(object sender, PaintEventArgs e) { DrawHistogram(e.Graphics, picHisto.BackColor, DataValues, picHisto.ClientSize.Width, picHisto.ClientSize.Height); }
Когда размер PictureBox программы изменяется, его обработчик события Resize обновляет его, заставляя обработчик событий Paint снова запускаться.
// Перерисовать. private void picHisto_Resize(object sender, EventArgs e) { picHisto.Refresh(); }
Следующий код показывает метод DrawHistogram.
// Нарисуем гистограмму. private void DrawHistogram(Graphics gr, Color back_color, float[] values, int width, int height) { Color[] Colors = new Color[] { Color.Red, Color.LightGreen, Color.Blue, Color.Pink, Color.Green, Color.LightBlue, Color.Orange, Color.Yellow, Color.Purple }; gr.Clear(back_color); // Сделайте преобразование в PictureBox. RectangleF data_bounds = new RectangleF(0, 0, values.Length, MAX_VALUE); PointF[] points = { new PointF(0, height), new PointF(width, height), new PointF(0, 0) }; Matrix transformation = new Matrix(data_bounds, points); gr.Transform = transformation; // Нарисуем гистограмму. using (Pen thin_pen = new Pen(Color.Black, 0)) { for (int i = 0; i < values.Length; i++) { RectangleF rect = new RectangleF(i, 0, 1, values[i]); using (Brush the_brush = new SolidBrush(Colors[i % Colors.Length])) { gr.FillRectangle(the_brush, rect); gr.DrawRectangle(thin_pen, rect.X, rect.Y, rect.Width, rect.Height); } } } gr.ResetTransform(); gr.DrawRectangle(Pens.Black, 0, 0, width - 1, height - 1); }
Этот код применяет преобразование к объекту Graphics для сопоставления координат гистограммы, чтобы они заполнили PictureBox. Затем он перебирает значения данных, вычерчивая их гистограммы. Он превращает преобразование в число значений данных в ширину PictureBox, чтобы он мог рисовать каждую полосу шириной 1 в координатах значения.
Обратите внимание, что в коде используется пера шириной 0 для выделения строк. Перо шириной 0 всегда имеет ширину в 1 пиксель, независимо от того, какая трансформация используется. (Попробуйте использовать ручку шириной 1 и посмотрите, что произойдет.)
Когда пользователь нажимает на график, программа использует следующий код, чтобы определить, какая панель гистограммы находится под мышью, и отображает соответствующее значение данных.
// Отображение значения щелчка. private void picHisto_MouseDown(object sender, MouseEventArgs e) { // Определите, какое значение данных было нажато. float bar_wid = picHisto.ClientSize.Width / (int)DataValues.Length; int i = (int)(e.X / bar_wid); MessageBox.Show("Item " + i + " has value " + DataValues[i], "Value", MessageBoxButtons.OK, MessageBoxIcon.Information); }