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

Источник: http://csharphelper.com/blog/2015/09/draw-a-simple-histogram-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Adblock
detector