You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForms:循环生成堆叠柱状图仅显示单根柱子的解决方法

解决C# WinForms中循环生成堆叠柱状图仅显示单根柱子的问题

问题根源

你的代码只显示一根柱子的核心原因是:所有数据点的X轴值完全相同。你在循环中固定使用MBdtpFrom.Value.Month或MBdtpTo.Value.Month作为X坐标,不管循环遍历到哪个月份,X值都是同一个数字,导致所有系列的数据点都重叠在同一位置,看起来只有一根柱子。

另外你的循环逻辑存在错误:当处理结束年份yr == ToYear时,仍然从FromMonth循环到ToMonth,如果日期范围跨年度(比如从2023年10月到2024年3月),这个循环会因为FromMonth(10) > ToMonth(3)而不执行,完全漏掉结束年份的月份数据。

修复后的代码示例

public partial class Charts : Form
{
    public Charts()
    {
        InitializeComponent();
        // 初始化图表系列为堆叠柱状图类型
        foreach (var series in MBChart.Series)
        {
            series.ChartType = SeriesChartType.StackedColumn;
        }
    }

    private void LaborHrsButton_Click(object sender, EventArgs e)
    {
        // 清空旧数据和标题,避免重复叠加
        MBChart.Titles.Clear();
        foreach (var series in MBChart.Series)
        {
            series.Points.Clear();
        }

        DateTime fromDate = MBdtpFrom.Value;
        DateTime toDate = MBdtpTo.Value;

        // 设置图表标题与坐标轴
        MBChart.Titles.Add("Labor Hrs by Month");
        var MBChartArea = new ChartArea("LaborChartArea");
        MBChartArea.AxisX.Title = "Month";
        MBChartArea.AxisY.Title = "Total Labor Hours";
        MBChart.ChartAreas.Clear();
        MBChart.ChartAreas.Add(MBChartArea);

        // 遍历日期范围内的每一个月
        DateTime currentMonth = new DateTime(fromDate.Year, fromDate.Month, 1);
        while (currentMonth <= toDate)
        {
            // 生成唯一的月份标识,确保每个月对应独立柱子
            string xAxisLabel = $"{currentMonth.Year}-{currentMonth.Month:D2}";
            
            // 此处替换为数据库查询的实际工时数据
            int ceodHours = 10;
            int cnrHours = 23;
            int mpdHours = 10;
            int removalHours = 4;
            int uarHours = 54;
            int waterWashHours = 61;

            // 为每个系列添加对应月份的数据点
            MBChart.Series["CEOD"].Points.AddXY(xAxisLabel, ceodHours);
            MBChart.Series["CNR"].Points.AddXY(xAxisLabel, cnrHours);
            MBChart.Series["MPD"].Points.AddXY(xAxisLabel, mpdHours);
            MBChart.Series["Removal"].Points.AddXY(xAxisLabel, removalHours);
            MBChart.Series["UAR"].Points.AddXY(xAxisLabel, uarHours);
            MBChart.Series["Water Wash"].Points.AddXY(xAxisLabel, waterWashHours);

            // 切换到下一个月
            currentMonth = currentMonth.AddMonths(1);
        }
    }
}

关键修复点说明

  • 唯一X轴标识:用年份-月份的字符串作为X轴标签,确保每个月份对应独立的柱子位置,避免数据重叠。
  • 正确遍历月份:使用DateTime.AddMonths(1)遍历日期范围内的每个月,自动处理跨年度场景,无需复杂的年份/月份判断。
  • 清空旧数据:每次生成图表前清空系列旧数据和标题,避免多次点击按钮导致数据重复叠加。
  • 设置堆叠类型:初始化时将所有系列的ChartType设为StackedColumn,保证柱子以堆叠形式显示。

后续替换为数据库数据的思路

在遍历每个月时,根据currentMonth的年份和月份编写参数化SQL查询,获取对应月份各类型的工时总和:

SELECT 
    SUM(CEOD_Hours) AS CEOD,
    SUM(CNR_Hours) AS CNR,
    SUM(MPD_Hours) AS MPD,
    SUM(Removal_Hours) AS Removal,
    SUM(UAR_Hours) AS UAR,
    SUM(WaterWash_Hours) AS WaterWash
FROM LaborData
WHERE YEAR(WorkDate) = @Year AND MONTH(WorkDate) = @Month

将currentMonth.Year和currentMonth.Month作为参数传入,把查询结果赋值给对应的工时变量即可。

内容的提问来源于stack exchange,提问作者Zay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 08:17:49