Angular Grid 集計
Ignite UI for Angular の Angular UI グリッドには、グループ フッターとして列レベルで集計できる機能があります。Angular グリッド集計は、列内のデータ タイプに応じて、あるいは Grid にカスタム Angular テンプレートを実装することによって、定義済みのデフォルト集計項目を使用して別のコンテナーの列情報を表示できます。
Angular Grid 集計の例
import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { AppComponent } from "./app.component";
import { HttpClientModule } from "@angular/common/http";
import {
IgxButtonModule,
IgxGridModule,
IgxInputGroupModule,
IgxRippleModule,
IgxSwitchModule,
IgxIconModule
} from "igniteui-angular";
import { GridSample3Component } from "./grid/grid-sample-3/grid-sample-3.component";
import { LocalService } from "./grid/grid-sample-2/grid-sample-2.component";
import { IgxPreventDocumentScrollModule } from "./directives/prevent-scroll.directive";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
GridSample3Component
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxPreventDocumentScrollModule,
IgxButtonModule,
IgxGridModule,
IgxInputGroupModule,
IgxRippleModule,
HttpClientModule,
IgxIconModule
],
providers: [],
entryComponents: [],
schemas: []
})
export class AppModule {}
ts
import { Component, ViewChild } from '@angular/core';
import {
ColumnType,
IgxGridComponent,
IgxNumberSummaryOperand,
IgxSummaryResult } from 'igniteui-angular';
import { DATA } from '../../data/nwindData';
class MySummary {
public operate(data?: any[]): IgxSummaryResult[] {
const result = new IgxNumberSummaryOperand().operate(data);
result.push({
key: 'test',
label: 'Test',
summaryResult: data.filter((rec) => rec > 10 && rec < 30).length
});
return result;
}
}
@Component({
selector: 'app-grid-sample-3',
styleUrls: ['./grid-sample-3.component.scss'],
templateUrl: './grid-sample-3.component.html'
})
export class GridSample3Component {
@ViewChild('grid1', { read: IgxGridComponent, static: true })
public grid1: IgxGridComponent;
public mySummary = MySummary;
public data;
public productId = 0;
constructor() {
this.data = DATA;
this.productId = DATA.length;
}
public toggleSummary(column: ColumnType) {
column.hasSummary = !column.hasSummary;
}
}
ts
<div class="grid__wrapper">
<igx-grid [igxPreventDocumentScroll]="true" #grid1 [data]="data" [autoGenerate]="false" height="600px" width="100%">
<igx-paginator></igx-paginator>
<igx-column #col field="ProductID" header="Product ID" width="17%" [headerClasses]="'prodId'">
</igx-column>
<igx-column #col field="ProductName" header="Product Name" width="17%" [headerClasses]="'prodId'" [hasSummary]="true">
<ng-template igxCell let-cell="cell" let-val>
{{val}}
</ng-template>
<ng-template igxHeader let-col>
<div class="header-text">{{col.field}}</div>
<igx-icon class="header-icon" style.color="{{ col.hasSummary ? '#e41c77' : '' }}" (click)="toggleSummary(col)">functions</igx-icon>
</ng-template>
</igx-column>
<igx-column #col field="UnitPrice" header="Price" [filterable]="false" width="17%" [editable]="true" dataType="number"
[hasSummary]="true">
<ng-template igxCell let-cell="cell" let-val let-row>
${{val}}
</ng-template>
<ng-template igxHeader let-col>
<div class="header-text">{{col.field}}</div>
<igx-icon class="header-icon" style.color="{{ col.hasSummary ? '#e41c77' : '' }}" (click)="toggleSummary(col)">functions</igx-icon>
</ng-template>
</igx-column>
<igx-column #col field="UnitsInStock" header="Units In Stock" width="17%" dataType="number" [editable]="true"
[hasSummary]="false" [summaries]="mySummary">
<ng-template igxCell let-cell="cell" let-val let-row>
{{val}}
</ng-template>
<ng-template igxHeader let-col>
<div class="header-text">{{col.field}}</div>
<igx-icon class="header-icon" style.color="{{ col.hasSummary ? '#e41c77' : '' }}" (click)="toggleSummary(col)">functions</igx-icon>
</ng-template>
</igx-column>
<igx-column #col field="Discontinued" header="Discontinued" width="17%" [hasSummary]="true" [dataType]="'boolean'">
<ng-template igxCell let-cell="cell" let-val>
<img *ngIf="val" src="https://www.infragistics.com/angular-demos-lob/assets/images/grid/active.png" title="Continued" alt="Continued" />
<img *ngIf="!val" src="https://www.infragistics.com/angular-demos-lob/assets/images/grid/expired.png" title="Discontinued" alt="Discontinued" />
</ng-template>
<ng-template igxHeader let-col>
<div class="header-text">{{col.field}}</div>
<igx-icon class="header-icon" style.color="{{ col.hasSummary ? '#e41c77' : '' }}" (click)="toggleSummary(col)">functions</igx-icon>
</ng-template>
</igx-column>
<igx-column #col field="OrderDate" width="15%" [dataType]="'date'" [hasSummary]="true">
<ng-template igxCell let-cell="cell" let-val let-row>
{{ val | date: 'MMM d, yyyy' }}
</ng-template>
<ng-template igxHeader let-col>
<div class="header-text">{{col.field}}</div>
<igx-icon class="header-icon" style.color="{{ col.hasSummary ? '#e41c77' : '' }}" (click)="toggleSummary(col)">functions</igx-icon>
</ng-template>
</igx-column>
</igx-grid>
</div>
html
.grid-controls {
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
margin: 0 16px 24px;
igx-switch {
margin-top: 24px;
}
}
.grid__wrapper {
margin: 0 auto;
padding: 16px;
}
.header {
height: 100%;
}
:host ::ng-deep{
.igx-grid__th .title{
width: 100%;
cursor: auto;
}
@media screen and (max-width: 677px){
.header-icon {
padding-bottom: 17px;
padding-top: 17px;
font-size: 1.4em;
width: 1.1em;
height: 1.1em;
float: right;
}
.header-text {
float:left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 50%;
}
}
@media screen and (min-width: 677px){
.header-icon {
padding-top: 17px;
font-size: 1.4em;
width: 1.1em;
height: 1.1em;
float: right;
}
.header-text {
float:left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 50%;
}
}
@media screen and (min-width: 992px){
.header-icon {
padding-top: 17px;
font-size: 1.4em;
width: 1.1em;
height: 1.1em;
float: right;
margin-right: 10px;
cursor: pointer;
}
.header-text {
float:left;
white-space: nowrap;
width: 50%;
cursor: auto;
}
}
}
scss
このサンプルが気に入りましたか? 完全な Ignite UI for Angularツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
列の集計は列値すべての関数ですが、フィルタリングが適用された場合、列の集計はフィルターされた結果値の関数になります。
Grid 集計を列ごとに有効にして必要な列のみアクティブ化できます。Grid 集計は、列のデータ型に基づいてデフォルト集計の定義済みセットを提供します。
string
と boolean
data types
の場合、データ型の場合、以下の関数が利用できます。
number
、currency
、および percent
データ型の場合、以下の関数を使用できます。
- count
- min
- max
- average
- sum
date
データ型の場合、以下の関数が利用できます。
すべての利用可能な列データ型は、公式の列タイプ トピックにあります。
hasSummary
プロパティを true
に設定すると Grid 集計が列レベルで有効になります。各列の集計は列のデータ型に基づいて解決されます。igx-grid
のデフォルトの列データ型は string
のため、number
または date
固有の集計を適用するには、dataType
プロパティを number
または date
に設定します。集計値は、グリッドの locale
および列 pipeArgs
に従ってローカライズされて表示されます。
<igx-grid #grid1 [data]="data" [autoGenerate]="false" height="800px" width="800px" (columnInit)="initColumn($event)">
<igx-column field="ProductID" header="Product ID" width="200px" [sortable]="true"></igx-column>
<igx-column field="ProductName" header="Product Name" width="200px" [sortable]="true" [hasSummary]="true"></igx-column>
<igx-column field="ReorderLevel" width="200px" [editable]="true" [dataType]="'number'" [hasSummary]="true"></igx-column>
</igx-grid>
html
特定の列や列のリストを有効または無効にする他の方法として igx-grid のパブリック メソッド enableSummaries
/disableSummaries
を使用する方法があります。
<igx-grid #grid1 [data]="data" [autoGenerate]="false" height="800px" width="800px" (columnInit)="initColumn($event)" >
<igx-column field="ProductID" header="Product ID" width="200px" [sortable]="true"></igx-column>
<igx-column field="ProductName" header="Product Name" width="200px" [sortable]="true" [hasSummary]="true"></igx-column>
<igx-column field="ReorderLevel" width="200px" [editable]="true" [dataType]="'number'" [hasSummary]="false"></igx-column>
</igx-grid>
<button (click)="enableSummary()">Enable Summary</button>
<button (click)="disableSummary()">Disable Summary </button>
html
public enableSummary() {
this.grid1.enableSummaries([
{fieldName: 'ReorderLevel', customSummary: this.mySummary},
{fieldName: 'ProductID'}
]);
}
public disableSummary() {
this.grid1.disableSummaries('ProductName');
}
typescript
カスタム Grid 集計
この関数が要件に合わない場合、指定した列にカスタム集計を提供できます。これには、基本クラス IgxSummaryOperand
、IgxNumberSummaryOperand
、IgxDateSummaryOperand
のいずれかを列データ型や必要に応じてオーバーライドします。このように既存の関数を再定義、または新しい関数を追加できます。IgxSummaryOperand
クラスは、count
メソッドにデフォルト実装のみを提供します。IgxNumberSummaryOperand
は IgxSummaryOperand
を拡張し、min
、max
、sum
、average
を提供します。IgxDateSummaryOperand
は IgxSummaryOperand
を拡張し、追加で earliest
と latest
を提供します。
import { IgxSummaryResult, IgxSummaryOperand, IgxNumberSummaryOperand, IgxDateSummaryOperand } from 'igniteui-angular';
class MySummary extends IgxNumberSummaryOperand {
constructor() {
super();
}
operate(data?: any[]): IgxSummaryResult[] {
const result = super.operate(data);
result.push({
key: 'test',
label: 'Test',
summaryResult: data.filter(rec => rec > 10 && rec < 30).length
});
return result;
}
}
typescript
例に表示されるように、基本クラスは operate
メソッドを公開しているため、すべてのデフォルト集計を取得して結果を変更するか、まったく新しい集計結果を計算することができます。
このメソッドは IgxSummaryResult
のリストを返し、集計を計算するためのオプションのパラメーターを取得します。
interface IgxSummaryResult {
key: string;
label: string;
summaryResult: any;
}
typescript
以下の「すべてのデータにアクセスするカスタム集計」セクションを参照してください。
UnitsInStock
列にカスタム集計を追加します。summaries
プロパティを以下に作成するクラスに設定します。
<igx-grid #grid1 [data]="data" [autoGenerate]="false" height="800px" width="800px" (columnInit)="initColumn($event)" >
<igx-column field="ProductID" width="200px" [sortable]="true">
</igx-column>
<igx-column field="ProductName" width="200px" [sortable]="true" [hasSummary]="true">
</igx-column>
<igx-column field="UnitsInStock" width="200px" [dataType]="'number'" [hasSummary]="true" [summaries]="mySummary" [sortable]="true">
</igx-column>
<igx-column field="ReorderLevel" width="200px" [editable]="true" [dataType]="'number'" [hasSummary]="true">
</igx-column>
</igx-grid>
html
...
export class GridComponent implements OnInit {
mySummary = MySummary;
....
}
typescript
すべてのデータにアクセスするカスタム集計
カスタム列集計内のすべての Grid データにアクセスできます。IgxSummaryOperand operate
メソッドには、2 つの追加のオプション パラメーターが導入されています。
以下のコード スニペットで示されるように operate メソッドには以下の 3 つのパラメーターがあります。
- columnData - 現在の列の値のみを含む配列を提供します。
- allGridData - グリッド データソース全体を提供します。
- fieldName - 現在の列フィールド。
class MySummary extends IgxNumberSummaryOperand {
constructor() {
super();
}
operate(columnData: any[], allGridData = [], fieldName?): IgxSummaryResult[] {
const result = super.operate(allData.map(r => r[fieldName]));
result.push({ key: 'test', label: 'Total Discontinued', summaryResult: allData.filter((rec) => rec.Discontinued).length });
return result;
}
}
typescript
import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { AppComponent } from "./app.component";
import { GridAllDataSummaryComponent } from "./grid/grid-allData-summary/grid-allData-summary.component";
import { IgxGridModule } from "igniteui-angular";
import { IgxPreventDocumentScrollModule } from "./directives/prevent-scroll.directive";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
GridAllDataSummaryComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxPreventDocumentScrollModule,
IgxGridModule
],
providers: [],
entryComponents: [],
schemas: []
})
export class AppModule {}
ts
import { Component, ViewChild } from '@angular/core';
import {
IgxGridComponent,
IgxNumberSummaryOperand,
IgxSummaryResult } from 'igniteui-angular';
import { DATA } from '../../data/nwindData';
class DiscontinuedSummary {
public operate(data?: any[], allData = [], fieldName = ''): IgxSummaryResult[] {
const result = [];
result.push({
key: 'products',
label: 'Producs',
summaryResult: data.length
});
result.push({
key: 'total',
label: 'Total Items',
summaryResult: IgxNumberSummaryOperand.sum(data)
});
result.push({
key: 'discontinued',
label: 'Discontinued Producs',
summaryResult: allData.map(r => r['Discontinued']).filter((rec) => rec).length
});
result.push({
key: 'totalDiscontinued',
label: 'Total Discontinued Items',
summaryResult: IgxNumberSummaryOperand.sum(allData.filter((rec) => rec['Discontinued']).map(r => r[fieldName]))
});
return result;
}
}
@Component({
selector: 'app-grid-all-data-summary',
styleUrls: ['./grid-allData-summary.component.scss'],
templateUrl: './grid-allData-summary.component.html'
})
export class GridAllDataSummaryComponent {
@ViewChild('grid1', { read: IgxGridComponent, static: true })
public grid1: IgxGridComponent;
public discontinuedSummary = DiscontinuedSummary;
public data;
constructor() {
this.data = DATA;
}
}
ts
<div class="grid__wrapper">
<igx-grid [igxPreventDocumentScroll]="true" #grid1 [data]="data" [autoGenerate]="false" height="600px" width="100%">
<igx-paginator *ngIf="false"></igx-paginator>
<igx-column field="ProductID" header="Product ID" width="17%" [headerClasses]="'prodId'">
</igx-column>
<igx-column field="ProductName" header="Product Name" width="17%" [headerClasses]="'prodId'" >
</igx-column>
<igx-column field="UnitPrice" header="Price" [filterable]="false" width="17%" [editable]="true" dataType="number">
</igx-column>
<igx-column field="UnitsInStock" header="Units In Stock" width="17%" dataType="number" [editable]="true"
[hasSummary]="true" [summaries]="discontinuedSummary">
</igx-column>
<igx-column field="Discontinued" header="Discontinued" [editable]="true" width="17%" [dataType]="'boolean'">
</igx-column>
<igx-column field="OrderDate" width="15%" [dataType]="'date'" [hasSummary]="true">
</igx-column>
</igx-grid>
</div>
html
.grid__wrapper {
margin: 0 auto;
padding: 16px;
}
scss
集計テンプレート
igxSummary
は、列の集計の結果をコンテキストとして提供する列の集計を対象としています。
<igx-column ... [hasSummary]="true">
<ng-template igxSummary let-summaryResults>
<span> My custom summary template</span>
<span>{{ summaryResults[0].label }} - {{ summaryResults[0].summaryResult }}</span>
</ng-template>
</igx-column>
html
デフォルトの集計が定義されている場合、集計領域の高さは、集計の数が最も多い列とグリッドのサイズに応じてデザインにより計算されます。summaryRowHeight 入力プロパティを使用して、デフォルト値をオーバーライドします。引数として数値が必要であり、false 値を設定すると、グリッド フッターのデフォルトのサイズ設定動作がトリガーされます。
列の集計テンプレートは、列 summaryTemplate プロパティを必要な TemplateRef に設定することにより、API を介して定義できます。
import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { AppComponent } from "./app.component";
import { GridSummaryTemplateComponent } from "./grid/grid-summary-template/grid-summary-template.component";
import {
IgxGridModule,
IgxInputGroupModule,
IgxButtonGroupModule,
IgxSwitchModule
} from "igniteui-angular";
import { IgxPreventDocumentScrollModule } from "./directives/prevent-scroll.directive";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
GridSummaryTemplateComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxPreventDocumentScrollModule,
IgxGridModule,
IgxInputGroupModule,
IgxButtonGroupModule,
IgxSwitchModule
],
providers: [],
entryComponents: [],
schemas: []
})
export class AppModule {}
ts
import { Component, OnInit } from '@angular/core';
import { DisplayDensity, IgxNumberSummaryOperand, IgxSummaryResult } from 'igniteui-angular';
import { DATA } from '../../data/nwindData';
class DiscontinuedSummary {
public operate(data?: any[], allData = [], fieldName = ''): IgxSummaryResult[] {
const result = [];
result.push({
key: 'products',
label: 'Producs',
summaryResult: data.length
});
result.push({
key: 'total',
label: 'Total Items',
summaryResult: IgxNumberSummaryOperand.sum(data)
});
result.push({
key: 'discontinued',
label: 'Discontinued Producs',
summaryResult: allData.map(r => r['Discontinued']).filter((rec) => rec).length
});
result.push({
key: 'totalDiscontinued',
label: 'Total Discontinued Items',
summaryResult: IgxNumberSummaryOperand.sum(allData.filter((rec) => rec['Discontinued']).map(r => r[fieldName]))
});
return result;
}
}
@Component({
selector: 'app-grid-summary-template',
styleUrls: ['./grid-summary-template.component.scss'],
templateUrl: './grid-summary-template.component.html'
})
export class GridSummaryTemplateComponent implements OnInit {
public discontinuedSummary = DiscontinuedSummary;
public data;
public summaryHeight = 135;
public displayDensity: DisplayDensity = 'cosy';
public displayDensities;
public hasSummary = true;
constructor() {
this.data = DATA;
}
public ngOnInit(): void {
this.displayDensities = [
{ label: 'compact', selected: this.displayDensity === 'compact', togglable: true },
{ label: 'cosy', selected: this.displayDensity === 'cosy', togglable: true },
{ label: 'comfortable', selected: this.displayDensity === 'comfortable', togglable: true }
];
}
public selectDensity(event): void {
this.displayDensity = this.displayDensities[event.index].label;
}
}
ts
<div class="sample__wrapper">
<div class="controls-wrapper">
<igx-input-group>
<label igxLabel for="height">Summary Row Height</label>
<input igxInput name="height" type="number" [(ngModel)]="summaryHeight">
</igx-input-group>
<igx-switch [(ngModel)]="hasSummary">Toggle Summaries</igx-switch>
<igx-buttongroup [values]="displayDensities" (selected)="selectDensity($event)" [displayDensity]="displayDensity">
</igx-buttongroup>
</div>
<igx-grid [igxPreventDocumentScroll]="true" #grid1 [data]="data" [displayDensity]="displayDensity"
[summaryRowHeight]="summaryHeight" [autoGenerate]="false" height="550px" width="100%">
<igx-column field="ProductID" header="Product ID" width="10%" [headerClasses]="'prodId'" [groupable]="true">
</igx-column>
<igx-column field="ProductName" header="Product Name" width="17%" [headerClasses]="'prodId'" [groupable]="true">
</igx-column>
<igx-column field="UnitPrice" header="Price" [filterable]="false" width="17%" [editable]="true" dataType="number" [groupable]="true">
</igx-column>
<igx-column field="UnitsInStock" header="Units In Stock" width="21%" dataType="number" [editable]="true"
[hasSummary]="hasSummary" [summaries]="discontinuedSummary" [groupable]="true">
</igx-column>
<igx-column field="Discontinued" header="Discontinued" [editable]="true" width="17%" [dataType]="'boolean'" [groupable]="true">
</igx-column>
<igx-column field="OrderDate" width="18%" [dataType]="'date'" [hasSummary]="hasSummary" [groupable]="true">
<ng-template igxSummary let-summaryResults>
<div class="summary-temp">
<span><strong>{{ summaryResults[0].label }}</strong><span>{{ summaryResults[0].summaryResult }}</span></span>
<span><strong>{{ summaryResults[1].label }}</strong><span>{{ summaryResults[1].summaryResult }}</span></span>
</div>
</ng-template>
</igx-column>
</igx-grid>
</div>
html
.sample__wrapper {
display: flex;
flex-direction: column;
gap: 16px;
padding: 16px;
height: 100%;
overflow-y: auto;
}
igx-buttongroup {
max-width: 450px;
flex: 1;
}
.summary-temp {
display: flex;
flex-direction: column;
margin: 0 1px;
font-size: 14px;
line-height: 24px;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
span {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 4px;
justify-content: space-between;
color: hsla(var(--igx-gray-900));
span {
user-select: all;
max-width: 300px;
padding-right: 8px;
}
strong {
font-size: 12px;
text-transform: uppercase;
min-width: 70px;
justify-self: flex-start;
text-align: left;
color: hsla(var(--ig-secondary-600));
user-select: none;
}
}
> * {
padding: 8px 0;
line-height: 18px;
border-bottom: 1px dashed hsla(var(--igx-gray-400));
&:last-child {
border-bottom: none;
}
}
}
::-webkit-scrollbar {
width: 5px !important;
height: 5px !important;
}
.controls-wrapper {
display: flex;
align-items: center;
flex-direction: row;
gap: 16px;
}
scss
集計の無効化
disabledSummaries
プロパティは、Ignite UI for Angular グリッド集計機能に対して列ごとに正確な制御を提供します。このプロパティを使用すると、グリッド内の各列に表示される集計をカスタマイズして、最も関連性の高い意味のあるデータのみが表示されるようにすることができます。たとえば、配列で集計キーを指定することにより、['count', 'min', 'max']
などの特定の集計タイプを除外できます。
このプロパティは、コードを通じて実行時に動的に変更することもできるため、変化するアプリケーションの状態やユーザー操作に合わせてグリッドの集計を柔軟に調整できます。
次の例は、disabledSummaries
プロパティを使用してさまざまな列の集計を管理し、Ignite UI for Angular グリッドで特定のデフォルトおよびカスタムの集計タイプを除外する方法を示しています。
<igx-column
field="UnitPrice"
header="Unit Price"
dataType="number"
[hasSummary]="true"
[disabledSummaries]="['count', 'sum', 'average']"
>
</igx-column>
<igx-column
field="UnitsInStock"
header="Units In Stock"
dataType="number"
[hasSummary]="true"
[summaries]="discontinuedSummary"
[disabledSummaries]="['discontinued', 'totalDiscontinued']"
>
</igx-column>
html
UnitPrice
の場合、count
、sum
、average
などのデフォルトの集計は無効になっており、min
や max
などの他の集計は有効のままになっています。
UnitsInStock
の場合、total
や totalDiscontinued
などのカスタム集計は disabledSummaries
プロパティを使用して除外されます。
実行時に、disabledSummaries
プロパティを使用して集計を動的に無効にすることもできます。たとえば、特定の列のプロパティをプログラムで設定または更新して、ユーザー操作やアプリケーションの状態の変化に基づいて表示される集計を調整できます。
集計のフォーマット
デフォルトでは、組み込みの集計オペランドによって生成される集計結果は、グリッド locale
および列 pipeArgs
に従ってローカライズおよびフォーマットされます。カスタム オペランドを使用する場合、locale
と pipeArgs
は適用されません。集計結果のデフォルトの外観を変更する場合は、summaryFormatter
プロパティを使用してフォーマットできます。
public dateSummaryFormat(summary: IgxSummaryResult, summaryOperand: IgxSummaryOperand): string {
const result = summary.summaryResult;
if(summaryOperand instanceof IgxDateSummaryOperand && summary.key !== 'count'
&& result !== null && result !== undefined) {
const pipe = new DatePipe('en-US');
return pipe.transform(result,'MMM YYYY');
}
return result;
}
typescript
<igx-column ... [summaryFormatter]="dateSummaryFormat"></igx-column>
html
import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { AppComponent } from "./app.component";
import { GridSummaryFormatterComponent } from "./grid/grid-summary-formatter/grid-summary-formatter.component";
import { IgxGridModule } from "igniteui-angular";
import { IgxPreventDocumentScrollModule } from "./directives/prevent-scroll.directive";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
GridSummaryFormatterComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxPreventDocumentScrollModule,
IgxGridModule
],
providers: [],
entryComponents: [],
schemas: []
})
export class AppModule {}
ts
import { DatePipe } from '@angular/common';
import { Component, OnInit, ViewChild } from '@angular/core';
import { IgxDateSummaryOperand, IgxGridComponent, IgxSummaryOperand, IgxSummaryResult } from 'igniteui-angular';
import { DATA } from '../../data/nwindData';
@Component({
selector: 'app-grid-summary-formatter',
styleUrls: ['./grid-summary-formatter.component.scss'],
templateUrl: './grid-summary-formatter.component.html'
})
export class GridSummaryFormatterComponent implements OnInit {
@ViewChild('grid1', { read: IgxGridComponent, static: true })
public grid1: IgxGridComponent;
public data: any[];
public ngOnInit(): void {
this.data = DATA;
}
public dateSummaryFormat(summary: IgxSummaryResult, summaryOperand: IgxSummaryOperand): string {
const result = summary.summaryResult;
if (summaryOperand instanceof IgxDateSummaryOperand && summary.key !== 'count'
&& result !== null && result !== undefined) {
const pipe = new DatePipe('en-US');
return pipe.transform(result, 'MMM YYYY');
}
return result;
}
}
ts
<div class="grid__wrapper">
<igx-grid [igxPreventDocumentScroll]="true" #grid1 [data]="data" [autoGenerate]="false" height="600px" width="100%"
[allowFiltering]='true' filterMode="excelStyleFilter">
<igx-column field="ProductName" header="Product Name" [sortable]="true" [disableHiding]="true" [dataType]="'string'">
</igx-column>
<igx-column field="QuantityPerUnit" header="Quantity Per Unit" [sortable]="true" [disableHiding]="true" [dataType]="'string'">
</igx-column>
<igx-column field="UnitPrice" header="Unit Price Category" [sortable]="true" [disableHiding]="true" dataType="string">
</igx-column>
<igx-column field="OrderDate" header="Order Date" [sortable]="true" [disableHiding]="true" [dataType]="'date'" [hasSummary]="true"
[summaryFormatter]="dateSummaryFormat">
</igx-column>
<igx-column field="Discontinued" header="Discontinued" [sortable]="true" [disableHiding]="true" [dataType]="'boolean'">
<ng-template igxCell let-cell="cell" let-val>
<img *ngIf="val" src="https://www.infragistics.com/angular-demos-lob/assets/images/grid/active.png" title="Continued" alt="Continued" />
<img *ngIf="!val" src="https://www.infragistics.com/angular-demos-lob/assets/images/grid/expired.png" title="Discontinued" alt="Discontinued" />
</ng-template>
</igx-column>
</igx-grid>
</div>
html
.grid__wrapper {
margin: 16px;
}
scss

グループの集計
列のグループがある場合、Grid はsummaryCalculationMode
と summaryPosition
を使用して集計配置の変更やモードの計算をします。これら 2 つのプロパティに加えて、IgxGrid は、参照するグループ行が縮小されたときに集計行が表示されたままであるかどうかを決定できる showSummaryOnCollapse
プロパティを公開します。
以下は、使用可能な summaryCalculationMode
プロパティの値です。
- rootLevelOnly - ルート レベルのみ集計が計算されます。
- childLevelsOnly - 子レベルのみ集計が計算されます。
- rootAndChildLevels - ルートと子レベルの両方の集計が計算されます。これがデフォルト値です。
以下は、使用可能な summaryPosition
プロパティの値です。
- top - 集計行はグループ列の子の前に表示されます。
- bottom - 集計行はグループ列の子の後に表示されます。これがデフォルト値です。
showSummaryOnCollapse
プロパティはブール値です。デフォルト値は false に設定されています。これは、親行が縮小されたときに集計行が非表示になることを意味します。プロパティが true に設定されている場合、グループ行が縮小されたときに、集計行は表示されたままになります。
デモ
集計のエクスポート
exportSummaries
オプションが IgxExcelExporterOptions
にあり、エクスポートされたデータにグリッドの集計を含めるかどうかを指定します。デフォルトの exportSummaries
値は false です。
IgxExcelExporterService
は、すべての列タイプのデフォルトの集計を同等の Excel 関数としてエクスポートするため、シートが変更された場合でも適切に機能し続けます。以下の例をご覧ください:
import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { BrowserModule } from "@angular/platform-browser";
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { AppComponent } from "./app.component";
import {
IgxGridModule,
IgxExcelExporterService
} from "igniteui-angular";
import { GridSummaryExportComponent } from "./grid/grid-summary-export/grid-summary-export.component";
import { IgxPreventDocumentScrollModule } from "./directives/prevent-scroll.directive";
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
GridSummaryExportComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxPreventDocumentScrollModule,
IgxGridModule
],
providers: [IgxExcelExporterService],
entryComponents: [],
schemas: []
})
export class AppModule {}
ts
import { Component, ViewChild } from '@angular/core';
import {
ColumnType,
IgxExcelExporterOptions,
IgxExcelExporterService,
IgxGridComponent,
IgxNumberSummaryOperand,
IgxSummaryResult } from 'igniteui-angular';
import { DATA } from '../../data/nwindData';
class MySummary {
public operate(data?: any[]): IgxSummaryResult[] {
const result = new IgxNumberSummaryOperand().operate(data);
result.push({
key: 'test',
label: 'Test',
summaryResult: data.filter((rec) => rec > 10 && rec < 30).length
});
return result;
}
}
@Component({
selector: 'app-grid-summary-export',
styleUrls: ['./grid-summary-export.component.scss'],
templateUrl: './grid-summary-export.component.html'
})
export class GridSummaryExportComponent {
@ViewChild('grid', { read: IgxGridComponent, static: true })
public grid: IgxGridComponent;
public mySummary = MySummary;
public data;
public productId = 0;
constructor(private excelExportService: IgxExcelExporterService) {
this.data = DATA;
this.productId = DATA.length;
}
public toggleSummary(column: ColumnType) {
column.hasSummary = !column.hasSummary;
}
public exportButtonHandler() {
this.excelExportService.export(this.grid, new IgxExcelExporterOptions('ExportedFile'));
}
}
ts
<div class="grid__wrapper">
<div class="button-container">
<button igxButton="raised" (click)="exportButtonHandler()">Export To Excel</button>
Press the button to export the Grid as a .xlsx file.
</div>
<igx-grid [igxPreventDocumentScroll]="true" #grid [data]="data" [autoGenerate]="false" height="650px" width="100%">
<igx-column #col field="ProductID" header="Product ID" [headerClasses]="'prodId'">
</igx-column>
<igx-column #col field="ProductName" header="Product Name" [headerClasses]="'prodId'" [hasSummary]="true">
<ng-template igxCell let-cell="cell" let-val>
{{val}}
</ng-template>
<ng-template igxHeader let-col>
<div class="header-text">{{col.field}}</div>
<igx-icon class="header-icon" style.color="{{ col.hasSummary ? '#e41c77' : '' }}" (click)="toggleSummary(col)">functions</igx-icon>
</ng-template>
</igx-column>
<igx-column #col field="UnitPrice" header="Price" [filterable]="false" [editable]="true" dataType="number"
[hasSummary]="true">
<ng-template igxCell let-cell="cell" let-val let-row>
${{val}}
</ng-template>
<ng-template igxHeader let-col>
<div class="header-text">{{col.field}}</div>
<igx-icon class="header-icon" style.color="{{ col.hasSummary ? '#e41c77' : '' }}" (click)="toggleSummary(col)">functions</igx-icon>
</ng-template>
</igx-column>
<igx-column #col field="UnitsInStock" header="Units In Stock" dataType="number" [editable]="true"
[hasSummary]="false" [summaries]="mySummary">
<ng-template igxCell let-cell="cell" let-val let-row>
{{val}}
</ng-template>
<ng-template igxHeader let-col>
<div class="header-text">{{col.field}}</div>
<igx-icon class="header-icon" style.color="{{ col.hasSummary ? '#e41c77' : '' }}" (click)="toggleSummary(col)">functions</igx-icon>
</ng-template>
</igx-column>
<igx-column #col field="Discontinued" header="Discontinued" [hasSummary]="true" [dataType]="'boolean'">
<ng-template igxCell let-cell="cell" let-val>
<img *ngIf="val" src="https://www.infragistics.com/angular-demos-lob/assets/images/grid/active.png" title="Continued" alt="Continued" />
<img *ngIf="!val" src="https://www.infragistics.com/angular-demos-lob/assets/images/grid/expired.png" title="Discontinued" alt="Discontinued" />
</ng-template>
<ng-template igxHeader let-col>
<div class="header-text">{{col.field}}</div>
<igx-icon class="header-icon" style.color="{{ col.hasSummary ? '#e41c77' : '' }}" (click)="toggleSummary(col)">functions</igx-icon>
</ng-template>
</igx-column>
<igx-column #col field="OrderDate" [dataType]="'date'" [hasSummary]="true">
<ng-template igxCell let-cell="cell" let-val let-row>
{{ val | date: 'MMM d, yyyy' }}
</ng-template>
<ng-template igxHeader let-col>
<div class="header-text">{{col.field}}</div>
<igx-icon class="header-icon" style.color="{{ col.hasSummary ? '#e41c77' : '' }}" (click)="toggleSummary(col)">functions</igx-icon>
</ng-template>
</igx-column>
</igx-grid>
</div>
html
.grid-controls {
display: flex;
flex-flow: column nowrap;
justify-content: space-between;
margin: 0 16px 24px;
igx-switch {
margin-top: 24px;
}
}
.grid__wrapper {
margin: 0 auto;
padding: 16px;
}
.header {
height: 100%;
}
:host ::ng-deep{
.igx-grid__th .title{
width: 100%;
cursor: auto;
}
@media screen and (max-width: 677px){
.header-icon {
padding-bottom: 17px;
padding-top: 17px;
font-size: 1.4em;
width: 1.1em;
height: 1.1em;
float: right;
}
.header-text {
float:left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 50%;
}
}
@media screen and (min-width: 677px){
.header-icon {
padding-top: 17px;
font-size: 1.4em;
width: 1.1em;
height: 1.1em;
float: right;
}
.header-text {
float:left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 50%;
}
}
@media screen and (min-width: 992px){
.header-icon {
padding-top: 17px;
font-size: 1.4em;
width: 1.1em;
height: 1.1em;
float: right;
margin-right: 10px;
cursor: pointer;
}
.header-text {
float:left;
white-space: nowrap;
width: 50%;
cursor: auto;
}
}
}
.button-container {
margin: 25px auto;
}
scss
エクスポートされたファイルには、シート内の各 DataRecord
のレベルを保持する非表示の列が含まれています。このレベルは、集計関数に含める必要があるセルを除外するために集計で使用されます。
以下の表では、デフォルトの各集計に対応する Excel 式を見つけることができます。
データ型 |
関数 |
Excel 関数 |
string 、boolean |
count |
="Count: "&COUNTIF(start:end, recordLevel) |
number 、currency 、percent |
count |
="Count: "&COUNTIF(start:end, recordLevel) |
|
min |
="Min: "&MIN(IF(start:end=recordLevel, rangeStart:rangeEnd)) |
|
max |
="Max: "&MAX(IF(start:end=recordLevel, rangeStart:rangeEnd)) |
|
average |
="Avg: "&AVERAGEIF(start:end, recordLevel, rangeStart:rangeEnd) |
|
sum |
="Sum: "&SUMIF(start:end, recordLevel, rangeStart:rangeEnd) |
date |
count |
="Count: "&COUNTIF(start:end, recordLevel) |
|
earliest |
="Earliest: "& TEXT(MIN(IF(start:end=recordLevel, rangeStart:rangeEnd)), format) |
|
latest |
="Latest: "&TEXT(MAX(IF(start:end=recordLevel, rangeStart:rangeEnd)), format) |
既知の問題と制限
制限 |
説明 |
カスタム集計のエクスポート |
カスタム集計は、Excel 関数ではなく文字列としてエクスポートされます。 |
テンプレート化された集計のエクスポート |
テンプレート化された集計はサポートされておらず、デフォルトのものとしてエクスポートされます。 |
キーボード ナビゲーション
集計行は、以下のキーボード操作でナビゲーションできます。
- UP - 1 つ上のセルへ移動。
- DOWN - 1 つ下のセルへ移動。
- LEFT - 1 つ左のセルへ移動。
- RIGHT - 1 つ右のセルへ移動。
- CTRL + LEFT または HOME - 左端のセルへ移動。
- CTRL + RIGHT または END - 右端のセルへ移動。
スタイル設定
ソート動作のスタイル設定は、すべてのテーマ関数とコンポーネント ミックスインが存在する index
ファイルをインポートする必要があります。
@use "igniteui-angular/theming" as *;
scss
最も簡単な方法は、grid-summary-theme
を拡張する新しいテーマを作成し、$background-color
、$focus-background-color
、$label-color
、$result-color
、$pinned-border-width
、$pinned-border-style
、および $pinned-border-color
パラメーターを受け取る方法です。
$custom-theme: grid-summary-theme(
$background-color: #e0f3ff,
$focus-background-color: rgba(#94d1f7, .3),
$label-color: #e41c77,
$result-color: black,
$pinned-border-width: 2px,
$pinned-border-style: dotted,
$pinned-border-color: #e41c77
);
scss
上記のようにカラーの値をハードコーディングする代わりに、palette
および color
関数を使用してカラーに関してより高い柔軟性を実現することができます。使い方の詳細についてはパレット
のトピックをご覧ください。
最後にコンポーネントのカスタム テーマを含めます。
@include css-vars($custom-theme);
scss
コンポーネントが Emulated
ViewEncapsulation を使用している場合、::ng-deep
を使用してこのカプセル化を解除する必要があります。
:host {
::ng-deep {
@include css-vars($custom-theme);
}
}
scss
デモ
API リファレンス
その他のリソース
コミュニティに参加して新しいアイデアをご提案ください。