WinForms中的重叠堆积面积图

时间:2019-07-02 09:16:53

标签: winforms charts data-visualization

我试图在WinForm应用程序中的现有图表上重叠堆积面积图(使用System.Windows.Forms.DataVisualization.Charting库)。

enter image description here

根据上述屏幕截图,绿色堆叠区域图表应位于突出显示的(黄色)色线处。但是,当前代码在现有堆积面积图(蓝色)的顶部创建它。

如何更改它,使蓝色和绿色图表重叠?

代码:

private void DrawChart()
    {
        var dataTable = new DataTable();
        dataTable.Columns.Add("Year");
        dataTable.Columns.Add("2020");
        dataTable.Columns.Add("2021");
        dataTable.Columns.Add("2022");
        dataTable.Columns.Add("2023");
        dataTable.Columns.Add("2024");

        var dr = dataTable.NewRow();
        dr = dataTable.NewRow();
        dr["Year"] = "Stacked Area 1";
        dr["2020"] = 20000;
        dr["2021"] = 60000;
        dr["2022"] = 130000;
        dr["2023"] = 190000;
        dr["2024"] = 220000;
        dataTable.Rows.Add(dr);

        dr = dataTable.NewRow();
        dr["Year"] = "Stacked Area 2";
        dr["2020"] = 30000;
        dr["2021"] = 70000;
        dr["2022"] = 140000;
        dr["2023"] = 200000;
        dr["2024"] = 230000;
        dataTable.Rows.Add(dr);


        dr = dataTable.NewRow();

        dr["Year"] = "Overlapping Stacked Area 1";
        dr["2020"] = 10000;
        dr["2021"] = 50000;
        dr["2022"] = 120000;
        dr["2023"] = 180000;
        dr["2024"] = 210000;
        dataTable.Rows.Add(dr);



        dr = dataTable.NewRow();
        dr["Year"] = "Overlapping Stacked Area 2";
        dr["2020"] = 15000;
        dr["2021"] = 60000;
        dr["2022"] = 130000;
        dr["2023"] = 190000;
        dr["2024"] = 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();

            if (chart.Series.FindByName(seriesName) == null)
            {
                chart.Series.Add(seriesName);
                switch (seriesName)
                {
                    case "Stacked Area 1":
                        chart.Series[seriesName].ChartType = SeriesChartType.StackedArea;
                        chart.Series[seriesName].Color = Color.Transparent;
                        chart.Series[seriesName].BorderDashStyle = ChartDashStyle.Dot;
                        chart.Series[seriesName].BorderWidth = 2;
                        chart.Series[seriesName].BorderColor = Color.Black;
                        break;
                    case "Stacked Area 2":
                        chart.Series[seriesName].ChartType = SeriesChartType.StackedArea;
                        chart.Series[seriesName].Color = Color.LightBlue;
                        chart.Series[seriesName].BorderDashStyle = ChartDashStyle.Dot;
                        chart.Series[seriesName].BorderWidth = 2;
                        chart.Series[seriesName].BorderColor = Color.Black;
                        break;
                    case "Overlapping Stacked Area 1":
                        chart.Series[seriesName].ChartType = SeriesChartType.StackedArea;
                        chart.Series[seriesName].SetDefault(true);
                        chart.Series[seriesName].Color = Color.Transparent;
                        chart.Series[seriesName].BorderDashStyle = ChartDashStyle.Dot;
                        chart.Series[seriesName].BorderWidth = 2;
                        chart.Series[seriesName].BorderColor = Color.FromArgb(100, Color.Green);

                        break;
                    case "Overlapping Stacked Area 2":
                        chart.Series[seriesName].ChartType = SeriesChartType.StackedArea;
                        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;
                }
            }

            chart.Series[seriesName].Points.Clear();
            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 = Convert.ToInt64(row[columnName].ToString());
                    chart.Series[seriesName].Points.AddXY(columnName, val);

                }
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

有多种方法可以解决此问题,但是我想说,最好的起点是将系列的类型从堆叠更改为“范围”。如果您查看该系列类型,肯定会找到您想要的。我创建了一些原始代码改编而成的示例代码。我之所以使用元组,是因为我不想花费大量时间进行此操作,但是我绝对不建议为此使用它们。

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

        }
    }