React Hierarchical Grid 集計
React Hierarchical Grid の Ignite UI for React 集計機能は、グループ フッターとして列ごとのレベルで機能します。React IgrHierarchicalGrid 集計は、列内のデータ タイプに応じて、あるいは IgrHierarchicalGrid
にカスタム テンプレートを実装することによって、定義済みのデフォルト集計項目を使用して別のコンテナの列情報を表示できます。
React Hierarchical Grid 集計概要の例
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrHierarchicalGridModule } from "@infragistics/igniteui-react-grids";
import { IgrHierarchicalGrid, IgrColumn, IgrRowIsland } from "@infragistics/igniteui-react-grids";
import SingersData from './SingersData.json';
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrHierarchicalGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private hierarchicalGrid: IgrHierarchicalGrid
private hierarchicalGridRef(r: IgrHierarchicalGrid) {
this.hierarchicalGrid = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.hierarchicalGridRef = this.hierarchicalGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrHierarchicalGrid
autoGenerate={false}
data={this.singersData}
ref={this.hierarchicalGridRef}
id="hierarchicalGrid"
primaryKey="ID">
<IgrColumn
field="Artist"
header="Artist"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Photo"
header="Photo"
dataType="image">
</IgrColumn>
<IgrColumn
field="Debut"
header="Debut"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="GrammyNominations"
header="Grammy Nominations"
dataType="number"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="GrammyAwards"
header="Grammy Awards"
dataType="number"
hasSummary={true}>
</IgrColumn>
<IgrRowIsland
childDataKey="Albums"
autoGenerate={false}>
<IgrColumn
field="Album"
header="Album"
dataType="string">
</IgrColumn>
<IgrColumn
field="LaunchDate"
header="Launch Date"
dataType="date">
</IgrColumn>
<IgrColumn
field="BillboardReview"
header="Billboard Review"
dataType="number"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="USBillboard200"
header="US Billboard 200"
dataType="number"
hasSummary={true}>
</IgrColumn>
<IgrRowIsland
childDataKey="Songs"
autoGenerate={false}>
<IgrColumn
field="Number"
header="No."
dataType="string">
</IgrColumn>
<IgrColumn
field="Title"
header="Title"
dataType="string"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Released"
header="Released"
dataType="date">
</IgrColumn>
<IgrColumn
field="Genre"
header="Genre"
dataType="string">
</IgrColumn>
</IgrRowIsland>
</IgrRowIsland>
<IgrRowIsland
childDataKey="Tours"
autoGenerate={false}>
<IgrColumn
field="Tour"
header="Tour"
dataType="string">
</IgrColumn>
<IgrColumn
field="StartedOn"
header="Started on"
dataType="string">
</IgrColumn>
<IgrColumn
field="Location"
header="Location"
dataType="string">
</IgrColumn>
<IgrColumn
field="Headliner"
header="Headliner"
dataType="string">
</IgrColumn>
</IgrRowIsland>
</IgrHierarchicalGrid>
</div>
</div>
);
}
private _singersData: any[] = SingersData;
public get singersData(): any[] {
return this._singersData;
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
このサンプルが気に入りましたか? 完全な Ignite UI for Reactツールキットにアクセスして、すばやく独自のアプリの作成を開始します。無料でダウンロードできます。
列の集計は列値すべての関数ですが、フィルタリングが適用された場合、列の集計はフィルターされた結果値の関数になります。
IgrHierarchicalGrid
集計を列ごとに有効にして必要な列のみアクティブ化できます。IgrHierarchicalGrid
集計は、列のデータ型に基づいてデフォルト集計の定義済みセットを提供します。
string
および boolean
dataType
の場合、以下の関数が利用できます:
- Count
number
、currency
、および percent
データ型の場合、以下の関数を使用できます。
- Count
- Min
- Max
- Average
- Sum
date
データ型の場合、以下の関数が利用できます:
- Count
- Earliest
- Latest
すべての利用可能な列データ型は、公式の列タイプトピックにあります。
hasSummary
プロパティを true に設定すると IgrHierarchicalGrid
集計が列レベルで有効になります。各列の集計は列のデータ型に基づいて解決されます。IgrHierarchicalGrid
のデフォルトの列データ型は string
のため、number
または date
固有の集計を適用するには、dataType
プロパティを number
または date
に設定します。集計値は、グリッドの locale
および列 pipeArgs
に従ってローカライズされて表示されます。
<IgrHierarchicalGrid autoGenerate="false" data={this.singersData} ref={this.hierarchicalGridRef} id="hierarchicalGrid" primaryKey="ID">
<IgrColumn field="Artist" header="Artist" hasSummary="true"></IgrColumn>
<IgrColumn field="Photo" header="Photo" dataType="Image"></IgrColumn>
<IgrColumn field="Debut" header="Debut" hasSummary="true"></IgrColumn>
<IgrColumn field="GrammyNominations" header="Grammy Nominations" dataType="Number" hasSummary="true"></IgrColumn>
<IgrColumn field="GrammyAwards" header="Grammy Awards" dataType="Number" hasSummary="true"></IgrColumn>
<IgrRowIsland childDataKey="Albums" autoGenerate="false">
<IgrColumn field="Album" header="Album" dataType="String"></IgrColumn>
<IgrColumn field="LaunchDate" header="Launch Date" dataType="Date"></IgrColumn>
<IgrColumn field="BillboardReview" header="Billboard Review" dataType="Number" hasSummary="true"></IgrColumn>
<IgrColumn field="USBillboard200" header="US Billboard 200" dataType="Number" hasSummary="true" ></IgrColumn>
</IgrRowIsland>
</IgrHierarchicalGrid>
tsx
特定の列や列のリストを有効または無効にする他の方法として IgrHierarchicalGrid
のパブリック メソッド enableSummaries
/disableSummaries
を使用する方法があります。
function enableSummary() {
hierarchicalGridRef.current.enableSummaries([
{fieldName: 'GrammyNominations'},
{fieldName: 'GrammyAwards'}
]);
}
function disableSummary() {
hierarchicalGridRef.current.disableSummaries(['GrammyNominations']);
}
<IgrHierarchicalGrid autoGenerate="false" data={this.singersData} ref={this.hierarchicalGridRef} id="hierarchicalGrid" primaryKey="ID">
<IgrColumn field="Artist" header="Artist" hasSummary="true"></IgrColumn>
<IgrColumn field="Photo" header="Photo" dataType="Image"></IgrColumn>
<IgrColumn field="Debut" header="Debut" hasSummary="true"></IgrColumn>
<IgrColumn field="GrammyNominations" header="Grammy Nominations" dataType="Number" hasSummary="true"></IgrColumn>
<IgrColumn field="GrammyAwards" header="Grammy Awards" dataType="Number" hasSummary="true"></IgrColumn>
</IgrHierarchicalGrid>
<button onClick={enableSummary}>Enable Summary</button>
<button onClick={disableSummary}>Disable Summary </button>
tsx
集計テンプレート
Summary
は、列の集計の結果をコンテキストとして提供する列の集計を対象としています。
function summaryTemplate(ctx: IgrSummaryTemplateContext) {
return (
<>
<span>My custom summary template</span>
<span>{ctx.dataContext.implicit[0].label} - {ctx.dataContext.implicit[0].summaryResult}</span>
</>
);
}
<IgrColumn hasSummary="true" summaryTemplate={summaryTemplate}></IgrColumn>
tsx
デフォルトの集計が定義されている場合、集計領域の高さは、集計の数が最も多い列とグリッドの --ig-size
に応じてデザインにより計算されます。summaryRowHeight
入力プロパティを使用して、デフォルト値をオーバーライドします。引数として数値が必要であり、falsy の値を設定すると、グリッド フッターのデフォルトのサイズ設定動作がトリガーされます。
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrPropertyEditorPanelModule } from "@infragistics/igniteui-react-layouts";
import { IgrHierarchicalGridModule } from "@infragistics/igniteui-react-grids";
import { IgrPropertyEditorPanel, IgrPropertyEditorPropertyDescription } from "@infragistics/igniteui-react-layouts";
import { IgrHierarchicalGrid, IgrColumn, IgrRowIsland } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, PropertyEditorPanelDescriptionModule, WebHierarchicalGridDescriptionModule } from "@infragistics/igniteui-react-core";
import SingersData from './SingersData.json';
import { IgrPropertyEditorPropertyDescriptionChangedEventArgs } from "@infragistics/igniteui-react-layouts";
import { IgrSummaryTemplateContext } from "@infragistics/igniteui-react-grids";
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
import 'igniteui-webcomponents/themes/light/bootstrap.css';
const mods: any[] = [
IgrPropertyEditorPanelModule,
IgrHierarchicalGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private propertyEditorPanel1: IgrPropertyEditorPanel
private propertyEditorPanel1Ref(r: IgrPropertyEditorPanel) {
this.propertyEditorPanel1 = r;
this.setState({});
}
private summaryRowHeightEditor: IgrPropertyEditorPropertyDescription
private toggleSummariesEditor: IgrPropertyEditorPropertyDescription
private sizeEditor: IgrPropertyEditorPropertyDescription
private hierarchicalGrid: IgrHierarchicalGrid
private hierarchicalGridRef(r: IgrHierarchicalGrid) {
this.hierarchicalGrid = r;
this.setState({});
}
private column1: IgrColumn
private column2: IgrColumn
private column3: IgrColumn
private column4: IgrColumn
constructor(props: any) {
super(props);
this.propertyEditorPanel1Ref = this.propertyEditorPanel1Ref.bind(this);
this.webHierarchicalGridHasSummariesChange = this.webHierarchicalGridHasSummariesChange.bind(this);
this.webHierarchicalGridSetGridSize = this.webHierarchicalGridSetGridSize.bind(this);
this.hierarchicalGridRef = this.hierarchicalGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="options vertical">
<IgrPropertyEditorPanel
componentRenderer={this.renderer}
target={this.hierarchicalGrid}
descriptionType="WebHierarchicalGrid"
isHorizontal="true"
isWrappingEnabled="false"
ref={this.propertyEditorPanel1Ref}>
<IgrPropertyEditorPropertyDescription
propertyPath="SummaryRowHeight"
label="Summary Row Height"
valueType="Number"
name="SummaryRowHeightEditor">
</IgrPropertyEditorPropertyDescription>
<IgrPropertyEditorPropertyDescription
label="Toggle Summaries"
valueType="Boolean1"
primitiveValue="True"
changed={this.webHierarchicalGridHasSummariesChange}
name="ToggleSummariesEditor">
</IgrPropertyEditorPropertyDescription>
<IgrPropertyEditorPropertyDescription
name="SizeEditor"
label="Grid Size:"
valueType="EnumValue"
dropDownNames={["Small", "Medium", "Large"]}
dropDownValues={["Small", "Medium", "Large"]}
changed={this.webHierarchicalGridSetGridSize}>
</IgrPropertyEditorPropertyDescription>
</IgrPropertyEditorPanel>
</div>
<div className="container fill">
<IgrHierarchicalGrid
autoGenerate={false}
data={this.singersData}
ref={this.hierarchicalGridRef}
id="hierarchicalGrid"
primaryKey="ID">
<IgrColumn
field="Artist"
header="Artist"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Photo"
header="Photo"
dataType="image"
hasSummary={true}
summaries={this.singerSummary}
name="column1">
</IgrColumn>
<IgrColumn
field="Debut"
header="Debut">
</IgrColumn>
<IgrColumn
field="GrammyNominations"
header="Grammy Nominations"
dataType="number"
hasSummary={true}
summaryTemplate={this.webHierarchicalGridSummaryTemplateStyle}
name="column2">
</IgrColumn>
<IgrColumn
field="GrammyAwards"
header="Grammy Awards"
dataType="number"
hasSummary={true}
summaryTemplate={this.webHierarchicalGridSummaryTemplate}
name="column3">
</IgrColumn>
<IgrRowIsland
childDataKey="Albums"
autoGenerate={false}>
<IgrColumn
field="Album"
header="Album"
dataType="string"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="LaunchDate"
header="Launch Date"
dataType="date"
hasSummary={true}
summaryTemplate={this.webRowIslandGridSummaryTemplateStyle}
name="column4">
</IgrColumn>
<IgrColumn
field="BillboardReview"
header="Billboard Review"
dataType="number"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="USBillboard200"
header="US Billboard 200"
dataType="number"
hasSummary={true}>
</IgrColumn>
<IgrRowIsland
childDataKey="Songs"
autoGenerate={false}>
<IgrColumn
field="Number"
header="No."
dataType="string"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Title"
header="Title"
dataType="string"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Released"
header="Released"
dataType="date"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Genre"
header="Genre"
dataType="string"
hasSummary={true}>
</IgrColumn>
</IgrRowIsland>
</IgrRowIsland>
</IgrHierarchicalGrid>
</div>
</div>
);
}
private _singersData: any[] = SingersData;
public get singersData(): any[] {
return this._singersData;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
PropertyEditorPanelDescriptionModule.register(context);
WebHierarchicalGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webHierarchicalGridHasSummariesChange(sender: any, args: IgrPropertyEditorPropertyDescriptionChangedEventArgs): void {
let newValue = sender.primitiveValue as boolean;
const grid = this.hierarchicalGrid;
var column1 = grid.getColumnByName("Photo");
var column2 = grid.getColumnByName("GrammyNominations");
var column3 = grid.getColumnByName("GrammyAwards");
column1.hasSummary = newValue;
column2.hasSummary = newValue;
column3.hasSummary = newValue;
}
public webHierarchicalGridSetGridSize(sender: any, args: IgrPropertyEditorPropertyDescriptionChangedEventArgs): void {
var newVal = (args.newValue as string).toLowerCase();
var grid = document.getElementById("hierarchicalGrid");
grid.style.setProperty('--ig-size', `var(--ig-size-${newVal})`);
}
public webHierarchicalGridSummaryTemplateStyle = (e: { dataContext: IgrSummaryTemplateContext }) => {
const summaryResults = e.dataContext.implicit;
return (
<div className="summary-temp">
<span><strong>{ summaryResults[0].label }</strong><span>{ (summaryResults[0] as any).summaryResult }</span></span>
<span><strong>{ summaryResults[1].label }</strong><span>{ (summaryResults[1] as any).summaryResult }</span></span>
<span><strong>{ summaryResults[2].label }</strong><span>{ (summaryResults[2] as any).summaryResult }</span></span>
</div>
);
}
public webHierarchicalGridSummaryTemplate = (e: { dataContext: IgrSummaryTemplateContext }) => {
const summaryResults = e.dataContext.implicit;
return (
<div className="summary-temp">
<span>{ summaryResults[0].label }<span>{ (summaryResults[0] as any).summaryResult }</span></span>
<span>{ summaryResults[1].label }<span>{ (summaryResults[1] as any).summaryResult }</span></span>
<span>{ summaryResults[2].label }<span>{ (summaryResults[2] as any).summaryResult }</span></span>
</div>
);
}
public webRowIslandGridSummaryTemplateStyle = (e: { dataContext: IgrSummaryTemplateContext }) => {
const summaryResults = e.dataContext.implicit;
return (
<div className="summary-temp">
<span><strong>{ summaryResults[0].label }</strong><span>{ (summaryResults[0] as any).summaryResult }</span></span>
<span><strong>{ summaryResults[1].label }</strong><span>{ (new Date((summaryResults[2] as any).summaryResult)).toDateString() }</span></span>
</div>
);
}
private singerSummary = {
sum(data: any[] = []): number {
return data.length && data.filter((el) => el === 0 || Boolean(el)).length ? data.filter((el) => el === 0 || Boolean(el)).reduce((a, b) => +a + +b) : 0;
},
operate(data?: any[], allData: any[] = [], fieldName = ''): any[] {
const result = [] as any[];
result.push({
key: 'nominatedSingers',
label: 'Nominated Singers',
summaryResult: allData.filter((rec) => rec['GrammyNominations'] > 0).length
});
result.push({
key: 'singersWithAwards',
label: 'Singers with Awards',
summaryResult: allData.filter((rec) => rec['GrammyAwards'] > 0).length
});
result.push({
key: 'nominations',
label: 'Total Nominations',
summaryResult: this.sum(allData.map(r => r['GrammyNominations']))
} );
result.push({
key: 'awards',
label: 'Total Awards',
summaryResult: this.sum(allData.map(r => r['GrammyAwards']))
});
return result;
}
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
.summary-temp {
display: flex;
flex-direction: column;
margin: 0 1px;
font-size: 14px;
line-height: 24px;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
> * {
padding: 8px 0;
line-height: 18px;
border-bottom: 1px dashed hsla(var(--igx-gray-400));
&:last-child {
border-bottom: none;
}
}
}
.summary-temp span {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 4px;
justify-content: space-between;
color: hsla(var(--ig-gray-900));
}
.summary-temp span span {
user-select: all;
max-width: 300px;
padding-right: 8px;
}
.summary-temp span 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;
}
css
無効な集計
disabledSummaries
プロパティは、React Hierarchical Grid の集計機能に対して列ごとに正確な制御を提供します。このプロパティを使用すると、IgrHierarchicalGrid 内の各列に表示される集計をカスタマイズして、最も関連性の高い意味のあるデータのみが表示されるようにすることができます。たとえば、配列で集計キーを指定することにより、['count', 'min', 'max']
などの特定の集計タイプを除外できます。
このプロパティは、コードを通じて実行時に動的に変更することもできるため、変化するアプリケーションの状態やユーザー操作に合わせて IgrHierarchicalGrid の集計を柔軟に調整できます。
次の例は、disabledSummaries
プロパティを使用してさまざまな列の集計を管理し、React Hierarchical Grid で特定のデフォルトおよびカスタムの集計タイプを除外する方法を示しています。
<!-- Disable default summaries -->
<IgrColumn
field="UnitPrice"
header="Unit Price"
dataType="number"
hasSummary={true}
disabledSummaries="['count', 'sum', 'average']"
/>
<!-- Disable custom summaries -->
<IgrColumn
field="UnitsInStock"
header="Units In Stock"
dataType="number"
hasSummary={true}
summaries={discontinuedSummary}
disabledSummaries="['discontinued', 'totalDiscontinued']"
/>
tsx
UnitPrice
の場合、count
、sum
、average
などのデフォルトの集計は無効になっており、min
や max
などの他の集計は有効のままになっています。
UnitsInStock
の場合、discontinued
や totalDiscontinued
などのカスタム集計は disabledSummaries
プロパティを使用して除外されます。
実行時に、disabledSummaries
プロパティを使用して集計を動的に無効にすることもできます。たとえば、特定の列のプロパティをプログラムで設定または更新して、ユーザー操作やアプリケーションの状態の変化に基づいて表示される集計を調整できます。
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrButton, IgrDialog, IgrCheckbox } from "@infragistics/igniteui-react";
import { IgrButtonModule, IgrDialogModule, IgrCheckboxModule } from "@infragistics/igniteui-react";
import { IgrHierarchicalGridModule, IgrSummaryOperand, IgrSummaryResult, IgrNumberSummaryOperand } from "@infragistics/igniteui-react-grids";
import { IgrHierarchicalGrid, IgrRowIsland, IgrColumn } from "@infragistics/igniteui-react-grids";
import SingersData from './SingersData.json';
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
IgrHierarchicalGridModule.register();
IgrButtonModule.register();
IgrDialogModule.register();
IgrCheckboxModule.register();
export class GrammySummary extends IgrSummaryOperand {
operate(data: any[] = [], allData: any[] = [], fieldName: string = ""): IgrSummaryResult[] {
const result: IgrSummaryResult[] = [];
result.push({
key: "count",
label: "Count",
summaryResult: allData.filter((rec) => rec["Artist"] !== undefined && rec["Artist"] !== null && rec["Artist"] !== "").length
});
result.push({
key: "nominatedSingers",
label: "Nominated Singers",
summaryResult: allData.filter((rec) => rec["GrammyNominations"] > 0).length
});
result.push({
key: "singersWithAwards",
label: "Singers with Awards",
summaryResult: allData.filter((rec) => rec["GrammyAwards"] > 0).length
});
result.push({
key: "nominations",
label: "Total Nominations",
summaryResult: allData.reduce((sum, rec) => sum + (rec["GrammyNominations"] || 0), 0)
});
result.push({
key: "awards",
label: "Total Awards",
summaryResult: allData.reduce((sum, rec) => sum + (rec["GrammyAwards"] || 0), 0)
});
return result;
}
}
export default class Sample extends React.Component<any, any> {
private hierarchicalGrid: IgrHierarchicalGrid;
private dialog: IgrDialog;
constructor(props: any) {
super(props);
this.state = {
currentColumn: null,
disableAllBtnDisabled: false,
enableAllBtnDisabled: false,
checkboxStates: [],
columns: [
{ field: "Artist", header: "Artist", hasSummary: true, disabledSummaries: [] },
{ field: "Photo", header: "Photo", dataType: "image", hasSummary: true, summaries: GrammySummary, disabledSummaries: [] },
{ field: "Debut", header: "Debut", hasSummary: true, disabledSummaries: [] },
{ field: "GrammyNominations", header: "Grammy Nominations", dataType: "number", hasSummary: true, disabledSummaries: [] },
{ field: "GrammyAwards", header: "Grammy Awards", dataType: "number", hasSummary: true, disabledSummaries: [] }
]
};
this.hierarchicalGridRef = this.hierarchicalGridRef.bind(this);
this.dialogRef = this.dialogRef.bind(this);
this.openDialog = this.openDialog.bind(this);
this.updateCheckboxes = this.updateCheckboxes.bind(this);
this.toggleSummary = this.toggleSummary.bind(this);
this.disableAllSummaries = this.disableAllSummaries.bind(this);
this.enableAllSummaries = this.enableAllSummaries.bind(this);
}
hierarchicalGridRef = (ref: IgrHierarchicalGrid) => {
this.hierarchicalGrid = ref;
};
dialogRef = (ref: IgrDialog) => {
this.dialog = ref;
if (this.dialog) {
this.dialog.closeOnOutsideClick = true;
this.dialog.keepOpenOnEscape = false;
}
};
private _singersData: any[] = SingersData;
public get singersData(): any[] {
return this._singersData;
}
openDialog = (column: any) => {
const columnState: any | undefined = this.state.columns.find((c: any) => c.field === column.field);
this.setState({
currentColumn: columnState!,
checkboxStates: [],
}, () => {
this.updateCheckboxes();
this.dialog?.show();
});
};
getSummaryResults(operand: any, data: any[], field: string): IgrSummaryResult[] {
if (typeof operand === "function") {
operand = new operand();
}
if (operand instanceof IgrSummaryOperand) {
return operand.operate([], data, field, null);
} else if (!operand) {
return new IgrSummaryOperand().operate([], data, field, null);
}
return [];
}
getDefaultSummaries(data: any[], field: string): IgrSummaryResult[] {
const columnInstance = this.hierarchicalGrid.columns.find((c: any) => c.field === field);
if (columnInstance && columnInstance.summaries && typeof columnInstance.summaries.operate === 'function') {
return columnInstance.summaries.operate([], data, field, null);
}
return [];
}
updateCheckboxes() {
if (!this.state.currentColumn || !this.hierarchicalGrid) return;
const gridData: any[] = this.hierarchicalGrid.data;
let allSummaries: IgrSummaryResult[] = [];
if (this.state.currentColumn.summaries) {
allSummaries = this.getSummaryResults(this.state.currentColumn.summaries, gridData, this.state.currentColumn.field);
} else {
allSummaries = this.getDefaultSummaries(gridData, this.state.currentColumn.field);
}
let allDisabled: boolean = true;
let allEnabled: boolean = true;
const checkboxStates: any[] = allSummaries.map(summary => {
const isDisabled = this.state.currentColumn.disabledSummaries.includes(summary.key);
if (isDisabled) {
allEnabled = false;
} else {
allDisabled = false;
}
return {
label: summary.label,
key: summary.key,
checked: isDisabled,
};
});
this.setState({
checkboxStates,
disableAllBtnDisabled: allDisabled,
enableAllBtnDisabled: allEnabled,
});
}
toggleSummary = (summaryKey: string) => {
if (!this.state.currentColumn || !this.hierarchicalGrid) return;
const { currentColumn, columns } = this.state;
const updatedDisabledSummaries: string[] = currentColumn.disabledSummaries.includes(summaryKey)
? currentColumn.disabledSummaries.filter((key: any) => key !== summaryKey)
: [...currentColumn.disabledSummaries, summaryKey];
const updatedColumns: any[] = columns.map((col: any) =>
col.field === currentColumn.field
? { ...col, disabledSummaries: updatedDisabledSummaries }
: col
);
this.setState({
currentColumn: { ...currentColumn, disabledSummaries: updatedDisabledSummaries },
columns: updatedColumns,
}, () => {
this.hierarchicalGrid.markForCheck();
});
};
disableAllSummaries = () => {
if (!this.state.currentColumn || !this.hierarchicalGrid) return;
const gridData: any[] = this.hierarchicalGrid.data;
let allSummaries: IgrSummaryResult[] = [];
if (this.state.currentColumn.summaries) {
allSummaries = this.getSummaryResults(this.state.currentColumn.summaries, gridData, this.state.currentColumn.field);
} else {
allSummaries = this.getDefaultSummaries(gridData, this.state.currentColumn.field);
}
const allSummaryKeys: string[] = allSummaries.map(s => s.key);
const updatedColumns: any[] = this.state.columns.map((col: any) =>
col.field === this.state.currentColumn!.field
? { ...col, disabledSummaries: allSummaryKeys }
: col
);
this.setState((prevState: any) => ({
currentColumn: { ...prevState.currentColumn!, disabledSummaries: allSummaryKeys },
columns: updatedColumns,
disableAllBtnDisabled: true,
enableAllBtnDisabled: false,
}), () => {
this.updateCheckboxes();
this.hierarchicalGrid.markForCheck();
});
};
enableAllSummaries = () => {
if (!this.state.currentColumn || !this.hierarchicalGrid) return;
const updatedColumns: any[] = this.state.columns.map((col: any) =>
col.field === this.state.currentColumn!.field
? { ...col, disabledSummaries: [] }
: col
);
this.setState((prevState: any) => ({
currentColumn: { ...prevState.currentColumn!, disabledSummaries: [] },
columns: updatedColumns,
disableAllBtnDisabled: false,
enableAllBtnDisabled: true,
}), () => {
this.updateCheckboxes();
this.hierarchicalGrid.markForCheck();
});
};
public render(): JSX.Element {
return (
<div className="grid-wrapper container sample ig-typography">
<div className="summaries">
<p className="summaries-title">Disable Summaries for Column:</p>
{this.state.columns.map((col: any) => (
<IgrButton
key={col.field}
className="summary-button"
variant="contained"
onClick={() => this.openDialog({ field: col.field, header: col.header })}
>
<span>{col.header}</span>
</IgrButton>
))}
</div>
<IgrDialog ref={this.dialogRef} title={this.state.currentColumn ? `Disable Summaries for ${this.state.currentColumn.header}` : ""}>
<div className="summaries-dialog-items">
{this.state.currentColumn && this.state.checkboxStates.map((checkbox: any) => (
<IgrCheckbox
key={checkbox.key}
className="summaries-dialog-item"
checked={checkbox.checked}
onClick={() => this.toggleSummary(checkbox.key)}
>
<span>{checkbox.label}</span>
</IgrCheckbox>
))}
</div>
<IgrButton key="disableAll" slot="footer" variant="flat" onClick={this.disableAllSummaries} disabled={this.state.disableAllBtnDisabled}><span>Disable All</span></IgrButton>
<IgrButton key="enableAll" slot="footer" variant="flat" onClick={this.enableAllSummaries} disabled={this.state.enableAllBtnDisabled}><span>Enable All</span></IgrButton>
</IgrDialog>
<div className="container fill">
<IgrHierarchicalGrid
autoGenerate={false}
data={this.singersData}
ref={this.hierarchicalGridRef}
id="hierarchicalGrid"
primaryKey="ID">
<IgrColumn
field="Artist"
header="Artist"
hasSummary={true}
disabledSummaries={this.state.columns.find((col: any) => col.field === "Artist")?.disabledSummaries}>
</IgrColumn>
<IgrColumn
field="Photo"
header="Photo"
dataType="Image"
hasSummary={true}
summaries={GrammySummary}
disabledSummaries={this.state.columns.find((col: any) => col.field === "Photo")?.disabledSummaries}>
</IgrColumn>
<IgrColumn
field="Debut"
header="Debut"
hasSummary={true}
disabledSummaries={this.state.columns.find((col: any) => col.field === "Debut")?.disabledSummaries}>
</IgrColumn>
<IgrColumn
field="GrammyNominations"
header="Grammy Nominations"
dataType="Number"
hasSummary={true}
disabledSummaries={this.state.columns.find((col: any) => col.field === "GrammyNominations")?.disabledSummaries}>
</IgrColumn>
<IgrColumn
field="GrammyAwards"
header="Grammy Awards"
dataType="Number"
hasSummary={true}
disabledSummaries={this.state.columns.find((col: any) => col.field === "GrammyAwards")?.disabledSummaries}>
</IgrColumn>
<IgrRowIsland
childDataKey="Albums"
autoGenerate={false}>
<IgrColumn
field="Album"
header="Album"
dataType="String"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="LaunchDate"
header="Launch Date"
dataType="Date"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="BillboardReview"
header="Billboard Review"
dataType="Number"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="USBillboard200"
header="US Billboard 200"
dataType="Number"
hasSummary={true}>
</IgrColumn>
<IgrRowIsland
childDataKey="Songs"
autoGenerate={false}>
<IgrColumn
field="Number"
header="No."
dataType="String"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Title"
header="Title"
dataType="String"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Released"
header="Released"
dataType="Date"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Genre"
header="Genre"
dataType="String"
hasSummary={true}>
</IgrColumn>
</IgrRowIsland>
</IgrRowIsland>
<IgrRowIsland
childDataKey="Tours"
autoGenerate={false}>
<IgrColumn
field="Tour"
header="Tour"
dataType="String"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="StartedOn"
header="Started on"
dataType="String"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Location"
header="Location"
dataType="String"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Headliner"
header="Headliner"
dataType="String"
hasSummary={true}>
</IgrColumn>
</IgrRowIsland>
</IgrHierarchicalGrid>
</div>
</div>
);
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx.grid-wrapper {
margin: 0 auto;
padding: 16px;
height: 87%;
}
.grid-wrapper .summaries {
margin-bottom: 1rem;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.grid-wrapper .summaries-title {
margin: 0 0 1rem 0;
flex-basis: 100%;
font-weight: bold;
}
.grid-wrapper .summary-button {
margin-right: 1rem;
}
igc-dialog {
border: 1px solid #e0e0e0;
border-radius: 8px;
}
igc-dialog::part(title) {
color: #1E6DFE;
}
.summaries-dialog-items {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.summaries-dialog-items .summaries-dialog-item {
display: flex;
align-items: center;
padding: 0 1rem;
}
css
集計のフォーマット
デフォルトでは、組み込みの集計オペランドによって生成される集計結果は、グリッド locale
および列 pipeArgs
に従ってローカライズおよびフォーマットされます。カスタム オペランドを使用する場合、locale
と pipeArgs
は適用されません。集計結果のデフォルトの外観を変更する場合は、summaryFormatter
プロパティを使用してフォーマットできます。
public summaryFormatter(
summary: IgrSummaryResult,
summaryOperand: IgrSummaryOperand
): string {
const result = summary.summaryResult;
if (summary.key !== "count" && result !== null && result !== undefined) {
const format = new Intl.DateTimeFormat("en", { year: "numeric" });
return format.format(new Date(result));
}
return result;
}
<IgrColumn hasSummary="true" summaryFormatter={this.summaryFormatter}></IgrColumn>
tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrHierarchicalGridModule } from "@infragistics/igniteui-react-grids";
import { IgrHierarchicalGrid, IgrColumn, IgrRowIsland } from "@infragistics/igniteui-react-grids";
import SingersData from './SingersData.json';
import { IgrSummaryResult, IgrSummaryOperand } from "@infragistics/igniteui-react-grids";
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrHierarchicalGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private hierarchicalGrid: IgrHierarchicalGrid
private hierarchicalGridRef(r: IgrHierarchicalGrid) {
this.hierarchicalGrid = r;
this.setState({});
}
private debutColumn: IgrColumn
private column1: IgrColumn
constructor(props: any) {
super(props);
this.hierarchicalGridRef = this.hierarchicalGridRef.bind(this);
this.webHierarchicalGridRenderedExpand = this.webHierarchicalGridRenderedExpand.bind(this);
this.webHierarchicalGridSummaryFormatter = this.webHierarchicalGridSummaryFormatter.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrHierarchicalGrid
autoGenerate={false}
data={this.singersData}
ref={this.hierarchicalGridRef}
id="hierarchicalGrid"
primaryKey="ID"
allowFiltering={true}
filterMode="excelStyleFilter"
rendered={this.webHierarchicalGridRenderedExpand}>
<IgrColumn
field="Artist"
header="Artist"
sortable={true}>
</IgrColumn>
<IgrColumn
field="Debut"
header="Debut Decade"
sortable={true}
hasSummary={true}
name="debutColumn">
</IgrColumn>
<IgrColumn
field="GrammyNominations"
header="Grammy Nominations"
dataType="number"
sortable={true}>
</IgrColumn>
<IgrColumn
field="GrammyAwards"
header="Grammy Awards"
dataType="number"
sortable={true}>
</IgrColumn>
<IgrRowIsland
childDataKey="Albums"
autoGenerate={false}
allowFiltering={true}
filterMode="excelStyleFilter">
<IgrColumn
field="Album"
header="Album"
dataType="string"
sortable={true}>
</IgrColumn>
<IgrColumn
field="LaunchDate"
header="Launch Date"
dataType="date"
sortable={true}
hasSummary={true}
summaryFormatter={this.webHierarchicalGridSummaryFormatter}
name="column1">
</IgrColumn>
<IgrColumn
field="BillboardReview"
header="Billboard Review"
dataType="number"
sortable={true}>
</IgrColumn>
<IgrColumn
field="USBillboard200"
header="US Billboard 200"
dataType="number"
sortable={true}>
</IgrColumn>
<IgrRowIsland
childDataKey="Songs"
autoGenerate={false}>
<IgrColumn
field="Number"
header="No."
dataType="string">
</IgrColumn>
<IgrColumn
field="Title"
header="Title"
dataType="string">
</IgrColumn>
<IgrColumn
field="Released"
header="Released"
dataType="date">
</IgrColumn>
<IgrColumn
field="Genre"
header="Genre"
dataType="string">
</IgrColumn>
</IgrRowIsland>
</IgrRowIsland>
<IgrRowIsland
childDataKey="Tours"
autoGenerate={false}>
<IgrColumn
field="Tour"
header="Tour"
dataType="string">
</IgrColumn>
<IgrColumn
field="StartedOn"
header="Started on"
dataType="string">
</IgrColumn>
<IgrColumn
field="Location"
header="Location"
dataType="string">
</IgrColumn>
<IgrColumn
field="Headliner"
header="Headliner"
dataType="string">
</IgrColumn>
</IgrRowIsland>
</IgrHierarchicalGrid>
</div>
</div>
);
}
private _singersData: any[] = SingersData;
public get singersData(): any[] {
return this._singersData;
}
public webHierarchicalGridRenderedExpand(args:any): void {
var hierarchicalGrid = this.hierarchicalGrid;
hierarchicalGrid.expandAll();
setTimeout(() => {
hierarchicalGrid.getColumnByName("Debut").formatter = (value: number) => Math.floor(value / 10) * 10 + 's';
}, 100);
}
public webHierarchicalGridSummaryFormatter(summary: IgrSummaryResult, summaryOperand: IgrSummaryOperand): string {
const result = summary.summaryResult;
if (summary.key !== "count" && result !== null && result !== undefined) {
const format = new Intl.DateTimeFormat("en", { year: "numeric" });
return format.format(new Date(result));
}
return result;
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
キーボード ナビゲーション
集計行は、以下のキーボード操作でナビゲーションできます。
- 上矢印 - 1 つ上のセルへ移動。
- 下矢印 - 1 つ下のセルへ移動。
- 左矢印 - 1 つ左のセルへ移動。
- 右矢印 - 1 つ右のセルへ移動。
- CTRL + 左矢印 または HOME - 左端のセルへ移動。
- CTRL + 右矢印 または END - 右端のセルへ移動。
スタイル設定
定義済みのテーマに加えて、利用可能な CSS プロパティのいくつかを設定することで、グリッドをさらにカスタマイズできます。 一部の色を変更したい場合は、最初にグリッドのクラスを設定する必要があります。
<IgrHierarchicalGrid id="hierarchicalGrid">
</IgrHierarchicalGrid>
tsx
次に、そのクラスに関連する CSS プロパティを設定します。
#hierarchicalGrid {
--ig-grid-summary-background-color:#e0f3ff;
--ig-grid-summary-focus-background-color: rgba( #94d1f7, .3 );
--ig-grid-summary-label-color: rgb(228, 27, 117);
--ig-grid-summary-result-color: black;
}
css
デモ
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrHierarchicalGridModule } from "@infragistics/igniteui-react-grids";
import { IgrHierarchicalGrid, IgrColumn, IgrRowIsland } from "@infragistics/igniteui-react-grids";
import SingersData from './SingersData.json';
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
const mods: any[] = [
IgrHierarchicalGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private hierarchicalGrid: IgrHierarchicalGrid
private hierarchicalGridRef(r: IgrHierarchicalGrid) {
this.hierarchicalGrid = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.hierarchicalGridRef = this.hierarchicalGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrHierarchicalGrid
autoGenerate={false}
data={this.singersData}
ref={this.hierarchicalGridRef}
id="hierarchicalGrid"
primaryKey="ID">
<IgrColumn
field="Artist"
header="Artist"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Photo"
header="Photo"
dataType="image">
</IgrColumn>
<IgrColumn
field="Debut"
header="Debut"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="GrammyNominations"
header="Grammy Nominations"
dataType="number"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="GrammyAwards"
header="Grammy Awards"
dataType="number"
hasSummary={true}>
</IgrColumn>
<IgrRowIsland
childDataKey="Albums"
autoGenerate={false}>
<IgrColumn
field="Album"
header="Album"
dataType="string">
</IgrColumn>
<IgrColumn
field="LaunchDate"
header="Launch Date"
dataType="date">
</IgrColumn>
<IgrColumn
field="BillboardReview"
header="Billboard Review"
dataType="number"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="USBillboard200"
header="US Billboard 200"
dataType="number"
hasSummary={true}>
</IgrColumn>
<IgrRowIsland
childDataKey="Songs"
autoGenerate={false}>
<IgrColumn
field="Number"
header="No."
dataType="string">
</IgrColumn>
<IgrColumn
field="Title"
header="Title"
dataType="string"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="Released"
header="Released"
dataType="date">
</IgrColumn>
<IgrColumn
field="Genre"
header="Genre"
dataType="string">
</IgrColumn>
</IgrRowIsland>
</IgrRowIsland>
<IgrRowIsland
childDataKey="Tours"
autoGenerate={false}>
<IgrColumn
field="Tour"
header="Tour"
dataType="string">
</IgrColumn>
<IgrColumn
field="StartedOn"
header="Started on"
dataType="string">
</IgrColumn>
<IgrColumn
field="Location"
header="Location"
dataType="string">
</IgrColumn>
<IgrColumn
field="Headliner"
header="Headliner"
dataType="string">
</IgrColumn>
</IgrRowIsland>
</IgrHierarchicalGrid>
</div>
</div>
);
}
private _singersData: any[] = SingersData;
public get singersData(): any[] {
return this._singersData;
}
}
// rendering above component in the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
tsx/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
#hierarchicalGrid {
--ig-grid-summary-background-color:#e0f3ff;
--ig-grid-summary-focus-background-color: rgba( #94d1f7, .3 );
--ig-grid-summary-label-color: rgb(228, 27, 117);
--ig-grid-summary-result-color: black;
}
css
API リファレンス
その他のリソース
コミュニティに参加して新しいアイデアをご提案ください。