Нарисуйте простую гистограмму в 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);
}
