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
相关产品推荐
相关产品推荐

