首页 > 学院 > 开发设计 > 正文

ASP.NET 简单的柱形图实现(附带示例)

2019-11-17 01:47:18
字体:
来源:转载
供稿:网友

asp.net 简单的柱形图实现(附带示例)

对于一些内部系统的项目,各种图表是在所难免的,因为图表可以更加清晰的表达出想看到的数据。

因为之前从来没有做过关于图表的东西,唯一能想到的就是“验证码”,所以应该是一个思路,用GDI去搞。

数据懒着去搞了,记得前些日子在亚航官网查机票,就想到这些数据还挺适合做这个DEMO的,所以就先借用一下亚航的数据喽。

数据大概就是这样子的,日期及价钱。

我选了其中“9月27日-10月10日”正好两周的数据作为此次Demo的测试数据。

原理就是跟实现验证码一模一样,通过给<img>标签修改src属性来操作柱形图的变化,src属性导向的页面是另外一个页,非显示柱形图本页。

然后就是如何利用GDI画柱形图。

先上一下效果图:

下面看一下部分代码片段

html代码:

<body>    <form id="form1" runat="server">    <div>        <asp:ImageButton ID="img_last" runat="server" ImageUrl="~/Left.jpg" AlternateText="Left" OnClientClick="return false;" />        <img id="img_bar" src="GenerateImage.aspx?page_num=0&from=北京&to=清迈" alt="" />        <asp:ImageButton ID="img_next" runat="server" ImageUrl="~/Right.jpg" AlternateText="Right" OnClientClick="return false;" />    </div>    <asp:HiddenField ID="hf_pagenum" runat="server" Value="0" />    <asp:HiddenField ID="hf_recordnum" runat="server" />    </form></body>

js代码:

        $(function () {            var $pagenum = $("#hf_pagenum");            var $recordnum = $("#hf_recordnum");            $("#img_last").click(function () {                if (parseInt($pagenum.val()) - 1 >= 0) {                    $pagenum.val(parseInt($pagenum.val()) - 1);                    $("#img_bar").attr("src", "GenerateImage.aspx?page_num=" + $pagenum.val() + "&from=北京&to=清迈");                }            })            $("#img_next").click(function () {                if (parseInt($pagenum.val()) + 1 < parseInt($recordnum.val())/7) {                    $pagenum.val(parseInt($pagenum.val()) + 1);                    $("#img_bar").attr("src", "GenerateImage.aspx?page_num=" + $pagenum.val() + "&from=北京&to=清迈");                }            })        })

后台代码:

1、一些坐标点的声明

    PRivate readonly int WEEKDAYS = 7;//一周的天数    private readonly int Y_UNIT_NUM = 10;    private readonly int CHAR_X_LEFT = 110;    private readonly int CHAR_X_TOP = 388;    private readonly int CHAR_Y_LEFT = 30;    private readonly int CHAR_Y_TOP = 79;    private readonly int TITLE_LEFT = 140;//柱形图标题 起始X坐标    private readonly int TITLE_TOP = 18;//柱形图标题 起始Y坐标    private readonly int TIME_LEFT = 170;//柱形图日期 起始X坐标    private readonly int TIME_TOP = 48;//柱形图日期 起始Y坐标    private readonly int GRID_X_LEFT = 150;//背景网格 X左边位移    private readonly int GRID_X_TOP = 80;//背景网格 X上边位移    private readonly int GRID_X_BOTTOM = 380;//背景网格 X下边位移    private readonly int GRID_Y_TOP = 110;    private readonly int GRID_Y_LEFT = 100;    private readonly int GRID_Y_RIGHT = 580;    private readonly int GRID_UNIT_WIDTH = 50;//网格单元宽度    private readonly int GRID_UNIT_HEIGHT = 30;//网格单元高度    private readonly int DATA_UNIT_WIDTH = 40;//柱单元宽度    private readonly int DATA_UNIT_HEIGHT = 30;//柱单元高度

2、筛选当页数据方法

为了是通过点击下一页,上一页按钮,对数据进行筛选,选出当页显示数据进行绘制

    protected DataSet QueryDisplayRecord(int pagenum)    {        DataSet ds = new DataSet();        DataTable dt = new DataTable();        dt.Columns.Add(new DataColumn("date"));        dt.Columns.Add(new DataColumn("price"));        for (int i = 7 * pagenum; i < (goStr.Count >= WEEKDAYS * (pagenum + 1) ? WEEKDAYS * (pagenum + 1) : goStr.Count); i++)        {            DataRow dr = dt.NewRow();            dr["date"] = goStr.Keys.Take(i + 1).Last(); ;            dr["price"] = goStr.Values.Take(i + 1).Last(); ;            dt.Rows.Add(dr);        }        ds.Tables.Add(dt);        return ds;    }

哦,对了,这里用的是dictionary<string, string>暂时存的模拟数据,正常情况当然要是通过数据库了。

3、生成图片

    protected void CreateImage(string from, string to, int pagenum, DataSet ds)    {        Font font_Note = new System.Drawing.Font("Arial", 9, FontStyle.Regular);//x轴,y轴,解释内容字体    小字        Font font_GraphicName = new System.Drawing.Font("微软雅黑", 18, FontStyle.Regular);//图表名称 字体      大字        Font font_GraphicTime = new System.Drawing.Font("微软雅黑", 14, FontStyle.Regular);//图表时间 字体      大字        Brush brush_Blue = new SolidBrush(Color.Black);//蓝色线条        if (ds != null)        {            int height = 620, width = 650;            System.Drawing.Bitmap image = new System.Drawing.Bitmap(width, height);            Graphics g = Graphics.FromImage(image);            g.Clear(Color.White);            System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.LightGray, Color.LightGray, 1.2f, true);            //调用FillRectangle方法使用指定颜色填充柱形图的内部            g.FillRectangle(Brushes.WhiteSmoke, 0, 0, width, height);            Brush brush1 = new SolidBrush(Color.Black);            //应用DrawString方法输出文字信息            g.DrawString(from + " 至 " + to + " 机票分析图 (单位:CNY)", font_GraphicName, brush_Blue, new PointF(TITLE_LEFT, TITLE_TOP));            //画图片的边框线            g.DrawRectangle(new Pen(Color.Black), 0, 0, image.Width - 1, image.Height - 1);            Pen mypen = new Pen(brush, 1);            //绘制横向线条            for (int i = 0; i < WEEKDAYS; i++)            {                g.DrawLine(mypen, GRID_X_LEFT + GRID_UNIT_WIDTH * i, GRID_X_TOP, GRID_X_LEFT + GRID_UNIT_WIDTH * i, GRID_X_BOTTOM);            }            Pen mypen1 = new Pen(Color.Black, 2);            g.DrawLine(mypen1, GRID_X_LEFT - GRID_UNIT_WIDTH, GRID_X_TOP, GRID_X_LEFT - GRID_UNIT_WIDTH, GRID_X_BOTTOM);            for (int i = 0; i < Y_UNIT_NUM; i++)            {                g.DrawLine(mypen, GRID_Y_LEFT, GRID_Y_TOP + GRID_UNIT_HEIGHT * i, GRID_Y_RIGHT, GRID_Y_TOP + GRID_UNIT_HEIGHT * i);            }            g.DrawLine(mypen1, GRID_Y_LEFT, GRID_Y_TOP + GRID_UNIT_HEIGHT * (Y_UNIT_NUM - 1), GRID_Y_RIGHT, GRID_Y_TOP + GRID_UNIT_HEIGHT * (Y_UNIT_NUM - 1));            //x轴            for (int i = 0; i < WEEKDAYS; i++)            {                g.DrawString(ds.Tables[0].Rows[i][0].ToString().Substring(ds.Tables[0].Rows[i][0].ToString().LastIndexOf(',') + 1), font_Note, Brushes.Black, CHAR_X_LEFT + GRID_UNIT_WIDTH * i, CHAR_X_TOP);            }            //y轴            string[] money = { "5000CNY", "4500CNY", "4000CNY", "3500CNY", "3000CNY", "2500CNY", "2000CNY", "1500CNY", "1000CNY", "500CNY" };            for (int i = 0; i < Y_UNIT_NUM; i++)            {                g.DrawString(money[i].ToString(), font_Note, Brushes.Black, CHAR_Y_LEFT, CHAR_Y_TOP + DATA_UNIT_HEIGHT * i);            }            int[] Count = new int[WEEKDAYS];            int j = 0;            for (j = 0; j < WEEKDAYS; j++)            {                Count[j] = Convert.ToInt32(ds.Tables[0].Rows[j][1].ToString());            }            //显示柱状效果            ImageAttributes imgAtt = new ImageAttributes();            imgAtt.SetWrapMode(WrapMode.TileFlipXY);//为了使柱形图片无渐变色效果            for (int i = 0; i < WEEKDAYS; i++)            {                g.DrawImage(bitmap, new Rectangle(GRID_Y_LEFT + GRID_UNIT_WIDTH * i + (GRID_UNIT_WIDTH - DATA_UNIT_WIDTH) / 2, (int)(380 - (Count[i] > 5000 ? 5000 : Count[i]) * 3F / 50F), 40, (int)(Count[i] * 3F / 50F)), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, imgAtt);            }            //创建其支持存储区为内存的流            System.IO.MemoryStream ms = new System.IO.MemoryStream();            //将此图像以指定格式保存到指定流中            image.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);            //清除缓冲区流中的所有内容输出            Response.ClearContent();            //设置输出MIME类型            Response.ContentType = "image/Gif";            Response.BinaryWrite(ms.ToArray());        }        else        {            int height = 380, width = 570;            System.Drawing.Bitmap image = new System.Drawing.Bitmap(wi
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表