ceds
ceds

Reputation: 2215

Winform Charting Histogram - Draw bar from start to end of bin

I'm trying to create a proper histogram using the standard charting library in Winforms C#. Currently my histogram looks as follows:

enter image description here

    var dataPointSeries = new System.Windows.Forms.DataVisualization.Charting.Series
    {
        Name = chartName,
        Color = Colors.blue,
        IsVisibleInLegend = false,
        ChartType = SeriesChartType.Column,
        MarkerStyle = MarkerStyle.None,
        BorderWidth = 1,
        BorderColor = Color.White


    };
    for (int i = 0; i < data.hDataPoints.Count(); i++)
    {
        dataPointSeries.Points.AddXY(Charts.Functions.RoundValue(data.hDataPoints[i].fromBin), data.hDataPoints[i].probability);
    }

    chart.Series.Add(dataPointSeries);
    chart.Series[0]["PointWidth"] = "1";

The problem that I'm having is the bars are not displayed correctly. For a histogram, the bar needs to start at the lower bin and end at the upper bin. The chart control draws the bar in the middle of the upper or lower bin depending on which one you choose as the X data point.

Any idea how to fix this?

Upvotes: 1

Views: 6150

Answers (2)

Paniom
Paniom

Reputation: 35

TaW's answer about dividing the interval in half is correct, and will center the bar between two values (as desired in historgrams which are used to represent bins, not discrete values).

But to get a truly gapless histogram - if that is the look you are going for - add the following code:

chart.Series[0]["PointWidth"] = "1";

This should push the thickness of your bars to the full width of your range.

Upvotes: 0

TaW
TaW

Reputation: 54463

What you show is the automatic default display.

If you want to change it you need to code the correct values you want in the X-Axis.

Looks like you want this:

Axis ax = chart.ChartAreas[0].AxisX;

ax.Minimum = -500;
ax.Maximum = 5500;
ax.Interval = 1000;
ax.IntervalOffset = -500;

enter image description here

Note that there will always be a small gap between the data points columns and half of it at the borders..

Also note that in a column chart each column (or, for multiseries charts, each group of data points,) is always centered at the x-axis value. Anything else would be misleading! The start/end ie the left/right edges of the column do not have any meaning!! Columns are only about their center!

If you would want anything else (and you don't if you are making a histogram) you would use an Area type chart.

If you find this counter-intutive get used to it by imagining adding another Series and the principle will become clear..

And if you decide you really need to associate a column to a value range then simply set its x-value to the middle of that range..:

        ax.Interval = 1000;
        ax.IntervalOffset = 0;
        ax.Minimum = 0;
        ax.Maximum = 6000;
         foreach (DataPoint dp in chart.Series[0].Points) dp.XValue += ax.Interval/2;

enter image description here

Again, note the gaps between the data points columns and half of it at the borders..

Upvotes: 3

Related Questions