MS图表堆栈列超出绘图点

时间:2015-06-28 15:41:21

标签: c# winforms charts mschart stacked-chart

在尝试绘制堆积柱图时,我注意到对于其中一个系列中只有2个有效数据点的多个系列,图表显示错误:

enter image description here

用于生成的代码与我之前发布的问题here中的代码相同。有人可以帮忙吗?不确定需要解决此问题的其他细节,所以如有必要,我会提供更多信息..

1 个答案:

答案 0 :(得分:1)

默认情况下,在Chart所有列类型中,使用可用的DataPoints填充可用空间,当只有少数DataPoints时,它们的列变得非常胖......

您有两种选择:

  • 您可以为缺少X-Value的每个DataPoints添加虚拟点数;假人应该Y-Values

  • 0
  • 更简单:您可以控制列宽。唯一的困难是决定宽度,当然还要找到隐藏得很好的定制属性'

注意:要想正常工作,您需要明确一个X-Values的概念!如果您只是在碰巧出现时添加积分,则您可能无法添加“缺失”积分。假人或控制X-Axis范围..

enter image description here

enter image description here

示例显示每年一个DataPoint一年。

以下是两个选项的代码示例:

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);
    }
}

这里我们只添加两个点,但以像素控制列宽。另外,我们将Maximum设置为X-Axis,以便显示整整12个月的范围。为此,我们需要计算最大值的DateTime转换为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();
}

注意:在第二个示例中,由于宽度设置为像素,因此Chart不会缩放!这意味着如果您使图表非常小,列将重叠!

因此,如果您想要缩放,您可能需要在每个SizeChanged事件中计算它。对于此计算,您必须知道图表中有多少DataPoints应该能够来展示;你不能使用Points.Count值,因为你错过了很多点......

以下是此类缩放代码的示例:

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);
}

请注意,所有图表Position值都在图表ClientSize百分比中,因此我们需要将其用作因素..