1
votes

While attempting to plot a stacked columns chart, I noticed that for multiple series with only 2 valid data points in one of the series, the chart appears wrong:

enter image description here

The code used to generate is the same as the one in the question I previously posted here. Anyone can help? Not sure what other details are needed to solve this, so I will provide more info if necessary..

1
Have you resolved your problems? - TaW

1 Answers

1
votes

In a Chart all Column-types by default fill the available space with the available DataPoints and when only a few DataPoints are there, their columns become ridiculously fat..

You have two options:

  • You could add dummy points to each X-Value where the DataPoints are missing; the dummies should have Y-Values of 0

  • Much simpler: You can controls the Column Width. The only difficulties are to decide on a width and of course finding the well-hidden 'custom-property'

Note: For either of to work well, you need to have a clear concept of which X-Values you will have! If you only add points when they happen to come along you either won't be able to add the 'missing' dummies or to control the X-Axis range..

enter image description here

enter image description here

The examples show one year with one DataPoint per month.

Here is a code example for both options:

private void button1_Click(object sender, EventArgs e)
{
    chart1.Series.Clear();
    Series S = chart1.Series.Add("S1");
    S.ChartType = SeriesChartType.StackedColumn;
    Random R = new Random(123);
    DateTime dt = Convert.ToDateTime("2015-01-01");
    chart1.ChartAreas[0].AxisX.LabelStyle.Format = "dd.MM.yy";
    for (int m = 1; m < 12; m++)
    {
        // This can be a real or a dummy point, depending on a simple condition..
        S.Points.AddXY(dt.AddMonths(m), (m <= 2) ? R.Next(100): 0);
    }
}

Here we add only two points but control the column width in pixels. In addition we set a Maximum to the X-Axis, so that is show the full 12 months range. To do so we need to calculate the DateTime of the maximum and the convert it to double..:

private void button1_Click(object sender, EventArgs e)
{
    chart1.Series.Clear();
    Series S = chart1.Series.Add("S1");
    S.ChartType = SeriesChartType.StackedColumn;
    S.SetCustomProperty("PixelPointWidth", "20"); // <- control the column width in pixels

    Random R = new Random(123);
    DateTime dt = Convert.ToDateTime("2015-01-01");
    chart1.ChartAreas[0].AxisX.LabelStyle.Format = "dd.MM.yy";
    for (int m = 1; m < 12; m++)
    {
        // here we add only a few points:
        if (m <= 2) S.Points.AddXY(dt.AddMonths(m), R.Next(100));  
    }
    // to control the displayed time range we set a Maximum
    chart1.ChartAreas[0].AxisX.Maximum = dt.AddMonths(12).ToOADate();
}

Note: In the second example since the width is set in pixels it will not scale with the Chart! This means that if you make the chart very small the columns will overlap!

So if you want scaling you may want have to calculate it on every SizeChanged event.. For this calculation you will have to know just how many DataPoints the chart should be able to display; you can't use the Points.Count values since you are missing so many points..

Here is an example of such a scaling code:

private void chart1_SizeChanged(object sender, EventArgs e)
{
    int pointCount = 12;
    float columnwidth = 0.3f;
    ChartArea CA = chart1.ChartAreas[0];
    int width = (int)(1f * chart1.ClientSize.Width * 
                      CA.InnerPlotPosition.Width / 100f  / pointCount * columnwidth );
    chart1.Series[0].SetCustomProperty("PixelPointWidth", "" + width);
}

Note that all chart Position values are in percent of the chart ClientSize so we need to use that as a factor..