ASP.net曲线图生成程序

 这是我写的一个生成简单曲线图的程序,效果还是不错的,不过其中也有一些问题,比如如果数据中出现负数,特别是很大的负数就会使得一部分曲线不能够显示出来,还有就是如何才能保证曲线处于坐标轴的中间部位?请知道的朋友帮忙看一下,谢谢。
    public static string draw(IList<TargerAnalyse.AggregativeDataSet> ds, string Field, string Title)
    
{
        
if (ds == nullreturn null;

        
if (Field == "" || Field == string.Empty || Field == nullreturn null;


        
//取得记录数量
        int count = ds.Count;

        
if (count < 2return null;

        
//图表高度
        int height = 600;
        
//记算图表宽度
        int wd = 80 + 12 * (count - 1);
        
//设置最小宽度为800
        if (wd < 800) wd = 800;
        
//生成Bitmap对像
        Bitmap img = new Bitmap(wd, height);
        
//生成绘图对像
        Graphics g = Graphics.FromImage(img);
        
//定义黑色画笔
        Pen Bp = new Pen(Color.Black);
        
//定义红色画笔
        Pen Rp = new Pen(Color.Red);
        
//定义银灰色画笔
        Pen Sp = new Pen(Color.Silver);
        
//定义大标题字体
        Font Bfont = new Font("Arial"12, FontStyle.Bold);
        
//定义一般字体
        Font font = new Font("Arial"8);
        
//定义大点的字体
        Font Tfont = new Font("Arial"10);
        
//绘制底色
        g.DrawRectangle(new Pen(Color.White, height), 00, img.Width, img.Height);
        
//定义黑色过渡型笔刷
        LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(00, img.Width, img.Height), Color.Black, Color.Black, 1.2Ftrue);
        
//定义蓝色过渡型笔刷
        LinearGradientBrush Bluebrush = new LinearGradientBrush(new Rectangle(00, img.Width, img.Height), Color.Blue, Color.Blue, 1.2Ftrue);
        
//绘制大标题
        g.DrawString(Title, Bfont, brush, 3005);
        
//左边距
        int zuobian = 40;
        
//右边距
        int youbian = 40;
        
//上边距
        int shangbian = 60;
        
//下边距
        int xiabian = 40;
        
//间隔
        int xjiange = (wd - zuobian - youbian) / count; // 60;
        int yjiange = (height - shangbian - xiabian) / count; //60;
        
//图示位置
        int ts = zuobian + xjiange * (count - 1+ 20;
        
//取得合计数
        double nums = 0;
        
//取得最小值
        double min = 0;
        
//取得最大值
        double max = 0;

        
bool IsHasNegative = false;
        
for (int i = 0; i < count; i++)
        
{
            nums 
+= Math.Abs(Convert.ToDouble(ds[i][Field]));
            
if (Convert.ToDouble(ds[i][Field]) < min)
            
{
                min 
= Convert.ToDouble(ds[i][Field]);

            }

            
if (Convert.ToDouble(ds[i][Field]) > max)
            
{
                max 
= Math.Abs(Convert.ToDouble(ds[i][Field]));
            }

            
if (Convert.ToDouble(ds[i][Field]) < 0) IsHasNegative = true;
        }


        
//绘制图片边框
        g.DrawRectangle(Bp, 00, img.Width - 1, img.Height - 1);

        
//绘制竖坐标线       
        for (int i = 0; i < count; i++)
        
{
            g.DrawLine(Sp, zuobian 
+ xjiange * i, shangbian, zuobian + xjiange * i, height - xiabian);

            
if (i % 2 == 1)
            
{
                
string st = Convert.ToString(ds[i]["bbny"]);
                g.DrawString(st, font, brush, zuobian 
+ xjiange * i - 20, height - xiabian + 5);
            }


        }

        
//绘制时间轴坐标标签
        
//for (int i = 0; i < count; i += 2)
        
//{
        
//    string st = Convert.ToString(ds.Tables[0].Rows[i]["bbny"]);
        
//    g.DrawString(st, font, brush, zuobian + xjiange * i - 20, height - xiabian+5);
        
//}
        
//绘制横坐标线
        for (int i = 0; i < count; i++)
        
{
            
if (height - xiabian - yjiange * i > shangbian)
                g.DrawLine(Sp, zuobian, height 
- xiabian - yjiange * i, zuobian + xjiange * (count - 1), height - xiabian - yjiange * i);
        }


        
//绘制竖坐标轴
        g.DrawLine(Bp, zuobian, shangbian - 15, zuobian, height - xiabian);
        
//绘制横坐标轴
        if (!IsHasNegative)
            g.DrawLine(Bp, zuobian, height 
- xiabian, zuobian + xjiange * (count - 1+ 15, height - xiabian);
        
else
            g.DrawLine(Bp, zuobian, 
300, zuobian + xjiange * (count - 1+ 15300);

        
//均值所对应得Y坐标
        int zhy = (int)(((double)(height - shangbian - xiabian)) * nums / count / max) - (height - shangbian - xiabian) / 2;

        
//定义曲线转折点
        Point[] p = new Point[count];
        
for (int i = 0; i < count; i++)
        
{
            p[i].X 
= zuobian + xjiange * i;
            
//p[i].Y = 360 - Convert.ToInt32(ds.Tables[0].Rows[i][Field]) / 5 * 3 / 5;
            
//p[i].Y =Convert.ToInt32( System.Math.Round(Convert.ToDouble(height-shangbian-xiabian)*(Convert.ToDouble(ds.Tables[0].Rows[i][Field])) / nums))+shangbian ;
            if (!IsHasNegative)
                p[i].Y 
= height - (int)((double)(height - shangbian - xiabian) * (Convert.ToDouble(ds[i][Field])) / max) + shangbian + zhy - xiabian;
            
else
            
{
                
if (Convert.ToDouble(ds[i][Field]) > 0)
                    p[i].Y 
= height / 2 - (int)((double)(height / 2 - shangbian) * (Convert.ToDouble(ds[i][Field])) / max) + shangbian;
                
else
                    p[i].Y 
= height / 2 + (int)((double)(height / 2 - xiabian) * (Math.Abs(Convert.ToDouble(ds[i][Field]))) / max);

            }

        }


        
//绘制曲线
        g.DrawCurve(Rp, p);

        
for (int i = 0; i < count; i++)
        
{
            
//绘制数据
            g.DrawString(ds[i][Field].ToString(), font, Bluebrush, p[i].X - 5, p[i].Y - 10);
            
//绘制数据点
            g.DrawRectangle(Rp, p[i].X - 1, p[i].Y - 122);
        }

        
//绘制竖坐标标题
        g.DrawString("指标", Tfont, brush, 5, shangbian - 20);
        
//绘制横坐标标题
        g.DrawString("月度", Tfont, brush, zuobian + xjiange * (count - 1+ 20, height - xiabian + 5);


        
//保存绘制的图片
        
//MemoryStream stream = new MemoryStream();
        
//img.Save(stream, ImageFormat.Jpeg);
        Random r = new Random(1);
        
string filepath = System.Web.Hosting.HostingEnvironment.MapPath("~\\chart\\"+ r.Next().ToString() + ".jpg";
        img.Save(filepath, ImageFormat.Jpeg);
        g.Dispose();
        img.Dispose();
        
//return stream;
        return filepath;
    }
正常情况下的曲线图:

出现问题时的曲线图:
posted @ 2007-05-14 12:10  秦巴故人  阅读(5926)  评论(9编辑  收藏  举报