首页 新闻 会员 周边

C# 绘制统计图

0
悬赏园豆:5 [已解决问题] 解决于 2010-01-25 20:44

C# 绘制统计图(柱状图, 折线图, 扇形图)

yadxmy的主页 yadxmy | 初学一级 | 园豆:195
提问于:2010-01-23 19:05
< >
分享
最佳答案
0

最好用控件,要不自己画,我只做过柱状图,自己画的,给你参考参考

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.Web.UI.HtmlControls;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing;
using System.IO;


public partial class ShopFlow_Total_SFTotalGraph : System.Web.UI.Page
{
    protected string connStr = Utils.ConnectionShopFlow;
    protected DataTable dt = null;
    protected string sqlStr = "";
    private void Page_Load(object sender, System.EventArgs e) //自己的代码(绘制柱状图)
    {
        string mCO = "";
        string mProcess = "";
        string mDDate = "";
        if (Session["CO"] != null)
        {
            mCO = Session["CO"].ToString().Trim();
        }
        else
        {
            mCO = "SZ";

        }
        mDDate = Request.Params["DDate"].ToString().Trim();
        mProcess = Request.Params["Process"].ToString().Trim();
        sqlStr = "SFTotalGraph '"+mCO+"','"+mDDate+"','"+mProcess+"'";
        dt = Utils.executeQueryT(sqlStr, Utils.ConnectionShopFlow);
        MemoryStream stream = new MemoryStream();
        MemoryStream columnarStream = new MemoryStream();
        Bitmap graph = null;

        string mID = Request.Params["ID"].ToString().Trim();
        if (mID == "1")
        {
            graph = getLineGraph("KPI Monitor", 800, 450, dt);
        }
        else
        {
            graph = getColumnarGraph("Hour Yield Columnar Graph", 800, 300, dt);
        }
        graph.Save(stream, ImageFormat.Jpeg);
        //图片输出
        Response.Clear();
        Response.ContentType = "image/jpeg";
        Response.BinaryWrite(stream.ToArray());
    }

    public Bitmap getColumnarGraph(string title, int width, int height, DataTable chartTable)
    {
        string mProcess = Request.Params["Process"].ToString().Trim();
        Bitmap bm = new Bitmap(width, height);
        Graphics g = Graphics.FromImage(bm);
        g.Clear(Color.White);

        DataTable dt = chartTable;
        const int top = 60;
        const int left = 50;

        if (width < left * 2 || height < top * 2)
        {
            g.DrawString("绘图区域太小", new Font("Tahoma", 8),
                Brushes.Blue, new PointF(0, 0));
            return bm;
        }

        //计算最高的点 
        float highPoint = 1;
        foreach (DataRow dr in dt.Rows)
        {
            if (highPoint < Convert.ToSingle(dr[0]))
            {
                highPoint = Convert.ToSingle(dr[0]);
            }

            if (highPoint < Convert.ToSingle(dr[1]))
            {
                highPoint = Convert.ToSingle(dr[1]);
            }

            if (highPoint < Convert.ToSingle(dr[2]))
            {
                highPoint = Convert.ToSingle(dr[2]);
            }
        }
        try
        {
            //画大标题 
            g.DrawString(title, new Font("Tahoma", 16), Brushes.Fuchsia, new PointF(2, 2));
            StringFormat drawFormat = new StringFormat();
            drawFormat.FormatFlags = StringFormatFlags.DirectionVertical;

            if (mProcess == "ALL" || mProcess == "SMT")
            {
                g.DrawString("[红--" + dt.Columns[0].ToString() + "]", new Font("Tahoma", 8),
                    Brushes.Red, new PointF(2, top), drawFormat);
            }
            if (mProcess == "ALL" || mProcess == "DIP")
            {
                g.DrawString("[蓝--" + dt.Columns[1].ToString() + "]", new Font("Tahoma", 8),
                    Brushes.Blue, new PointF(17, top), drawFormat);
            }
            if (mProcess == "ALL" || mProcess == "TEST")
            {
                g.DrawString("[绿--" + dt.Columns[2].ToString() + "]", new Font("Tahoma", 8),
                    Brushes.Green, new PointF(32, top), drawFormat);
            }

            //画条形图 
            float barWidth = (Convert.ToSingle(width) - left) / (dt.Rows.Count * 4 + 1);
            PointF barOrigin = new PointF(left + barWidth, 0);
            float barHeight = dt.Rows.Count;
            float topFontSize = (barWidth / highPoint.ToString().Length);

            if (topFontSize > 2 * top / 3)
            {
                topFontSize = 2 * top / 3;
            }
            if (topFontSize < 5)
            {
                topFontSize = 5;
            }
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                //底部字体的大小
                float bottomFontSize = (2 * barWidth / dt.Rows[i][3].ToString().Length) + 2;
                if (bottomFontSize > 2 * top / 3)
                {
                    bottomFontSize = 2 * top / 3;
                }

                barHeight = Convert.ToSingle(dt.Rows[i][0]) * (height - 2 * top) / highPoint * 1;
                barOrigin.Y = height - barHeight - top;
                g.FillRectangle(new SolidBrush(Color.Red), barOrigin.X, barOrigin.Y, barWidth, barHeight);
                //柱状图底部
                g.DrawString(dt.Rows[i][3].ToString(), new Font("Tahoma", bottomFontSize), Brushes.Black,
                    new PointF(barOrigin.X, height - top));
                //柱状图顶部
                g.DrawString(dt.Rows[i][0].ToString(), new Font("Tahoma", topFontSize), Brushes.Red,
                    new PointF(barOrigin.X, barOrigin.Y - 3 * topFontSize / 2));

                barOrigin.X = barOrigin.X + barWidth;


                barHeight = Convert.ToSingle(dt.Rows[i][1]) * (height - 2 * top) / highPoint * 1;
                barOrigin.Y = height - barHeight - top;
                g.FillRectangle(new SolidBrush(Color.Blue), barOrigin.X, barOrigin.Y, barWidth, barHeight);
                //柱状图顶部
                g.DrawString(dt.Rows[i][1].ToString(), new Font("Tahoma", topFontSize), Brushes.Blue,
                    new PointF(barOrigin.X, barOrigin.Y - 3 * topFontSize / 2));
                barOrigin.X = barOrigin.X + (barWidth);


                barHeight = Convert.ToSingle(dt.Rows[i][2]) * (height - 2 * top) / highPoint * 1;
                barOrigin.Y = height - barHeight - top;
                g.FillRectangle(new SolidBrush(Color.Green), barOrigin.X, barOrigin.Y, barWidth, barHeight);
                //柱状图顶部
                g.DrawString(dt.Rows[i][1].ToString(), new Font("Tahoma", topFontSize), Brushes.Green,
                    new PointF(barOrigin.X, barOrigin.Y - 3 * topFontSize / 2));
                barOrigin.X = barOrigin.X + (barWidth * 2);
            }

            //设置边 
            g.DrawLine(new Pen(Color.Black, 2), new Point(left, top),
                new Point(left, height - top));

            g.DrawLine(new Pen(Color.Black, 2), new Point(left, height - top),
                new Point(left + width, height - top ));

            g.Dispose();
            return bm;
        }
        catch
        {
            return bm;
        }
    }

    public Bitmap getLineGraph(string title, int width, int height, DataTable chartTable)
    {
        string mProcess = Request.Params["Process"].ToString().Trim();
        string mDDate = Request.Params["DDate"].ToString().Trim();
        Bitmap bm = new Bitmap(width, height);
        Graphics g = Graphics.FromImage(bm);
        g.Clear(Color.White);

        const int kd = 100; //设置精度
        const int top = 50;
        const int left = 20;
        if (width < left * 2 || height < top * 2)
        {
            g.DrawString("绘图区域太小", new Font("Tahoma", 8),
                Brushes.Blue, new PointF(0, 0));
            return bm;
        }

        if (chartTable == null)
        {
            g.DrawString("没有数据", new Font("Tahoma", 7),
                Brushes.Blue, new PointF(0, 0));
            return bm;
        }

        DataTable dt = chartTable;

        //计算最高的点
        int dLine = 0;
        string dDay = DateTime.Now.ToString("yyyy-MM-dd");
        int dHour =  DateTime.Now.Hour;
        float highPoint = 1;
        foreach (DataRow dr in dt.Rows)
        {
            if (highPoint < Convert.ToSingle(dr[0]))
            {
                highPoint = Convert.ToSingle(dr[0]);
            }

            if (highPoint < Convert.ToSingle(dr[1]))
            {
                highPoint = Convert.ToSingle(dr[1]);
            }

            if (highPoint < Convert.ToSingle(dr[2]))
            {
                highPoint = Convert.ToSingle(dr[2]);
            }
            if (int.Parse(dr[3].ToString().Substring(0, 2)) <= dHour)
            {
                dLine = dLine + 1;
            }
        }

        //建立一个Graphics对象实例 
        //try
        //{
            //画大标题 
            g.DrawString(title, new Font("Tahoma", 15), Brushes.Fuchsia, new PointF(300, 2));
            StringFormat drawFormat = new StringFormat();
            drawFormat.FormatFlags = StringFormatFlags.LineLimit;
            g.DrawString("output", new Font("Tahoma", 10),
                        Brushes.Black, new PointF(left+5, 5), drawFormat);
            if (mProcess == "ALL")
            {
                g.DrawString("[红--" + dt.Columns[0].ToString() + "]", new Font("Tahoma", 10),
                    Brushes.Red, new PointF(500, 5), drawFormat);
                g.DrawString("[蓝--" + dt.Columns[1].ToString() + "]", new Font("Tahoma", 10),
                    Brushes.Blue, new PointF(576, 5), drawFormat);
                g.DrawString("[绿--" + dt.Columns[2].ToString() + "]", new Font("Tahoma", 10),
                   Brushes.Green, new PointF(640, 5), drawFormat);
            }
            else if (mProcess == "SMT")
            {
                g.DrawString("[" + mProcess + "]", new Font("Tahoma", 12),
                    Brushes.Blue, new PointF(600, 5), drawFormat);
            }
            else if (mProcess == "DIP")
            {
                g.DrawString("[" + mProcess + "]", new Font("Tahoma", 12),
                    Brushes.Blue, new PointF(600, 5), drawFormat);
            }
            else if (mProcess == "TEST")
            {
                g.DrawString("[" + mProcess + "]", new Font("Tahoma", 12),
                    Brushes.Blue, new PointF(600, 5), drawFormat);
            }

                //画条形图 
            float barWidth = (Convert.ToSingle(width) - left) / (dt.Rows.Count + 1);
            PointF barOrigin = new PointF(left + barWidth, 0);
            float barHeight = dt.Rows.Count;
            float topFontSize = 9;
            float bottomFontSize = 9;
            PointF[] pt1 = null;
            PointF[] pt2 = null;
            PointF[] pt3 = null;
            pt1 = new PointF[dt.Rows.Count];
            pt2 = new PointF[dt.Rows.Count];
            if (mProcess == "ALL")
            {
                pt3 = new PointF[dt.Rows.Count];
            }
            else
            {
                pt3 = new PointF[(dt.Rows.Count - 1) * kd + 1];
            }

            int s = 0;
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                if (mProcess == "ALL")
                {
                    //底部字体的大小
                    barHeight = Convert.ToSingle(dt.Rows[i][0]) * (height - 2 * top) / highPoint * 1;
                    barOrigin.Y = height - barHeight - top;
                    g.FillEllipse(new SolidBrush(Color.Red), barOrigin.X - 3, barOrigin.Y - 3, 6, 6);
                    pt1[i] = new PointF(barOrigin.X, barOrigin.Y);
                    //顶部
                    g.DrawString(dt.Rows[i][0].ToString(), new Font("Tahoma", topFontSize), Brushes.Red,
                        new PointF(barOrigin.X, barOrigin.Y - 4 * topFontSize / 2));

                    barHeight = Convert.ToSingle(dt.Rows[i][1]) * (height - 2 * top) / highPoint * 1;
                    barOrigin.Y = height - barHeight - top;
                    g.FillEllipse(new SolidBrush(Color.Blue), barOrigin.X - 3, barOrigin.Y - 3, 6, 6);
                    pt2[i] = new PointF(barOrigin.X, barOrigin.Y);
                    //顶部
                    g.DrawString(dt.Rows[i][1].ToString(), new Font("Tahoma", topFontSize), Brushes.Blue,
                        new PointF(barOrigin.X, barOrigin.Y - 4 * topFontSize / 2));


                    barHeight = Convert.ToSingle(dt.Rows[i][2]) * (height - 2 * top) / highPoint * 1;
                    barOrigin.Y = height - barHeight - top;
                    g.FillEllipse(new SolidBrush(Color.Green), barOrigin.X - 3, barOrigin.Y - 3, 6, 6);
                    pt3[i] = new PointF(barOrigin.X, barOrigin.Y);
                    //顶部
                    g.DrawString(dt.Rows[i][2].ToString(), new Font("Tahoma", topFontSize), Brushes.Green,
                        new PointF(barOrigin.X, barOrigin.Y - 4 * topFontSize / 2));
                    barOrigin.X = barOrigin.X + barWidth;
                }
                else
                {
                    //底部字体的大小
                    barHeight = Convert.ToSingle(dt.Rows[i][0]) * (height - 2 * top) / highPoint * 1;
                    barOrigin.Y = height - barHeight - top;
                    if (i == dt.Rows.Count - 1)
                    {
                        //g.FillEllipse(new SolidBrush(Color.Black), barOrigin.X - 3, barOrigin.Y - 3, 6, 6);
                    }
                    pt1[i] = new PointF(barOrigin.X, barOrigin.Y);
                    //顶部
                    if (i == dt.Rows.Count - 1)
                    {
                        g.DrawString(dt.Rows[i][0].ToString(), new Font("Tahoma", topFontSize), Brushes.Black,
                            new PointF(barOrigin.X, barOrigin.Y - 4 * topFontSize / 2));
                    }
                    barHeight = Convert.ToSingle(dt.Rows[i][1]) * (height - 2 * top) / highPoint * 1;
                    barOrigin.Y = height - barHeight - top;
                    if (i == dt.Rows.Count - 1)
                    {
                        //g.FillEllipse(new SolidBrush(Color.Black), barOrigin.X - 3, barOrigin.Y - 3, 6, 6);
                    }
                    pt2[i] = new PointF(barOrigin.X, barOrigin.Y);
                    //顶部
                    if (i == dt.Rows.Count - 1)
                    {
                        g.DrawString(dt.Rows[i][1].ToString(), new Font("Tahoma", topFontSize), Brushes.Black,
                            new PointF(barOrigin.X, barOrigin.Y - 4 * topFontSize / 2));
                    }

                    barHeight = Convert.ToSingle(dt.Rows[i][2]) * (height - 2 * top) / highPoint * 1;
                    barOrigin.Y = height - barHeight - top;
                    g.FillEllipse(new SolidBrush(Color.Black), barOrigin.X - 3, barOrigin.Y - 3, 6, 6);                   
                    //顶部
                    g.DrawString(dt.Rows[i][2].ToString(), new Font("Tahoma", topFontSize), Brushes.Black,
                        new PointF(barOrigin.X, barOrigin.Y - 4 * topFontSize / 2));
                    //每个分段之间加几个点
                    pt3[s] = new PointF(barOrigin.X, barOrigin.Y);
                    if (i < dt.Rows.Count - 1)
                    {
                        for (int j = 1; j <= kd-1; j++)
                        {
                            float barHeightNext = Convert.ToSingle(dt.Rows[i + 1][2]) * (height - 2 * top) / highPoint * 1;
                            float barHeightAdd = (barHeightNext - barHeight) / kd;
                            float barWidthAdd = barWidth / kd;
                            barOrigin.Y = height - top - (barHeight + barHeightAdd * j);
                            s = s + 1;
                            //g.FillEllipse(new SolidBrush(Color.Red), barOrigin.X + barWidthAdd * j - 3, barOrigin.Y, 6, 6);
                            pt3[s] = new PointF(barOrigin.X + barWidthAdd * j, barOrigin.Y);

                        }
                        s = s + 1;
                        barOrigin.X = barOrigin.X + barWidth;
                    }                  
                }
            }
            if (dt.Rows.Count > 10)
            {
                int dis = dt.Rows.Count / 10;
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    if (i % dis == 0)
                    {
                        g.DrawLine(new Pen(Color.Black, 2), new PointF(left + (i + 1) * barWidth, height - top + 5),
                            new PointF(left + (i + 1) * barWidth, height - top - 3));
                        //底部
                        g.DrawString(dt.Rows[i][3].ToString(), new Font("Tahoma", bottomFontSize), Brushes.Black,
                            new PointF(left + (i + 1) * barWidth, height - top));
                    }
                    else
                    {
                        g.DrawLine(new Pen(Color.Gray, 1), new PointF(left + (i + 1) * barWidth, height - top + 3),
                            new PointF(left + (i + 1) * barWidth, height - top - 3));
                    }
                }
                int dis1 = (int) (highPoint / 10);
                int k = 0;
                int h = (height - top-top) / 10;
                for (int i = 0; i <= (height - top-top); i = i + h)
                {
                    g.DrawLine(new Pen(Color.Black, 2), new PointF(left, height - top - i), new PointF(left + 4, height - top - i));
                    g.DrawString(k.ToString(), new Font("Tahoma", bottomFontSize), Brushes.Black, new PointF(left + 4, height - top - i));

                    k = k + dis1;
                }             
            }
            else
            {
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    g.DrawLine(new Pen(Color.Gray, 1), new PointF(left + (i + 1) * barWidth, height - top + 3),
                        new PointF(left + (i + 1) * barWidth, height - top - 3));
                }
            }

            //绘制曲线
            if (mProcess == "ALL")
            {
                for (int i = 1; i < dt.Rows.Count-1; i++)
                {
                    if (mDDate != dDay || (mDDate == dDay && i <= dLine))
                    {
                        g.DrawLine(new Pen(new SolidBrush(Color.Red), 2), pt1[i - 1], pt1[i]);
                        g.DrawLine(new Pen(new SolidBrush(Color.Blue), 2), pt2[i - 1], pt2[i]);
                        g.DrawLine(new Pen(new SolidBrush(Color.Green), 2), pt3[i - 1], pt3[i]);
                    }
                }       
            }
            else
            {
                g.DrawLines(new Pen(new SolidBrush(Color.Gray), 1), pt1);
                g.DrawLines(new Pen(new SolidBrush(Color.Gray), 1), pt2);
                //g.DrawLines(new Pen(new SolidBrush(Color.Blue), 2), pt3);

                barHeight = Convert.ToSingle(dt.Rows[0][0]) * (height - 2 * top) / highPoint * 1;
                float minY = barHeight + top;//height - barHeight - top;
                barHeight = Convert.ToSingle(dt.Rows[0][1]) * (height - 2 * top) / highPoint * 1;
                float maxY = barHeight + top; // height - barHeight - top;
                Response.Write("minY="+minY.ToString()+"  maxY="+maxY.ToString());
                for (int i = 1; i < (dt.Rows.Count - 1) * kd; i++)
                {
                    if (mDDate != dDay || (mDDate == dDay && i<=(dLine)*kd))
                    {
                        float hh = height - pt3[i].Y;
                        if (hh <= minY)
                        {
                            g.DrawLine(new Pen(new SolidBrush(Color.Red), 2), pt3[i - 1], pt3[i]);
                        }
                        else if (hh > minY && hh <= maxY)
                        {
                            g.DrawLine(new Pen(new SolidBrush(Color.Green), 2), pt3[i - 1], pt3[i]);
                        }
                        else if (hh > maxY)
                        {
                            g.DrawLine(new Pen(new SolidBrush(Color.YellowGreen), 2), pt3[i - 1], pt3[i]);
                        }
                        else
                        {
                            g.DrawLine(new Pen(new SolidBrush(Color.Black), 2), pt3[i - 1], pt3[i]);
                        }
                    }
                }               
            }
            //设置边 
           
            g.DrawLine(new Pen(Color.Black, 2), new Point(left, top-50),
                new Point(left, height - top));
            g.DrawLine(new Pen(Color.Black, 2), new Point(left, height - top),
                new Point(left + width, height - top));
           
            //设置箭头
            g.DrawLine(new Pen(Color.Black, 2), new Point(left, top - 50),
                new Point(left - 5, top - 45));
            g.DrawLine(new Pen(Color.Black, 2), new Point(left, top - 50),
                new Point(left + 5, top - 45));
            g.DrawLine(new Pen(Color.Black, 2), new Point(left + width-22, height - top),
                new Point(left + width - 27, height - top-5));
            g.DrawLine(new Pen(Color.Black, 2), new Point(left + width-22, height - top),
                new Point(left + width - 27, height - top+5));
            g.Dispose();

            return bm;
        //}
        //catch
        //{
        //    return bm;
        //}
    }

}

收获园豆:5
陳修君 | 菜鸟二级 |园豆:480 | 2010-01-25 14:57
能不能把数据库也给我发过来啊,让我完整的看一下效果 我的邮箱是:lmx710474593@163.com 感谢!!
过客恋媛 | 园豆:200 (初学一级) | 2010-03-12 16:22
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册