Draw a simple histogram in C#

[histogram]

When the program loads, the following code generates some random data.

private const int MIN_VALUE = 0;
private const int MAX_VALUE = 100;

private float[] DataValues = new float[10];

// Make some random data.
private void Form1_Load(object sender, EventArgs e)
{
    Random rnd = new Random();

    // Create data.
    for (int i = 0; i < DataValues.Length; i++)
        DataValues[i] = rnd.Next(MIN_VALUE + 5, MAX_VALUE - 5);
}

This code creates a new Random object and uses it to fill the DataValues array with random values.

The form’s Paint event handler calls the DrawHistogram method, which does all of the interesting work.

// Draw the histogram.
private void picHisto_Paint(object sender, PaintEventArgs e)
{
    DrawHistogram(e.Graphics, picHisto.BackColor, DataValues,
        picHisto.ClientSize.Width, picHisto.ClientSize.Height);
}

When the program’s PictureBox resizes, its Resize event handler refreshes it, making the Paint event handler run again.

// Redraw.
private void picHisto_Resize(object sender, EventArgs e)
{
    picHisto.Refresh();
}

The following code shows the DrawHistogram method.

// Draw a histogram.
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);

    // Make a transformation to the 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;

    // Draw the histogram.
    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);
}

This code applies a transformation to the Graphics object to map the histogram’s coordinates so they fill the PictureBox. It then loops through the data values drawing their histogram bars. It makes the transformation map the number of data values to the PictureBox‘s width so it can draw each bar with a width of 1 in value coordinates.

Note that the code uses a pen of width 0 to outline the bars. A pen of width 0 is always drawn 1 pixel wide no matter what transformation is in use. (Try using a pen of width 1 and see what happens.)

When the user clicks on the graph, the program uses the following code to determine which histogram bar is under the mouse and displays the corresponding data value.

// Display the value clicked.
private void picHisto_MouseDown(object sender, MouseEventArgs e)
{
    // Determine which data value was clicked.
    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);
}


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in drawing, graphics, mathematics and tagged , , , , , , , , . Bookmark the permalink.

5 Responses to Draw a simple histogram in C#

  1. http://www.freeoffice2013.com

    BLOG.CSHARPHELPER.COM: Draw a simple histogram in C#

  2. jawad says:

    Hi sir thank you for sharing such a valuable piece of information, may i know what gr.clear(back_color) , and what type of an object is referenced by gr here?

    • RodStephens says:

      Here gr is the Graphics object doing the drawing. In this example, it’s a Graphics object given to the program by the PictureBox‘s Paint event handler and passed into the DrawHistogram method.

      The Graphics class’s Clear method clears the drawing object with a given color. In this example, it basically clears the PictureBox‘s background with the color passed into the method via the back_color parameter.

      If you download the example, you can see how the pieces fit together better.

  3. p.v. says:

    Great approach! Clear and robust working code.

  4. Jur93n says:

    Nice, works like a charm !

Leave a Reply

Your email address will not be published. Required fields are marked *