Use label controls to draw a simple labeled histogram in C#

[histogram]

The example Draw a simple labeled histogram in C# draws a labeled histogram on a PictureBox in that control’s Paint event handler. It does a fair amount of work to ensure that the histogram’s bars are in their proper positions and that the labels are correctly positioned over the bars.

This example uses a slightly simpler albeit less flexible approach. It uses Label controls with blank text and different background colors to display the histogram’s bars. It then places other Label controls above the histogram bars.

When the program loads, it uses the following code to create its Label controls.

// Make some random data.
private void Form1_Load(object sender, EventArgs e)
{
    // Do not allow the user to resize the form.
    FormBorderStyle = FormBorderStyle.FixedDialog;

    Color[] Colors = new Color[] {
        Color.Red, Color.LightGreen, Color.Blue,
        Color.Pink, Color.Green, Color.LightBlue,
        Color.Orange, Color.Yellow, Color.Purple
    };

    Random rand = new Random();

    const int num_values = 10;
    int wid = picHisto.ClientSize.Width / num_values;

    for (int i = 0; i < num_values; i++)
    {
        int value = rand.Next(5, 95);

        // Make a label to be the histogram.
        Label lbl_hist = new Label();
        lbl_hist.Parent = picHisto;
        lbl_hist.BackColor = Colors[i % Colors.Length];
        lbl_hist.BorderStyle = BorderStyle.FixedSingle;
        lbl_hist.Width = wid;
        lbl_hist.Height =
            (int)(picHisto.ClientSize.Height * value / 100f);
        lbl_hist.Left = i * wid;
        lbl_hist.Top =
            picHisto.ClientSize.Height - lbl_hist.Height;

        // Make a label to display the value.
        Label lbl_value = new Label();
        lbl_value.Parent = picHisto;
        lbl_value.BackColor = Color.Transparent;
        lbl_value.Text = value.ToString();
        lbl_value.TextAlign = ContentAlignment.TopCenter;
        lbl_value.Left = lbl_hist.Left;
        lbl_value.Width = lbl_hist.Width;
        lbl_value.Height = 15;
        lbl_value.Top = lbl_hist.Top - lbl_value.Height;
    }
}

The form’s Load event handler starts by setting the form’s border style to FixedDialog. The previous example redrew its histogram and repositioned its labels whenever the form resized. Unfortunately, there’s no easy way to make controls automatically resize to occupy a percentage of the form, so this example’s technique of using control’s to display the histogram won’t work.

(Actually, there are a couple of ways that you could do this. First, you could rearrange the control’s in the form’s Resize event handler. You could also use a TableLayoutPanel to automatically resize the controls, but that would be pretty confusing to set up. An even better solution would be to make a new container control that let you specify a control’s position and size as percentages of the container’s size. If you decide to give any of those methods a try, post a comment below.)

After setting the form’s border style, the code creates an array of colors to use in the histogram bars. It then sets variable wid equal to the width that each bar should have.

The code then enters a loop to generate the histogram values. Each time through the loop, the code creates a random value and then creates a Label control to be the value’s histogram bar. It then sets the control’s properties. These are mostly self-explanatory. The only non-trivial trick here is that label’s position gives its top, so the code needs to calculate that position to make all of the bars line up on the bottom of the histogram. (When you create a new control, it’s also easy to forget to give it a parent. In that case, the control won’t appear.)

Next, the code creates a second Label control to display the histogram bar’s numeric value and sets that control’s properties. Again, this is more or less straightforward. The only challenge here is to position the Label nicely centered above its bar.

That’s all there is to this program. Because it uses controls to create the histogram, those controls automatically display the histogram and redraw themselves if needed, so you don’t need to handle the PictureBox control’s Paint event. The downsize is that this version won’t resize its histogram if you resize the form.

Download the example program to see additional details.


Download Example   Follow me on Twitter   RSS feed   Donate




About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.
This entry was posted in drawing, graphics, mathematics and tagged , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.