ASP.NET图形化的曲线图类

chart.cs

using  System;
using  System.Drawing;

namespace  Report
{
    
///   <summary>
    
///  Chart 的摘要说明。
    
///  ==================================================================================================
    
///  
    
///     ClassName  :Report.Chart  
    
///     Intro      :
    
///     Example    :  
    
///     Ver        :0.2
    
///      
    
///     Author     :ttyp  
    
///     Email      :ttyp@21cn.com  
    
///     Date       :2007-7-30
    
///  ==================================================================================================
    
///   </summary>
     public   class  Chart
    {
        
public  Chart(){}

        
private   string     _data     =   "" ;
        
private   int         _width     =   100 ;
        
private   int         _height     =   100 ;
        
private   int         _padding =   8 ;
        
private  Color    _grid_color         =  Color.FromArgb( 0x93 , 0xbe , 0xe2 );
        
private  Color    _border_color     =  Color.FromArgb( 0x93 , 0xbe , 0xe2 );
        
private  Font    _font             =   new  Font( " Arial " , 8 );

        
public  Font Font
        {
            
get  {  return  _font;}
            
set  { _font  =  value;}
        }

        
public  Color BorderColor
        {
            
get  {  return  _border_color;}
            
set  { _border_color  =  value;}
        }

        
public  Color GridColor
        {
            
get  {  return  _grid_color;}
            
set  { _grid_color  =  value;}
        }

        
public   int  Padding
        {
            
get  {  return  _padding;}
            
set  { _padding  =  Math.Max( 0 ,value);}
        }

        
public   int  Width
        {
            
get  {  return  _width;}
            
set  { _width  =  Math.Max( 0 ,value);}
        }

        
public   int  Height
        {
            
get  {  return  _height;}
            
set  { _height  =  Math.Max( 0 ,value);}
        }

        
public   string  Data
        {
            
get  {  return  _data;}
            
set  { _data  =  value;}
        }

        
public   void  Render()
        {
            
int  width         =   this .Width;
            
int  height         =   this .Height;
            
int  padding         =   this .Padding;    
    
            
            System.Drawing.Bitmap image 
=   new  System.Drawing.Bitmap(width,height);    
            
            Graphics g 
=  Graphics.FromImage(image);

            
// 清空图片背景色
            g.Clear(Color.White);

            
// 虚线画笔
            Pen dot                 =   new  Pen( this .GridColor);
            dot.DashStyle    
=  System.Drawing.Drawing2D.DashStyle.Dot;

            
// 实线画笔
            Pen solid             =   new  Pen( this .BorderColor);

            
// 文字字体
            Font font             =   this .Font;        
            
try
            {                

                
// 冗余,去除最后的数据分割标记,防止空数据
                 if ( this .Data.EndsWith( " ; " ))
                {
                    
this .Data  =   this .Data.Substring( 0 , this .Data.Length - 1 );
                }

                
string [] info  =   this .Data.Split( ' ; ' );         // 数据信息

                
if (info.Length >= 2 )
                {
                

                    
string [] lines  =  info[ 0 ].Split( ' , ' );     // 图例
                     string [] units  =  info[ 1 ].Split( ' , ' );     // 单位和标题格式,a,b,c,d  a 纵坐标单位 b 纵坐标格式 N 数字 D 时间 后面是具体格式,c 横坐标单位 d 横坐标格式(同b)

                    
// 曲线颜色表
                    Color[] color     =   new  Color[]{Color.Blue,Color.Green,Color.Red,Color.Gray,Color.Black,Color.Magenta,Color.Cyan,Color.Yellow,Color.DeepPink,Color.BurlyWood,Color.DarkRed,Color.Gold};


                    
// 图例文字的大小
                    SizeF sFont             =  GetMaxSize(lines,g,font);

                    
// 获得刻度文字高度
                     int  textHeight         =  ( int )(sFont.Height * 3 / 2 );

                    
// 曲线点的个数
                     int  points             =  info.Length - 2 ;

                    
// 得到曲线点数组集合
                     string [,] curve  =   new   string [info.Length - 2 ,lines.Length + 1 ];
                    
for ( int  i = 0 ;i < points;i ++ )
                    {
                        
string [] l  =  info[i + 2 ].Split( ' , ' );
                        
int  len  =  l.Length;
                                                
                        
for ( int  j = 0 ;j <= lines.Length;j ++ )
                        {
                            
if (j < len)
                            {                        
                                curve[i,j] 
=  l[j];
                            }
                            
else
                            {
                                curve[i,j] 
=   " N " ;             // 非数据,不画线
                            }
                        }                
                    }        
        
                    
// 获得最大,最小值
                     double  maxY,minY,maxX,minX;

                    GetMaxMin(curve,
out  maxY, out  minY, out  maxX, out  minX);
                    
// 冗余最大最小值
                     if (maxY == minY)
                    {
                        
if (maxY == 0 )
                        {
                            maxY 
=   10 ;
                            minY 
=   - 10 ;
                        }
                        
else
                        {
                            
if (maxY > 0 )
                            {
                                maxY 
=  maxY * 2 ;
                                minY 
=   0 ;
                            }
                            
else
                            {
                                maxY 
=   0 ;
                                minY 
=  maxY * 2 ;
                            }
                        }
                    }

                    
if (maxX == minX)
                    {
                        
if (maxX == 0 )
                        {
                            maxX 
=   10 ;
                            minX 
=   - 10 ;
                        }
                        
else
                        {
                            
if (maxX > 0 )
                            {
                                maxX 
=  maxX * 2 ;
                                minY 
=   0 ;
                            }
                            
else
                            {
                                maxX 
=   0 ;
                                minX 
=  maxX * 2 ;
                            }
                        }
                    }

                    
// 获取坐标框的上下左右
                     float  left         =  (padding * 2 + sFont.Height + 2   +  sFont.Width  +  padding + GetMaxSize(units[ 1 ],g,font).Width + padding);
                    
float  bottom     =  height - padding - textHeight;
                    
float  top         =  padding;
                    
float  right         =  width  - padding;

                    
// 获取曲线框的宽度和高度(比坐标框略小)
                     float  yWidth  =  bottom - top - GetMaxSize(units[ 0 ],g,font).Height * 3 / 2 - padding;
                    
float  xWidth  =  right - left - GetMaxSize(units[ 3 ],g,font).Width / 2   -  sFont.Width  - padding;


                    
// ---------------------------------------------------------------------------------

                    
// 获取最大行
                     int  maxrow     =  ( int )(yWidth / (sFont.Height / 2 * 3 ));
                    maxrow    
=  Math.Max(maxrow, 1 );

                    
// 获取Y步进值
                     float  stepYv  =  ( float )((maxY - minY) / (maxrow));

                    
if (units[ 1 ].Length > 1 )
                    {
                        
// 整数分割,调整最大行和最大最小值
                         if (units[ 1 ].Substring( 0 , 1 ).ToLower() == " d " )
                        {
                            maxY    
=  Math.Ceiling(maxY);
                            minY    
=  Math.Floor(minY);
                            stepYv    
=  ( float )Math.Ceiling((maxY - minY) / maxrow);
                            maxrow    
=  ( int )((maxY - minY) / stepYv);                            
                        }    
                    }

                    
float  stepy         =  ( float )((yWidth / (maxY - minY)) * stepYv);

                
                    
// ---------------------------------------------------------------------------------


                    
// 得到最大的网格列(最多10列)
                     int  maxcol     =  points;
                    maxcol        
=  Math.Min(points,maxcol);
                    maxcol        
=  Math.Max(maxcol, 1 );

                    
// 获取X步进值
                     float  stepXv  =  ( float )((maxX - minX) / (maxcol));

                    
if (units[ 3 ].Length > 1 )
                    {
                        
// 整数分割,调整最大和最小值,以及步进
                         if (units[ 3 ].Substring( 0 , 1 ).ToLower() == " d " )
                        {
                            maxX    
=  Math.Ceiling(maxX);
                            minX    
=  Math.Floor(minX);
                            stepXv    
=  ( float )Math.Ceiling((maxX - minX) / maxcol);
                            maxcol    
=  ( int )((maxX - minX) / stepXv);
                        }                
                    }

                    
// 获得最大显示列数
                     int  dispcol  =  ( int )((xWidth) / (GetMaxSize(units[ 3 ].Substring( 1 ),g,font).Width + padding));
                    dispcol 
=  Math.Max(dispcol, 1 );

                    
// 如果最大显示列小于最大列,则应该缩减
                     if (dispcol < maxcol)
                    {
                        stepXv    
=  ( float )Math.Ceiling((maxX - minX) / dispcol);
                        maxcol    
=  ( int )((maxX - minX) / stepXv);
                    }


                    
float  stepx  =  ( float )((xWidth / (maxX - minX)) * stepXv);


                    
// 获得最大的曲线数目
                     int  maxline     =  color.Length;            
                    maxline        
=  Math.Min(maxline,lines.Length);


                    
// 画图例边框
                    g.DrawRectangle(solid, padding, (height - ((sFont.Height + 5 ) * maxline + 2 * padding)) / 2 ,padding * 2 + sFont.Height + 2   +  sFont.Width, (sFont.Height + 5 ) * maxline + 2 * padding);

                    
// 画图例
                     for ( int  i = 0 ;i < maxline;i ++ )
                    {
                        SolidBrush fb 
=   new  SolidBrush(color[i]);
                        SolidBrush bl 
=   new  SolidBrush(Color.Black);
                        
// 画图例方框
                        g.FillRectangle(fb,padding * 2 , (height - ((sFont.Height + 5 ) * maxline + 2 * padding)) / 2 + (sFont.Height + 5 ) * i + padding,sFont.Height, sFont.Height);
                        
// 画图例文字
                        g.DrawString(lines[i], font, bl, padding * 2 + sFont.Height + 2 ,(height - ((sFont.Height + 5 ) * maxline + 2 * padding)) / 2 + (sFont.Height + 5 ) * i + padding);

                    }                


                    
// 画坐标
                    g.DrawLine(solid,left,top,left,bottom);         // Y
                    g.DrawLine(solid,left,bottom,right,bottom);     // X

                    
// 画坐标箭头
                    g.DrawLine(solid,left,top,left - padding / 3 ,top + padding / 2 );             // Y箭头
                    g.DrawLine(solid,left,top,left + padding / 3 ,top + padding / 2 );

                    g.DrawLine(solid,right,bottom,right
- padding / 2 ,bottom - padding / 3 );     // X箭头
                    g.DrawLine(solid,right,bottom,right - padding / 2 ,bottom + padding / 3 );


                
                    
// 画X刻度
                     for ( int  i = 0 ;i <= maxcol;i ++ )
                    {
                        SolidBrush bl 
=   new  SolidBrush(Color.Black);
                        
if (i > 0 )
                        {
                            g.DrawLine(dot,left
+ i * stepx,top + padding,left + i * stepx,bottom);    
                        }

                        
string  text  =   "" ;

                        
switch (units[ 3 ].Substring( 0 , 1 ).ToString())
                        {
                            
case   " N " :
                                text 
=  (minX + stepXv * i).ToString(units[ 3 ].Substring( 1 ));
                                
break ;
                            
case   " D " :
                                text 
=  DateTime.FromOADate(( int )(minX + stepXv * i)).ToString(units[ 3 ].Substring( 1 ));                                
                                
break ;
                        }        

                        SizeF xf 
=  GetMaxSize(text,g,font);
                    
                        g.DrawString(text, font, bl, left
+ i * stepx - xf.Width / 2 ,bottom + xf.Height / 2 );                

                        
if (i == 0 )
                        {
                            g.DrawString(units[
2 ], font, bl, right - GetMaxSize(units[ 2 ],g,font).Width,bottom);                    
                        }

                        
if (points <= 1 )
                        {
                            
break ;
                        }
                    }

                    
// 画Y刻度
                     for ( int  i = 0 ;i <= maxrow;i ++ )
                    {
                        SolidBrush bl 
=   new  SolidBrush(Color.Black);

                        
if (i > 0 )
                        {
                            g.DrawLine(dot,left,bottom
- i * stepy,right - padding,bottom - i * stepy);    
                        }


                        
string  text  =   "" ;

                        
switch (units[ 1 ].Substring( 0 , 1 ).ToString())
                        {
                            
case   " N " :
                                text 
=   (minY + i * stepYv).ToString(units[ 1 ].Substring( 1 ));
                                
break ;
                            
case   " D " :
                                text 
=  DateTime.FromOADate( int .Parse(curve[i, 0 ])).ToString(units[ 1 ].Substring( 1 ));                                
                                
break ;
                        }        

                        SizeF xf 
=  GetMaxSize(text,g,font);
                    
                        g.DrawString(text, font, bl, left
- xf.Width,bottom - stepy * i - xf.Height / 2 );                

                        
if (i == 0 )
                        {
                            g.DrawString(units[
0 ], font, bl, left - GetMaxSize(units[ 0 ],g,font).Width - 3 ,top);                    
                        }
                    }

                    
// 画图片的边框线
                    g.DrawRectangle(solid,  0 0 , image.Width  -   1 , image.Height  -   1 );

                    
float [] px  =   new   float [maxline];
                    
float [] py  =   new   float [maxline];

                    
bool []    ps  =   new   bool [maxline];

                    
// 画曲线
                     for ( int  j = 0 ;j < points;j ++ )
                    {
                        
float  v   =   float .Parse(curve[j, 0 ]);
                        
float  cx  =  ( float )(left + (xWidth) * (v - minX) / (maxX - minX));

                        
for ( int  i = 0 ;i < maxline;i ++ )
                        {            
                            
try
                            {
                                
float  w   =   float .Parse(curve[j,i + 1 ]);
                                
float  cy  =  ( float )(bottom  -  (yWidth) * (w - minY) / (maxY - minY));

                                
if (ps[i])
                                {
                                    Pen cp 
=   new  Pen(color[i]);
                                    g.DrawLine(cp,px[i],py[i],cx,cy);
                                }

                                px[i] 
=  cx;
                                py[i] 
=  cy;
                                ps[i] 
=   true ;

                                
if (points == 1 )
                                {
                                    image.SetPixel((
int )cx,( int )cy,color[i]);
                                }
                            }
                            
catch
                            {
                                ps[i] 
=   false ;
                            }
                        }
                    }
                }
                
else
                {
                    
string  msg  =   " no data " ;
                    g.DrawString(msg,font,
new  SolidBrush(Color.Black), (width  -  GetMaxSize(msg,g,font).Width) / 2 ,(height - GetMaxSize(msg,g,font).Height) / 2 );
                }

                System.Web.HttpContext.Current.Response.ClearContent();
                System.Web.HttpContext.Current.Response.ContentType
= " image/Gif " ;

                image.Save(System.Web.HttpContext.Current.Response.OutputStream,System.Drawing.Imaging.ImageFormat.Gif);

            }
            
finally
            {
                g.Dispose();
                image.Dispose();
            }
        }

        
private  SizeF GetMaxSize( string [] s,Graphics g,Font f)
        {
            
string  max  =   "" ;

            
for ( int  i = 0 ;i < s.Length;i ++ )
            {
                
if (s[i].Length > max.Length)
                {
                    max 
=  s[i];
                }
            }

            
return  g.MeasureString(max,f);
        }

        
private  SizeF GetMaxSize( string  s,Graphics g,Font f)
        {
            
return  g.MeasureString(s,f);
        }

        
private   void  GetMaxMin( string [,] data, out   double  maxY, out   double  minY, out   double  maxX, out   double  minX)
        {
            
int  row  =   0 ;
            
int  col  =   0 ;

            
double  m  = double .MinValue,n = double .MaxValue;
            
double  p  = double .MinValue,q = double .MaxValue;

            row 
=  data.GetLength( 0 );
            col 
=  data.GetLength( 1 );

            
for ( int  i = 0 ;i < row;i ++ )
            {
                
for ( int  j = 0 ;j < col;j ++ )
                {
                    
double  v  =   0 ;
                    
                    
try
                    {
                        v 
=   double .Parse(data[i,j]);
                    
                        
if (j > 0 )
                        {
                            
if (v > m)
                            {
                                m 
=  v;
                            }
                            
if (v < n)
                            {
                                n 
=  v;
                            }
                        }
                        
else
                        {
                            
if (v > p)
                            {
                                p 
=  v;
                            }
                            
if (v < q)
                            {
                                q 
=  v;
                            }
                        }
                    }
                    
catch {}
                }
            }

            maxY 
=  m;
            minY 
=  n;

            maxX 
=  p;
            minX 
=  q;
        }
    }
}

使用方法

demo.cs

private   void  Page_Load( object  sender, System.EventArgs e)
        {

            
string  data  =   " Total,T1,T2,T3,T4;(kwh),N0.0,(day),Dyyyy-MM-dd; " ;

            
int  days  =   50 ;
            DateTime start 
=  DateTime.Now.AddDays( - 1 * days);

            System.Random random 
=   new  Random();

            System.Text.StringBuilder sb 
=   new  System.Text.StringBuilder();

            sb.Append(data);

            
string [] b  =   new   string [days];

            
for ( int  i = 0 ;i < days;i ++ )
            {
                
string [] a  =   new   string [ 6 ];

                a[
0 =  (( int )DateTime.Now.AddDays( - 1 * i).ToOADate()).ToString();

                
for ( int  j = 1 ;j < 6 ;j ++ )
                {
                    System.Threading.Thread.Sleep(
1 );

                    a[j] 
=  random.Next( 100 ).ToString();

                }

                b[i] 
= string .Join( " , " ,a);
            }

            sb.Append(
string .Join( " ; " ,b));

            data 
=  sb.ToString();

            Report.Chart chart 
=   new  Report.Chart();

            chart.Data        
=  data;
            chart.Width        
=   800 ;
            chart.Height    
=   200 ;
            chart.Padding    
=   8 ;
            chart.Font 
=   new  System.Drawing.Font( " 楷体2312 " , 8 );

            chart.Render();

        }

demo图


原文出处: http://blog.csdn.net/shanliwa/archive/2007/09/26/1801095.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值