Есть несколько способов решить эту проблему, но я бы сказал, что для начала лучше всего изменить тип рядов со стека на диапазон.Если вы посмотрите на этот тип серии, это определенно будет то, что вы ищете.Я создал пример кода, адаптированный из вашего исходного кода.Я использовал кортежи, потому что я не хотел тратить на это огромное количество времени, но я определенно не рекомендовал бы использовать их для этого.
private void DrawChart()
{
var dataTable = new DataTable();
dataTable.Columns.Add("Year");
dataTable.Columns.Add("2020",typeof(Tuple<int,int>));
dataTable.Columns.Add("2021",typeof(Tuple<int,int>));
dataTable.Columns.Add("2022",typeof(Tuple<int,int>));
dataTable.Columns.Add("2023",typeof(Tuple<int,int>));
dataTable.Columns.Add("2024", typeof(Tuple<int, int>));
var dr = dataTable.NewRow();
dr = dataTable.NewRow();
dr["Year"] = "Range 1";
dr["2020"] = new Tuple<int,int>(20000, 30000);
dr["2021"] = new Tuple<int,int>(60000, 70000);
dr["2022"] = new Tuple<int,int>(130000, 140000);
dr["2023"] = new Tuple<int,int>(190000, 200000);
dr["2024"] = new Tuple<int,int>(220000, 230000);
dataTable.Rows.Add(dr);
dr = dataTable.NewRow();
dr["Year"] = "Range 2";
dr["2020"] = new Tuple<int,int>(10000, 25000);
dr["2021"] = new Tuple<int,int>(50000, 90000);
dr["2022"] = new Tuple<int,int>(120000, 130000);
dr["2023"] = new Tuple<int,int>(180000, 210000);
dr["2024"] = new Tuple<int,int>(210000, 220000);
dataTable.Rows.Add(dr);
chart.ChartAreas["Default"].AxisX.Crossing = 0;
chart.ChartAreas["Default"].AxisY.Crossing = 0;
chart.Visible = true;
foreach (DataRow row in dataTable.Rows)
{
string seriesName = row["Year"].ToString();
Series series = null;
if (chart.Series.FindByName(seriesName) == null)
{
series = chart.Series.Add(seriesName);
switch (seriesName)
{
case "Range 1":
chart.Series[seriesName].ChartType = SeriesChartType.Range;
chart.Series[seriesName].Color = Color.FromArgb(100,Color.LightBlue);
chart.Series[seriesName].BorderDashStyle = ChartDashStyle.Dot;
chart.Series[seriesName].BorderWidth = 2;
chart.Series[seriesName].BorderColor = Color.Black;
break;
case "Range 2":
chart.Series[seriesName].ChartType = SeriesChartType.Range;
chart.Series[seriesName].SetDefault(true);
chart.Series[seriesName].Color = Color.FromArgb(100, Color.Green);
chart.Series[seriesName].BorderDashStyle = ChartDashStyle.Dot;
chart.Series[seriesName].BorderWidth = 2;
chart.Series[seriesName].BorderColor = Color.FromArgb(100, Color.Green);
break;
}
}
if (series == null) continue;
var years = dataTable.Columns.Count;
for (int i = 1; i < years; i++)
{
string columnName = dataTable.Columns[i].ColumnName;
if (row[columnName] != null && !String.IsNullOrEmpty(row[columnName].ToString()))
{
var val = (Tuple<int,int>) row[columnName];
series.Points.AddXY(columnName, val.Item1,val.Item2);
}
}
}
}