如何在C# Chart中按周统计并显示出生日期数量?
Got it! The problem with your current code is that you’re grouping directly by the full BirthDate value—so you’re getting a count for every single day instead of rolling entries up by week. Let’s adjust this to group by weeks instead, with clear labels for your chart.
Step 1: Update the Grouping Logic
Instead of grouping by the raw BirthDate, we’ll group by a combination of year and week number (to avoid mixing weeks across years). We’ll also create a human-readable label for each week to display on the chart’s X-axis.
Here’s the updated grouping code (using .NET Core 3.0+/NET 5+’s built-in ISOWeek class for standard week calculations):
// First, filter out any null BirthDates to avoid errors var validBirthDates = lst.Where(l => l.BirthDate != null).ToList(); // Group by ISO standard week (Monday as first day of week) var result = validBirthDates .GroupBy(l => new { Year = ISOWeek.GetYear(l.BirthDate.Value), WeekNumber = ISOWeek.GetWeekOfYear(l.BirthDate.Value) }) .Select(cl => new { // Custom label for the X-axis (e.g., "Week 24 (2024)") WeekLabel = $"Week {cl.Key.WeekNumber} ({cl.Key.Year})", Count = cl.Count().ToString() }) .OrderBy(item => item.WeekLabel) // Ensure weeks are in order on the chart .ToList();
Step 2: Adjust the Chart Binding
Since we’re now using a WeekLabel field instead of BirthDate, update the X-axis binding:
chart2.Series["Series1"].XValueMember = "WeekLabel";
Full Updated Code
Putting it all together:
// Filter out null birth dates var validBirthDates = lst.Where(l => l.BirthDate != null).ToList(); // Group and count by week var result = validBirthDates .GroupBy(l => new { Year = ISOWeek.GetYear(l.BirthDate.Value), WeekNumber = ISOWeek.GetWeekOfYear(l.BirthDate.Value) }) .Select(cl => new { WeekLabel = $"Week {cl.Key.WeekNumber} ({cl.Key.Year})", Count = cl.Count().ToString() }) .OrderBy(item => item.WeekLabel) .ToList(); // Convert to DataTable and bind to chart DataTable dt = Utility.ConvertToDataTable(result); chart2.DataSource = dt; chart2.Name = "BirthDate"; chart2.Series["Series1"].XValueMember = "WeekLabel"; chart2.Series["Series1"].YValueMembers = "Count"; this.chart2.Titles.Remove(this.chart1.Titles.FirstOrDefault()); this.chart2.Titles.Add("Weekly Enrollment Chart"); chart2.Series["Series1"].IsValueShownAsLabel = true;
For .NET Framework 4.x (No ISOWeek Support)
If you’re stuck on an older framework, use this custom week calculation (adjust firstDayOfWeek to match your preferred start day):
var result = validBirthDates .GroupBy(l => { DayOfWeek firstDayOfWeek = DayOfWeek.Sunday; // Change to Monday if needed int diff = l.BirthDate.Value.DayOfWeek - firstDayOfWeek; if (diff < 0) diff += 7; DateTime weekStart = l.BirthDate.Value.AddDays(-diff); return new { WeekStart = weekStart }; }) .Select(cl => new { WeekLabel = $"Week starting {cl.Key.WeekStart:MM/dd/yyyy}", Count = cl.Count().ToString() }) .OrderBy(item => item.WeekLabel) .ToList();
Key Notes
- Year + Week Pairing: Grouping by both year and week ensures weeks at the end/start of a year don’t get merged (e.g., Week 52 2023 vs Week 1 2024).
- Sorting: Always order the results by week label/start date—otherwise your chart will display weeks in random order.
- Null Handling: The initial filter prevents crashes if any
BirthDatevalues are null.
内容的提问来源于stack exchange,提问作者Kushal Bhattarai

