微软图表控件MsChart
使用环境:.Net 3.5 Sp1以及VS 2008的开发环境
1.安装
1.1 . dotnetfx35setup.exe
.net3.5的安装包 .NET Framework又称 .Net框架。
是由微软开发,一个致力于敏捷软件开发(Agile software development)、快速应用开发(Rapid application development)、平台无关性和网络透明化的软件开发平台。
若环境中已存在此程序则不需要再次安装
1.2 MSChart.exe :使用到的MSChart控件
1.3 MSChart_VisualStudioAddOn.exe 是一个插件,安装之后,MSChart控件才可以在VS2008环境中使用。
1.4 MSChartLP_chs.exe 一个中文语言包
1.5 打开 VS2008 -》工具箱;比如将此控件添加到Data的控件集合中,则选中Data,鼠标右键选择‘选择项’,打开选择项
在.NET Framwork组件中选中‘Chart’,确认返回,如下图:
这样工具栏中就会出现Chart控件了。
2.使用:
Chart控件主要的部分由五个:
1.Annotations --图形注解集合
2.ChartAreas --图表区域集合
3.Legends --图例集合
4.Series --图表序列集合(即图表数据对象集合)
5.Titles --图标的标题集合
Annotations注解集合
Annotations是一个对图形的一些注解对象的集合,所谓注解对象,类似于对某个点的详细或者批注的说明,比如,在图片上实现各个节点的关键信息,如下图方框和黄色的小方框:
一个图形上可以拥有多个注解对象,可以添加十多种图形样式的注解对象,包括常见的箭头、云朵、矩行、图片等等注解符号,通过各个注解对象的属性,可以方便的设置注解对象的放置位置、呈现的颜色、大小、文字内容样式等常见的属性。(此属性我在做程序的时候并没有使用到,这是网上的相关解释了)
ChartAreas图表区域集合
CharAreas就是一个作图的区域,一个Chart控件可以有多个CharAreas集合,一个CharAreas集合中可以有多个Series图标序列。
需要注意的是,绘图区域只是一个可以作图的区域范围,它本身并不包含要作图形的各种属性数据。
多绘图区效果图如下,分为上下两个绘图区域,分别表示不同的绘图数据:
程序中的CharAreas属性设置的代码:
<ChartAreas> <asp:ChartArea Name="ChartArea1" BackGradientStyle="TopBottom" BackImageWrapMode="TileFlipX" BackColor="Gainsboro" BorderColor="Gainsboro" BorderDashStyle="DashDot" ShadowColor="224, 224, 224"> <AxisX TitleFont="Microsoft Sans Serif, 8.25pt" LineColor="64, 64, 64, 64"> <MinorGrid Enabled="false" /> <MinorTickMark Enabled="false" /> <MajorGrid Enabled="false" /> <MajorTickMark /> <LabelStyle Font="Trebuchet MS, 8.25pt" /> </AxisX> <AxisY2 TitleFont="Microsoft Sans Serif, 8.25pt"> <MinorGrid Enabled="false" /> <MinorTickMark Enabled="false" /> <MajorGrid Enabled="false" /> <MajorTickMark /> <LabelStyle Font="Trebuchet MS, 8.25pt" /> </AxisY2> <AxisY TitleFont="Microsoft Sans Serif, 8.25pt"> <MinorGrid Enabled="false" /> <MinorTickMark Enabled="false" /> <MajorGrid LineColor="60,60,60,60" /> </AxisY> </asp:ChartArea> </ChartAreas>
显示图形如下:
这里比较郁闷的是,在图中有一条X轴,两条Y轴,这样就会出现三条轴线,我想设置一下表格线,刚开始是在设计页面中点击Chart控件的属性,但始终找不到如何设置,最会是在aspx页面中进行设置的。
ChartAreas主要属性如下:
ChartAreas:增加多个绘图区域,每个绘图区域包含独立的图表组、数据源,用于多个图表类型在一个绘图区不兼容时。
AlignmentOrientation:图表区对齐方向,定义两个绘图区域间的对齐方式。
AlignmentStyle:图表区对齐类型,定义图表间用以对其的元素。
AlignWithChartArea:参照对齐的绘图区名称。
InnerPlotPosition:图表在绘图区内的位置属性。
Auto:是否自动对齐。
Height:图表在绘图区内的高度(百分比,取值在0-100)
Width:图表在绘图区内的宽度(百分比,取值在0-100)
X,Y:图表在绘图区内左上角坐标
Position:绘图区位置属性,同InnerPlotPosition。
Name:绘图区名称。
Axis:坐标轴集合
Title:坐标轴标题
TitleAlignment:坐标轴标题对齐方式
Interval:轴刻度间隔大小
IntervalOffset:轴刻度偏移量大小
MinorGrid:次要辅助线
MinorTickMark:次要刻度线
MajorGrid:主要辅助线
MajorTickMark:主要刻度线
DataSourceID:MSChart的数据源。
Legends:图例说明。
Palette:图表外观定义。
Legends图例集合
Legends是一个图例的集合,即标注图形中各个线条或颜色的含义
此属性主要设置图表里的一些说明性的东西,用到的不是太多。
Series图表序列
图表序列,应该是整个绘图中最关键的内容了,通俗点说,即是实际的绘图数据区域,实际呈现的图形形状,就是由此集合中的每一个图表来构成的,可以往集合里面添加多个图表,每一个图表可以有自己的绘制形状、样式、独立的数据等。
需要注意的是,每一个图表,你可以指定它的绘制区域(见ChartAreas的说明),让此图表呈现在某个绘图区域,也可以让几个图表在同一个绘图区域叠加,如下图:
上面两幅图,分别表示了把图表放在不同的绘制区域和放在同一个绘制区域的情况。
Series的主要属性:
IsValueShownAsLabel:是否显示数据点标签,如果为true,在图表中显示每一个数据值
Label:数据点标签文本
LabelFormat:数据点标签文本格式
LabelAngle:标签字体角度
Name:图表名称
Points:数据点集合
XValueType:横坐标轴类型
YValueType:纵坐标轴类型
XValueMember:横坐标绑定的数据源(如果数据源为Table,则填写横坐标要显示的字段名称)
YValueMembers:纵坐标绑定的数据源(如果数据源为Table,则填写纵坐标要显示的字段名称,纵坐标可以有两个)
ChartArea:图表所属的绘图区域名称
ChartType:图表类型(柱形、饼形、线形、点形等)
Legend:图表使用的图例名称
Titles:标题集合。
width:MSChart的宽度。
height:MSChart的高度。
Titles标题合集
根据字面含义即可以理解,是图表的标题配置,同样可以添加多个标题,以及设置标题的样式及文字、位置等属性。多看一下它的属性即能明白各自的含义。
其它属性
相对来说,我觉得比较有用的属性有三个,分别是:Label、Tooltip以及Url链接。
Label即标签的含义,可以在图片的关键位置进行一些关键数字或文字的描述,如下图:
像上图:X轴和Y轴的文字便是标签,以及图表曲线中的红点上的文字,也是标签,添加了标签,可以让人更容易的对内容进行理解。
Tooltip即提示的含义,用于在各个关键点,如:标签、图形关键点、标题等当鼠标移动上去的时候,提示用户一些相关的详细或说明信息,例如上图,可以给曲线中的每一个点增加Tooltip的属性,写上需要详细说明的内容,比如:详细的销售明细,那么,在鼠标移动到这个点的时候,会自动弹出提示信息。
Tooltip可以支持简单方式以及自定义的方式,简单方式即像平时Html页面设置的title之类的属性效果,而自定义的方式,则可以实现图形、文本等各种复杂的提示信息显示。详细的方式请参考官方例子的:Interactivity and AJAX/Tooltips以及Interactivity and AJAX/Client Side Scripts下面的相关例子。
Url链接,图表控件中,有一大半的控件都有Url及Tooltip的属性,你可以设置此属性,在鼠标点击的时候,代到其它相应的页面去。
下面是本次项目中aspx页面中有关Chart控件设置的代码(包含上面的ChartAreas):
<td style="width:850px" align="center"> <div id="divReportR" style="width:750px" runat="server"> <asp:Chart ID="ChReport" runat="server" Width="800px" BackColor="255, 224, 192" BackGradientStyle="TopBottom" BackSecondaryColor="White" BorderlineColor="64, 64, 64" BorderlineDashStyle="Solid" PaletteCustomColors="255, 128, 0" Height="350px"> <Legends> <asp:Legend Docking="Bottom" Name="Legend1" BackColor="224, 224, 224" LegendStyle="Row" MaximumAutoSize="20"> </asp:Legend> </Legends> <BorderSkin BackColor="DarkGray" BorderColor="Silver" SkinStyle="Raised" /> <Titles> <asp:Title Font="Microsoft Sans Serif, 14pt, style=Bold" ForeColor="Teal" Name="Title1" Text="上传数据误差分析"> </asp:Title> </Titles> <Series> <asp:Series Name="Series1" LegendText="直方图" Legend="Legend1" CustomProperties="LabelStyle=Top, DrawSideBySide=False"> </asp:Series> <asp:Series BorderColor="White" LegendText="正态图" BorderWidth="3" ChartArea="ChartArea1" ChartType="Spline" Color="192, 0, 192" Legend="Legend1" Name="Series2" YAxisType="Secondary" MarkerBorderColor="Green" MarkerColor="White" MarkerStyle="Circle"> </asp:Series> </Series> <ChartAreas> <asp:ChartArea Name="ChartArea1" BackGradientStyle="TopBottom" BackImageWrapMode="TileFlipX" BackColor="Gainsboro" BorderColor="Gainsboro" BorderDashStyle="DashDot" ShadowColor="224, 224, 224"> <AxisX TitleFont="Microsoft Sans Serif, 8.25pt" LineColor="64, 64, 64, 64"> <MinorGrid Enabled="false" /> <MinorTickMark Enabled="false" /> <MajorGrid Enabled="false" /> <MajorTickMark /> <LabelStyle Font="Trebuchet MS, 8.25pt" /> </AxisX> <AxisY2 TitleFont="Microsoft Sans Serif, 8.25pt"> <MinorGrid Enabled="false" /> <MinorTickMark Enabled="false" /> <MajorGrid Enabled="false" /> <MajorTickMark /> <LabelStyle Font="Trebuchet MS, 8.25pt" /> </AxisY2> <AxisY TitleFont="Microsoft Sans Serif, 8.25pt"> <MinorGrid Enabled="false" /> <MinorTickMark Enabled="false" /> <MajorGrid LineColor="60,60,60,60" /> </AxisY> </asp:ChartArea> </ChartAreas> </asp:Chart> </div></td>
后台的绑定代码:
private void ShowChart(DataSet dsStats) { double num1 = Convert.ToDouble(dsStats.Tables[1].Rows[2][1]); double num2 = Convert.ToDouble(dsStats.Tables[1].Rows[3][1]); double numInteval = Math.Round((num1/(num2-1)),2);//直方图组距 double numMaxHis = Convert.ToDouble(dsStats.Tables[3].Rows[0]["numHis"]); double numMaxProp = Convert.ToDouble(dsStats.Tables[3].Rows[0]["numProp"]); ChReport.DataSource = dsStats.Tables[2]; DataTable dtStats = dsStats.Tables[2]; for (int i = 0; i < dtStats.Rows.Count; i++) { ChReport.ChartAreas["ChartArea1"].AxisX.Interval = numInteval;//设置X轴的刻度间距 //ChReport.ChartAreas["ChartArea1"].AxisY2.Interval = ChReport.ChartAreas["ChartArea1"].AxisY.Interval * (Math.Round(numMaxProp / numMaxHis)); //绑定数据 double Xpoint = 0; double Ypoint2 = 0; double Ypoint = 0; double.TryParse(dtStats.Rows[i]["numGroup"].ToString(), out Xpoint); double.TryParse(dtStats.Rows[i]["numHistogram"].ToString(), out Ypoint); double.TryParse(dtStats.Rows[i]["numProportion"].ToString(), out Ypoint2); ChReport.Series["Series1"].Points.AddXY(Xpoint, Ypoint); ChReport.Series["Series2"].Points.AddXY(Xpoint, Ypoint2); //显示平滑曲线上的Label及其数值 ChReport.Series["Series2"].IsValueShownAsLabel = true; ChReport.Series["Series2"].Points[i].Label = (Math.Round(Ypoint2, 2, MidpointRounding.AwayFromZero)*100).ToString() + "%"; } //设置X轴和Y轴的刻度范围 double numMax = 2; double numMin = -2; double.TryParse(txtUpperSizeLimit.Text, out numMax); double.TryParse(txtLowerSizelimit.Text, out numMin); ChReport.ChartAreas[0].AxisX.Minimum = numMin; ChReport.ChartAreas[0].AxisX.Maximum = numMax; ChReport.ChartAreas[0].AxisY.Minimum = 0; ChReport.ChartAreas[0].AxisY2.Minimum = 0; ChReport.DataBind(); }
在此程序中第一个Y轴的刻度是可以动态变化的,但是X轴的刻度却不然,于是我手动设置了X轴的间隔
ChReport.ChartAreas["ChartArea1"].AxisX.Interval = numInteval;//numInteval为要设置的间隔的值,double类型
要注意的是X轴和两个Y轴的刻度范围一定要设置(设置一个值就行<最大值或最小值>),不然会出现刻度范围的响应错误(至少在我的程序中是这样的),如下:
double numMax = 2;
double numMin = -2;
double.TryParse(txtUpperSizeLimit.Text, out numMax);
double.TryParse(txtLowerSizelimit.Text, out numMin);
ChReport.ChartAreas[0].AxisX.Minimum = numMin;
ChReport.ChartAreas[0].AxisX.Maximum = numMax;
ChReport.ChartAreas[0].AxisY.Minimum = 0;
ChReport.ChartAreas[0].AxisY2.Minimum = 0;
在第二个Y轴上要以百分比的形式显示,但又不能直接实现,于是加载了Chart控件的Customize方法
#region Web Form Designer generated code protected override void OnInit(EventArgs e) { this.ChReport.Customize += new EventHandler(ChReport_Customize); base.OnInit(e); } // 初始化chart控件第二个y轴坐标客户端显示样式 百分比 void ChReport_Customize(object sender, EventArgs e) { System.Web.UI.DataVisualization.Charting.CustomLabelsCollection yAxisLabels = ChReport.ChartAreas["ChartArea1"].AxisY2.CustomLabels; if (yAxisLabels.Count > 0) { // Change text of the first Y axis label yAxisLabels[0].Text = "0%"; // Change Y axis labels for (int labelIndex = 1; labelIndex < yAxisLabels.Count; labelIndex++) { double x = Convert.ToDouble(yAxisLabels[labelIndex].Text); double y = Convert.ToDouble(yAxisLabels[yAxisLabels.Count - 1].Text); double v = (x / y) * 100*numPropMax; string text = Math.Round(v, 0, MidpointRounding.AwayFromZero).ToString() + "%"; yAxisLabels[labelIndex].Text = text; } } } #endregion
这里仍会有一个问题就是,如果你设置了Y轴上的百分比,即对Y轴上的刻度进行了设置,那么就一定要在MSChart的绑定代码中设置相对应的Y轴的最大值(即某一个轴上的刻度值和最大值,要么都设置,要么都不设置,不然图线上的数字不会和刻度值相匹配),上述代码改为:
double numMax = 2;
double numMin = -2;
double.TryParse(txtUpperSizeLimit.Text, out numMax);
double.TryParse(txtLowerSizelimit.Text, out numMin);
ChReport.ChartAreas[0].AxisX.Minimum = numMin;
ChReport.ChartAreas[0].AxisX.Maximum = numMax;
ChReport.ChartAreas[0].AxisY.Minimum = 0;
ChReport.ChartAreas[0].AxisY2.Minimum = 0;
ChReport.ChartAreas[0].AxisY2.Maximum = numPropMax;
在此次的程序中如果同时设置了Y轴的刻度和最大值,则会出现的一种状况是系统会误判Y轴Label的数量,和要显示的刻度的数量不相等,,这样也会造成表格中的点的显示Y值和刻度值不一致,那么就要让表格内的点的Y坐标和Y轴的刻度对应,设置代码如下:
System.Web.UI.DataVisualization.Charting.CustomLabelsCollection yAxisLabels = ChReport.ChartAreas["ChartArea1"].AxisY2.CustomLabels;
ChReport.ChartAreas[0].AxisY2.Interval =Math.Round( (numPropMax / (yAxisLabels.Count-1)),numDigit);
完整的后台代码如下:
private void ShowChart(DataSet dsStats) { double num1 = Convert.ToDouble(dsStats.Tables[1].Rows[2][1]); double num2 = Convert.ToDouble(dsStats.Tables[1].Rows[3][1]); double numInteval = Math.Round((num1/(num2-1)),2);//直方图组距 double numMaxHis = Convert.ToDouble(dsStats.Tables[3].Rows[0]["numHis"]); double numMaxProp = Convert.ToDouble(dsStats.Tables[3].Rows[0]["numProp"]); double numMaxShow=Convert.ToDouble(dsStats.Tables[3].Rows[0]["numShow"]); //ChReport.DataSource = dsStats.Tables[2]; DataTable dtStats = dsStats.Tables[2]; for (int i = 0; i < dtStats.Rows.Count; i++) { ChReport.ChartAreas["ChartArea1"].AxisX.Interval = numInteval;//设置X轴的刻度间距 //ChReport.ChartAreas["ChartArea1"].AxisY2.Interval = ChReport.ChartAreas["ChartArea1"].AxisY.Interval * (Math.Round(numMaxProp / numMaxHis)); //绑定数据 (Ypoint2/numMaxProp*numMaxShow) double Xpoint = 0; double Ypoint2 = 0; double Ypoint = 0; double.TryParse(dtStats.Rows[i]["numGroup"].ToString(), out Xpoint); double.TryParse(dtStats.Rows[i]["numHistogram"].ToString(), out Ypoint); double.TryParse(dtStats.Rows[i]["numProportion"].ToString(), out Ypoint2); ChReport.Series["Series1"].Points.AddXY(Xpoint, Ypoint); ChReport.Series["Series2"].Points.AddXY(Xpoint, Ypoint2); //ChReport.Series["Series1"].XValueMember = "numGroup"; //ChReport.Series["Series1"].YValueMembers = "numHistogram"; //ChReport.Series["Series2"].XValueMember = "numGroup"; //ChReport.Series["Series2"].YValueMembers = "numProportion"; //显示平滑曲线上的Label及其数值 ChReport.Series["Series2"].IsValueShownAsLabel = true; ChReport.Series["Series2"].Points[i].Label = (Math.Round(Ypoint2, 2, MidpointRounding.ToEven) * 100).ToString() + "%"; } //设置X轴和Y轴的刻度范围 double numMax = 2; double numMin = -2; double.TryParse(txtUpperSizeLimit.Text, out numMax); double.TryParse(txtLowerSizelimit.Text, out numMin); ChReport.ChartAreas[0].AxisX.Minimum = numMin; ChReport.ChartAreas[0].AxisX.Maximum = numMax; ChReport.ChartAreas[0].AxisY.Minimum = 0; ChReport.ChartAreas[0].AxisY2.Minimum = 0; ChReport.ChartAreas[0].AxisY2.Maximum = numPropMax; ChReport.ChartAreas[0].AxisY2.IntervalType = DateTimeIntervalType.Number; ChReport.ChartAreas[0].AxisY2.IsLabelAutoFit = true; ChReport.DataBind(); } #endregion #region Web Form Designer generated code protected override void OnInit(EventArgs e) { this.ChReport.Customize += new EventHandler(ChReport_Customize); base.OnInit(e); } // 初始化chart控件第二个y轴坐标客户端显示样式 百分比 void ChReport_Customize(object sender, EventArgs e) { System.Web.UI.DataVisualization.Charting.CustomLabelsCollection yAxisLabels = ChReport.ChartAreas["ChartArea1"].AxisY2.CustomLabels; ChReport.ChartAreas[0].AxisY2.Interval =Math.Round( (numPropMax / (yAxisLabels.Count-1)),numDigit); if (yAxisLabels.Count > 0) { // Change text of the first Y axis label yAxisLabels[0].Text = "0%"; // Change Y axis labels for (int labelIndex = 1; labelIndex < yAxisLabels.Count; labelIndex++) { double x = Convert.ToDouble(yAxisLabels[labelIndex].Text); double y = Convert.ToDouble(yAxisLabels[yAxisLabels.Count - 1].Text); double v = (x / y) * 100 * numPropMax; string text = Math.Round(v, 2, MidpointRounding.ToEven).ToString() + "%"; yAxisLabels[labelIndex].Text = text; } } } #endregion
OnInit是是个页面生命周期中的一个,完整的页面周期如下:
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; namespace AccountWeb { public partial class Test002 : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } #region OnPreInit 第一步 protected override void OnPreInit(EventArgs e) { //检查 IsPostBack 属性来确定是不是第一次处理该页。 //创建或重新创建动态控件。 //动态设置主控页。 //动态设置 Theme 属性。 //读取或设置配置文件属性值。 //注意 //如果请求是回发请求,则控件的值尚未从视图状态还原。如果在此阶段设置控件属性,则其值可能会在下一事件中被重写。 base.OnPreInit(e); } #endregion #region OnInit 第二步 protected override void OnInit(EventArgs e) { //在所有控件都已初始化且已应用所有外观设置后引发。使用该事件来读取或初始化控件属性。 base.OnInit(e); } #endregion #region OnInitComplete 第三步 protected override void OnInitComplete(EventArgs e) { //由 Page 对象引发。使用该事件来处理要求先完成所有初始化工作的任务。 base.OnInitComplete(e); } #endregion #region PreLoad 第四步 protected override void OnPreLoad(EventArgs e) { //如果需要在 Load 事件之前对页或控件执行处理,请使用该事件。 //在 Page 引发该事件后,它会为自身和所有控件加载视图状态,然后会处理 Request 实例包括的任何回发数据。 base.OnPreLoad(e); } #endregion #region OnLoad 第五步 protected override void OnLoad(EventArgs e) { //Page 在 Page 上调用 OnLoad 事件方法,然后以递归方式对每个子控件执行相同操作,如此循环往复,直到加载完本页和所有控件为止。 //使用 OnLoad 事件方法来设置控件中的属性并建立数据库连接。 base.OnLoad(e); } #endregion #region 控件事件 第六步 protected void Button1_Click(object sender, EventArgs e) { //用这些事件来处理特定控件事件,如 Button 控件的 Click 事件或 TextBox 控件的 TextChanged 事件。 //注意 //在回发请求中,如果页包含验证程序控件,请在执行任何处理之前检查 Page 和各个验证控件的 IsValid 属性。 } #endregion #region OnLoadComplete 第七步 protected override void OnLoadComplete(EventArgs e) { //对需要加载页上的所有其他控件的任务使用该事件。 base.OnLoadComplete(e); } #endregion #region OnPreRender 第八步 protected override void OnPreRender(EventArgs e) { //在该事件发生前: //Page 对象会针对每个控件和页调用 EnsureChildControls。 //设置了 DataSourceID 属性的每个数据绑定控件会调用 DataBind 方法。有关更多信息,请参见下面的数据绑定控件的数据绑定事件。 //页上的每个控件都会发生 PreRender 事件。使用该事件对页或其控件的内容进行最后更改。 base.OnPreRender(e); } #endregion #region SaveStateComplete 第九步 protected override void OnSaveStateComplete(EventArgs e) { //在该事件发生前,已针对页和所有控件保存了 ViewState。将忽略此时对页或控件进行的任何更改。 //使用该事件执行满足以下条件的任务:要求已经保存了视图状态,但未对控件进行任何更改。 base.OnSaveStateComplete(e); } #endregion #region Render 第十步 //Render //这不是事件;在处理的这个阶段,Page 对象会在每个控件上调用此方法。所有 ASP.NET Web 服务器控件都有一个用于写出发送给浏览器的控件标记的 Render 方法。 //如果创建自定义控件,通常要重写此方法以输出控件的标记。不过,如果自定义控件只合并标准的 ASP.NET Web 服务器控件,不合并自定义标记,则不需要重写 Render 方法。有关更多信息,请参见开发自定义 ASP.NET 服务器控件。 //用户控件(.ascx 文件)自动合并呈现,因此不需要在代码中显式呈现该控件。 #endregion #region OnUnload 第十一步 protected override void OnUnload(EventArgs e) { //该事件首先针对每个控件发生,继而针对该页发生。在控件中,使用该事件对特定控件执行最后清理,如关闭控件特定数据库连接。 //对于页自身,使用该事件来执行最后清理工作,如:关闭打开的文件和数据库连接,或完成日志记录或其他请求特定任务。 //注意 //在卸载阶段,页及其控件已被呈现,因此无法对响应流做进一步更改。如果尝试调用方法(如 Response.Write 方法),则该页将引发异常。 base.OnUnload(e); } #endregion } }
using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; namespace AccountWeb { public partial class Test002 : System.Web.UI.Page { static int count = 0; protected void Page_Load(object sender, EventArgs e) { Response.Write(count.ToString()+": "+ "Page_Load <br />"); count++ ; } protected override void OnPreInit(EventArgs e) { base.OnPreInit(e); Response.Write(count.ToString()+": "+ "OnPreInit <br />"); count++ ; } protected override void OnInit(EventArgs e) { base.OnInit(e); Response.Write(count.ToString()+": "+ "OnInit <br />"); count++ ; } protected override void OnLoad(EventArgs e) { base.OnLoad(e); Response.Write(count.ToString()+": "+ "OnLoad <br />"); count++ ; } protected override void OnPreLoad(EventArgs e) { base.OnPreLoad(e); Response.Write(count.ToString()+": "+ "OnPreLoad <br />"); count++ ; } protected override void OnLoadComplete(EventArgs e) { base.OnLoadComplete(e); Response.Write(count.ToString()+": "+ "OnLoadComplete <br />"); count++ ; } protected override void OnInitComplete(EventArgs e) { base.OnInitComplete(e); Response.Write(count.ToString()+": "+ "OnInitComplete <br />"); count++ ; } protected override void OnUnload(EventArgs e) { base.OnUnload(e); } protected override void OnDataBinding(EventArgs e) { base.OnDataBinding(e); Response.Write(count.ToString()+": "+ "OnDataBinding <br />"); count++ ; } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); Response.Write(count.ToString()+": "+ "OnPreRender <br />"); count++ ; } protected void btnGraphics_Click(object sender, EventArgs e) { //Bitmap bmp = new Bitmap(10, 10); //Graphics g = Graphics.FromImage(bmp); Response.Write(count.ToString()+": "+ "btnGraphics_Click <br />"); count++ ; } } }
程序中用到了两个方法,但并不包含在Math中,我自己写了出来,以后可能还会用到的吧。
#region Math计算方法 /// <summary> /// 求标准偏差 STDEV(value1, value2, value3, ...) /// </summary> /// <param name="numArray">参与计算的数组</param> /// <param name="numCount">数组的个数</param> /// <returns></returns> public double STDEV(double[] numArray, int numCount) { if ((numCount <= 1) || numArray.Length == 0) return 0; double numtotel = 0; double numpowtotel = 0; double numetator = 0; double denomonator = 0; for (int i = 0; i < numArray.Length; i++) { numtotel += numArray[i]; numpowtotel += Math.Pow(numArray[i], 2); } numetator = numCount * numpowtotel - Math.Pow(numtotel, 2); denomonator = numCount * (numCount - 1); return Math.Sqrt(numetator/denomonator); } /// <summary> /// NORMDIST(x,mean,standard_dev,cumulative) /// 在此处的cumulative=false 返回概率密度函数;若cumulative=true则返回累积分布函数 /// </summary> /// <param name="X">需要计算其分布的数值</param> /// <param name="Mean">分布的算术平均值</param> /// <param name="Standard_dev">分布的标准偏差</param> /// <returns></returns> public double NORMDIST(double X, double Mean, double Standard_dev) { double nummultip1 = 0; double nummultip2 = 0; double numexp = 0; numexp = -(Math.Pow((X - Mean), 2) / (2 * Math.Pow(Standard_dev, 2))); nummultip1 = 1 / (Math.Sqrt(2 * Math.PI) * Standard_dev); nummultip2 = Math.Exp(numexp); return nummultip1 * nummultip2; } #endregion
做一个程序,用到了正则表达式的一些东西,不会,就去学习,有用到Excel表格的操作,不太懂,再去看了看怎样操作,期间有关正态分布函数NORMDIST会不会大于1的问题,不懂,研究了小半天,亲,这都是高中学的概率分布和大一时的高数微积分啊,汗颜啊。MSChart的东西也是从0开始,像我这样功底不好的程序员做编程真心伤不起啊。