二十八、UI-Grid Grouping 分组

原文:Tutorial: 209 Grouping

分组功能允许您根据特定列中的相似值对行进行分组, 在某些方面类似于 excel 数据透视表的效果。不按分组的列可以聚合, 例如, 统计每个组中的行数。

api 文档中提供有”分组” 的功能, 包括分组本身和 treeBase 文档中的共享函数。特别是:

  • grouping columnDef and treeBase columnDef
  • grouping gridOptions and treeBase gridOptions
  • grouping publicApi and treeBase publicApi

树结构本身被记录在 treeBase。

可以在 columnDef 选项中来设置分组:
grouping: { groupPriority: 0 }
或为列中的聚合设置 treeAggregation: {type: uiGridGroupingConstants.aggregation.COUNT}.

默认情况下分组列会显示在前面, 这将提供更直观的效果。为了避免对pinning 的依赖关系, 是将分组的列作为整体来移动的, 而不是使用pinning 功能。

分组有排序功能, 允许用户更改排序顺序或使用外部排序功能, 并将结果分组。标记为分组的列排序优先级最高。

任何分组的列都有 suppressRemoveSort 设置, 当列被取消分组时, suppressRemoveSort 将返回到 columnDef 中的值。

分组和聚合应与筛选一起使用, 它应只对筛选的行进行分组和聚合。

无法编辑组页眉行, 如果使用选择功能, 则无法选择。但是, 它们可以被导出。

默认情况下, 组 rowHeader 始终可见。如果希望 groupRowHeader 仅在至少一列分组时出现, 则可以在gridOption中设置 treeRowHeaderAlwaysVisible: false

表格初始化之后更改分组, 可以调用以下方法:

  • groupColumn:对单个列进行分组。将其添加到当前分组的末尾, 因此, 如果希望这是唯一的分组, 首先需要删除现有的分组列。添加一个asc排序 , 如果没有一个
  • ungroupColumn:取消单个列
  • aggregateColumn:设置列的聚合, 包括关闭聚合。首先自动删除任何排序。
  • setGrouping:将所有分组集中在一个序列中, 删除现有分组
  • getGrouping:获取表格的分组配置
  • clearGrouping:清除当前分组设置

以下几点需要注意:
- treeIndent:随着分组级别的加深, 展开按钮将缩进多个像素 (默认为 10)。更大的值看起来更好, 但占用更多的空间。
- treeRowHeaderWidth:分组行标题的宽度
- customTreeAggregationFinalizerFn:如果列有一个 cellFilter, 则插入文本 (例如 “min: xxxx”) 通常会破坏 cellFilter。可以定义一个自定义聚合终结器, 以不同的方式处理此文本, 可以在代码中应用筛选, 或者跳过包含的聚合文本。这也可以用来跳过计数的统计。

如果要取消分组列中的数据 (只显示在groupHeader 行中), 则可以通过对允许分组的任何列重写 cellTemplate, 如下所示:

cellTemplate: '<div ng-if="!col.grouping || col.grouping.groupPriority === undefined || col.grouping.groupPriority === null || ( row.groupHeader && col.grouping.groupPriority === row.treeLevel )" class="ui-grid-cell-contents" title="TOOLTIP">{{COL_FIELD CUSTOM_FILTERS}}div>'

在下面的示例中, 此操作仅在状态列上完成。这不包括在基本代码中, 因为它可能与用户的自定义模板进行交互。

调整聚合工作的方式可以通过定义 columnsProcessor (比 groupingColumnProcessor 更高 (更高) 的优先级 (高于 400), 以及查找分组或聚合列并更改诸如 treeAggregationFn 或 customTreeAggregationFinalizerFn 的内容来完成。有关示例, 请参见教程320。

Example

在这个例子中, 先按 “状态” 列,然后是 “性别” 列, 统计名称 , 并找到每个分组的最大年龄, 最后计算平均余额。我们禁止在 “平衡” 列上显示聚合文本, 因为我们希望将其格式化为货币… 但这意味着我们不能轻易地看到它是一个平均值。

我们编写一个函数来提取状态和性别的聚合数据 (如果您更改了分组, 则此函数将停止工作), 并将它们写入控制台。

代码:
index.html


<html ng-app="app">
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js">script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-touch.js">script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.js">script>
    <script src="http://ui-grid.info/docs/grunt-scripts/csv.js">script>
    <script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js">script>
    <script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js">script>
    <script src="/release/ui-grid.js">script>
    <script src="/release/ui-grid.css">script>
    <script src="app.js">script>
  head>
  <body>
    <div ng-controller="MainCtrl">
      <button id="expandAll" type="button" class="btn btn-success" ng-click="expandAll()">Expand Allbutton>
      <button id="toggleFirstRow" type="button" class="btn btn-success" ng-click="toggleRow(0)">Toggle First Rowbutton>
      <button id="toggleSecondRow" type="button" class="btn btn-success" ng-click="toggleRow(1)">Toggle Second Rowbutton>
      <button id="changeGrouping" type="button" class="btn btn-success" ng-click="changeGrouping()">Change Groupingbutton>
      <button id="getAggregates" type="button" class="btn btn-success" ng-click="getAggregates()">Get Aggregatesbutton>
      <div id="grid1" ui-grid="gridOptions" ui-grid-grouping class="grid">div>
    div>
  body>
html>

main.css

.grid {
  width: 500px;
  height: 400px;
}

app.js

var app = angular.module('app', ['ngAnimate', 'ngTouch', 'ui.grid', 'ui.grid.grouping' ]);

app.controller('MainCtrl', ['$scope', '$http', '$interval', 'uiGridGroupingConstants', function ($scope, $http, $interval, uiGridGroupingConstants ) {
  $scope.gridOptions = {
    enableFiltering: true,
    treeRowHeaderAlwaysVisible: false,
    columnDefs: [
      { name: 'name', width: '30%' },
      { name: 'gender', grouping: { groupPriority: 1 }, sort: { priority: 1, direction: 'asc' }, width: '20%', cellFilter: 'mapGender' },
      { name: 'age', treeAggregationType: uiGridGroupingConstants.aggregation.MAX, width: '20%' },
      { name: 'company', width: '25%' },
      { name: 'registered', width: '40%', cellFilter: 'date', type: 'date' },
      { name: 'state', grouping: { groupPriority: 0 }, sort: { priority: 0, direction: 'desc' }, width: '35%', cellTemplate: '
{{COL_FIELD CUSTOM_FILTERS}}
'
}, { name: 'balance', width: '25%', cellFilter: 'currency', treeAggregationType: uiGridGroupingConstants.aggregation.AVG, customTreeAggregationFinalizerFn: function( aggregation ) { aggregation.rendered = aggregation.value; } } ], onRegisterApi: function( gridApi ) { $scope.gridApi = gridApi; } }; $http.get('/data/500_complex.json') .success(function(data) { for ( var i = 0; i < data.length; i++ ){ var registeredDate = new Date( data[i].registered ); data[i].state = data[i].address.state; data[i].gender = data[i].gender === 'male' ? 1: 2; data[i].balance = Number( data[i].balance.slice(1).replace(/,/,'') ); data[i].registered = new Date( registeredDate.getFullYear(), registeredDate.getMonth(), 1 ) } delete data[2].age; $scope.gridOptions.data = data; }); $scope.expandAll = function(){ $scope.gridApi.treeBase.expandAllRows(); }; $scope.toggleRow = function( rowNum ){ $scope.gridApi.treeBase.toggleRowTreeState($scope.gridApi.grid.renderContainers.body.visibleRowCache[rowNum]); }; $scope.changeGrouping = function() { $scope.gridApi.grouping.clearGrouping(); $scope.gridApi.grouping.groupColumn('age'); $scope.gridApi.grouping.aggregateColumn('state', uiGridGroupingConstants.aggregation.COUNT); }; $scope.getAggregates = function() { var aggregatesTree = []; var gender var recursiveExtract = function( treeChildren ) { return treeChildren.map( function( node ) { var newNode = {}; angular.forEach(node.row.entity, function( attributeCol ) { if( typeof(attributeCol.groupVal) !== 'undefined' ) { newNode.groupVal = attributeCol.groupVal; newNode.aggVal = attributeCol.value; } }); newNode.otherAggregations = node.aggregations.map( function( aggregation ) { return { colName: aggregation.col.name, value: aggregation.value, type: aggregation.type }; }); if( node.children ) { newNode.children = recursiveExtract( node.children ); } return newNode; }); } aggregatesTree = recursiveExtract( $scope.gridApi.grid.treeBase.tree ); console.log(aggregatesTree); }; }]) .filter('mapGender', function() { var genderHash = { 1: 'male', 2: 'female' }; return function(input) { var result; var match; if (!input){ return ''; } else if (result = genderHash[input]) { return result; } else if ( ( match = input.match(/(.+)( \(\d+\))/) ) && ( result = genderHash[match[1]] ) ) { return result + match[2]; } else { return input; } }; });

Demo

二十八、UI-Grid Grouping 分组_第1张图片

作者水平有限,不当之处敬请指正。

 

感谢您的阅读,如果觉得文章对您有帮助,请支持一下。
​​​​这里写图片描述

你可能感兴趣的:(angularjs,ui-grid中文api)