Диаграмма с перекрытием областей в WinForms - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь наложить диаграмму с областями с накоплением на существующую диаграмму в приложении 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 Ответ

1 голос
/ 08 июля 2019

Есть несколько способов решить эту проблему, но я бы сказал, что для начала лучше всего изменить тип рядов со стека на диапазон.Если вы посмотрите на этот тип серии, это определенно будет то, что вы ищете.Я создал пример кода, адаптированный из вашего исходного кода.Я использовал кортежи, потому что я не хотел тратить на это огромное количество времени, но я определенно не рекомендовал бы использовать их для этого.

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

        }
    }
...