zoukankan      html  css  js  c++  java
  • 用c#画饼图和条形图,做数据统计

    先上效果图:

    饼图:

    条形图:

    通过在网上找资料,自己稍微整理下,注释配代码如下:

    1、画饼图的全部代码

    /// <summary>       

    /// 根据四率 得到扇形图       

    /// </summary>       

    /// <param name="width"></param>       

    /// <param name="heigh"></param>       

    /// <param name="r">饼图半径</param>       

    /// <param name="familyName"></param>       

    /// <param name="data"></param>       

    /// <returns></returns>       

    public Bitmap GetBitmap(int width, int heigh, int r,string familyName, Dictionary<string, double> data)       

    {           

        Bitmap bitmap = new Bitmap(width, heigh);           

        Graphics graphics = Graphics.FromImage(bitmap);

                //用白色填充整个图片,因为默认是黑色           

        graphics.Clear(Color.White);

                //抗锯齿           

        graphics.SmoothingMode = SmoothingMode.HighQuality;

                //高质量的文字           

        graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;

                //像素均偏移0.5个单位,以消除锯齿           

        graphics.PixelOffsetMode = PixelOffsetMode.Half;

                //第一个色块的原点位置           

        PointF basePoint = new PointF(10, 20);

                //色块的大小           

        SizeF theSize = new SizeF(45, 16);

                //第一个色块的说明文字的位置           

        PointF textPoint = new PointF(basePoint.X + 50, basePoint.Y);           

        foreach (var item in data)           

        {               

        RectangleF baseRectangle = new RectangleF(basePoint, theSize);               

        //画代表色块               

        graphics.FillRectangle(new SolidBrush(getColor(item.Key.ToString())), baseRectangle);

              graphics.DrawString(item.Key.ToString(), new Font(familyName, 11), Brushes.Black, textPoint);

              basePoint.Y += 30;               

        textPoint.Y += 30;           

       }

                //扇形区所在边框的原点位置           

        Point circlePoint = new Point(Convert.ToInt32( textPoint.X+90),35);

                //总比 初始值           

        float totalRate = 0;           

        //起始角度 Y周正方向           

        float startAngle = 30;           

        //当前比 初始值           

        float currentRate = 0;

                //圆所在边框的大小           

        Size cicleSize=new Size(r*2,r*2);

                //圆所在边框的位置           

        Rectangle circleRectangle=new Rectangle(circlePoint,cicleSize);

                foreach (var item in data) totalRate += float.Parse(item.Value.ToString());           

    foreach (var item in data)           

    {               

          currentRate = float.Parse(item.Value.ToString()) / totalRate * 360;

                    graphics.DrawPie(Pens.White, circleRectangle, startAngle, currentRate);               

          graphics.FillPie(new SolidBrush(getColor(item.Key.ToString())), circleRectangle, startAngle, currentRate);

                    //至此 扇形图已经画完,下面是在扇形图上写上说明文字

                    //当前圆的圆心 相对图片边框原点的坐标               

          PointF cPoint = new PointF(circlePoint.X+r, circlePoint.Y+r);

                    //当前圆弧上的点               

          //cos(弧度)=X轴坐标/r               

          //弧度=角度*π/180               

          double relativeCurrentX = r * Math.Cos((360 - startAngle - currentRate / 2) * Math.PI / 180);               

          double relativecurrentY = r * Math.Sin((360 - startAngle - currentRate / 2) * Math.PI / 180);

                    double currentX = relativeCurrentX+cPoint.X;               

        double currentY = cPoint.Y - relativecurrentY;

                    //内圆上弧上的 浮点型坐标               

        PointF currentPoint=new PointF(float.Parse(currentX.ToString()),float.Parse(currentY.ToString()));               

        //外圆弧上的点          

            double largerR = r + 25;

                    double relativeLargerX = largerR * Math.Cos((360 - startAngle - currentRate / 2) * Math.PI / 180);               

        double relativeLargerY = largerR * Math.Sin((360 - startAngle - currentRate / 2) * Math.PI / 180);

                    double largerX = relativeLargerX + cPoint.X;               

        double largerY = cPoint.Y - relativeLargerY;

                    //外圆上弧上的 浮点型坐标                

        PointF largerPoint=new PointF(float.Parse(largerX.ToString()),float.Parse(largerY.ToString()));

                    //将两个点连起来                

          //graphics.DrawLine(Pens.Black, currentPoint, largerPoint);

                    //外圆上 说明文字的位置                

        PointF circleTextPoint = new PointF(float.Parse( largerX.ToString()),float.Parse( largerY.ToString()));                              

        //在外圆上的点的附近合适的位置 写上说明                

      if (largerX >= 0 && largerY >= 0)//第1象限  实际第二象限                

    {                    

    //circleTextPoint.Y -= 15;                    

    circleTextPoint.X -= 35;               

      }

                     if (largerX <= 0 && largerY >= 0)//第2象限  实际第三象限                

    {                

         //circleTextPoint.Y -= 15;                    

    //circleTextPoint.X -= 65;                

    }             

        if (largerX <= 0 && largerY <= 0)//第3象限  实际第四象限                

    {                 

        //circleTextPoint.X -= 45;               

          circleTextPoint.Y += 30;              

       }               

      if (largerX >= 0 && largerY <= 0)//第4象限  实际第一象限                

    {                    

    circleTextPoint.X -= 15;                    

    //circleTextPoint.Y += 5;                

    }

                    //象限差异解释:在数学中 二维坐标轴中 右上方 全为正,在计算机处理图像时,右下方全为正。相当于顺时针移了一个象限序号                              

        graphics.DrawString(item.Key.ToString() + " " + (currentRate/360).ToString("p2"), new Font(familyName, 11), Brushes.Black, circleTextPoint);                       

               startAngle += currentRate;           

    }

                return bitmap;      

    }

    2、获得配色的代码:

            Color getColor(string scoreLevel)         {           

    Color c=Color.White;          

      if (scoreLevel.Contains("优秀"))           

         c = Color.FromArgb(57,134,155);         

       if (scoreLevel.Contains("良好"))               

    c = Color.FromArgb(70,161,185);           

    if (scoreLevel.Contains("一般"))               

    c = Color.FromArgb(124,187,207);           

    if (scoreLevel.Contains("不及格"))               

    c = Color.FromArgb(181,212,224);

                return c;       

    }

    3、画条形图的代码

       /// <summary>     

       /// 获得柱状图      

      /// </summary>      

      /// <param name="width"></param>     

       /// <param name="heigh"></param>      

      /// <param name="familyName"></param>      

      /// <param name="data"></param>       

    /// <param name="PaperScore"></param>      

      /// <returns></returns>       

    public Bitmap GetBargraph(int width, int heigh, string familyName, Dictionary<string, double> data, int PaperScore)      

      {             if (data != null)         

       {

                    Bitmap bitmap = new Bitmap(width, heigh);          

          Graphics graphics = Graphics.FromImage(bitmap);             

       //用白色填充整个图片,因为默认是黑色               

    graphics.Clear(Color.White);     

               //抗锯齿            

        graphics.SmoothingMode = SmoothingMode.HighQuality;        

            //高质量的文字             

       graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;           

         //像素均偏移0.5个单位,以消除锯齿            

        graphics.PixelOffsetMode = PixelOffsetMode.Half;              

      double maxCount = 0;            

        //以最多人数为基准            

        foreach (var item in data) if (Convert.ToDouble(item.Value.ToString()) > maxCount)                 

           maxCount = Convert.ToDouble(item.Value.ToString());

                    //在距离底部25像素的地方 画上分数线 并标上四个分数         

           //该分数线的宽度是图片宽度的85%             

       //分数线原点位置        

            PointF scoreLineStartPoint = new PointF(width * 0.15f / 2f, heigh - 25f);        

            //分数线终点位置               

    PointF scoreLineEndPoint = new PointF(scoreLineStartPoint.X + width * 0.85f, scoreLineStartPoint.Y);         

           graphics.DrawLine(Pens.Black, scoreLineStartPoint, scoreLineEndPoint);           

         //定义:最多人数的那项占图片高度的85%             

       //每项*高度的85%/maxCount=该项的高度

                    float currentX = width * 0.85f * (1f / 9)//直线上的1/9处为起点            

            + width * 0.15f / 2// 图片的两边 空 15%  ,每边空15%的一半                     ;        

            float perWidth = width * 0.85f * (1f / 9);              

      foreach (var item in data)              

      {

                        //当前等级的原点描述:Height-25-(人数*0.9/maxcount)           

             float currentHeight = (float)item.Value * 0.85f * heigh / (float)maxCount;

                        //颜色 全部用淡蓝色                 

       graphics.FillRectangle(new SolidBrush(Color.FromArgb(70, 161, 187)), currentX, heigh - 25 - currentHeight - 1, perWidth, currentHeight);

                        //画当前区间的左边的线                 

       graphics.DrawLine(Pens.Black, currentX, scoreLineStartPoint.Y, currentX, scoreLineStartPoint.Y + 3);

                        //在上面5像素处写上人数

                        graphics.DrawString(item.Value.ToString() + "(人)", new Font(familyName, 11), Brushes.Black, currentX - 4, heigh - 25 - currentHeight - 1 - 18);

                        graphics.DrawString(item.Key.ToString(), new Font(familyName, 11), Brushes.Black, currentX, scoreLineStartPoint.Y + 3);

                        currentX += perWidth;//向右移一个柱形宽度单位              

          //画当前区间的右边的线                

        graphics.DrawLine(Pens.Black, currentX, scoreLineStartPoint.Y, currentX, scoreLineStartPoint.Y + 3);     

                   currentX += perWidth;//向右移一个柱形宽度单位                 }

                    graphics.DrawString("(等级)", new Font(familyName, 11), Brushes.Black, currentX - perWidth + 3f, scoreLineStartPoint.Y + 3);   

                 return bitmap;             }             else return null;         }

    4、调用柱状图的一般处理程序(饼图类似)

                string datas = context.Request.QueryString["data"];

                ScoreStatistics s = new ScoreStatistics();           

    data = s.TransferToObject<Dictionary<string, double>>(datas);

          

                MemoryStream mem = new MemoryStream();           

    Bitmap chart = scoreStaticsBLL.GetBargraph(450, 280, "宋体", data, 120);           

    chart.Save(mem, ImageFormat.Jpeg);           

    context.Response.ContentType = "image/jpeg";

                context.Response.BinaryWrite(mem.ToArray());

    调用图片的页面代码就是一个 图片控件,src的地址为上面的一般处理程序的相对网站地址

  • 相关阅读:
    文件编程---库函数
    linux文件编程----系统调用
    makefile工程管理
    快速上手日期插件laydate
    js判断浏览器类型以及语言
    谷歌支付服务端详细讲解(PHP)
    php中的date和strtotime函数妙用
    本地搭建GitLab
    mysql查询语句常用字段操作函数
    php中签名公钥、私钥(SHA1withRSA签名)以及AES(AES/ECB/PKCS5Padding)加密解密详解
  • 原文地址:https://www.cnblogs.com/langu/p/2586205.html
Copyright © 2011-2022 走看看