Title: Make a simple histogram in C#
This example displays a histogram showing the distribution of random values that simulate rolling two 6-sided dice.
At design time I gave the program's form two groups of Label controls across the bottom of the form. The bottommost group displays the labels for the bars, which in this case are 2, 3, 4, ..., 12.
The second group of labels form the colored bars themselves. Those labels are named lbl2, lbl3, and so forth.
When the program starts, it uses the following code to generate some random data.
// Make some data.
private void Form1_Load(object sender, EventArgs e)
{
// Make an array to hold counts for values
// between 2 and 12 with indexes between 0 and 10.
int[] counts = new int[11];
// Make the values.
Random rand = new Random();
for (int i = 0; i < 1000; i++)
{
// Roll two 6-sided dice.
int new_value = rand.Next(1, 7) + rand.Next(1, 7);
int index = new_value - 2;
counts[index]++;
}
// Make a simple histogram.
Label[] labels = { lbl2, lbl3, lbl4, lbl5, lbl6,
lbl7, lbl8, lbl9, lbl10, lbl11, lbl12 };
MakeHistogram(labels, counts);
}
This program simulates rolling two 6-sided dice to generate values between 2 and 12. It stores the number of times a value is generated in the counts array with indexes 0 through 11. For example, when the data is finished the value counts[0] holds the number of times the value 2 was generated.
The program first creates the counts array to hold the counts. It then enters a loop that sets new_value equal to two random numbers between 1 and 6. It then increments the corresponding counts entry.
After it finishes generating the values, the code calls the following MakeHistogram method to display the histogram.
// Display the values.
private void MakeHistogram(Label[] labels, int[] values)
{
// Calculate a scale so the largest
// value fits nicely on the form.
int available_height = labels[0].Bottom - 5;
int max = values.Max();
float scale = available_height / (float)max;
for (int i = 0; i < labels.Length; i++)
{
int height = (int)(scale * values[i]);
labels[i].Top = labels[i].Bottom - height;
labels[i].Height = height;
}
}
This method first gets the available height and the largest value in the values array. From those it calculates a scale factor that it can use to ensure that the largest value fits in the available space.
Next the code loops through the values. For each value the method calculates the appropriate height. It then sets the corresponding Label control's Top property to the position it must have to keep its bottom at its current position when it has the new height. It then sets the control's height. (What do you think happens if you set the Height before you set Top?)
That's all there is to this example. It's not very flexible but it's also not very complicated. A similar technique also works well if you want to make a horizontal histogram with the bars extending to the right.
Download the example to experiment with it and to see additional details.
|