文档帮助

术语、图标和标签

许多类在使用配置对象创建(实例化)类时,具有用于快捷方式的名称。快捷方式名称称为别名(如果类扩展 Ext.Component,则称为xtype)。别名/xtype 列在适用类的类名旁边,以便快速参考。

访问级别

框架类或其成员可以指定为privateprotected。否则,类/成员为publicPublicprotectedprivate是访问描述符,用于传达如何以及何时应该使用类或类成员。

成员类型

成员语法

下面是一个示例类成员,我们可以对其进行剖析以显示类成员的语法(在这种情况下,从 Ext.button.Button 类中查看的 lookupComponent 方法)。

lookupComponent ( item ) : Ext.Component
protected

在初始化items配置期间将原始配置对象添加到此容器中,或添加新项目时(added),或{@link #insert inserted}时调用。

此方法将传递的对象转换为实例化的子组件。

当需要对子项创建应用特殊处理时,可以在子类中覆盖此方法。

参数

item :  Object

正在添加的配置对象。

返回值
Ext.Component

要添加的组件。

让我们看看成员行中的每个部分

成员标志

API 文档使用许多标志来进一步传达类成员的功能和意图。标签可以用文本标签、缩写或图标表示。

类图标

- 表示框架类

- 单例框架类。*有关更多信息,请参阅单例标志

- 组件类型框架类(Ext JS 框架中扩展 Ext.Component 的任何类)

- 表示类、成员或指南在当前查看版本中是新的

成员图标

- 表示类型为 config 的类成员

- 表示类型为 property 的类成员

- 表示类型为 method 的类成员

- 表示类型为 event 的类成员

- 表示类型为 theme variable 的类成员

- 表示类型为 theme mixin 的类成员

- 表示类、成员或指南在当前查看版本中是新的

类成员快速导航菜单

在 API 文档页面上类名称正下方是与当前类拥有的成员类型相对应的按钮行。每个按钮按类型显示成员数(此计数在应用筛选器时更新)。单击按钮将导航到该成员部分。将鼠标悬停在成员类型按钮上将显示一个弹出菜单,其中包含该类型的所有成员,以便快速导航。

Getter 和 Setter 方法

与类配置选项相关的 Getter 和 Setter 方法将显示在方法部分以及 API 文档和成员类型菜单的配置部分中,它们与之一起工作的配置正下方。Getter 和 Setter 方法文档将位于配置行中,以便于参考。

历史记录栏

您的页面历史记录保存在本地存储中,并显示在顶部标题栏正下方(使用可用空间)。默认情况下,显示的唯一搜索结果是与您当前正在查看的产品/版本匹配的页面。您可以通过单击历史记录栏右侧的 按钮并选择“全部”单选选项来扩展显示内容。这将在历史记录栏中显示所有产品/版本的所有最近页面。

在历史记录配置菜单中,您还将看到最近访问的页面列表。结果按“当前产品/版本”和“全部”单选选项进行筛选。单击 按钮将清除历史记录栏以及本地存储中保存的历史记录。

如果在历史记录配置菜单中选择“全部”,则将启用“在历史记录栏中显示产品详细信息”的复选框选项。选中后,每个历史页面的产品/版本将与历史记录栏中的页面名称一起显示。将光标悬停在历史记录栏中的页面名称上还将显示产品/版本作为工具提示。

搜索和筛选器

可以使用页面顶部的搜索字段搜索 API 文档和指南。

在 API 文档页面上,还有一个筛选器输入字段,它使用筛选器字符串筛选成员行。除了按字符串筛选外,您还可以按访问级别、继承和只读筛选类成员。这是使用页面顶部的复选框完成的。

API 类导航树底部的复选框筛选类列表以包含或排除私有类。

单击空搜索字段将显示您最近 10 次搜索,以便快速导航。

API 文档类元数据

每个 API 文档页面(除了 Javascript 原语页面)都有一个与该类相关的元数据的菜单视图。此元数据视图将具有以下一个或多个

展开和折叠示例和类成员

可运行的示例(Fiddle)默认情况下在页面上展开。你可以使用代码块左上角的箭头单独折叠和展开示例代码块。你还可以使用页面右上角的切换按钮切换所有示例的折叠状态。折叠所有状态将在页面加载之间记住。

类成员默认情况下在页面上折叠。你可以使用成员行左侧的箭头图标或全局使用展开/折叠所有切换按钮右上角展开和折叠成员。

桌面 -vs- 移动视图

在较窄的屏幕或浏览器上查看文档将导致针对较小尺寸优化视图。桌面和“移动”视图之间的主要区别是

查看类源

可以通过单击 API 文档页面顶部的类名称来查看类源。可以通过单击成员行右侧的“查看源”链接来查看类成员的源。

Ext JS 7.8.0


顶部

多维数据透视

其他资源

示例

关于

透视网格组件可以快速汇总大量数据。它提供了一种简单的方法,可以将许多数据点浓缩成一种格式,使趋势和见解更加明显。一个经典的例子是销售数据。一家公司通常会记录其在给定时期内进行的所有销售。这通常会包含数千行数据。透视网格允许您查看每位销售人员的表现、哪些城市产生最多的收入、产品在不同城市之间的表现等。

注意:本指南介绍了 Ext JS SDK 高级版本中捆绑的透视包。

想象一下您有以下网格面板

image alt text

您如何轻松地实现一个客户端解决方案来回答以下问题?

  1. 约翰·杜的总订单金额是多少?

  2. 按国家统计的总订单金额是多少?

  3. 某个销售人员在特定年份的表现如何?

这些都是透视网格解决的问题类型。我们来看看答案的可视化方式。

image alt text

image alt text

透视网格未捆绑在 Ext JS 框架中,但很容易在应用程序中需要它。无论你使用的是 Sencha Cmd 生成的应用程序,还是使用自己设计的应用程序结构,只需几个步骤即可包括透视网格代码和样式。

要求

Ext JS

Sencha 透视网格适用于 Sencha Ext JS 的经典工具包和现代工具包。

Sencha Cmd

无需 Sencha Cmd 即可使用透视网格。但是,使用 Cmd 允许你通过应用程序的 app.json 文件无缝地包含透视网格包。

安装

将透视网格与 Sencha Cmd 配合使用

透视网格提供完整的源代码,打包方式便于部署到应用程序的包文件夹中。

要在应用程序中包含透视网格,只需修改应用程序根目录中的 app.json 文件,以需要透视网格包

{

    "name": "YourApp",

    "requires": [

        "pivot"

    ],

    "id": "391a5ff6-2fd8-4e10-84d3-9114e1980e2d"

}

该包支持经典和现代工具包,因此无需依赖工具包的配置。

不使用 Sencha Cmd 使用透视网格

SDK 包含透视网格代码的编译版本,可供不使用 Sencha Cmd 的用户使用。要以这种方式包含透视网格,请从你的索引页链接以下资源

{unzippedFolder}/packages/pivot/build/{toolkit}/pivot.js

{unzippedFolder}/packages/pivot/build/{toolkit}/{themeName}/resources/pivot-all.css

在应用程序目录中包括以下内容

{unzippedFolder}/packages/pivot/build/{toolkit}/{themeName}/resources/images/

使用透视网格

透视网格依赖于扩展本机网格面板的两部分 - 轴和聚合。轴允许你确定行和列的位置,而聚合管理分组计算。这些部分需要在透视网格使用的透视矩阵对象上定义。

让我们通过想象上面讨论的用例来深入了解透视网格。首先,我们将数据集分解为销售人员和年份。我们可以通过配置顶部和左侧轴来做到这一点

{
    xtype: 'pivotgrid',

    matrix: {

        leftAxis: [{

            width: 80,

            dataIndex: 'salesperson',

            header: 'Salesperson'

        }],

        topAxis: [{

            dataIndex: 'year',

            header: 'Year',

            direction: 'ASC'

        }]

        // ... more configs
    }
}    

这将产生如下视图

image alt text

聚合

接下来,我们将设置聚合,以便可以适当地计算单元格值。
透视网格开箱即用包含许多聚合方法。

  • 求和

  • 平均值

  • 最小值

  • 最大值

  • 计数

  • groupSumPercentage - 如果约翰在美国和德国销售商品,你可能希望了解从总销售额中销售到美国的百分比。groupSumPercentage 方法计算当前项目总和占父项目总和的百分比。

  • groupCountPercentage - 这与 groupSumPercentage 相同,但使用计数而不是总和。

  • 方差

  • 方差P

  • 标准差

  • 标准差P

你还可以提供自己的聚合函数进行自定义处理。以下示例演示了如何通过在聚合数组中配置每个聚合器来聚合多个字段(销售额和数量)。如你所见,我们正在为数量使用自定义聚合器。

{
    xtype: 'pivotgrid',

    matrix: {

        aggregate: [{

            measure: 'amount',

            header: 'Sales',

            aggregator: 'sum',

            align: 'right',

            width: 85,

            renderer: Ext.util.Format.numberRenderer('0,000.00')

        }, {

            measure: 'orderid',

            header: 'Qnt',

            aggregator: function(records, measure, matrix, rowGroupKey, colGroupKey) {

                // custom aggregator logic

                return records.length;

            },

            align: 'right',

            width: 85,

            renderer: Ext.util.Format.numberRenderer('0,000.00')

        }]

        // ... more configs
    }
}    

以上是一个简单的示例,展示了可能的做法。如果你正在编写自己的聚合方法,最好重写 Ext.pivot.Aggregators。在重写中,你可以添加你的函数,并将函数名称用作聚合器配置名称。

Ext.define('Overrides.pivot.Aggregators', {

    override: 'Ext.pivot.Aggregators',

    myOwnFnText: 'My special fn', // useful when using the Configurator plugin
    myOwnFn: function(records) {

        // custom aggregator logic

        return records.length;

    }

});

// Then you can define your aggregate config in this manner

aggregate: [{

    // ...

    dataIndex:    'field',

    aggregator: 'myOwnFn'

    // ...

}]

也可以在 ViewController 中定义聚合函数。

Ext.define('App.view.Pivot', {
    extend: 'Ext.pivot.Grid',
    controller: 'pivot',

    matrix: {
        aggregate: [{

            // ...

            dataIndex: 'field',

            aggregator: 'myOwnFn'

            // ...

        }]

        // ...
    }
});

Ext.define('App.view.PivotController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.pivot',

    myOwnFn: function(records, measure, matrix, rowGroupKey, colGroupKey){
        // custom aggregate function
        return records.length;
    }
});

功能

排序结果

在定义维度时,你可以设置以下配置来影响排序结果。

  • 可排序:设置为 True 以对结果进行排序(默认值为 true)。

  • 方向:您可以指定是否要对结果进行排序(升序)ASC 或(降序)DESC(默认值为 ASC)。

  • caseSensitiveSort:配置为 true 以使过滤与完全匹配的大小写相匹配(默认值为 true)。

  • sorterFn:自定义排序函数。

  • sortIndex:您可能希望使用记录中另一个字段的值对结果进行排序。假设您有一个字段“month-name”,其值如 Jan、Feb 等,另一个字段“month-value”的值如 1、2 等。有意义的做法是获取“month-name”(dataIndex)中的结果,并按“month-value”(sortIndex)进行排序。

多个总计

默认情况下,透视表会计算行中的总计。您可以选择是否显示总计。可以通过两种方式在行中添加多个总计

  • 您可以侦听透视表触发的 pivotbuildtotals 事件。事件处理程序作为参数传递,其中包含一个总计值数组和默认值。该数组中的每个对象都应有一个“title”和一个“values”数组,这些数组将用于生成总计记录。

  • 您可以扩展其中一个矩阵类并使用模板方法 onBuildTotals 来执行与上述相同的逻辑。

您提供的新的总计将以透视表中的默认总计样式显示。

// ...

listeners: {

    pivotbuildtotals: function(matrix, totals) {

        var dataAvg = {},

            dataMax = {};

        Ext.Array.each(matrix.model, function(field) {

            var result,

            agg;

            if (field.col && field.agg) {

                agg = matrix.aggregate.getByKey(field.agg);

                result = matrix.results.get(matrix.grandTotalKey, field.col);

                if (result && agg) {

                    dataAvg[field.name] = result.calculateByFn(
                                            'totalavg', 
                                            agg.dataIndex, 
                                            Ext.pivot.Aggregators.avg);

                    dataMax[field.name] = result.calculateByFn(
                                            'totalmax', 
                                            agg.dataIndex, 
                                            Ext.pivot.Aggregators.max);

                }

            }

        });

        totals.push({

            title: 'Grand total (avg)',

            values: dataAvg

        }, {

            title: 'Grand total (max)',

            values: dataMax

        });

    }

}

// ...

范围分组

假设您在一个轴上为年份提供了结果,并且您希望将它们分组为 80 年代、90 年代等。您可以通过两种方式实现此目的

  • 您可以在维度上定义一个“grouperFn”,该维度将传递记录,并应返回组值(即 80 年代、90 年代等)。

  • 您可以在源模型上定义一个具有“convert”函数的新字段,并且执行与上述相同的操作。

grouperFn 示例

leftAxis: [{

    // ...

    grouperFn: function(record) {

        var dataIndex = this.dataIndex,

            recIndex = record.get(dataIndex);

        if (recIndex >= 1980 && recIndex < 1990) return "80'";

        if (recIndex >= 1990 && recIndex < 2000) return "90'";

        return 'Rest';

    }

    // ...

}]

过滤

透视表提供两种类型的过滤器

标签过滤器

标签过滤器允许您通过评估为顶部或左侧轴结果生成的值(即以...开头、不以...开头、以...结尾等)来过滤结果。

值过滤器

值过滤器允许您通过评估为每个顶部/左侧轴对计算的值(即等于、大于、前 10 项、前 10%、前 10 个总和等)来过滤结果。

过滤器在左侧或顶部轴的维度项上进行配置。

aggregate: [{
    id: 'agg1',

    dataIndex: 'value',

    aggregator: 'sum',

    header: 'Total'
}],

leftAxis: [{

    // ...

    filter: {

        type: 'value',

        operator: 'top10',

        topOrder: 'top',

        topType: 'sum',

        value: 9500,

        dimensionId: 'agg1'

    }

    // ...

}]

有关更多信息,请查看过滤器类(Ext.pivot.filter.*)。

缓冲渲染

透视表网格的计算完成后,透视表存储中可能会有数千条记录。为了防止 DOM 不堪重负,您可能希望使用 BufferedRenderer 插件。BufferedRenderer 自 Ext JS 4.2.0 版本以来一直可用。在版本 5+ 中,默认情况下在网格面板上使用 BufferedRendering。

BufferedRenderer 允许用户滚动数千条记录,而无需一次在屏幕上渲染所有记录的性能损失。

外观

布局

透视表网格通过 viewLayoutType 配置提供了两种布局类型:大纲和紧凑。

大纲

image alt text

{
    xtype: 'pivotgrid',

    matrix: {

        viewLayoutType: 'outline'

        // ... more configs
    }
}

紧凑

image alt text

{
    xtype: 'pivotgrid',

    matrix: {

        viewLayoutType: 'compact',

        compactViewColumnWidth: 250,

        textRowLabels: 'Row labels'

        // ... more configs
    }
}

总计定位

可以为左侧和顶部轴配置总计的位置。总计可以设置为 firstlastnone

当组折叠时,组总计将始终可见。无论在某个轴上配置了哪些总计,都会发生这种情况。当组展开时,也将使用相同的配置。

{
    xtype: 'pivotgrid',

    matrix: {

        rowSubTotalsPosition:       'first',

        rowGrandTotalsPosition:     'last',

        colSubTotalsPosition:       'last',

        colGrandTotalsPosition:     'last'

        // ... more configs
    }
}

渲染器

渲染器可用于设置轴结果的标签格式。例如

{
    xtype: 'pivotgrid',

    matrix: {

        topAxis: {
            dataIndex: 'month',

            labelRenderer: function(value){
                return Ext.Date.monthNames[value];
            }
        }

        // ... more configs
    }
}

还可以用于设置聚合维度上的输出值格式

{
    xtype: 'pivotgrid',

    matrix: {

        aggregate: [{
            dataIndex: 'amount',

            aggregator: 'sum',

            formatter: 'number("0,000.00")'
        }, {
            dataIndex: 'qty',

            aggregator: 'sum',

            renderer: Ext.util.Format.numberRenderer('0,000.00')
        }]

        // ... more configs
    }
}

视图控制器也可以用于定义渲染器。

Ext.define('App.view.Pivot', {
    extend: 'Ext.pivot.Grid',
    controller: 'pivot',

    matrix: {
        topAxis: {
            // ...

            dataIndex: 'month',

            labelRenderer: 'monthRenderer'

            // ...
        },

        aggregate: [{
            // ...

            dataIndex: 'field',

            renderer: 'myOwnFn'

            // ...
        }]

        // ...
    }
});

Ext.define('App.view.PivotController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.pivot',

    monthRenderer: function(value){
        return Ext.Date.monthNames[value];
    },

    myOwnFn: function(value, meta, record){
        // custom renderer function
        return value;
    }
});

样式

透视表网格的样式取决于所使用的工具包。

经典工具包

聚合维度渲染器可用于设置单元格样式和设置输出值格式

{
    xtype: 'pivotgrid',

    matrix: {

        aggregate: {
            dataIndex: 'amount',

            aggregator: 'sum',

            renderer: function(value, meta, record) {

                if (value > 40000) {

                    meta.style = "background-color: yellow;";

                }

                return Ext.util.Format.number(value, '0,000.00');

            }
        }

        // ... more configs
    }
}

使用上述渲染器,生成的网格输出将显示为

image alt text

渲染器配置也可以用于左轴维度来设置单元格样式。

你也可以在渲染器函数中定义更复杂的逻辑。例如,下面的渲染器在总和低于模型上其他字段的平均值时,会以不同的样式设置单元格。

{
    xtype: 'pivotgrid',

    matrix: {

        aggregate: {
            dataIndex: 'amount',

            aggregator: 'sum',

            renderer: function(value, meta, record, recordIndex, columnIndex, store, view) {

                var grid = view.up('pivotgrid'),

                    topItem = grid.getTopAxisItem(meta.column),

                    leftItem = grid.getLeftAxisItem(record),

                    result;

                if (topItem && leftItem) {

                    result = grid.getMatrix().results.get(leftItem.key, topItem.key);

                    // if you already have the avg configured on another 
                    // dimension just fetch the result

                    // result.getValue('avg')

                    // otherwise calculate the result

                    result.calculateByFn('avg', 'some-other-field', Ext.pivot.Aggregators.avg);

                    if (value < result.getValue('avg')) {

                        meta.style = "background-color: yellow;";

                    }

                }

                return Ext.util.Format.number(value, '0,000.00');

            }

        }

        // ... more configs
    }
}

现代工具包

行上的 ViewModel

让我们看这个示例

 {
     xtype: 'pivotgrid',
     itemConfig: {
         viewModel: {
             type: 'pivot-row-model'
         },
         bind: {
             userCls: '{rowStyle}'
             // or you can define a template
             //userCls: '{record.isRowGroupHeader:pick("","pivotRowHeader")}'
         }
     }
     // ... more configs
 }

在 ViewModel 中,我们会声明一个将使用记录数据的公式。记录具有为该行显示的所有值以及以下附加字段

  • isRowGroupHeader
  • isRowGroupTotal
  • isRowGrandTotal
  • leftAxisKey:这是总计键或标识左轴项的键

所有这些属性都可以帮助我们设置整个行的样式,而无需了解生成的列。

在某些情况下,我们可能希望设置透视网格中生成的正值和负值的样式。这可以按如下方式完成。

 {
     xtype: 'pivotgrid',
     itemConfig: {
         viewModel: {
             type: 'default'
         }
     },
     topAxisCellConfig: {
         bind: {
             userCls: '{value:sign("pivotCellNegative","pivotCellPositive")}'
         }
     }
     // ... more configs
 }

以下数据可用于绑定模板

  • column
    • isColGroupTotal:这告诉我们该特定单元格的列是组总计
    • isColGrandTotal:这告诉我们该特定单元格的列是总计
  • value:单元格值

注意:在这种情况下,你不能使用公式,因为列和值是动态生成的,不能在公式中替换。

还可以设置左轴或聚合的特定维度的样式

 {
     xtype: 'pivotgrid',
     itemConfig: {
         viewModel: {
             type: 'default'
         }
     },
     matrix: {
         aggregate: [{
             dataIndex:  'value',
             aggregator: 'sum',
             align:      'right',
             cellConfig: {
                 bind: {
                     userCls: '{value:sign("pivotCellNegative","pivotCellPositive")}'
                 }
             }
         },{
             dataIndex:  'value',
             aggregator: 'count'
         }],
         leftAxis: [{
             dataIndex:  'person',
             // This is used only when `viewLayoutType` is `outline`
             cellConfig: {
                 bind: {
                     userCls: '{record.isRowGroupHeader::pick("","pivotRowHeader")}'
                 }
             }
         },{
             dataIndex:  'country'
         }]
         // ... more configs
     }
 }
单元格上的 ViewModel

此方案允许你定义用于单元格绑定的公式。小心,因为这意味着每个单元格将有自己的 ViewModel,这可能会降低透视网格的性能。仅在必要时使用它。

 {
     xtype: 'pivotgrid',
     leftAxisCellConfig: {
         viewModel: {
             type: 'default'
         },
         bind: {
             userCls: '{record.isRowGroupHeader::pick("","pivotRowHeader")}'
         }
     },
     topAxisCellConfig: {
         viewModel: {
             type: 'pivot-cell-model' // to be able to define your own formulas
         },
         bind: {
             userCls: '{value:sign("pivotCellNegative","pivotCellPositive")}'
             //userCls: '{column.isColGrandTotal:pick(null,"pivotCellGrandTotal")}'
             //userCls: '{cellCls}
         }
     }
     // ... more configs
 }

此方法允许你在绑定模板和公式中使用记录、列和值。

如果有多个聚合维度可用,并且你希望设置其中一个维度的样式,则可以像这样定义该维度上的绑定

 {
     xtype: 'pivotgrid',
     matrix: {
         aggregate: [{
             dataIndex:  'value',
             aggregator: 'sum',
             align:      'right',
             cellConfig: {
                 viewModel: {
                     type: 'pivot-cell-model'
                 },
                 bind: {
                     userCls: '{value:sign("pivotCellNegative","pivotCellPositive")}'
                     //userCls: '{column.isColGrandTotal:pick(null,"pivotCellGrandTotal")}'
                     //userCls: '{cellCls}
                 }
             }
         },{
             dataIndex:  'value',
             aggregator: 'count'
         }]
         // ... more configs
     }
 }

有状态

可以通过使用 stateful: true 以及 stateId 将透视网格配置为有状态。该状态将保存你为左、上和聚合提供的全部维度配置。它还将调用展开或折叠组的状态。

注意:此功能仅在经典工具包中可用。

锁定网格

你可以通过在透视网格上设置 enableLocking: true 来“锁定”左轴列。
这允许你滚动顶部轴生成的列。

注意:此功能仅在经典工具包中可用。

插件

单元格编辑

此插件允许用户编辑透视网格单元格。它使用更新器来处理透视网格单元格后面的记录。

{
    xtype: 'pivotgrid',

    plugins: [{
        ptype: 'pivotcellediting',
        clicksToEdit: 1,
        defaultUpdater: 'uniform' // define here the type of editing: 'overwrite', 'increment', 'percentage', 'uniform'
    }]

    // ... more configs
}

可以定义更多更新器。有关更多信息,请查看更新器类(Ext.pivot.update.*)。

此插件还提供了在透视网格上触发的两个事件,你可以使用它们来预/后处理编辑:pivotbeforeupdatepivotupdate

注意:此功能仅在经典工具包中可用。

范围编辑器

此插件允许用户编辑透视网格结果。用户可以双击透视网格单元格,这将打开一个窗口,其中包含用于更新的各种字段。以下类型的编辑可用

  • 百分比:提供的值是百分比,应使用该百分比增加该单元格后面所有记录的值。

  • 增量:提供的值将添加到每条记录上的现有值。

  • 覆盖:提供的值将替换每条记录上的现有值。

  • 均匀:提供的值将在所有记录上均匀分布。

此插件还提供了在透视网格上触发的两个事件,你可以使用它们来预/后处理编辑:pivotbeforeupdatepivotupdate

下钻

下钻插件允许用户下钻到透视网格结果中。用户可以双击透视网格单元格,这将打开一个对话框窗口,其中包含一个网格,该网格包含由该单元格获取的记录。

可以通过与普通 Ext JS 网格相同的方式配置插件上的 columns 配置,来自定义在下钻窗口中显示的网格。

在透视网格中使用远程计算时,需要提供 remoteStore 配置,该配置将被插件过滤。

导出器

导出器插件允许将透视网格结果导出到类系统中可用的任何导出器类型。该插件使用开箱即用的以下导出器的exporter

  • excel Excel 2007 xlsx 格式

  • xml Excel 2003 xml 格式

  • csv CSV 文件

  • tsv TSV 文件

  • html Html 文件

该插件向透视网格组件添加了两个新方法

  • saveDocumentAs:此函数将保存导出的文件

  • getDocumentData:返回导出文档内容

这两个函数都接受一个 config 对象作为参数

  • type:这是导出器类型(_默认为excel)。

  • onlyExpandedNodes:设置为 true 以仅导出展开的组(默认为false)。

  • showSummary:设置为 false 以从导出中排除总计(默认为true)。

  • title:设置一个标题,显示在导出文档中列标题上方。

  • fileName:已保存文件的名称。

每个导出器都可能带有自己的一组附加配置。当调用其中一个函数时,可以将这些配置提供给上述配置对象。

saveDocumentAs 尝试使用特定于浏览器的功能来保存文档。如果浏览器没有保存文件的功能,则生成的文件的内容将发送到服务器脚本,服务器将使用可下载文件的正确标头进行响应。

服务器脚本的 URL 可以自定义为 Ext.exporter.File#property-url,服务器脚本可以内部托管。可以在exporter包根目录中的 server 文件夹中找到 Node 和 PHP 的实现。

配置器

配置器插件允许用户使用拖放功能轻松配置透视网格。

此插件最重要的配置是fields。这必须是一个字段数组,可以通过 DND 用于配置透视网格。如果在使用本地矩阵时 fields 配置为空,则该插件将自动从存储模型中提取所有字段。

每个 字段 都具有一个settings配置,该配置为字段使用提供了一些限制。可以在settings中定义以下配置

  • cls:要添加到此配置器字段的 CSS 类

  • style:类似于 Ext.Component#cfg-style

  • fixed:如果您希望将字段固定在特定区域,则必须在此处定义这些区域。可能的值:aggregateleftAxistopAxis

  • allowed:在此处定义此字段可用于的区域。可能的值:aggregateleftAxistopAxis

  • aggregators:在此处定义当字段配置为聚合时可用的函数。

  • renderers:这些渲染器仅用于聚合维度。

  • formatters:格式化程序仅用于聚合维度。

示例

Ext.define('App.view.Pivot', {
    extend: 'Ext.pivot.Grid',
    controller: 'pivot',

    plugins: {
        ptype: 'pivotconfigurator', // use `type` for modern toolkit

        fields: [{
            dataIndex:  'quantity',
            header:     'Qty',
            // You can even provide a default aggregator function to be used when this field is dropped
            // on the agg dimensions
            aggregator: 'min',
            formatter: 'number("0")',

            settings: {
                // Define here in which areas this field could be used
                allowed: ['aggregate'],
                // Set a custom style for this field to inform the user that it can be dragged only to "Values"
                style: {
                    fontWeight: 'bold'
                },
                // Define here custom formatters that ca be used on this dimension
                formatters: {
                    '0': 'number("0")',
                    '0%': 'number("0%")'
                }
            }
        }, {
            dataIndex:  'amount',
            header:     'Value',

            settings: {
                // Define here in which areas this field could be used
                allowed: 'aggregate',
                // Define here what aggregator functions can be used when this field is
                // used as an aggregate dimension
                aggregators: ['sum', 'avg', 'count'],
                // Set a custom style for this field to inform the user that it can be dragged only to "Values"
                style: {
                    fontWeight: 'bold'
                },
                // Define here custom renderers that can be used on this dimension
                renderers: {
                    'Colored 0,000.00': 'coloredRenderer' // coloredRenderer is a function on the ViewController
                },
                // Define here custom formatters that ca be used on this dimension
                formatters: {
                    '0': 'number("0")',
                    '0.00': 'number("0.00")',
                    '0,000.00': 'number("0,000.00")',
                    '0%': 'number("0%")',
                    '0.00%': 'number("0.00%")'
                }
            }
        }, {
            dataIndex:  'year',
            header:     'Year',

            settings: {
                // Define here the areas in which this field is fixed and cannot be moved from
                fixed: ['topAxis']
            }
        }, {
            dataIndex:      'month',
            header:         'Month',
            labelRenderer:  'monthLabelRenderer', // monthLabelRenderer is a function available on the ViewController

            settings: {
                // Define here what aggregator functions can be used when this field is
                // used as an aggregate dimension
                aggregators: ['count'],
                // Define here in which areas this field could be used
                allowed: ['leftAxis', 'topAxis']
            }
        }]
    }
});

Ext.define('App.view.PivotController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.pivot',

    monthLabelRenderer: function(value){
        return Ext.Date.monthNames[value];
    },

    // implementation for classic toolkit
    //coloredRenderer: function(v, meta){
    //    if(meta) {
    //        meta.style = Ext.String.format('color: {0};', v > 500 ? 'green' : 'red');
    //    }
    //    return Ext.util.Format.number(v, '0,000.00');
    //}

    // implementation for modern toolkit
    coloredRenderer: function(v, record, dataIndex, cell, column){
        cell.setStyle( Ext.String.format('color: {0};', v > 500 ? 'green' : 'red') );
        return Ext.util.Format.number(v, '0,000.00');
    }
});

配置器插件会触发透视网格上的事件,允许您进一步自定义用户交互。在经典工具包中,此类事件的实现是beforeshowconfigfieldmenu,它允许您在配置器字段菜单中定义更多菜单。

image alt text

Ext.define('App.view.Pivot', {
    extend: 'Ext.pivot.Grid',
    controller: 'pivot',

    plugins: 'pivotconfigurator',

    matrix: {
        // ...
    },

    listeners: {
        beforeshowconfigfieldmenu: 'getCustomMenus'        
    }
});

Ext.define('App.view.PivotController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.pivot',

    getCustomMenus: function (panel, options) {
        options.menu.add({
            text: 'Custom menu item',
            handler: function(){
                Ext.Msg.alert('Custom menu item', Ext.String.format('Do something for "{0}"', options.field.getHeader()));
            }
        });
    }

});

矩阵类

事件

矩阵类触发的多数事件都会中继到透视网格,并带有pivot前缀。

基本矩阵

基本矩阵类构建顶部和左侧轴项。它还计算每个左侧/顶部项对的结果。

本地矩阵

将矩阵类型设置为local表示浏览器将负责计算数据。本地矩阵非常适合中小型数据集。

{
    xtype: 'pivotgrid',

    // ...

    matrix: {

        type: 'local', // default value

        store: 'YourStore',

        recordsPerJob: 1000,

        timeBetweenJobs: 2,

        leftAxis: [],

        topAxis: [],

        aggregate: []

    }

    // ...

}

本地矩阵进程将记录存储在多个作业中,以帮助防止在使用中等规模数据集时浏览器过载。您可以选择配置每个作业应处理多少条记录,以及作业之间应等待多长时间。

远程矩阵

在浏览器中计算大型数据集可能需要花费大量时间,并可能导致浏览器无响应。如果您正在使用大型数据集,则应使用远程矩阵。远程矩阵将序列化您的所有配置并将其发送到服务器,以便您可以在远程执行计算。

{
    xtype: 'pivotgrid',

    // ...

    matrix: {

        type: 'remote',

        url: 'http://your-backend-url',

        timeout: 3000, // optional config used by the Ajax call

        leftAxis: [],

        topAxis: [],

        aggregate: []

    }

    // ...

}

常见问题

发送到服务器的内容是什么?

leftAxis、topAxis 和 aggregate 是维度项对象的数组。这些数组被序列化并作为 Ajax 请求中的参数发送。

params = {

    leftAxis: leftAxis,

    topAxis: topAxis,

    aggregate: aggregate,

    grandTotalKey: 'grandtotal', // the value configured for grandTotalKey on the matrix

    keysSeparator: '#_#' // the value configured for keysSeparator on the matrix

};

// ...

Ext.Ajax.request({

    // ...

    url: me.url,

    timeout: me.timeout,

    jsonData: params,

    // ...

});

在执行 Ajax 调用之前,将通过 beforerequest 事件(实际上已中继到数据透视网格作为 pivotbeforerequest)或通过模板方法 onBeforeRequest 收集其他参数。

JSON 响应应是什么样的?

数据透视网格期望以特定格式的 JSON 响应。响应应返回 leftAxis 和 topAxis 的项数组以及 left/top 项对的所有结果。

注意:“id”属性非常重要。如果未指定,将生成一个 id。

{

    success: true,

    leftAxis: [{

        key: '-1276511163', // provide your own key but be careful to avoid conflicts with keysSeparator

        value: 'Macromedia',

        // following is the id of the dimension, the one that you 
        // provided or was generated

        dimensionId: 'leftAxis1'

    }, {

        // when multiple dimensions are provided then the result key 
        // should be formatted like this

        key: '-1276511163#_#243243', // use the keysSeparator that was sent to the server

        value: 'Steve',

        // following is the id of the dimension, the one that you 
        // provided or was generated

        dimensionId: 'leftAxis2'

    }],

    topAxis: [{

        // same like leftAxis

    }],

    results: [{

        leftKey: '-1276511163',

        topKey: '34535345435',

        values: {

            agg1: 4345.34, // agg1 is the id of the aggregate dimension

            agg2: 244 // agg2 is the id of the 2nd aggregate dimension defined

        }

    }]

}

针对矩阵生成了一个名为“grandtotal”的键,用于大汇总计算。您可以通过更改 matrix.grandTotalKey 的值来修改此命名方案。

如果在 leftKeytopKey 上同时使用,它表示两个轴的大汇总。

如果用于 leftKey,它表示为每个提供的 topKey 提供的列的大汇总。

如果用于 topKey,它表示为每个提供的 leftKey 提供的行的大汇总。

如何在服务器上计算?

pivot 包中的服务器文件夹包含一个 PHP 示例,展示了服务器端计算的一种方法。也就是说,您还可以用任何服务器端语言编写自己的实现,只要它返回上面描述的 JSON 对象即可。

错误处理

如果服务器计算失败,您可以发送回 success: false 以及您希望在数据透视客户端处理的任何其他元数据信息。远程矩阵类将识别调用失败,并将触发“requestexception”事件,该事件将中继到数据透视网格作为“pivotrequestexception”。

结论

Sencha 数据透视网格为从大型数据集中收集汇总信息提供了理想的解决方案。数据集中的特定字段可以突出显示为完整数据集的定量汇总,使用户能够从多个视点可视化数据集。

有关如何配置数据透视网格的更多示例,请参阅 SDK 下载中的 KitchenSink 示例文件夹。

Ext JS 7.8.0