/// ///////////////////////////////////////////////////////////////////////
/// 控件说明:图表控件支持直线,矩形,饼图三种样式
///         Items:需要图像化的数据(传入DataTable)
///         Text:图表名称
///         DataStdName:标准值名称
///         DataName:对比值名称
///         ChatStyle :图表类型(ColumniationStyle)
///         Kddw:刻度单位,这里柱状图用的刻度单位是100
///         KdCount:刻度数,这里柱状图用的是5
/// 日期:20050623
/// 修改说明:from CNblogs
///////////////////////////////////////////////////////////////////////////


using System;
using System.Collections;
using System.Web.UI;
using System.Data;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Web;
using System.ComponentModel;

[ assembly: TagPrefix(
"WebControl""ci") ]
namespace WebControl
{
    
public enum ColumniationStyle
    
{
        histogram, beeline, caky
    }


    
/// <summary>
    
///    柱状图控件
    
///    需要传入列表项名,值,超级连接地址
    
/// </summary>

    [ToolboxData("<{0}:Columniation runat=server></{0}:Columniation>")]
    
public class Columniation: System.Web.UI.WebControls.WebControl
    
{
        
private DataTable items;//列表项名称和值
       
        
private string text="实时数据";
        
private string datastd="标准值";
        
private string data="实时数据";
        
private ColumniationStyle _showType = ColumniationStyle.histogram;

        
int kds=5//刻度数
        int kddw=100;  //没刻度大小

        
int zmheight=300//真个图区高
        int zmwidth=640;  //真个图区宽

        
int height=250;//呈现区高
        int width=530;
        
int cxtop=30;//呈现区距顶距离
        int cxleft=30;//呈现区左边距离

        Color bzlink
=Color.Black;//标准线颜色
        Color bz=Color.Coral;//标准柱颜色
        Color ss=Color.CornflowerBlue;//实时柱颜色

        
//int cx=1;
    

        [Bindable(
true),Category("Appearance"),DefaultValue("")]
        
public string Text
        
{
            
get
            
{
                
return text;
            }


            
set
            
{
                text 
= value;
            }

        }

        
        [Bindable(
true),Category("Appearance"),DefaultValue("")]
        
public string DataStdName
        
{
            
get
            
{
                
return datastd;
            }


            
set
            
{
                datastd 
= value;
            }

        }


        [Bindable(
true),Category("Appearance"),DefaultValue("")]
        
public string DataName
        
{
            
get
            
{
                
return data;
            }


            
set
            
{
                data 
= value;
            }

        }


        
/// <summary>
        
/// 文本框中显示值还是名称。缺省显示值。
        
/// </summary>

        [Bindable(true), Category("Schema"), DefaultValue(ColumniationStyle.histogram),
        Description(
"图表样式,默认为柱状图"), DesignOnly(true)]
        
public ColumniationStyle ShowType
        
{
            
get
            
{
                
return this._showType ;
            }

            
set
            
{
                
this._showType = value;
            }

        }
    

        
/// <summary>
        
/// 需要呈现的数据
        
/// </summary>

        public DataTable Items
        
{
            
set
            
{items=value;}
        }


        
/// <summary>
        
/// 需要显示的刻度量
        
/// </summary>

        public int Kdcount
        
{
            
set {kds=value;}
        }


        
/// <summary>
        
/// 刻度大小
        
/// </summary>


        
public int Kddw
        
{set{kddw=value;}}
        


        
public ColumniationStyle ChatStyle
        
{set{this._showType=value;}}


        
/// <summary> 
        
/// 将此控件呈现给指定的输出参数。
        
/// </summary>
        
/// <param text="output"> 要写出到的 HTML 代码 </param>

        protected override void Render(HtmlTextWriter output)
        
{
            
//设计样式
            output.Write(makeimage(items,@"c:/"));
            
        }


        
private string makeimage(DataTable dt,string imagefile)
        
{
            
if(dt==null)
            
{
                
return "没有数据";
            }


            
//调整宽度
            width=30*dt.Rows.Count+10;
            zmwidth
=width+cxleft+80;
            
//Font
            Font fontlegend = new Font("verdana",9);
            
//创建一个画布
            Bitmap bm=new Bitmap(zmwidth,zmheight);
            
//在新建的画布上画一个图
            Graphics bp=Graphics.FromImage(bm);
            
//填充背景
            bp.Clear(Color.White);
            
//填充图表呈现区背景(画刷,起点x,起点Y,高,宽)
            bp.FillRectangle(new SolidBrush(Color.WhiteSmoke),cxleft,cxtop,width,height);
            
//描绘呈现区边框
            bp.DrawRectangle(Pens.Black,cxleft,cxtop,width,height);
            
//绘制图表名称
            bp.DrawString(text,fontlegend,new SolidBrush(Color.Black),new PointF(zmwidth/2,10));
            
            
if(this._showType!=ColumniationStyle.caky)
            
{
                
//绘制图表说明
                bp.DrawRectangle(Pens.Black,cxleft+width+10,zmheight/2,60,30);
                
//标准图例
                bp.FillRectangle(new SolidBrush(bz),cxleft+width+10+2,zmheight/2+4,8,8);
                
//文字说明
                bp.DrawString(datastd,fontlegend,new SolidBrush(Color.Black),new PointF(cxleft+width+10+2+8,zmheight/2+4));
                
//实时图例
                bp.FillRectangle(new SolidBrush(ss),cxleft+width+10+2,zmheight/2+16,8,8);
                
//文字说明
                bp.DrawString(data,fontlegend,new SolidBrush(Color.Black),new PointF(cxleft+width+10+2+8,zmheight/2+16));
                
//通过循环绘制标准线
                for(int i=1;i<=kds;i++)
                
{
                    
if(i*bl(kddw)>height)
                    
{break;}
                    
//绘制刻度名
                    bp.DrawString(System.Convert.ToString((i*kddw)),fontlegend,new SolidBrush(Color.Black),new PointF(2,zmheight-(bl(i*kddw)+(zmheight-cxtop-height)+4)));
                    
//填充标准线(画刷,起点X,起点Y,宽,高)
                    int top=zmheight-((int)bl(i*kddw)+(zmheight-cxtop-height));
                    bp.DrawLine(
new Pen(bzlink),new Point(cxleft-4,top),new Point(cxleft+width,top));
                }

            }

            
            
switch(this._showType)
            
{
                
case ColumniationStyle.histogram:
                
{
                    
#region  柱状图
                    
//通过循环画出柱状图
                    for(int i=0;i<dt.Rows.Count;i++)
                    
{   
                        
//标准刻度
                        float bzkd=bl(Convert.ToSingle(dt.Rows[i].ItemArray[1]));
                        
//实际刻度
                        float sjkd=bl(Convert.ToSingle(dt.Rows[i].ItemArray[2]));
                        
int top=zmheight-(int)bzkd-(zmheight-cxtop-height);
                        
//填充标准柱(画刷,起点X,起点Y,宽,高)
                        bp.FillRectangle(new SolidBrush(bz),(i*30)+cxleft+10,top,10,bzkd);
                        top
=zmheight-(int)sjkd-(zmheight-cxtop-height);
                        bp.FillRectangle(
new SolidBrush(ss),(i*30)+cxleft+20,top,10,sjkd);
                
                        
//填充项目名称(输出文字,字体,画刷,位置)
                        bp.DrawString(dt.Rows[i].ItemArray[0].ToString(),fontlegend,new SolidBrush(Color.Black),new PointF((i*30)+cxleft+5,height+cxtop+1));
                
                    }

                    
#endregion

                    
break;
                }

                
case ColumniationStyle.beeline:
                
{
                    
#region  曲线
                    
//通过循环画出曲线图   
                    int x=-1;
                    
int bzy=-1;
                    
int ssy=-1;
                    
for(int i=0;i<dt.Rows.Count;i++)
                    
{   
               
                        
//标准刻度
                        float bzkd=bl(Convert.ToSingle(dt.Rows[i].ItemArray[1]));
                        
//实际刻度
                        float sjkd=bl(Convert.ToSingle(dt.Rows[i].ItemArray[2]));
                        
int bztop=zmheight-(int)bzkd-(zmheight-cxtop-height)-3;
                        
//填充标准柱(画刷,起点X,起点Y,宽,高)
                        bp.FillRectangle(new SolidBrush(bz),(i*30)+cxleft,bztop,6,6);
                        
int sstop=zmheight-(int)sjkd-(zmheight-cxtop-height)-3;
                        
//填充实时点(画刷,起点X,起点Y,宽,高)
                        bp.FillRectangle(new SolidBrush(ss),(i*30)+cxleft,sstop,6,6);
                    
                        
//绘制点到点连接线
                        if(x!=-1)
                        
{
                            
//绘制标准点连接线
                            bp.DrawLine(new Pen(bz,1.6F),new Point(x-3,bzy+4),new Point((i*30)+cxleft+10,bztop+4));
                            
//绘制实时点连接线
                            bp.DrawLine(new Pen(ss,1.6F),new Point(x+3,ssy+4),new Point((i*30)+cxleft+10,sstop+4));
                        }

                        x
=(i*30)+cxleft+10;
                        bzy
=bztop;
                        ssy
=sstop;
                    }

                    
#endregion

                    
break;
                }

                
case ColumniationStyle.caky:
                
{
                    
#region 饼图
                    
float currentdegree=0.0f;
                    
                    StringFormat stringFormat 
= new StringFormat();
                    stringFormat.Alignment 
= StringAlignment.Near;
                    stringFormat.LineAlignment 
= StringAlignment.Center;
                    
                    Hashtable arlNum 
= new Hashtable();    
                    
float total = 0;    

                    SolidBrush blackbrush
=new SolidBrush(Color.Black);
                    
                    
for(int i=0;i<dt.Rows.Count;i++)
                    
{  
                        arlNum.Add(i, dt.Rows[i].ItemArray[
1]);
                        total 
+= Convert.ToInt32(dt.Rows[i].ItemArray[1]);
                    }


                    Rectangle pierect 
= new Rectangle(cxleft+width/6,cxtop, height-20, height-20);

                    
int eHeight = 12;
                    
int TitleX = cxleft+width/2+width/4;
                    
int TitleY = 0;    
                    
foreach(DictionaryEntry ht in arlNum)
                    
{
                        SolidBrush brush 
= new SolidBrush(PieColor(Convert.ToInt32(ht.Key)));

                        
//******画扇形图及其中的百分比********//
                        bp.FillPie(brush, pierect, currentdegree,Convert.ToSingle(ht.Value) / total * 360);
                            
                        currentdegree 
+= Convert.ToSingle(ht.Value) / total * 360;

                        
//示例图(画刷,起点X,起点Y,宽,高)
                        TitleY = cxtop+Convert.ToInt32(ht.Key)*eHeight;
                        bp.FillRectangle(brush,TitleX,TitleY
+4,50,16);
                        bp.DrawRectangle(Pens.Black,TitleX,TitleY
+4,50,16);
                        
//Font
                        string sfont = Convert.ToString(Math.Round(Convert.ToDecimal(Convert.ToInt32(ht.Value) * 100 / total),2)) + "%";
                        bp.DrawString(sfont, fontlegend, blackbrush,
new PointF(TitleX+2,TitleY+14), stringFormat);
                        bp.DrawString(dt.Rows[Convert.ToInt32(ht.Key)][
0].ToString(), fontlegend, blackbrush,new PointF(TitleX+54,TitleY+14), stringFormat);
                    
                    }

                    
#endregion

                    
break;
                }


            }

                
            
            FileStream fs
=new FileStream(Page.Server.MapPath(Page.Request.Url.AbsolutePath.Replace(".aspx",".jpg")),FileMode.Create);
            bm.Save(fs,ImageFormat.Jpeg);

            bm.Dispose();
            bp.Dispose();
            fs.Close();
                    
            
return "<img src="+Page.Request.Url.AbsolutePath.Replace(".aspx",".jpg")+" ></img>";
    
        }



        
private Color PieColor(int intColor)
        
{
            
switch(intColor)
            
{
                
case 1:
                    
return Color.Blue;
                
case 2:
                    
return Color.Green;
                
case 3:
                    
return Color.GreenYellow;
                
case 4:
                    
return Color.Red;
                
case 5:
                    
return Color.Brown;
                
case 6:
                    
return Color.DarkGray;
                
case 7:
                    
return Color.Salmon;
                
case 8:
                    
return Color.Plum;
                
case 9:
                    
return Color.SkyBlue;
                
case 10:
                    
return Color.AliceBlue;
                
case 11:
                    
return Color.AntiqueWhite;
                
case 12:
                    
return Color.Aquamarine;
                
case 13:
                    
return Color.Azure;
                
case 14:
                    
return Color.Beige;
                
case 15:
                    
return Color.Bisque;
                
case 16:
                    
return Color.BlanchedAlmond;
                
case 17:
                    
return Color.BlueViolet;
                
case 18:
                    
return Color.BurlyWood;
                
case 19:
                    
return Color.CadetBlue;
                
case 20:
                    
return Color.Chartreuse;
                
default:
                    
return Color.Moccasin;
            }

        }



        
/// <summary>
        
/// 换算成实际值
        
/// </summary>
        
/// <param text="kd">提供的值</param>
        
/// <returns>返回换算后的实际值</returns>

        private float bl(float kd)
        
{
            
float bls=1;
            bls
=(float)height/((float)kds*(float)kddw);
            
return (float)kd*bls;
        }


    }


}

效果:

di
调用示例:
        private void ShowData()
        
{
            DataTable dt
=new DataTable();
            
            
            dt.Columns.AddRange(
new DataColumn[]{new DataColumn("name",typeof(string)),
                                                    
new DataColumn("bz",typeof(Decimal)),
                                                    
new DataColumn("db",typeof(Decimal))
                                                
                                                }
);
            
            DataRow dr
=dt.NewRow();
            
            dr[
"name"]="点1";
            dr[
"bz"]="100";
            dr[
"db"]="150";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点2";
            dr[
"bz"]="110";
            dr[
"db"]="200";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点3";
            dr[
"bz"]="120";
            dr[
"db"]="300";
            dt.Rows.Add(dr);

            
            dr
=dt.NewRow();
            dr[
"name"]="点4";
            dr[
"bz"]="130";
            dr[
"db"]="250";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点5";
            dr[
"bz"]="140";
            dr[
"db"]="400";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点6";
            dr[
"bz"]="150";
            dr[
"db"]="375";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点7";
            dr[
"bz"]="160";
            dr[
"db"]="437";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点8";
            dr[
"bz"]="170";
            dr[
"db"]="340";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点9";
            dr[
"bz"]="180";
            dr[
"db"]="50";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点10";
            dr[
"bz"]="190";
            dr[
"db"]="460";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点11";
            dr[
"bz"]="200";
            dr[
"db"]="150";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点12";
            dr[
"bz"]="210";
            dr[
"db"]="200";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点13";
            dr[
"bz"]="220";
            dr[
"db"]="300";
            dt.Rows.Add(dr);

            
            dr
=dt.NewRow();
            dr[
"name"]="点14";
            dr[
"bz"]="230";
            dr[
"db"]="250";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点15";
            dr[
"bz"]="240";
            dr[
"db"]="400";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点16";
            dr[
"bz"]="250";
            dr[
"db"]="375";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点17";
            dr[
"bz"]="260";
            dr[
"db"]="437";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点18";
            dr[
"bz"]="270";
            dr[
"db"]="340";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点19";
            dr[
"bz"]="280";
            dr[
"db"]="50";
            dt.Rows.Add(dr);

            dr
=dt.NewRow();
            dr[
"name"]="点20";
            dr[
"bz"]="290";
            dr[
"db"]="460";
            dt.Rows.Add(dr);

    
            Columniation1.Items 
=dt;
            Columniation1.Kddw 
= 100;
            Columniation1.Kdcount 
= 5;
            Columniation1.ChatStyle
=this.style;
            
//string path=@"c:/";
            
//DIV1.InnerHtml = this.makeimage(dt,path);

        }
posted on 2006-08-30 11:40  冷火  阅读(314)  评论(0编辑  收藏  举报