不知不觉年后上班一个多月了,2011年的一个季度就这样快过完了,天气也渐渐暖和了。就等着天气热了,可以去校园篮球场上耍耍,有段日子没碰篮球了,也有段日子没写博客了,都不知道有什么东西可写,这就说明了自己这段日子没学习了,后面必须加油,全力准备系统集成项目管理工程师的考试了。
根据标题大家也应该清楚这篇文章的主题了,这是年后上班闲的时候利用Dundas Chart控件做的一个图形。由于项目组重组,一直忙没顾上写这篇文章。今天总算有闲暇时间,写这篇文章供大家参考学习。其实,也可以使用MS Chart完成,效果都是一样的。
首先,呈现Default.aspx页面代码:
View Code
1 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
2
3 <%@ Register assembly="DundasWebChart" namespace="Dundas.Charting.WebControl" tagprefix="DCWC" %>
4
5 <%@ Register assembly="System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" namespace="System.Web.UI.DataVisualization.Charting" tagprefix="asp" %>
6
7 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
8
9 <html xmlns="http://www.w3.org/1999/xhtml">
10 <head runat="server">
11 <title></title>
12 </head>
13 <body>
14 <form id="form1" runat="server">
15 <div>
16 <DCWC:Chart ID="Chart1" runat="server" Height="400px" Width="500px" Palette="Pastel">
17 <legends>
18 <DCWC:Legend Alignment="Center" DockInsideChartArea="False"
19 DockToChartArea="Default" Name="Default">
20 </DCWC:Legend>
21 </legends>
22 <Titles>
23 <DCWC:Title DockInsideChartArea="False" DockToChartArea="Default"
24 Font="华文宋体, 15pt" Name="Title1" Text="多项式趋势线">
25 </DCWC:Title>
26 </Titles>
27 <series>
28 <DCWC:Series BorderColor="64, 64, 64" Name="Series1" ShadowOffset="1">
29 </DCWC:Series>
30 <DCWC:Series BorderColor="64, 64, 64" Name="Series2" ShadowOffset="1">
31 </DCWC:Series>
32 <DCWC:Series Name="Series3">
33 </DCWC:Series>
34 </series>
35 <chartareas>
36 <DCWC:ChartArea Name="Default">
37 </DCWC:ChartArea>
38 </chartareas>
39 </DCWC:Chart>
40 </div>
41 </form>
42 </body>
43 </html>
2
3 <%@ Register assembly="DundasWebChart" namespace="Dundas.Charting.WebControl" tagprefix="DCWC" %>
4
5 <%@ Register assembly="System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" namespace="System.Web.UI.DataVisualization.Charting" tagprefix="asp" %>
6
7 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
8
9 <html xmlns="http://www.w3.org/1999/xhtml">
10 <head runat="server">
11 <title></title>
12 </head>
13 <body>
14 <form id="form1" runat="server">
15 <div>
16 <DCWC:Chart ID="Chart1" runat="server" Height="400px" Width="500px" Palette="Pastel">
17 <legends>
18 <DCWC:Legend Alignment="Center" DockInsideChartArea="False"
19 DockToChartArea="Default" Name="Default">
20 </DCWC:Legend>
21 </legends>
22 <Titles>
23 <DCWC:Title DockInsideChartArea="False" DockToChartArea="Default"
24 Font="华文宋体, 15pt" Name="Title1" Text="多项式趋势线">
25 </DCWC:Title>
26 </Titles>
27 <series>
28 <DCWC:Series BorderColor="64, 64, 64" Name="Series1" ShadowOffset="1">
29 </DCWC:Series>
30 <DCWC:Series BorderColor="64, 64, 64" Name="Series2" ShadowOffset="1">
31 </DCWC:Series>
32 <DCWC:Series Name="Series3">
33 </DCWC:Series>
34 </series>
35 <chartareas>
36 <DCWC:ChartArea Name="Default">
37 </DCWC:ChartArea>
38 </chartareas>
39 </DCWC:Chart>
40 </div>
41 </form>
42 </body>
43 </html>
接着,呈现Default.aspx.cs页面代码:
View Code
1 protected void Page_Load(object sender, EventArgs e)
2 {
3 Chart1.Series[0].Type = SeriesChartType.Point;
4 Chart1.Series[0].Color = Color.Red;
5 Chart1.Series[0].MarkerStyle = MarkerStyle.Circle;
6 Chart1.Series[1].Type = SeriesChartType.Spline;
7 Chart1.Series[1].Color = Color.Blue;
8 Chart1.Series[2].Type = SeriesChartType.Spline;
9 Chart1.Series[2].Color = Color.Green;
10
11 drawLine();
12 }
13 public void drawLine()
14 {
15 double[] xVal = new double[6] { 1, 2, 3, 4, 5, 6 };
16 double[] yVal = new double[6] { 24, 13, 63, 35, 56, 8 };
17 double[] fiting = new double[6];
18 double[] modulus = new double[2];
19 double[] yNew = new double[6];
20 string formula = "";
21 double a = 0, b = 0;
22
23 bool tag = CurveSimulate.linefit.CalculateLine(xVal, yVal, ref modulus);
24
25 if (tag)
26 {
27 a = Math.Round(modulus[0], 3);
28 b = Math.Round(modulus[1], 2);
29 formula = a.ToString() + " * x + " + b.ToString();
30 for (int i = 0; i < 6; i++)
31 {
32 yNew[i] = b + a * xVal[i];
33 Chart1.Series[0].Points.AddXY(i + 1, yVal[i]);
34 Chart1.Series[2].Points.AddXY(i + 1, yNew[i]);
35 }
36 Chart1.Series[2].Name = formula;
37 }
38 }
2 {
3 Chart1.Series[0].Type = SeriesChartType.Point;
4 Chart1.Series[0].Color = Color.Red;
5 Chart1.Series[0].MarkerStyle = MarkerStyle.Circle;
6 Chart1.Series[1].Type = SeriesChartType.Spline;
7 Chart1.Series[1].Color = Color.Blue;
8 Chart1.Series[2].Type = SeriesChartType.Spline;
9 Chart1.Series[2].Color = Color.Green;
10
11 drawLine();
12 }
13 public void drawLine()
14 {
15 double[] xVal = new double[6] { 1, 2, 3, 4, 5, 6 };
16 double[] yVal = new double[6] { 24, 13, 63, 35, 56, 8 };
17 double[] fiting = new double[6];
18 double[] modulus = new double[2];
19 double[] yNew = new double[6];
20 string formula = "";
21 double a = 0, b = 0;
22
23 bool tag = CurveSimulate.linefit.CalculateLine(xVal, yVal, ref modulus);
24
25 if (tag)
26 {
27 a = Math.Round(modulus[0], 3);
28 b = Math.Round(modulus[1], 2);
29 formula = a.ToString() + " * x + " + b.ToString();
30 for (int i = 0; i < 6; i++)
31 {
32 yNew[i] = b + a * xVal[i];
33 Chart1.Series[0].Points.AddXY(i + 1, yVal[i]);
34 Chart1.Series[2].Points.AddXY(i + 1, yNew[i]);
35 }
36 Chart1.Series[2].Name = formula;
37 }
38 }
最后,趋势线的计算方法:
View Code
1 public class linefit
2 {
3 /// <summary>
4 /// 根据离散点计算线性方程【f(x)=ax+b】
5 /// </summary>
6 /// <param name="x">X轴坐标集合</param>
7 /// <param name="y">Y轴坐标集合</param>
8 /// <param name="modulus">线性方程系数,一次 a,常量 b </param>
9 /// <returns>返回True</returns>
10 public static bool CalculateLine(double[] x, double[] y, ref double[] modulus)
11 {
12 double xe, ye, xye, xxe, sx = 0, sy = 0, sxy = 0, sxx = 0, a, b;
13 int count = x.Length;
14 double[,] ar = new double[count, 2];
15
16 for (int i = 0; i < count; i++)
17 {
18 ar[i, 0] = x[i];
19 ar[i, 1] = y[i];
20 }
21
22 for (int m = 0; m < count; m++)
23 {
24 sx = sx + ar[m, 0];
25 sy = sy + ar[m, 1];
26 sxx = sxx + ar[m, 0] * ar[m, 0];
27 sxy = sxy + ar[m, 0] * ar[m, 1];
28 }
29 xe = sx / count;
30 ye = sy / count;
31 xye = sxy / count;
32 xxe = sxx / count;
33 a = Math.Round((xye - xe * ye) / (xxe - xe * xe), 3);
34 b = Math.Round(ye - a * xe,3);
35
36 modulus[0] = a;
37 modulus[1] = b;
38
39 return true;
40 }
41 }
2 {
3 /// <summary>
4 /// 根据离散点计算线性方程【f(x)=ax+b】
5 /// </summary>
6 /// <param name="x">X轴坐标集合</param>
7 /// <param name="y">Y轴坐标集合</param>
8 /// <param name="modulus">线性方程系数,一次 a,常量 b </param>
9 /// <returns>返回True</returns>
10 public static bool CalculateLine(double[] x, double[] y, ref double[] modulus)
11 {
12 double xe, ye, xye, xxe, sx = 0, sy = 0, sxy = 0, sxx = 0, a, b;
13 int count = x.Length;
14 double[,] ar = new double[count, 2];
15
16 for (int i = 0; i < count; i++)
17 {
18 ar[i, 0] = x[i];
19 ar[i, 1] = y[i];
20 }
21
22 for (int m = 0; m < count; m++)
23 {
24 sx = sx + ar[m, 0];
25 sy = sy + ar[m, 1];
26 sxx = sxx + ar[m, 0] * ar[m, 0];
27 sxy = sxy + ar[m, 0] * ar[m, 1];
28 }
29 xe = sx / count;
30 ye = sy / count;
31 xye = sxy / count;
32 xxe = sxx / count;
33 a = Math.Round((xye - xe * ye) / (xxe - xe * xe), 3);
34 b = Math.Round(ye - a * xe,3);
35
36 modulus[0] = a;
37 modulus[1] = b;
38
39 return true;
40 }
41 }
预览图:
总结:
本篇文章的技术核心是在趋势线公式的计算方法,其余的实现都是很简单的,但是也花费了很多精力和查找资料,最终完成了上面图的效果。
如果大家还有其它的好的方法,可以拿出来分享;或者知道其它好的绘图控件集成这样的功能,也可以提出来,供大家一块学习。