
/**//**//**//*
* **************************************************************
* Author:SunnyZhao Vendor:Facet Date:2005/06/23
* Description: 简单的VML-Rect控件
* *************************************************************
*/
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Collections;
using System.Collections.Specialized;

namespace Facet.VML_Chart


{

/**//**//**//// <summary>
/// SimpleRect 的摘要说明。
/// </summary>
[DefaultProperty("Text"),
ToolboxData("<{0}:SimpleRect runat=server></{0}:SimpleRect>")]
public class SimpleRect : System.Web.UI.WebControls.WebControl

{
private string sOutputText;
private string data = "1,2,3"; //数据
private string dataInfor; //与数据对应的横坐标信息
private Unit width = 500;
private Unit height = 400;
private string colorArr; //柱状图的颜色
string[] aryHorizon;
string[] aryDetail;
int HorSplitNum; //X轴分成几份

double HorSplitLen; //X轴每份的 VML 长度
double VerSplitLen; //Y轴每份的 VML 长度

int intVerSplitAmt; //Y轴每一份的 VML 长度

属性区域属性区域#region 属性区域
//数据值
[Bindable(true),Category("Data"),DefaultValue("1,2,3")]
public string Data

{
get

{
return data;
}
set

{
data=value;
}
}

//数据的中文名称(相当于横坐标名称)
[Bindable(true),Category("Data"),DefaultValue("")]
public string DataInfor

{
get

{
return this.dataInfor ;
}
set

{
dataInfor=value;
}
}
//宽度
[Bindable(true),Category("Data"),DefaultValue("")]
public override Unit Width

{
get

{
return this.width;
}
set

{
base.Width = value;
}
}
//高度
[Bindable(true),Category("Data"),DefaultValue("")]
public override Unit Height

{
get

{
return this.height;
}
set

{
base.Height = value;
}
}

#endregion

protected override void Render(HtmlTextWriter output)

{
aryHorizon = this.DataInfor.Split(',');
aryDetail = this.Data.Split(',');
HorSplitNum = aryHorizon.Length;

VerSplitLen = 4800 / 5; //纵坐标分成五分,计算每份的长度
HorSplitLen = 7300 / HorSplitNum; //横坐标分 HorSplitNum 分,计算每份长度

int nAmp=HorSplitNum/5; //nAmp只是一个系数,因为水平方向画的矩形的多少可以不同,所以宽度要动态改变
if (nAmp<1) nAmp = 1; //因此 nAmp 给定了一个改变宽度的大概的比例系数而已。
//开辟VML区域
//if(this.Width.Value==0) this.Width =500;
if(this.Height.Value==0) this.Height=400;
this.sOutputText = "<v:group id='root_0' style='position:relative;width:"+this.Width+";height:"+this.Height+";' coordsize='6000,6000'>";
//划X,Y轴
this.sOutputText += "<v:line from='0,0' to='7300,0' style='z-index:200;'>"
+ " <v:stroke endarrow='classic' weight='2px' color='#000000'/>"
+ "</v:line>";
this.sOutputText += "<v:line from='0,0' to='0,-5500' style='z-index:200;'>"
+ " <v:stroke endarrow='classic' weight='2px' color='#000000'/>"
+ "</v:line>";

if(!(this.DataInfor=="" || this.Data==""))

{
//划 X 轴的坐标值
this.sOutputText += this.DrawHorizontal();

//划 Y 轴的坐标值
this.sOutputText += this.DrawVertical();

//划 柱子
this.sOutputText += this.drawRectDetail(nAmp);
}
//The End
this.sOutputText += "</v:group>";
output.Write(sOutputText);
}




方法区域,划坐标轴以及具体的图形方法区域,划坐标轴以及具体的图形#region 方法区域,划坐标轴以及具体的图形

/**//**//**//*
* **************************************************************
* Function: DrawHorizontal()
* Description: 划横坐标的坐标值 以及 垂直于 X 轴的虚线( 坐标原点 O:(0,0) )
* Input:
* Where Use:
* *************************************************************
*/
private string DrawHorizontal()

{
string sReturnValue = String.Empty;
int i;
//划横坐标的坐标值
for(i = 0;i < HorSplitNum;i ++)

{
int width = 300;
double left = 0 + (i+0.5) * HorSplitLen - width/2;
string htmlHorSplit;
htmlHorSplit = "<v:shape style='left:" + left + ";top:100;width:" + width + ";height:300;'>"
+ " <v:textbox inset='0,0,0,0'>" + aryHorizon[i] + "</v:textbox>"
+ "</v:shape>";
sReturnValue += htmlHorSplit;

/**//**//**//*将文字竖起来写
<table cellpadding='0' cellspacing='0'>
<tr>
<td style='layout-flow:vertical-ideographic'>" + aryHorizon[i] + "</td>
</tr>
</table>
上面的方法可以将文字竖起来写*/
}
//划垂直于 X 轴的虚线
for(i = 1;i < HorSplitNum;i ++)

{
double XPoint = 0 + (i * HorSplitLen);
string line;
line = "<v:line from='"+XPoint+",0' to='"+XPoint+",-5500'>"
+ " <v:stroke dashstyle='dot' opacity='0.45' weight='0.9pt' color='#000000'/>"
+ "</v:line>";
sReturnValue += line;
}

return sReturnValue;
}



/**//**//**//*
* **************************************************************
* Function: DrawVertical()
* Description: 划纵坐标的坐标值以及垂直于 Y 轴的虚线
* Input:
* Where Use:
* *************************************************************
*/
private string DrawVertical()

{
string sReturnValue = "";
double MaxAmount = 0; //用来保存计算出来的纵坐标上数值的最大值,是一个数量值
int i;
for(i=0;i<aryDetail.Length;i++)
if(Convert.ToDouble(aryDetail[i])>MaxAmount)
MaxAmount = Convert.ToDouble(aryDetail[i]);
//我们把纵坐标分成了 5 分,所以计算每一个大概相当于多少个单位量,取整数,数量值
string strVerSplitAmt = Convert.ToString(MaxAmount / 5).Split('.')[0];
if(strVerSplitAmt == "0")
intVerSplitAmt = 1;
else

{
if(strVerSplitAmt.Length>=2)

{ //如 123 ,处理后的值为 130
//intVerSplitAmt = parseInt((parseInt(strVerSplitAmt.substr(0, 1),10)*10 + (parseInt(strVerSplitAmt.substr(1, 1), 10) + 1)) + MakeZeroArray(strVerSplitAmt.length - 2).join(""), 10);
string strTemp = Convert.ToString((Convert.ToInt32(strVerSplitAmt.Substring(0,1))*10)) + Convert.ToString((Convert.ToInt32(strVerSplitAmt.Substring(1,1))+1));
for(i=0;i<strVerSplitAmt.Length-strTemp.Length;i++)
strTemp += "0";
intVerSplitAmt = Convert.ToInt32(strTemp);
}
else

{ //如 12 ,处理后的值为 13
intVerSplitAmt = Convert.ToInt32(strVerSplitAmt) + 1;
}
}
//划 Y 纵坐标的坐标值( 坐标原点 O:(0,0) )
for (i = 1; i <= 5; i ++)

{
double height = 400;
double top = 0 - VerSplitLen * i - height/2; //再减去高度的一半,是为了让他看起来是居中的
string htmlVerSplit;
htmlVerSplit = "<v:shape style='width:400;left:-400;top:"+top+";height:"+height+"'>"
+ " <v:textbox inset='0,0,0,0'>" + intVerSplitAmt*i + "</v:textbox>"
+ "</v:shape>";
sReturnValue += htmlVerSplit;
}
//划垂直于 Y 轴的虚线 ( 坐标原点 O:(0,0) )
for (i = 1; i <= 5; i ++)

{
double YPoint = 0 - VerSplitLen * i;
string line;
line = "<v:line from='0,"+YPoint+"' to='7300,"+YPoint+"'>"
+ " <v:stroke dashstyle='dot' opacity='0.45' weight='0.9pt' color='#000000'/>"
+ "</v:line>";
sReturnValue += line;
}
return sReturnValue;
}



/**//**//**//*
* **************************************************************
* Function: drawRectDetail()
* Description: 划柱子( 坐标原点 O:(0,0) )
* Input:
* Where Use:
* *************************************************************
*/
private string drawRectDetail(int intAmp)

{
string sReturnValue = "";
int m = 0;
for(m = 0;m < aryDetail.Length;m ++)

{ // intAmp 给定了一个大概的矩形宽度的比例系数
double intWidth = 300.0D/intAmp + 50;
double intHeight= Convert.ToDouble(aryDetail[m]) * VerSplitLen / intVerSplitAmt;
double top = 0 - intHeight;
double left = 0 + (m+0.5) * HorSplitLen - intWidth/2; //我们让矩形落在每分的中间
string title = aryHorizon[m] + ": " + aryDetail[m];
string htmlRect; //划柱子
htmlRect = "<v:rect style='top:" + top + ";left:" + left + ";height:" + intHeight + ";width:" + intWidth + ";'"
+ " fillcolor='#0000ff' filled='T' title='" + title + "'"
+ " strokecolor='#000000' stroked='T' style='cursor:hand' onclick=alert('" + aryDetail[m] + "')>"
+ "</v:rect>";
sReturnValue += htmlRect;
string htmlDesc; //在柱子上面写注释
top -= 350;
htmlDesc = "<v:rect style='top:"+ top + ";left:"+ left + ";height:300;width:" + intWidth +"' fillcolor='#fbd9fb';filled='t'></v:rect>"
+ "<v:shape style='top:"+ top + ";left:"+ left + ";height:300;width:" + intWidth +"'>"
+ " <v:textbox style='TEXT-ALIGN: center' inset='0,0,0,0'>"+aryDetail[m]+"</v:textbox>"
+ "</v:shap>";
sReturnValue += htmlDesc;
}
return sReturnValue;
}

#endregion
}
}