65.9K
CodeProject 正在变化。 阅读更多。
Home

深入了解 ASP.NET 图表控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.68/5 (16投票s)

2010年10月13日

CPOL

5分钟阅读

viewsIcon

66340

downloadIcon

868

图表控件让您能够自由地开发图形化报表。

引言

当您开发应用程序时,有时需要开发一些报表工具。例如,您的数据库中保存了销售人员每天完成的销售数量信息,您希望以美观的图形格式为管理层呈现这些信息。能够选择一个日期范围,选择几名销售人员,并显示他们每天的总销售额将是多么棒的事情。要实现这一点,您需要什么?首先是记录的数据,然后是能够以图形格式显示这些数据的能力。数据本身不成问题。使用数据库工具和 C# 工具,您可以对数据进行任何操作。您可以进行筛选、分组、计算等。幸运的是,有一个更简单但非常出色的解决方案,它被称为 ASP.NET 图表控件。在本文中,我想深入探讨一下这个控件。我相信它将帮助您在短时间内掌握这个控件。它使用起来很有趣,并且具有许多可能性。

ASP.NET 图表控件

下面的图 1 显示了一个包含两个数据系列的图表控件。该控件的架构简单明了。它有三个非常重要的集合:

  1. 标题
  2. 图表区域
  3. 系列文章

标题集合可以包含多个 Title 对象;每个对象代表一个标题。它们可以按顺序一个接一个地显示,您也可以控制设置。图表区域集合包含多个 ChartArea 对象;每个对象代表一个显示图表数据的区域。它们也可以按顺序一个接一个地显示,并且具有高度的可配置性。系列集合包含多个 Series 对象;每个对象代表数据系列本身。它是一组对应的数字,这些数字代表图表的垂直和水平方向。对于这张图:

系列 1
X 0 1 2 3 4 5 6 7 8 9
Y 7 8 6 2 8 3 4 1 5 3
系列 2
X 0 1 2 3 4 5 6 7 8 9
Y 6 5 6 9 7 4 4 4 3 2

下面的图片不言自明。

Chart.gif

没有必要添加多个标题和/或图表区域。通常,您只需要一个标题和一个图表区域。如果您想比较两个或多个系列的数据,可以将它们放在同一个图表区域内。此控件允许您进行大量调整。图 2 显示了控件的不同配置。

Chart1.gif

实现

好消息是 ASP.NET 图表控件是微软开发的,而且是免费的。您可以在网上找到并下载它。它是一个名为 System.Web.DataVisualization.dll 的程序集。通常,在从互联网安装时,它会被放置在 GAC(全局程序集缓存)中,并与其他可用的系统引用一起出现,但您也可以将该文件直接放在您的 bin 文件夹中,并通过浏览进行引用。它将作为私有程序集工作。如果您想将应用程序部署到不包含该程序集在 GAC 中的共享托管服务器上,这一点非常方便。我在我的文章中附带了该文件,因此您可以从这里下载:

渲染时,图表以 HTML 源中的图像形式呈现。类似这样:

<img id="Chart1" 
  src="https://codeproject.org.cn/ChartImg.axd?i=
       chart_e12f8822706a422ea567f6b4dc5974ef_1.png&
       g=45d8c6d5ff874c67a29fe91059a8cbe5"
  alt="" style="height:300px;width:800px;border-width:0px;" />

为了处理扩展名为 .axd 的图像源,您需要在 Web 配置文件中添加一个 HTTP 处理程序。找到 <system.web> 下的 <httpHandlers> 部分,并添加以下内容:

<httpHandlers>
<add path="ChartImg.axd" verb="GET,HEAD" 
    type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, 
           System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, 
           PublicKeyToken=31bf3856ad364e35"
    validate="false" />
</httpHandlers>

对于新版本的 IIS,您可以将处理程序添加到 <system.webServer> 下的 <handlers> 部分:

<handlers>
<remove name="ChartImageHandler"/>
<add name="ChartImageHandler" preCondition="integratedMode" 
   verb="GET,HEAD"
   path="ChartImg.axd" 
   type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, 
         System.Web.DataVisualization, Version=3.5.0.0, 
         Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</handlers>

另外,找到 <system.web> 下的 <controls> 部分,并添加控件:

<controls>
<add tagPrefix="asp" namespace="System.Web.UI.DataVisualization.Charting"
     assembly="System.Web.DataVisualization, Version=3.5.0.0, 
               Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</controls>

代码

这是一个非常简单的 ASP.NET 应用程序,只有一个 Default.aspx 文件和对应的 Default.aspx.cs 文件。在继续之前,您需要将 ASP.NET 图表控件安装到您的 Visual Studio 工具箱中。

  1. 打开您的工具箱。
  2. 将鼠标指针指向您想用于 Chart 控件的选项卡。
  3. 右键单击并选择“选择项…”;等待“选择工具箱项”窗口出现。
  4. 在“.NET Framework 组件”下,单击“浏览”按钮,然后向下浏览到 System.Web.DataVisualization.dll 文件。
  5. 选择该文件并单击“确定”——图表控件将出现在您的工具箱中。

安装后,只需将 Chart 控件从设计视图拖放到页面上即可。

<%@ Page Language="C#" AutoEventWireup="true" 
   CodeBehind="Default.aspx.cs" Inherits="Chart._Default" %>

<%@ Register Assembly="System.Web.DataVisualization, Version=3.5.0.0, 
                       Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    Namespace="System.Web.UI.DataVisualization.Charting" 
    TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Chart ID="Chart1" runat="server" Width="800" >
            <Series>
                <asp:Series Name="Series1">
                </asp:Series>
                <asp:Series Name="Series2">
                </asp:Series>
            </Series>
            <ChartAreas>
                <asp:ChartArea Name="ChartArea1">
                </asp:ChartArea>
            </ChartAreas>
        </asp:Chart>
    </div>
    <asp:CheckBox ID="chkCompare" runat="server" 
       Text="Compare two sets of data" AutoPostBack="true" /><br />
    <asp:CheckBox ID="chkDisplay3D" runat="server" 
       Text="Display 3D" AutoPostBack="true" /><br />
    <asp:CheckBox ID="chkShowValues" runat="server" 
       Text="Show Metrics Values" AutoPostBack="true" /><br />
    <asp:DropDownList ID="ddlChartType" 
             runat="server" AutoPostBack="true">
        <asp:ListItem Text="Column"></asp:ListItem>
        <asp:ListItem Text="Line"> </asp:ListItem>
        <asp:ListItem Text="StepLine"></asp:ListItem>
        <asp:ListItem Text="Pie"></asp:ListItem>
        <asp:ListItem Text="Area"></asp:ListItem>
        <asp:ListItem Text="Bar"></asp:ListItem>
        <asp:ListItem Text="BoxPlot"></asp:ListItem>
        <asp:ListItem Text="Doughnut"></asp:ListItem>
    </asp:DropDownList>
    </form>
</body>
</html>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.DataVisualization.Charting;
using System.Drawing;

namespace Chart
{
    public class DataInfo
    {
        public int X { get; set; }
        public int Y1 { get; set; }
        public int Y2 { get; set; }
    }

    public partial class _Default : System.Web.UI.Page
    {
        private bool compare;
        private bool display3d;
        private bool showValues;
        private string charType = "Column";

        protected void Page_Load(object sender, EventArgs e)
        {

            List<DataInfo> list = new List<DataInfo>();
            Random r = new Random(23);
            for (int i = 0; i < 10; i++)
            {
                DataInfo di = new DataInfo();
                di.X = i;
                di.Y1 = r.Next(1, 10);
                di.Y2 = r.Next(1, 10);
                list.Add(di);
            }

            this.Chart1.DataSource = list;

            GetChartPreferences();
        }

        protected void Page_Prerender(object sender, EventArgs e)
        {
            ConfigureChart();
            if (!compare)
                Chart1.Series.Remove(Chart1.Series[1]);
        }

        private void ConfigureChart()
        {
            Chart1.Titles.Add(new Title("Title 1: my chart"));
            ConfigurTitle(Chart1.Titles[0]);
            ConfigureArea(Chart1.ChartAreas[0]);
            ConfigureSeries(Chart1.Series[0], "X", "Y1");
            ConfigureSeries(Chart1.Series[1], "X", "Y2");
            Chart1.Series[1].ChartArea = Chart1.ChartAreas[0].Name;
        }

        private void ConfigureArea(ChartArea area)
        {
            //configure Chart Areas:
            area.ShadowColor = Color.Gray;
            area.ShadowOffset = 10;
            area.AxisY.Title = area.Name + " -  v e r t i c a l";
            area.AxisX.Title = area.Name + " -  H o r i z o n t a l";
            area.AxisX.IsMarginVisible = true;
            area.Area3DStyle.Enable3D = display3d;
        }

        private void ConfigurTitle(Title title)
        {
            //configure Title:
            title.BorderColor = Color.Silver;
            title.BorderDashStyle = ChartDashStyle.Solid;
            title.ShadowColor = Color.Gray;
            title.ShadowOffset = 6;

            title.Font = new Font(FontFamily.GenericSansSerif, (float)13);
        }

        private void ConfigureSeries(Series series, string xValue, string vValue)
        {

            //configure Series:
            series.XValueMember = xValue;
            series["ShowMarkerLines"] = "True";
            series.YValueMembers = vValue;
            series.MarkerStyle = MarkerStyle.Square;
            series.IsValueShownAsLabel = showValues;

            switch (charType)
            {
                case "Line":
                    series.ChartType = SeriesChartType.Line;
                    break;
                case "Column":
                    series.ChartType = SeriesChartType.Column;
                    break;
                case "Pie":
                    series.ChartType = SeriesChartType.Pie;
                    break;
                case "Area":
                    series.ChartType = SeriesChartType.Area;
                    break;
                case "Bar":
                    series.ChartType = SeriesChartType.Bar;
                    break;
                case "BoxPlot":
                    series.ChartType = SeriesChartType.BoxPlot;
                    break;
                case "Doughnut":
                    series.ChartType = SeriesChartType.Doughnut;
                    break;
                case "StepLine":
                    series.ChartType = SeriesChartType.StepLine;
                    break;
            }
        }

        private void GetChartPreferences()
        {
            if (!string.IsNullOrEmpty(Request[chkShowValues.UniqueID]))
                showValues = true;

            if (!string.IsNullOrEmpty(Request[chkDisplay3D.UniqueID]))
                display3d = true;

            if (!string.IsNullOrEmpty(Request[chkCompare.UniqueID]))
                compare = true;

            if (!string.IsNullOrEmpty(Request[ddlChartType.UniqueID]))
                charType = Request[ddlChartType.UniqueID];
        }
    }
}

解释

Default.aspx

<asp:Chart ID="Chart1" runat="server" Width="800" >
    <Series>
        <asp:Series Name="Series1">
        </asp:Series>
        <asp:Series Name="Series2">
        </asp:Series>
    </Series>
    <ChartAreas>
        <asp:ChartArea Name="ChartArea1">
        </asp:ChartArea>
    </ChartAreas>
</asp:Chart>

我创建了一个包含一个图表区域和两个数据系列的图表。页面上有一些复选框和一个下拉列表,其 auto-postback 设置为 true。每次更改设置时,图表都会以不同的方式显示。我可以使其变为 3D、显示/隐藏数据值、比较两个数据系列,或者只显示第一个,以及/或更改图表的样式。

Default.aspx.cs

我声明了一个新类:

public class DataInfo
{
    public int X { get; set; }
    public int Y1 { get; set; }
    public int Y2 { get; set; }
}

公共属性 X 将代表两个数据系列的 X 轴,公共属性 Y1 将代表第一个系列 Y 轴,公共属性 Y2 将代表第二个系列 Y 轴。

在 Load 事件中,我创建了一个 DataInfo 列表并随机填充它。然后我将列表作为数据源分配给我的 Chart。之后,其余的只是图表配置问题。

protected void Page_Load(object sender, EventArgs e)
{
    List<DataInfo> list = new List<DataInfo>();
    Random r = new Random(23);
    for (int i = 0; i < 10; i++)
    {
        DataInfo di = new DataInfo();
        di.X = i;
        di.Y1 = r.Next(1, 10);
        di.Y2 = r.Next(1, 10);
        list.Add(di);
    }

    this.Chart1.DataSource = list;
    GetChartPreferences();
}

为了使我的代码更易读,我将配置分解为几个简单的过程:

  1. ConfigureArea
  2. ConfigurTitle
  3. ConfigureSeries

花点时间玩玩这些函数,您会发现有许多可用的配置选项。我只使用了一小部分来让您对控件有个大致了解。

结论

这是显示应用程序图形化数据的非常酷且简单的方式。它为您节省了大量的开发时间。该控件高度可定制。如果您喜欢这篇文章,请投票。

© . All rights reserved.