使用 ASP.NET 2.0 创建 3D 柱状图






4.44/5 (9投票s)
如何在 ASP.NET 2.0 中使用 Graphics、Bitmap 对象创建 3D 柱状图
引言
在本文中,我将展示如何使用 Drawing 对象创建 3D 柱状图。本文介绍如何在 Web 应用程序中创建 3D 柱状图。通常很难找到关于这些问题的文档,因此希望本文能让开发人员创建自己的 3D 图表。

背景
Bitmap 图像通过提供具有 ADO.NET 2.0 功能的 X 轴、Y 轴坐标来显示 3D 柱状图,并且它具有 Gridview 控件来显示柱状图的 DataPresentation。
Using the Code
要试用代码,只需下载并解压缩文件,然后启动 Visual Studio 2005。从菜单中选择“打开:Web 站点”并选择目录(3D Bar Chart)。我已经在 web.config 中包含了一个简单的数据库路径,并且在 App_Code 文件夹中有一个 DataAccessLayer,其文件名为 Dal.cs。它包含两个 *.aspx 页面,一个用于创建柱状图,另一个用于在另一个 *.aspx 页面中存储 Imagecontrol。
3D 柱状图
它用于以图形方式显示采购订单 ID 的采购金额信息。我只是使用了 Bitmap 类和 Drawing 类对象来创建具有 3D 效果的矩形柱状图。通过使用 Bitmap 类作为 Graph 的画布和 Graphics 类,它具有绘制矩形、线条等的所有函数。Graphics 对象具有 Bitmap 对象,用于将绘图图像的内容复制到 Bitmap 位置。例如
Bitmap objXValuePanel = new Bitmap(200, 350); 
// Canvas to display x-axis values 
Graphics graphicGraph = Graphics.FromImage(objgraph); 
Graphics graphicXValuePanel = Graphics.FromImage(objXValuePanel);
x、y 坐标的值是从数据库中获取的,在特定表中为每个坐标提供了一个单独的列名。例如:x 轴表示 POID,y 轴表示金额字段。DrawLine 是一个用于绘制 X 轴和 Y 轴的函数,FillRectangle 是一个用于从 X 轴和 Y 轴绘制矩形的函数,它传递五个参数。Brush --- 用于使用具有颜色的 solidBrush 对象绘制线条;X 轴 --- x 轴的位置;Y 轴 ---- y 轴的位置;X 轴宽度,Y 轴高度。例如
graphicGraph.FillRectangle(brush, 200,250, 20, 200); 
这里有一个 Gridview ASP.NET 2.0 控件,用于显示 3D 柱状图的 DataPresentation。gridview 的 ID 为 gvDetails,其 autogeneratecolumn 设置为 true,并提供两个列信息。与来自 Dal.cs 中的 GetPodetails() 函数生成的 Dataset 对象绑定;SqlConnection 对象用于建立连接,它从 Web.config 中获取,使用 ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()。
这是 Web.config 中的 ConnectionString
<configuration>
	<appsettings>
	<connectionstrings>
  		<add id="sa;password=aqs123;" name=""ConnectionString""
                  providername=""System.Data.SqlClient"" database="3DBarChart""
                  connectionstring=""server=XENO-NEW2;" />  
 	</connectionstrings>
</configuration>
现在您要做的就是将要显示在网格中的数据关联起来,如下所示
Dal dal = new Dal(); ---Dal is the class name in App_Code folder for DataAccess
DataSet ds = null;
 private void BindGrid()
    {
        try
        {
            ds = new DataSet();
            ds=dal.GetPodetails();
            ViewState["DsDetails"] = ds;
            gvDetails.DataSource = ds;
            gvDetails.DataBind();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
Gridview 皮肤
现在我们有了数据,让我们让它看起来更好一点。这应该不会太难;HTML 默认值一定是由一位非常优秀的软件开发人员定义的。GridView 可以使用皮肤来设置其外观。有几个预定义的皮肤,您可以通过在网格的智能标记中选择“Auto-Format”来选择。但那样就没什么乐趣了。
<gridview id="gvDetails"  runat="server" cellpadding="4" forecolor="#333333"
    gridlines="None"> 
<footerstyle forecolor=""White"" backcolor=""#5D7B9D"" font-bold=""True"" />
<rowstyle forecolor=""#333333"" backcolor=""#F7F6F3"" />
<editrowstyle backcolor=""#999999"" />
<selectedrowstyle forecolor="#333333" backcolor="#E2DED6" font-bold="True" />
<pagerstyle forecolor=""White"" backcolor=""#284775"" horizontalalign=""Center"" />
<headerstyle forecolor="White" backcolor="#5D7B9D" font-bold="True" />
<alternatingrowstyle forecolor=""#284775"" backcolor=""White"" />
</gridview>
现在,这是用于绘制 3D 柱状图的代码,在 Chartdisplay.aspx 页面中我调用了 drawchart() 函数。
用于生成 3D 柱状图
 public void DrawChart()
    {
        DataSet objds = new DataSet();
        objds = (DataSet)ViewState["DsDetails"];
        Session["dataset"] = objds;
        int count = objds.Tables[0].Rows.Count;
        int result = 0;
        if (objds.Tables[0].Rows.Count > 0)
        {
            string[] keyValue = new string[count];
            float[] values = new float[count];
            for (int i = 0; i < count; i++)
            {
                keyValue[i] = objds.Tables[0].Rows[i]["POLineID"].ToString();
                if (objds.Tables[0].Rows[i]["MerchandiseAmount"].ToString() == null)
                    values[i] = float.Parse("0.0");
                else
                    values[i] = float.Parse(
                        objds.Tables[0].Rows[i]["POLineID"].ToString());
                if (float.Parse(
                    objds.Tables[0].Rows[i]["MerchandiseAmount"].ToString()) == 0.0)
                {
                    result++;
                }                
            }         
         
            if (result != count)
            {
                ImageSelect.Visible = true;
             // the image Control that will have bitmap image after
             // generating 3DBar Chart the Bitmap image 
	    // will redirect to this image control 
                ImageSelect.ImageUrl = FormatURL("PurchaseOrderReport");
            }
            else
            {
                lbl_err.ForeColor = System.Drawing.Color.Red;
                lbl_err.Text = "The image cannot be displayed for zero Amount";
                lbl_err.Visible = true;
                ImageSelect.Visible = false;
            }
        }
    }
用于生成 3D 柱状图
    public string FormatURL(string strArgument)
    {
        return ("Readimage.aspx?report=" + strArgument);
    }
生成 3D 柱状图位于 Readimage.aspx 页面中。它包含 Session 对象中的数据集。它是在 Chartdisplay.aspx 页面 page_load 事件中为 Readimage.aspx 页面创建的
List<color> colorList;
    protected void Page_Load(object sender, EventArgs e)
    {
        string report=Request.QueryString["report"].ToString();
        DataSet ds = new DataSet();
        DataSet dsevent = new DataSet();
      
        try
        {
            if (report == "PurchaseOrderReport")
            {
                if (Session["dataset"] != null)
                    ds = (DataSet)Session["dataset"];
                InitColorList();
               
            }
            if (ds.Tables[0].Rows.Count > 0)
            {
                int count = ds.Tables[0].Rows.Count;
                string[] keyValue = new string[count];
                float[] values = new float[count];
                for (int i = 0; i < count; i++)
                {
                    keyValue[i] = ds.Tables[0].Rows[i]["POLineID"].ToString();
                    values[i] = float.Parse(
                        ds.Tables[0].Rows[i]["MerchandiseAmount"].ToString());
                }
                System.Drawing.Bitmap b3 = new System.Drawing.Bitmap(400, 400);
                b3 = Draw3DBarGraph(keyValue, values);
                Response.ContentType = "image/gif";
                b3.Save(Response.OutputStream, ImageFormat.Gif);
            }
            #region commented
          
            #endregion
        }
        catch (Exception ex)
        {
            ex.ToString();
        }
    }
这是在 Readimage.aspx 页面中生成 3D 柱状图的代码。该函数在生成具有两个数组变量(如 keyValue、Values,分别对应 X、Y 坐标)的柱状图后,返回 Bitmap 图像。
public Bitmap Draw3DBarGraph(string[] keyValue, float[] values)
 {
        string xLabel = "POID";
        string yLabel = "MerchandiseAmount";
        string fontFormat = "Courier";
        int alpha = 255;
        Bitmap objgraph = new Bitmap(550, 300);       // Canvas for graph
        Bitmap objXValuePanel = new Bitmap(200, 350); // Canvas to display x-axis values
        Graphics graphicGraph = Graphics.FromImage(objgraph);
        Graphics graphicXValuePanel = Graphics.FromImage(objXValuePanel);
        //    Paint the graph canvas white
        SolidBrush whiteBrush = new SolidBrush(Color.White);
        graphicGraph.FillRectangle(whiteBrush, 0, 0, 550, 300);
        Pen blackPen = new Pen(Color.Black, 2);
        graphicGraph.DrawLine(blackPen, new Point(20, 260), new Point(560, 260));
        graphicGraph.DrawLine(blackPen, new Point(20, 20), new Point(20, 260));
        float highestValue; //Highest value in the values array
        //    Get the highest value 
        float[] tempValue = new float[values.Length];
        for (int j = 0; j < values.Length; j++)
        {
            tempValue[j] = values[j];
        }
        Array.Sort<float>(tempValue);
        //For calculating the HighestValue in Amount field  and then Fixed the
        //maximum height of the Graph 
        highestValue = tempValue[values.Length - 1];
        //    Generate bar for each value
        for (int i = 0, x = 36; i < values.Length; i++)
        {
            SolidBrush brush = new SolidBrush(Color.FromArgb(alpha, colorList[i]));
            float barHeight;    //height of the bar
            //Calculate the Maximum height for the graph will be divided by
            //the max value in amount field
            barHeight = (values[i] / highestValue) * 170;
            //        Draw continuous shade for 3D effect
            float shadex = x + 10;
            float shadey = 244 - ((int)barHeight) + 10;
            for (int iLoop2 = 0; iLoop2 < 10; iLoop2++)
            {
                graphicGraph.FillRectangle(brush, shadex - iLoop2, shadey - iLoop2,
                    20, barHeight);
            }
            //        Draw bar
            graphicGraph.FillRectangle(new HatchBrush(HatchStyle.Percent50,
                brush.Color), x, 244 - barHeight, 20, barHeight);
            //Draw the X-axis Values 
            graphicGraph.DrawString(keyValue[i].ToString(), new Font("VERDANA",
                float.Parse("10.0"), FontStyle.Regular, GraphicsUnit.Point),
                Brushes.Red, x+5, 260);
            StringFormat sf = new StringFormat(StringFormatFlags.DirectionVertical);
            Font f = new Font(fontFormat, 8);
            SizeF sizef = graphicGraph.MeasureString("<- " + yLabel, f,
                Int32.MaxValue, sf);
            RectangleF rf = new RectangleF(0, 0, sizef.Width, sizef.Height);
            graphicGraph.DrawString((yLabel.Length > 0 ? "<- " : "") + yLabel, f,
                Brushes.Black, rf, sf);
            graphicGraph.DrawString(xLabel + (xLabel.Length > 0 ? " ->" : ""), f,
                Brushes.Black, 30, 285);
            RectangleF rf1 = new RectangleF();
            rf1.X =  x;
            //Value On the Bar in Y Axis 
            rf1.Y = 205-barHeight;
            rf1.Height = barHeight;
            rf1.Width = 50 + x;
            graphicGraph.DrawString(values[i].ToString(), f,Brushes.Red,rf1,sf);
            //        Increment the x position            
            x += 50;
        }
        //    Mask bottom with a white line
        Pen whitePen = new Pen(Color.White, 10);
        graphicGraph.DrawLine(whitePen, new Point(10, 400), new Point(430, 400));
        //    Increase the size of the canvas and draw axis
        //objgraph = EmbedAxis(objgraph, true);
        //    Draw the key-value pair with respective color code
        //objgraph = EmbedXPanel(objgraph);
        return (objgraph);
    }


