C#开发中如何为基于dataGridView生成的chart图表添加趋势线?
解决方案
你使用的是.NET 自带的 MSChart 控件,可直接调用内置的公式接口实现趋势线添加,不需要自行实现拟合逻辑,具体实现步骤如下:
1 修正原始数据绑定逻辑
你当前代码中X轴传入的是字符串类型的类别值,直接调用趋势线公式会触发数值类型不匹配的报错,需要先调整绑定逻辑,用数值索引作为X值,原始文本作为轴显示标签:
chart1.ChartAreas.Add("WY"); chart1.ChartAreas.Add("ZA"); // 提前设置系列X值类型为数值,适配趋势线计算要求 chart1.Series["WY"].XValueType = ChartValueType.Double; chart1.Series["ZA"].XValueType = ChartValueType.Double; for (int i = 0; i < dataGridView1.Rows.Count - 1; i++) { double xVal = i; string xLabel = dataGridView1.Rows[i].Cells[0].Value.ToString(); // 添加WY系列数据点 var wyPoint = this.chart1.Series["WY"].Points.AddXY(xVal, Convert.ToDouble(dataGridView1.Rows[i].Cells["WY"].Value.ToString())); wyPoint.AxisLabel = xLabel; // 添加ZA系列数据点 var zaPoint = this.chart1.Series["ZA"].Points.AddXY(xVal, Convert.ToDouble(textBox4.Text.ToString())); zaPoint.AxisLabel = xLabel; }
2 封装趋势线添加方法
通用的线性趋势线添加方法如下,支持控制是否显示:
/// <summary> /// 为指定系列添加线性趋势线 /// </summary> /// <param name="sourceSeriesName">要添加趋势线的源系列名称</param> /// <param name="trendLineName">趋势线系列的自定义名称</param> /// <param name="isVisible">是否显示趋势线</param> private void AddTrendLine(string sourceSeriesName, string trendLineName, bool isVisible) { // 先删除已存在的同名趋势线,避免重复添加 if (chart1.Series.IndexOf(trendLineName) > -1) { chart1.Series.Remove(chart1.Series[trendLineName]); } if (!isVisible) { return; } // 初始化趋势线系列样式 Series trendLine = new Series(trendLineName); trendLine.ChartType = SeriesChartType.Line; trendLine.BorderWidth = 2; trendLine.Color = Color.Red; // 可自行修改趋势线颜色 trendLine.IsVisibleInLegend = true; chart1.Series.Add(trendLine); // 调用内置线性回归公式计算趋势线 chart1.DataManipulator.FinancialFormula(FinancialFormula.Forecasting, "Linear,0,false,false", chart1.Series[sourceSeriesName], trendLine); }
3 实现可选显示逻辑
在窗体上添加对应复选框,在复选框的选中状态变更事件中调用上述方法即可实现按需展示趋势线:
private void chkWYTrend_CheckedChanged(object sender, EventArgs e) { AddTrendLine("WY", "WY趋势线", chkWYTrend.Checked); } private void chkZATrend_CheckedChanged(object sender, EventArgs e) { AddTrendLine("ZA", "ZA趋势线", chkZATrend.Checked); }
其他类型趋势线说明
如果需要使用移动平均等其他类型的趋势线,仅需要替换FinancialFormula枚举值即可,例如3周期移动平均的调用代码如下:
chart1.DataManipulator.FinancialFormula(FinancialFormula.MovingAverage, "3", chart1.Series[sourceSeriesName], trendLine);
注意事项
- 需先引入命名空间
using System.Windows.Forms.DataVisualization.Charting; - 绑定数据前需提前处理空值、非数值等异常数据,避免公式计算报错
内容的提问来源于stack exchange,提问作者Mlody_pb
相关产品推荐
相关产品推荐

