使用 WinForms 图表控件的分组条形图

Grouped bar chart with WinForms Chart Control

我可以用 MS Excel 像这样创建分组条形图。

我需要通过 WinForms 图表控件创建相同的图表。

我尝试了这段代码,但似乎我需要更复杂的解决方案来构建正确的图表,就像它在 MS Excel.

所以请帮我更正代码以构建分组条形图。 (这个很棒的 Microsoft 示例没有帮助 https://code.msdn.microsoft.com/mschart/Release/ProjectReleases.aspx?ReleaseId=4418

数据源

DataTable dtExc = new DataTable();

// Create columns
dtExc.Columns.Add((new DataColumn("StoodType", typeof(int))).Caption = "Stood");
dtExc.Columns.Add((new DataColumn("TotalMinutes", typeof(double))).Caption = "Time");

foreach (var exDataitem in allDataExc)
{
     DataRow drToAdd = dtExc.NewRow();

     drToAdd[0] = exDataitem.StoodTypeFullName;
     drToAdd[1] = exDataitem.TotalMinutes;

     dtExc.Rows.Add(drToAdd);   
}

图表

public Chart GenerateExcChart(DataTable dtChartDataSource, int width, int height, string bgColor, SeriesChartType seriesChartType,
            string axisXTitle, string axisYTitle)
        {
            Chart chart = new Chart()
            {
                Width = width,
                Height = height
            };


            chart.Legends.Add(new Legend() { Name = "Legend" });
            chart.Legends[0].Docking = Docking.Bottom;
            ChartArea chartArea = new ChartArea() { Name = "ChartArea" };

            //Remove X-axis grid lines
            chartArea.AxisX.MajorGrid.LineWidth = 0;
            chartArea.AxisX.Title = axisXTitle;

            chartArea.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
            chartArea.AxisX.IntervalType = DateTimeIntervalType.Number;

            //Remove Y-axis grid lines
            chartArea.AxisY.MajorGrid.LineWidth = 0;
            chartArea.AxisY.Interval = 1;
            chartArea.AxisY.Title = axisYTitle;

            //Chart Area Back Color
            chartArea.BackColor = Color.FromName(bgColor);
            chart.ChartAreas.Add(chartArea);
            chart.Palette = ChartColorPalette.BrightPastel;
            string series = string.Empty;

            //create series and add data points to the series
            if (dtChartDataSource != null)
            {
                foreach (DataColumn dc in dtChartDataSource.Columns)
                {
                    //a series to the chart
                    if (chart.Series.FindByName(dc.ColumnName) == null)
                    {
                        series = dc.ColumnName;
                        chart.Series.Add(series);
                        chart.Series[series].ChartType = seriesChartType;
                    }

                    var rowIndex = 0;
                    //Add data points to the series
                    foreach (DataRow dr in dtChartDataSource.Rows)
                    {
                        double dataPoint = 0;
                        double.TryParse(dr[dc.ColumnName].ToString(), out dataPoint);

                        var objDataPoint = new DataPoint();
                        objDataPoint.YValues = new double[] { dataPoint };
                        objDataPoint.XValue = rowIndex + 1;
                        objDataPoint.AxisLabel = rowIndex.ToString();

                        if (dataPoint == 0)
                        {
                            objDataPoint.IsEmpty = true;
                        }

                        chart.Series[series].Points.Add(objDataPoint);
                        rowIndex++;
                    }
                }
            }

            return chart;
        }

通过使用 Google 和一些实验,我更正了代码,使其满足我的需要。

public Chart GenerateExcChart(DataTable dtChartDataSource, int width, int height, string bgColor, SeriesChartType seriesChartType,
            string axisXTitle, string axisYTitle)
        {
            Chart chart = new Chart()
            {
                Width = width,
                Height = height
            };

            chart.Legends.Add(new Legend() { Name = "Legend" });
            chart.Legends[0].Docking = Docking.Bottom;
            ChartArea chartArea = new ChartArea() { Name = "ChartArea" };

            chartArea.AxisX.MajorGrid.LineWidth = 0;//Remove X-axis grid lines
            chartArea.AxisY.MajorGrid.LineWidth = 0;//Remove Y-axis grid lines

            chartArea.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
            chartArea.AxisY.IntervalAutoMode = IntervalAutoMode.VariableCount;
            chartArea.AxisX.IntervalType = DateTimeIntervalType.Number;
            chartArea.AxisY.IntervalType = DateTimeIntervalType.Number;

            chartArea.AxisX.LabelStyle.Angle = -45;

            chartArea.AxisX.Title = axisYTitle;
            chartArea.AxisY.Title = axisXTitle;

            //Chart Area Back Color
            chartArea.BackColor = Color.FromName(bgColor);
            chart.ChartAreas.Add(chartArea);
            chart.Palette = ChartColorPalette.BrightPastel;
            string series = string.Empty;

            //create series and add data points to the series
            if (dtChartDataSource != null)
            {
                series = "Series1";
                chart.Series.Add(series);
                chart.Series[series].ChartType = SeriesChartType.Column;
                chart.Series[series].XValueType = ChartValueType.Auto;
                chart.Series[series].YValuesPerPoint = 1;
                chart.Series[series].YValueType = ChartValueType.Auto;

                var rowIndex = 0;

                //Add data points to the series
                foreach (DataRow dr in dtChartDataSource.Rows)
                {
                    double dataPoint;
                    DataPoint objDataPoint = new DataPoint();

                    objDataPoint.AxisLabel = dr[dtChartDataSource.Columns[0].ColumnName].ToString();

                    double.TryParse(dr[dtChartDataSource.Columns[1].ColumnName].ToString(), out dataPoint);


                    objDataPoint.XValue = rowIndex;
                    objDataPoint.YValues = new double[] { dataPoint };

                    chart.Series[series].Points.Add(objDataPoint);

                    rowIndex++;
                }
            }

            chart.Series[0].IsVisibleInLegend = false;

            return chart;
        }