一、AspxPivotGrid控件的基础知识

AspxPivotGrid是DXperience开发控件中的一个功能庞大的数据分析和统计控件,在应对各种名目繁多的数据透视、数据汇总、数据分析方面,有非常好的表现。其最主要的特点表现为如下几点:

首先我们通过实际界面来认识一下ASPxPivotGrid控件,对它有一个直观的了解,也好为后面的讲述做一个铺垫。图1是运行界面,我们仔细观察这幅图:

 

我们这里做一个说明:

1、候选字段栏:这里列出数据源中所有可用于进行统计分析的字段,候选区内的字段,根据需要可在任何时候拖动到数据列区域或数据行区域,数据区内的数据会随时跟着变化。

2、数据列区域:统计分析表格的列字段配置区域,用于构成表格中的列记录(纵向显示的数据)。

3、数据行区域:统计分析表格的行字段配置区域,用于构成表格中的行记录(横向显示的数据)。

注意:通过标题按钮可以对字段值进行排序、本地过滤等操作。

4、数据区域:统计分析表格的待统计汇总的字段配置区域,这里列出的字段,要求为可进行统计分析的数据类型,通常为数值型数据或其他可用于统计的数据类型。

5、记录列数据汇总:用于汇总每列的数据汇总;

6、记录行数据汇总:用于汇总每行各个数据的汇总;

7、导出工具栏:非ASPxpivotGrid控件自带功能,需要另外处理,但导出数据功能是本控件很重要的一个功能。

8、查询条件:用于设定待统计数据的筛选范围。

通过这个图,我们可以了解到从这个交叉表可以了解到PivotGridControl控件具有以下特点:

1)     可定制的报表

终端用户能够定制PivotGridControl的字段。在字段标题上点击右键弹出字段列表框,通过鼠标拖拽增加或减少行、列、数据区域的字段,改变交叉报表的分析方式。

       2)     树形结构的字段值

图1的行区域有“部门、姓名”2个字段,部门是姓名的上级字段,在部门的字段值上显示了“展开/折叠按钮”。例如图3折叠字段值“儿科”后,数据区域的单元格将以“儿科”小计行的方式显示。

如果有2个以上的行(列)字段,除了最后一级,其它字段值都可以像树形节点一样展开/折叠。

3)     本地过滤

  界面上显示的字段标题具有本地过滤的功能。点击字段标题上的过滤按钮,可以弹出字段值列表。筛选字段值后,交叉表以此为条件过滤数据源中的数据后再进行汇总。当行、列字段值较多时,终端用户通过本地过滤减少行列数,只统计出当前关注的数据。

 

通过上面这些讲述,我们了解了AspxPivotGrid控件的一些特点,有了一些初步的认识,下面我们来看看如何使用这个控件来设计我们的软件。


二、AspxPivotGrid的基本用法

要使用AspxPivotGrid控件,首先要具有必要的开发环境(请见文件头部的介绍)。我们新建一个 aspxform,然后在工具栏中的 data &analytics分组中找到 AspxPivotGrid控件,把它拖到webform上,然后点该控件右上角的设计标签,如图2中的标识1所示:


之后,在图2中的标识2所示位置,指定控件所用的数据源,这里以一个Objectdatasource为例,设定为ods;

接下来,我们设置ASPxPivotGrid的字段。在图2标识3的位置,点击 Fields ,会看到接下来的界面,见图3所示。

图3标识1的位置,单击一下即可添加一个字段。

图3标识2的位置,设定字段在ASPxPivotGrid的位置,可选择的包括 列(ColumnArea),行(RowArea),过滤字段(FilterArea),数据(DataArea),根据需要选择即可;

图3标识3的位置,设定本字段属于哪个分组,根据需要录入分组名称。若没有分组,可为空。

图3标识4的位置,录入字段名称(对应数据库中的哪个字段)。请留意此处必须与数据库字段保持完全一致。至于ID,请设置一个完全不同于其他控件ID的值,通常我会设置为“Field”+字段名称。

图3标识5的位置,录入字段的显示标题。中文字符,这是最终用户看到的界面名称。

图3标识6的位置,是当需要把该字段作为一个计算字段的时候需要设置的。即当前字段以数据库字段为基础进行数据计算,但并不存在于数据库的时候方才需要如此设置。对应的还需要设置UnboundExpression、UnbountType等。

 

图3中的标识位置数据都设置完成以后,我们就完成了一个字段的添加。接下来依次添加我们需要的所有字段即可。所有字段都添加完成后,点击ok 按钮,就回到之前的设计界面。

查看webform对应的aspx文件源码,我们会看到下面这样的代码,请看图4.

 

图4中的代码,我们可以发现是很有规律的。上面我们写了那么多步骤做了那么多工作,无非就是生成了这些代码,增加了 一些 Fields,并根据需要设定了每个Field的一些属性。所以、朋友们不免要想:是不是可以用代码完成上面这些工作呢?答案当然是肯定的。后面我们会给 出方法。

 

查阅DevExpress的在线文档,不难发现ASPxpivotGrid控件实现了一个把数据导出的功能,其中提供了一个组件:ASPxPivotGridExporter,这就是ASPxpivotGrid控件导出数据的关键所在,它提供了如下几个方法:

 

ASPxPivotGridExporter1.ExportPdfToResponse(fileName, saveAs);
                   ASPxPivotGridExporter1.ExportXlsToResponse(fileName, saveAs);
                   ASPxPivotGridExporter1.ExportMhtToResponse(fileName, "utf-8", "ASPxPivotGridPrinting Sample", true,saveAs);
                   ASPxPivotGridExporter1.ExportRtfToResponse(fileName, saveAs);
                    ASPxPivotGridExporter1.ExportTextToResponse(fileName,saveAs);
                   ASPxPivotGridExporter1.ExportHtmlToResponse(fileName, "utf-8", "ASPxPivotGridPrinting Sample", true,saveAs);

我们在工具栏中找到这个组件,把它拖到aspxform中去,然后增加一个ASPxCombobox和两个按钮,如下图所示:
file:///C:/Users/Temp/msohtmlclip1/01/clip_image010.jpg
 
双击保存按钮,在Click事件中写下如下的代码:
   protectedvoid ASPxMenu2_ItemClick(object source,DevExpress.Web.ASPxMenu.MenuItemEventArgs e)
        {
            string s =e.Item.Name.ToString();
            string sFormat= mycbFormat.Text.ToString();
            if (s == "pivotSave")
            {
                Export(true,sFormat);
            }
            if (s == "pivotOpen")
            {
                Export(false,sFormat);
            }
        }
 
        void Export(bool saveAs,stringsFormat)
        {
            stringfileName = "PivotGrid";
            switch(sFormat)
            {
                case"pdf":
                   ASPxPivotGridExporter1.ExportPdfToResponse(fileName, saveAs);
                    break;
                case"Excel":
                   ASPxPivotGridExporter1.ExportXlsToResponse(fileName, saveAs);
                    break;
                case"Mht":
                   ASPxPivotGridExporter1.ExportMhtToResponse(fileName, "utf-8", "ASPxPivotGridPrinting Sample", true,saveAs);
                    break;
                case"Rtf":
                   ASPxPivotGridExporter1.ExportRtfToResponse(fileName, saveAs);
                    break;
                case"Text":
                   ASPxPivotGridExporter1.ExportTextToResponse(fileName, saveAs);
                    break;
                case"Html":
                   ASPxPivotGridExporter1.ExportHtmlToResponse(fileName, "utf-8", "ASPxPivotGridPrinting Sample", true,saveAs);
                    break;
            }
        }

这样便实现了根据最终用户选择的文件类型,导出ASPxpivotGrid数据到本地文件的功能。这样就极大方便了最终用户的使用,为用户进一步组织数据进行其他处理提供了便利。

三、AspxPivotGrid的高级用法

ASPxPivotGrid 是功能强大的,但设置字段的过程也是极其繁琐枯燥的。通过跟踪分析,我们发现设计器中的过程,其实只是在aspx文件中增加了fields一节,设置了每 个field的相关属性。那么,我们自然可以通过代码来实现相同的工作,从而一劳永逸,避免每次都去手工在设计器中设置字段了。

经比对,我们发现对于每个field,都需要设置如下几个属性:

Area :可选择的项目:RowArea,ColumnArea,DataArea,FilterArea;  含义为:字段所处的区域。

FieldName:字段名称,对应数据库的字段名;
Caption:字段标题;
AreaIndex:字段在当前区域的序号(第几位显示);
ID:当前字段的标识符号;
FormatType:格式化类型;数值、日期、字符串等;
FormatString:格式化字符串;
有了这几个基本属性,我们就可以用代码来绑定数据库的字段到ASPxpivotGrid控件中了。于是我们不难写出下面这样的代码:
foreach (ZiyuWeb.Entity.Sys_UIConfig item insConfigs)
            { 
                switch(item.pFieldArea)
                {
                    case"RowArea":
                        {
                            DevExpress.Web.ASPxPivotGrid.PivotGridField myField= newDevExpress.Web.ASPxPivotGrid.PivotGridField();
                            myField.Area =DevExpress.XtraPivotGrid.PivotArea.RowArea;
                            myField.FieldName =item.FieldName;
                            myField.Caption =item.FieldDescribe;
                            myField.AreaIndex =item.pAreaIndex;
                            myField.ID = "field" + item.FieldName;
                           myGrid.Fields.Add(myField);
                            if(item.DispFormat != null)
                            {
                                if(item.DispFormat.Contains("yy"))
                                {
                                   myGrid.Fields[item.FieldName].ValueFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
                                   myGrid.Fields[item.FieldName].ValueFormat.FormatString = "yyyy-MM-dd";//item.DispFormat;
                                   myGrid.Fields[item.FieldName].CellFormat.FormatType = DevExpress.Utils.FormatType.DateTime;
                                   myGrid.Fields[item.FieldName].CellFormat.FormatString = "yyyy-MM-dd";//item.DispFormat;
                                }
                            }
                            break;
                        }
                    case"ColumnArea":
                        {
                           DevExpress.Web.ASPxPivotGrid.PivotGridField myField = new DevExpress.Web.ASPxPivotGrid.PivotGridField();
                            myField.Area =DevExpress.XtraPivotGrid.PivotArea.ColumnArea;
                            myField.FieldName =item.FieldName;
                            myField.Caption =item.FieldDescribe;
                            myField.AreaIndex =item.pAreaIndex;
                            myField.ID = "field" + item.FieldName;
                           myGrid.Fields.Add(myField);
                            break;
                        }
                    case"DataArea":
                        {
                           DevExpress.Web.ASPxPivotGrid.PivotGridField myField = new DevExpress.Web.ASPxPivotGrid.PivotGridField();
                            myField.Area =DevExpress.XtraPivotGrid.PivotArea.DataArea;
                            myField.FieldName = item.FieldName;
                            myField.Caption =item.FieldDescribe;
                            myField.AreaIndex =item.pAreaIndex;
                            myField.ID = "field" + item.FieldName;
                            myGrid.Fields.Add(myField);
                            break;
                        }
                    case"FilterArea":
                    default:
                        {
                           DevExpress.Web.ASPxPivotGrid.PivotGridField myField = new DevExpress.Web.ASPxPivotGrid.PivotGridField();
                            myField.Area =DevExpress.XtraPivotGrid.PivotArea.FilterArea;
                            myField.FieldName =item.FieldName;
                            myField.Caption =item.FieldDescribe;
                            myField.AreaIndex =item.pAreaIndex;
                            myField.ID = "field" + item.FieldName;
                           myGrid.Fields.Add(myField);
                            break;
                        }
                }
            }
好了,这样我们就已经完成了绑定数据字段到ASPxpivotGrid控件的工作。接下来我们看看如何设置计算列到控件中去。
要设置计算列,就不得不留意如下几个属性:
UnboundFieldName:未绑定字段名称;
UnboundType:未绑定字段的数据类型,包括字符型,object、日期型、数值型。
UnboundExpression:计算列的计算表达式,可用的表达式种类很多,请大家查阅Devexpress的在线文档。
TopValueShowOthers:是否显示其他数据;
RunningTotal:是否统计;
TopValueType:统计类别,包括最大值、最小值、求和、平均值等等;
Caption:计算列的标题;
Area:计算列所处的位置:可选择的项目:RowArea,ColumnArea,DataArea,FilterArea;
ID:当前字段的标识符号;
FormatType:格式化类型;数值、日期、字符串等;
FormatString:格式化字符串;
有了这几个属性,自然我们能写出下面这样的代码,用于自动添加计算列到ASPxpivotGrid控件中去。
///<summary>
        ///PivotGrid增加计算列
        ///</summary>
        ///<param name="sFieldCaption">计算列的显示名称</param>
        ///<param name="sBaseFieldName">计算列基础列字段名称(基于哪个字段计算?若是多个字段计算则为string.Empty 即可)</param>
        ///<param name="sComputeExpresion">计算列的计算表达式例如 "[gg]*[length]/1000"</param>
        ///<param name="myGrid">PivotGrid控件</param>
        ///<param name="mySummarytype">统计类型</param>
        publicstaticvoidaddComputeField(string sFieldCaption, string sBaseFieldName, stringsComputeExpresion, DevExpress.Web.ASPxPivotGrid.ASPxPivotGrid myGrid,
            DevExpress.Data.PivotGrid.PivotSummaryTypemySummarytype)
        {
            DevExpress.Web.ASPxPivotGrid.PivotGridFieldmyFieldCP = new DevExpress.Web.ASPxPivotGrid.PivotGridField();
            myFieldCP.Area =DevExpress.XtraPivotGrid.PivotArea.DataArea;
            myFieldCP.Caption = sFieldCaption; 
            myFieldCP.ID = "Field_"  +sFieldCaption;
            myFieldCP.TopValueShowOthers=true;
            myFieldCP.RunningTotal = true;
            myFieldCP.TopValueType = PivotTopValueType.Sum;
            myFieldCP.SummaryType=mySummarytype;
            if(sBaseFieldName !=string.Empty)
              myFieldCP.FieldName =sBaseFieldName;
            myFieldCP.UnboundType =DevExpress.Data.UnboundColumnType.Object;
            myFieldCP.UnboundExpression =sComputeExpresion; 
            myGrid.Fields.Add(myFieldCP);
        }

 

有了这些代码,我们日后需要用到ASPxpivotGrid控件来统计分析数据的时候,只需要简单的写下两行代码即可:

ZiyuWeb.WebFunc.ZiyuDevAspxPivotGridHelper.ConfigPivotGrid("hzsendtotal",
 true, "sendate", ASPxPivotGrid1, true, "chart");//配置ASPxPivotGrid控件;
//下面两行代码是增加计算列的,如不需要,则保持原样,否则打开注释并根据需要调整代码即可;
 
      // 
ZiyuWeb.WebFunc.ZiyuDevAspxPivotGridHelper.addComputeField("面
积",string.Empty, "[gg]*[length]/1000", 
ASPxPivotGrid1,DevExpress.Data.PivotGrid.PivotSummaryType.Sum);

完整的代码和界面,请读者朋友们查看本文的示例项目。

 

在实际使用过程中,我们发现,ASPxpivotGrid控件,在面对大批量数据进行统计分析的时候,页面打开会比较慢,甚至会失去响应,这便有了一个问题:如何提高它的运行效率呢?

四、提高AspxPivotGrid的运行效率

ASPxPivotGrid 组件是一个基于ASP.NET平台下的全面的数据分析、数据挖掘、和可视化报表的解决方案。它的出现不仅可以为新的解决方案去除数据分析方面的种种缺陷, 也可以从根本上改善已有的大型数据分析软件在最终数据呈现上的不足,从而让你的最终用户能更好获取和分析相关数据。那么如何进一步提高 ASPxPivotGrid的性能,对数据进行高效切分,从而为客户提供一个非常直观的终端用户体验呢?这里我们从两方面来说明问题。

A、选择一个合适的数据源

我 们说并不是所有的数据源都符合你的程序。如果你每次访问的数据量在150,000以下的话,你最好使用SqlSever数据库,如果数据量超过 150,000行的话,你将考虑使用Analysis Services 即分析数据库,否则运行速度会很慢。当然如果你选择一个好的数据库服务器,那可以大于上面的数据,反之如果使用xml或者MS Access数据存储格式就可能更少了。

那么如何选择一个合适的数据库呢?首先,你需要估计一下你的数 据量,PivotGrid每次发送请求的一个数据量。如果你不知道实际的记录数,你可以根据列的成员特性推测出来。例如,你有7列:产品种类(50), 产品子类别(1000), 产品 (50000),国家 (10),省(400), 市 (10000), 顾客 (50000),这里括号中的数字是对应成员特有的记录数。我们分析一下,上面“产品种类, 产品子类别,国家,省和市”其实根本就没有提供新的度量数据,“产品种类”和“产品子类别”其实是包含在“产品”中,而“国家,省和市”所产生的度量数据 则体现在“顾客”信息记录中。因此我们很快就能通过“产品”和“顾客”的乘积得出记录数(50000 * 50000 = 2500 000)

B、性能优化以及对比

我们在选择了不同的数据库后,又该怎么提高PivotGrid的性能呢?

当 你使用SQL Server作为PivotGrid的数据源的话,总体性能大概由加载数据的时间、计算的时间、数据绘制时间三部分组成。为了提高数据加载时间,你可以在 数据服务器和Web服务器之间建立更好的连接,数据库服务器和Web服务器最好是使用同一台机器,调整数据服务器,以实现最佳的性能和缓存数据的检索。此 外我们还可以在服务端优化查询语句,比如"selectCategory, Product, Sales from Sales" 查询改为 "select Category, Product, sum(Sales) from Salesgroup by Category, Product".这样很大程度上能减少PivotGrid本身计算的时间。

当你使用分析服务器作为数 据源的话,对于每次请求它是不存在重载和重新计算数据的。它的数据和计算结果都是作为缓存,返回的仅仅是你请求的那部分数据。尽管这样,如果是小规模的查 询那速度还是低于SQL Server,但在大型数据集上它将产生更好的效果。事实上,如果没有使用Analysis Services的数据源,对于上百万条的数据我想你是很难得到满意结果的。


安装 DevExpress 控件库后在工具箱中找不到Devexpress的控件 devexpress控件讲解_字段

安装 DevExpress 控件库后在工具箱中找不到Devexpress的控件 devexpress控件讲解_数据_02

安装 DevExpress 控件库后在工具箱中找不到Devexpress的控件 devexpress控件讲解_控件_03

安装 DevExpress 控件库后在工具箱中找不到Devexpress的控件 devexpress控件讲解_字段_04