React Tree Grid Summaries
트리 그리드 React Ignite UI for React 요약 기능은 열별 수준에서 그룹 바닥글로 작동합니다. React IgrTreeGrid 요약은 사용자가 열 내의 데이터 유형에 따라 또는 사용자 정의 템플릿을 구현하여 사전 정의된 기본 요약 항목 집합이 있는 별도의 컨테이너에서 열 정보를 볼 수 있도록 하는 강력한 기능입니다. IgrTreeGrid
.
React Tree Grid Summaries Overview Example
export class OrdersTreeDataItem {
public constructor(init: Partial<OrdersTreeDataItem>) {
Object.assign(this, init);
}
public ID: number;
public ParentID: number;
public Name: string;
public Category: string;
public OrderDate: string;
public Units: number;
public UnitPrice: number;
public Price: number;
public Delivered: boolean;
}
export class OrdersTreeData extends Array<OrdersTreeDataItem> {
public constructor(items: Array<OrdersTreeDataItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new OrdersTreeDataItem(
{
ID: 1,
ParentID: -1,
Name: `Order 1`,
Category: ``,
OrderDate: `2010-02-17`,
Units: 1844,
UnitPrice: 3.73,
Price: 6884.38,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 101,
ParentID: 1,
Name: `Chocolate Chip Cookies`,
Category: `Cookies`,
OrderDate: `2010-02-17`,
Units: 834,
UnitPrice: 3.59,
Price: 2994.06,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 102,
ParentID: 1,
Name: `Red Apples`,
Category: `Fruit`,
OrderDate: `2010-02-17`,
Units: 371,
UnitPrice: 3.66,
Price: 1357.86,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 103,
ParentID: 1,
Name: `Butter`,
Category: `Diary`,
OrderDate: `2010-02-17`,
Units: 260,
UnitPrice: 3.45,
Price: 897,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 104,
ParentID: 1,
Name: `Potato Chips`,
Category: `Snack`,
OrderDate: `2010-02-17`,
Units: 118,
UnitPrice: 1.96,
Price: 231.28,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 105,
ParentID: 1,
Name: `Orange Juice`,
Category: `Beverages`,
OrderDate: `2010-02-17`,
Units: 261,
UnitPrice: 5.38,
Price: 1404.18,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 2,
ParentID: -1,
Name: `Order 2`,
Category: ``,
OrderDate: `2022-05-27`,
Units: 1831,
UnitPrice: 8.23,
Price: 15062.77,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 201,
ParentID: 2,
Name: `Frozen Shrimps`,
Category: `Seafood`,
OrderDate: `2022-05-27`,
Units: 120,
UnitPrice: 20.45,
Price: 2454,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 202,
ParentID: 2,
Name: `Ice Tea`,
Category: `Beverages`,
OrderDate: `2022-05-27`,
Units: 840,
UnitPrice: 7,
Price: 5880,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 203,
ParentID: 2,
Name: `Fresh Cheese`,
Category: `Diary`,
OrderDate: `2022-05-27`,
Units: 267,
UnitPrice: 16.55,
Price: 4418.85,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 204,
ParentID: 2,
Name: `Carrots`,
Category: `Vegetables`,
OrderDate: `2022-05-27`,
Units: 360,
UnitPrice: 2.77,
Price: 997.2,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 205,
ParentID: 2,
Name: `Apple Juice`,
Category: `Beverages`,
OrderDate: `2022-05-27`,
Units: 244,
UnitPrice: 5.38,
Price: 1312.72,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 3,
ParentID: -1,
Name: `Order 3`,
Category: ``,
OrderDate: `2022-08-04`,
Units: 1972,
UnitPrice: 3.47,
Price: 6849.18,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 301,
ParentID: 3,
Name: `Skimmed Milk 1L`,
Category: `Diary`,
OrderDate: `2022-08-04`,
Units: 1028,
UnitPrice: 3.56,
Price: 3659.68,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 302,
ParentID: 3,
Name: `Bananas 5 Pack`,
Category: `Fruit`,
OrderDate: `2022-08-04`,
Units: 370,
UnitPrice: 6.36,
Price: 2353.2,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 303,
ParentID: 3,
Name: `Cauliflower`,
Category: `Vegetables`,
OrderDate: `2022-08-04`,
Units: 283,
UnitPrice: 0.95,
Price: 268.85,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 304,
ParentID: 3,
Name: `White Chocolate Cookies`,
Category: `Cookies`,
OrderDate: `2022-08-04`,
Units: 291,
UnitPrice: 1.95,
Price: 567.45,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 4,
ParentID: -1,
Name: `Order 4`,
Category: ``,
OrderDate: `2023-01-04`,
Units: 1065,
UnitPrice: 5.56,
Price: 5923.5,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 401,
ParentID: 4,
Name: `Mini Milk Chocolate Cookie Bites`,
Category: `Cookies`,
OrderDate: `2023-01-04`,
Units: 68,
UnitPrice: 2.25,
Price: 153,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 402,
ParentID: 4,
Name: `Wild Salmon Fillets`,
Category: `Seafood`,
OrderDate: `2023-01-04`,
Units: 320,
UnitPrice: 16.15,
Price: 5168,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 403,
ParentID: 4,
Name: `Diet Lemonade`,
Category: `Beverages`,
OrderDate: `2023-01-04`,
Units: 437,
UnitPrice: 0.5,
Price: 218.5,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 404,
ParentID: 4,
Name: `Potatoes`,
Category: `Vegetables`,
OrderDate: `2023-01-04`,
Units: 240,
UnitPrice: 1.6,
Price: 384,
Delivered: true
}),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrTreeGridModule } from "@infragistics/igniteui-react-grids";
import { IgrTreeGrid, IgrColumn } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, WebTreeGridDescriptionModule } from "@infragistics/igniteui-react-core";
import { OrdersTreeDataItem, OrdersTreeData } from './OrdersTreeData';
import { IgrColumnTemplateContext } 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[] = [
IgrTreeGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private treeGrid: IgrTreeGrid
private treeGridRef(r: IgrTreeGrid) {
this.treeGrid = r;
this.setState({});
}
private column1: IgrColumn
private column2: IgrColumn
private column3: IgrColumn
private column4: IgrColumn
private column5: IgrColumn
private column6: IgrColumn
constructor(props: any) {
super(props);
this.treeGridRef = this.treeGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrTreeGrid
autoGenerate={false}
data={this.ordersTreeData}
ref={this.treeGridRef}
id="treeGrid"
primaryKey="ID"
foreignKey="ParentID">
<IgrColumn
field="ID"
header="Order ID">
</IgrColumn>
<IgrColumn
field="Name"
header="Order Product"
hasSummary={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column1">
</IgrColumn>
<IgrColumn
field="Units"
header="Units"
dataType="number"
hasSummary={true}
editable={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column2">
</IgrColumn>
<IgrColumn
field="UnitPrice"
header="Unit Price"
dataType="number"
hasSummary={true}
editable={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column3">
</IgrColumn>
<IgrColumn
field="Price"
header="Price"
dataType="number"
hasSummary={true}
editable={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column4">
</IgrColumn>
<IgrColumn
field="OrderDate"
header="Order Date"
dataType="date"
hasSummary={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column5">
</IgrColumn>
<IgrColumn
field="Delivered"
header="Delivered"
dataType="boolean"
hasSummary={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column6">
</IgrColumn>
</IgrTreeGrid>
</div>
</div>
);
}
private _ordersTreeData: OrdersTreeData = null;
public get ordersTreeData(): OrdersTreeData {
if (this._ordersTreeData == null)
{
this._ordersTreeData = new OrdersTreeData();
}
return this._ordersTreeData;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebTreeGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webTreeGridSummariesHeaderTemplate = (props: { dataContext: IgrColumnTemplateContext }) => {
const column = (props.dataContext as any).column;
return (
<div>
<span style={{ float: 'left' }}>{column.field}</span>
<span style={{ float: 'right', color: column.hasSummary ? '#e41c77' : '' }} onPointerDown={(e: any) => this.toggleSummary(column)}>∑</span>
</div>
);
}
public toggleSummary(field: IgrColumn) {
if (field) {
field.hasSummary = !field.hasSummary;
(this as any).setState({ summary: field.hasSummary });
}
}
}
// 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
Like this sample? Get access to our complete Ignite UI for React toolkit and start building your own apps in minutes. Download it for free.
The summary of the column is a function of all column values, unless filtering is applied, then the summary of the column will be function of the filtered result values
IgrTreeGrid
요약은 Ignite UI for React의 열별 수준에서 활성화할 수도 있는데, 이는 필요한 열에 대해서만 활성화할 수 있음을 의미합니다. IgrTreeGrid
summaries는 열의 데이터 유형에 따라 미리 정의된 기본 요약 집합을 제공하므로 시간을 절약할 수 있습니다.
string
및 boolean
dataType
의 경우 다음 함수를 사용할 수 있습니다.
- 세다
number
, currency
및 percent
데이터 유형의 경우 다음 함수를 사용할 수 있습니다.
- 세다
- 최소
- 맥스
- 평균
- 합집합
date
데이터 유형의 경우 다음 기능을 사용할 수 있습니다.
- 세다
- 가장 빠른
- 최신
사용 가능한 모든 열 데이터 유형은 공식 열 유형 항목에서 찾을 수 있습니다.
IgrTreeGrid
요약은 설정을 통해 열별로 사용할 수 있습니다. hasSummary
속성을 참. 또한 각 열에 대한 요약은 열 데이터 형식에 따라 확인된다는 점을 명심해야 합니다. 안에 IgrTreeGrid
기본 열 데이터 형식은 다음과 같습니다. string
, 그래서 당신이 원한다면 number
또는 date
특정 요약을 지정해야 합니다. dataType
속성을 number
또는 date
. 요약 값은 그리드에 따라 지역화되어 표시됩니다 locale
및 열 pipeArgs
.
<IgrTreeGrid autoGenerate="false" height="800px" width="800px">
<IgrColumn field="ID" header="Order ID">
</IgrColumn>
<IgrColumn field="Name" header="Order Product" hasSummary="true">
</IgrColumn>
<IgrColumn field="Units" header="Units" editable="true" dataType="number" hasSummary="true">
</IgrColumn>
</IgrTreeGrid>
tsx
특정 열 또는 열 목록에 대한 요약을 활성화/비활성화하는 다른 방법은 public method enableSummaries
/of를 disableSummaries
IgrTreeGrid
사용하는 것입니다.
function enableSummary() {
treeGridRef.current.enableSummaries([
{fieldName: 'Name'},
{fieldName: 'Units'}
]);
}
function disableSummary() {
treeGridRef.current.disableSummaries(['Units']);
}
<IgrTreeGrid autoGenerate="false" data={this.ordersTreeData} ref={this.treeGridRef} id="treeGrid" primaryKey="ID">
<IgrColumn field="ID" header="Order ID"></IgrColumn>
<IgrColumn field="Name" header="Order Product" hasSummary="true"></IgrColumn>
<IgrColumn field="Units" header="Units" editable="true" dataType="Number" hasSummary="true"></IgrColumn>
</IgrTreeGrid>
<button onClick={enableSummary}>Enable Summary</button>
<button onClick={disableSummary}>Disable Summary </button>
tsx
Summary Template
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
input 속성을 사용하여 기본값을 재정의합니다. 인수로 숫자 값이 필요하며 거짓 값을 설정하면 그리드 바닥글의 기본 크기 조정 동작이 트리거됩니다.
export class EmployeesNestedTreeDataItem {
public constructor(init: Partial<EmployeesNestedTreeDataItem>) {
Object.assign(this, init);
}
public Age: number;
public HireDate: string;
public ID: number;
public Name: string;
public Phone: string;
public OnPTO: boolean;
public ParentID: number;
public Title: string;
}
export class EmployeesNestedTreeData extends Array<EmployeesNestedTreeDataItem> {
public constructor(items: Array<EmployeesNestedTreeDataItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new EmployeesNestedTreeDataItem(
{
Age: 55,
HireDate: `2008-03-20`,
ID: 1,
Name: `Johnathan Winchester`,
Phone: `0251-031259`,
OnPTO: false,
ParentID: -1,
Title: `Development Manager`
}),
new EmployeesNestedTreeDataItem(
{
Age: 42,
HireDate: `2014-01-22`,
ID: 4,
Name: `Ana Sanders`,
Phone: `(21) 555-0091`,
OnPTO: true,
ParentID: -1,
Title: `CEO`
}),
new EmployeesNestedTreeDataItem(
{
Age: 49,
HireDate: `2014-01-22`,
ID: 18,
Name: `Victoria Lincoln`,
Phone: `(071) 23 67 22 20`,
OnPTO: true,
ParentID: -1,
Title: `Accounting Manager`
}),
new EmployeesNestedTreeDataItem(
{
Age: 61,
HireDate: `2010-01-01`,
ID: 10,
Name: `Yang Wang`,
Phone: `(21) 555-0091`,
OnPTO: false,
ParentID: -1,
Title: `Localization Manager`
}),
new EmployeesNestedTreeDataItem(
{
Age: 43,
HireDate: `2011-06-03`,
ID: 3,
Name: `Michael Burke`,
Phone: `0452-076545`,
OnPTO: true,
ParentID: 1,
Title: `Senior Software Developer`
}),
new EmployeesNestedTreeDataItem(
{
Age: 29,
HireDate: `2009-06-19`,
ID: 2,
Name: `Thomas Anderson`,
Phone: `(14) 555-8122`,
OnPTO: false,
ParentID: 1,
Title: `Senior Software Developer`
}),
new EmployeesNestedTreeDataItem(
{
Age: 31,
HireDate: `2014-08-18`,
ID: 11,
Name: `Monica Reyes`,
Phone: `7675-3425`,
OnPTO: false,
ParentID: 1,
Title: `Software Development Team Lead`
}),
new EmployeesNestedTreeDataItem(
{
Age: 35,
HireDate: `2015-09-17`,
ID: 6,
Name: `Roland Mendel`,
Phone: `(505) 555-5939`,
OnPTO: false,
ParentID: 11,
Title: `Senior Software Developer`
}),
new EmployeesNestedTreeDataItem(
{
Age: 44,
HireDate: `2009-10-11`,
ID: 12,
Name: `Sven Cooper`,
Phone: `0695-34 67 21`,
OnPTO: true,
ParentID: 11,
Title: `Senior Software Developer`
}),
new EmployeesNestedTreeDataItem(
{
Age: 44,
HireDate: `2014-04-04`,
ID: 14,
Name: `Laurence Johnson`,
Phone: `981-443655`,
OnPTO: false,
ParentID: 4,
Title: `Director`
}),
new EmployeesNestedTreeDataItem(
{
Age: 25,
HireDate: `2017-11-09`,
ID: 5,
Name: `Elizabeth Richards`,
Phone: `(2) 283-2951`,
OnPTO: true,
ParentID: 4,
Title: `Vice President`
}),
new EmployeesNestedTreeDataItem(
{
Age: 39,
HireDate: `2010-03-22`,
ID: 13,
Name: `Trevor Ashworth`,
Phone: `981-443655`,
OnPTO: true,
ParentID: 5,
Title: `Director`
}),
new EmployeesNestedTreeDataItem(
{
Age: 44,
HireDate: `2014-04-04`,
ID: 17,
Name: `Antonio Moreno`,
Phone: `(505) 555-5939`,
OnPTO: false,
ParentID: 18,
Title: `Senior Accountant`
}),
new EmployeesNestedTreeDataItem(
{
Age: 50,
HireDate: `2007-11-18`,
ID: 7,
Name: `Pedro Rodriguez`,
Phone: `035-640230`,
OnPTO: false,
ParentID: 10,
Title: `Senior Localization Developer`
}),
new EmployeesNestedTreeDataItem(
{
Age: 27,
HireDate: `2016-02-19`,
ID: 8,
Name: `Casey Harper`,
Phone: `0342-023176`,
OnPTO: true,
ParentID: 10,
Title: `Senior Localization`
}),
new EmployeesNestedTreeDataItem(
{
Age: 25,
HireDate: `2017-11-09`,
ID: 15,
Name: `Patricia Simpson`,
Phone: `069-0245984`,
OnPTO: false,
ParentID: 7,
Title: `Localization Intern`
}),
new EmployeesNestedTreeDataItem(
{
Age: 39,
HireDate: `2010-03-22`,
ID: 9,
Name: `Francisco Chang`,
Phone: `(91) 745 6200`,
OnPTO: false,
ParentID: 7,
Title: `Localization Intern`
}),
new EmployeesNestedTreeDataItem(
{
Age: 25,
HireDate: `2018-03-18`,
ID: 16,
Name: `Peter Lewis`,
Phone: `069-0245984`,
OnPTO: true,
ParentID: 7,
Title: `Localization Intern`
}),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrPropertyEditorPanelModule } from "@infragistics/igniteui-react-layouts";
import { IgrTreeGridModule } from "@infragistics/igniteui-react-grids";
import { IgrPropertyEditorPanel, IgrPropertyEditorPropertyDescription } from "@infragistics/igniteui-react-layouts";
import { IgrTreeGrid, IgrColumn } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, PropertyEditorPanelDescriptionModule, WebTreeGridDescriptionModule } from "@infragistics/igniteui-react-core";
import { EmployeesNestedTreeDataItem, EmployeesNestedTreeData } from './EmployeesNestedTreeData';
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,
IgrTreeGridModule
];
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 treeGrid: IgrTreeGrid
private treeGridRef(r: IgrTreeGrid) {
this.treeGrid = r;
this.setState({});
}
private column1: IgrColumn
constructor(props: any) {
super(props);
this.propertyEditorPanel1Ref = this.propertyEditorPanel1Ref.bind(this);
this.webTreeGridHasSummariesChange = this.webTreeGridHasSummariesChange.bind(this);
this.webTreeGridSetGridSize = this.webTreeGridSetGridSize.bind(this);
this.treeGridRef = this.treeGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="options vertical">
<IgrPropertyEditorPanel
componentRenderer={this.renderer}
target={this.treeGrid}
descriptionType="WebTreeGrid"
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.webTreeGridHasSummariesChange}
name="ToggleSummariesEditor">
</IgrPropertyEditorPropertyDescription>
<IgrPropertyEditorPropertyDescription
name="SizeEditor"
label="Grid Size:"
valueType="EnumValue"
dropDownNames={["Small", "Medium", "Large"]}
dropDownValues={["Small", "Medium", "Large"]}
changed={this.webTreeGridSetGridSize}>
</IgrPropertyEditorPropertyDescription>
</IgrPropertyEditorPanel>
</div>
<div className="container fill">
<IgrTreeGrid
autoGenerate={false}
data={this.employeesNestedTreeData}
ref={this.treeGridRef}
id="treeGrid"
primaryKey="ID"
foreignKey="ParentID">
<IgrColumn
field="Name">
</IgrColumn>
<IgrColumn
field="Age"
dataType="number"
hasSummary={true}
summaryTemplate={this.webTreeGridSummaryTemplate}
name="column1">
</IgrColumn>
<IgrColumn
field="Title"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="HireDate"
dataType="date">
</IgrColumn>
<IgrColumn
field="OnPTO"
dataType="boolean"
editable={true}
hasSummary={true}>
</IgrColumn>
</IgrTreeGrid>
</div>
</div>
);
}
private _employeesNestedTreeData: EmployeesNestedTreeData = null;
public get employeesNestedTreeData(): EmployeesNestedTreeData {
if (this._employeesNestedTreeData == null)
{
this._employeesNestedTreeData = new EmployeesNestedTreeData();
}
return this._employeesNestedTreeData;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
PropertyEditorPanelDescriptionModule.register(context);
WebTreeGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webTreeGridHasSummariesChange(sender: any, args: IgrPropertyEditorPropertyDescriptionChangedEventArgs): void {
let newValue = sender.primitiveValue as boolean;
const grid = this.treeGrid;
var column1 = grid.getColumnByName("Age");
var column2 = grid.getColumnByName("Title");
var column3 = grid.getColumnByName("OnPTO");
column1.hasSummary = newValue;
column2.hasSummary = newValue;
column3.hasSummary = newValue;
}
public webTreeGridSetGridSize(sender: any, args: IgrPropertyEditorPropertyDescriptionChangedEventArgs): void {
var newVal = (args.newValue as string).toLowerCase();
var grid = document.getElementById("treeGrid");
grid.style.setProperty('--ig-size', `var(--ig-size-${newVal})`);
}
public webTreeGridSummaryTemplate = (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>
<span><strong>{summaryResults[3].label}</strong><span>{(summaryResults[3] as any).summaryResult}</span></span>
</div>
);
}
}
// 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
Disabled Summaries
이 disabledSummaries
속성은 React Tree Grid 요약 기능에 대한 열별 정확한 제어를 제공합니다. 이 속성을 사용하면 사용자가 IgrTreeGrid의 각 열에 대해 표시되는 요약을 사용자 지정하여 가장 관련성이 높고 의미 있는 데이터만 표시되도록 할 수 있습니다. 예를 들어, 배열에서 요약 키를 지정하는 것과 같이 ['count', 'min', 'max']
특정 요약 유형을 제외할 수 있습니다.
또한 이 속성은 코드를 통해 런타임에 동적으로 수정할 수 있으므로 IgrTreeGrid의 요약을 애플리케이션 상태 또는 사용자 작업 변경에 맞게 조정할 수 있는 유연성을 제공합니다.
다음 예제에서는 속성을 사용하여 disabledSummaries
다른 열에 대한 요약을 관리하고 React 트리 그리드에서 특정 기본 및 사용자 지정 요약 유형을 제외하는 방법을 보여 줍니다.
<!-- 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
경우, 기본 요약은 , sum
와 average
같고 count
비활성화되어 있으며 다른 요약은 같고 min
max
활성 상태로 유지됩니다.
의 경우 UnitsInStock
, 및 totalDiscontinued
와 같은 discontinued
사용자 지정 요약은 disabledSummaries
속성을 사용하여 제외됩니다.
런타임에 요약은 속성을 사용하여 동적으로 비활성화할 수도 있습니다 disabledSummaries
. 예를 들어, 프로그래밍 방식으로 특정 열의 속성을 설정하거나 업데이트하여 사용자 작업 또는 응용 프로그램 상태 변경에 따라 표시되는 요약을 조정할 수 있습니다.
export class OrdersTreeDataItem {
public constructor(init: Partial<OrdersTreeDataItem>) {
Object.assign(this, init);
}
public ID: number;
public ParentID: number;
public Name: string;
public Category: string;
public OrderDate: string;
public Units: number;
public UnitPrice: number;
public Price: number;
public Delivered: boolean;
}
export class OrdersTreeData extends Array<OrdersTreeDataItem> {
public constructor(items: Array<OrdersTreeDataItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new OrdersTreeDataItem(
{
ID: 1,
ParentID: -1,
Name: `Order 1`,
Category: ``,
OrderDate: `2010-02-17`,
Units: 1844,
UnitPrice: 3.73,
Price: 6884.38,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 101,
ParentID: 1,
Name: `Chocolate Chip Cookies`,
Category: `Cookies`,
OrderDate: `2010-02-17`,
Units: 834,
UnitPrice: 3.59,
Price: 2994.06,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 102,
ParentID: 1,
Name: `Red Apples`,
Category: `Fruit`,
OrderDate: `2010-02-17`,
Units: 371,
UnitPrice: 3.66,
Price: 1357.86,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 103,
ParentID: 1,
Name: `Butter`,
Category: `Diary`,
OrderDate: `2010-02-17`,
Units: 260,
UnitPrice: 3.45,
Price: 897,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 104,
ParentID: 1,
Name: `Potato Chips`,
Category: `Snack`,
OrderDate: `2010-02-17`,
Units: 118,
UnitPrice: 1.96,
Price: 231.28,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 105,
ParentID: 1,
Name: `Orange Juice`,
Category: `Beverages`,
OrderDate: `2010-02-17`,
Units: 261,
UnitPrice: 5.38,
Price: 1404.18,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 2,
ParentID: -1,
Name: `Order 2`,
Category: ``,
OrderDate: `2022-05-27`,
Units: 1831,
UnitPrice: 8.23,
Price: 15062.77,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 201,
ParentID: 2,
Name: `Frozen Shrimps`,
Category: `Seafood`,
OrderDate: `2022-05-27`,
Units: 120,
UnitPrice: 20.45,
Price: 2454,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 202,
ParentID: 2,
Name: `Ice Tea`,
Category: `Beverages`,
OrderDate: `2022-05-27`,
Units: 840,
UnitPrice: 7,
Price: 5880,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 203,
ParentID: 2,
Name: `Fresh Cheese`,
Category: `Diary`,
OrderDate: `2022-05-27`,
Units: 267,
UnitPrice: 16.55,
Price: 4418.85,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 204,
ParentID: 2,
Name: `Carrots`,
Category: `Vegetables`,
OrderDate: `2022-05-27`,
Units: 360,
UnitPrice: 2.77,
Price: 997.2,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 205,
ParentID: 2,
Name: `Apple Juice`,
Category: `Beverages`,
OrderDate: `2022-05-27`,
Units: 244,
UnitPrice: 5.38,
Price: 1312.72,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 3,
ParentID: -1,
Name: `Order 3`,
Category: ``,
OrderDate: `2022-08-04`,
Units: 1972,
UnitPrice: 3.47,
Price: 6849.18,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 301,
ParentID: 3,
Name: `Skimmed Milk 1L`,
Category: `Diary`,
OrderDate: `2022-08-04`,
Units: 1028,
UnitPrice: 3.56,
Price: 3659.68,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 302,
ParentID: 3,
Name: `Bananas 5 Pack`,
Category: `Fruit`,
OrderDate: `2022-08-04`,
Units: 370,
UnitPrice: 6.36,
Price: 2353.2,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 303,
ParentID: 3,
Name: `Cauliflower`,
Category: `Vegetables`,
OrderDate: `2022-08-04`,
Units: 283,
UnitPrice: 0.95,
Price: 268.85,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 304,
ParentID: 3,
Name: `White Chocolate Cookies`,
Category: `Cookies`,
OrderDate: `2022-08-04`,
Units: 291,
UnitPrice: 1.95,
Price: 567.45,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 4,
ParentID: -1,
Name: `Order 4`,
Category: ``,
OrderDate: `2023-01-04`,
Units: 1065,
UnitPrice: 5.56,
Price: 5923.5,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 401,
ParentID: 4,
Name: `Mini Milk Chocolate Cookie Bites`,
Category: `Cookies`,
OrderDate: `2023-01-04`,
Units: 68,
UnitPrice: 2.25,
Price: 153,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 402,
ParentID: 4,
Name: `Wild Salmon Fillets`,
Category: `Seafood`,
OrderDate: `2023-01-04`,
Units: 320,
UnitPrice: 16.15,
Price: 5168,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 403,
ParentID: 4,
Name: `Diet Lemonade`,
Category: `Beverages`,
OrderDate: `2023-01-04`,
Units: 437,
UnitPrice: 0.5,
Price: 218.5,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 404,
ParentID: 4,
Name: `Potatoes`,
Category: `Vegetables`,
OrderDate: `2023-01-04`,
Units: 240,
UnitPrice: 1.6,
Price: 384,
Delivered: true
}),
];
super(...newItems.slice(0));
}
}
}
tsimport 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 { IgrTreeGridModule, IgrSummaryOperand, IgrSummaryResult } from "@infragistics/igniteui-react-grids";
import { IgrTreeGrid, IgrColumn } from "@infragistics/igniteui-react-grids";
import "@infragistics/igniteui-react-grids/grids/combined";
import "@infragistics/igniteui-react-grids/grids/themes/light/bootstrap.css";
import { OrdersTreeData } from './OrdersTreeData';
IgrTreeGridModule.register();
IgrButtonModule.register();
IgrDialogModule.register();
IgrCheckboxModule.register();
export class UnitsSummary extends IgrSummaryOperand {
operate(data: any[] = [], allData: any[] = [], fieldName: string = ""): IgrSummaryResult[] {
const result: IgrSummaryResult[] = [];
const values = allData.map((rec) => rec[fieldName]).filter((value) => value !== undefined && value !== null);
const totalSum = values.reduce((sum, value) => sum + value, 0);
const sortedValues = [...values].sort((a, b) => a - b);
const deliveredValues = allData
.filter((rec) => rec["Delivered"])
.map((rec) => rec[fieldName])
.filter((value) => value !== undefined && value !== null);
result.push({
key: "count",
label: "Count",
summaryResult: allData.length
});
result.push({
key: "min",
label: "Min",
summaryResult: values.length > 0 ? Math.min(...values) : "N/A"
});
result.push({
key: "max",
label: "Max",
summaryResult: values.length > 0 ? Math.max(...values) : "N/A"
});
result.push({
key: "sum",
label: "Sum",
summaryResult: totalSum
});
result.push({
key: "average",
label: "Average",
summaryResult: values.length > 0 ? totalSum / values.length : "N/A"
});
result.push({
key: "totalDelivered",
label: "Total Units Delivered",
summaryResult: deliveredValues.length > 0 ? deliveredValues.reduce((sum, value) => sum + value, 0) : "N/A"
});
result.push({
key: "medianUnits",
label: "Median Units",
summaryResult:
values.length > 0
? (() => {
const mid = Math.floor(sortedValues.length / 2);
return sortedValues.length % 2 !== 0 ? sortedValues[mid] : (sortedValues[mid - 1] + sortedValues[mid]) / 2;
})()
: "N/A"
});
result.push({
key: "uniqueCount",
label: "Count of Unique Unit Values",
summaryResult: values.length > 0 ? new Set(values).size : "N/A"
});
result.push({
key: "maxDifference",
label: "Max Difference Between Units",
summaryResult:
values.length > 1
? values.reduce((maxDiff, value, idx, arr) => {
if (idx === 0) return maxDiff;
const diff = Math.abs(value - arr[idx - 1]);
return Math.max(maxDiff, diff);
}, 0)
: "N/A"
});
return result;
}
}
export class DeliveredSummary extends IgrSummaryOperand {
operate(data: any[] = [], allData: any[] = [], fieldName: string = ""): IgrSummaryResult[] {
const result: IgrSummaryResult[] = [];
result.push({
key: "count",
label: "Count",
summaryResult: allData.length
});
result.push({
key: "true",
label: "True",
summaryResult: allData.filter((item) => item[fieldName] === true).length
});
result.push({
key: "false",
label: "False",
summaryResult: allData.filter((item) => item[fieldName] === false).length
});
return result;
}
}
export default class Sample extends React.Component<any, any> {
private treeGrid: IgrTreeGrid;
private dialog: IgrDialog;
constructor(props: any) {
super(props);
this.state = {
currentColumn: null,
disableAllBtnDisabled: false,
enableAllBtnDisabled: false,
checkboxStates: [],
columns: [
{ field: "ID", header: "Order ID", hasSummary: true, disabledSummaries: [] },
{ field: "Name", header: "Order Product", hasSummary: true, disabledSummaries: [] },
{ field: "Units", header: "Units", hasSummary: true, dataType: "number", summaries: UnitsSummary, disabledSummaries: [] },
{ field: "UnitPrice", header: "Unit Price", hasSummary: true, dataType: "number", disabledSummaries: [] },
{ field: "Price", header: "Price", hasSummary: true, dataType: "number", disabledSummaries: [] },
{ field: "Delivered", header: "Delivered", hasSummary: true, summaries: DeliveredSummary, disabledSummaries: [] },
{ field: "OrderDate", header: "Order Date", hasSummary: true, dataType: "date", disabledSummaries: [] },
],
};
this.treeGridRef = this.treeGridRef.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);
}
treeGridRef = (ref: IgrTreeGrid) => {
this.treeGrid = ref;
};
dialogRef = (ref: IgrDialog) => {
this.dialog = ref;
if (this.dialog) {
this.dialog.closeOnOutsideClick = true;
this.dialog.keepOpenOnEscape = false;
}
};
private _ordersTreeData: OrdersTreeData = null;
public get ordersTreeData(): OrdersTreeData {
if (this._ordersTreeData == null)
{
this._ordersTreeData = new OrdersTreeData();
}
return this._ordersTreeData;
}
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.treeGrid.columns.find(c => 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.treeGrid) return;
const gridData: any[] = this.treeGrid.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.treeGrid) 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.treeGrid.markForCheck();
});
};
disableAllSummaries = () => {
if (!this.state.currentColumn || !this.treeGrid) return;
const gridData: any[] = this.treeGrid.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.treeGrid.markForCheck();
});
};
enableAllSummaries = () => {
if (!this.state.currentColumn || !this.treeGrid) 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.treeGrid.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">
<IgrTreeGrid
autoGenerate={false}
data={this.ordersTreeData}
ref={this.treeGridRef}
id="treeGrid"
primaryKey="ID"
foreignKey="ParentID">
<IgrColumn
field="ID"
header="Order ID"
hasSummary={true}
disabledSummaries={this.state.columns.find((col: any) => col.field === "ID")?.disabledSummaries}>
</IgrColumn>
<IgrColumn
field="Name"
header="Order Product"
hasSummary={true}
disabledSummaries={this.state.columns.find((col: any) => col.field === "Name")?.disabledSummaries}>
</IgrColumn>
<IgrColumn
field="Units"
header="Units"
dataType="Number"
hasSummary={true}
summaries={UnitsSummary}
disabledSummaries={this.state.columns.find((col: any) => col.field === "Units")?.disabledSummaries}>
</IgrColumn>
<IgrColumn
field="UnitPrice"
header="Unit Price"
dataType="Number"
hasSummary={true}
disabledSummaries={this.state.columns.find((col: any) => col.field === "UnitPrice")?.disabledSummaries}>
</IgrColumn>
<IgrColumn
field="Price"
header="Price"
dataType="Number"
hasSummary={true}
disabledSummaries={this.state.columns.find((col: any) => col.field === "Price")?.disabledSummaries}>
</IgrColumn>
<IgrColumn
field="Delivered"
header="Delivered"
dataType="Boolean"
hasSummary={true}
summaries={DeliveredSummary}
disabledSummaries={this.state.columns.find((col: any) => col.field === "Delivered")?.disabledSummaries}>
</IgrColumn>
<IgrColumn
field="OrderDate"
header="Order Date"
dataType="Date"
hasSummary={true}
disabledSummaries={this.state.columns.find((col: any) => col.field === "OrderDate")?.disabledSummaries}>
</IgrColumn>
</IgrTreeGrid>
</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
Formatting summaries
기본적으로 기본 제공 요약 피연산자에 의해 생성된 요약 결과는 그리드 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
export class OrdersTreeDataItem {
public constructor(init: Partial<OrdersTreeDataItem>) {
Object.assign(this, init);
}
public ID: number;
public ParentID: number;
public Name: string;
public Category: string;
public OrderDate: string;
public Units: number;
public UnitPrice: number;
public Price: number;
public Delivered: boolean;
}
export class OrdersTreeData extends Array<OrdersTreeDataItem> {
public constructor(items: Array<OrdersTreeDataItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new OrdersTreeDataItem(
{
ID: 1,
ParentID: -1,
Name: `Order 1`,
Category: ``,
OrderDate: `2010-02-17`,
Units: 1844,
UnitPrice: 3.73,
Price: 6884.38,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 101,
ParentID: 1,
Name: `Chocolate Chip Cookies`,
Category: `Cookies`,
OrderDate: `2010-02-17`,
Units: 834,
UnitPrice: 3.59,
Price: 2994.06,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 102,
ParentID: 1,
Name: `Red Apples`,
Category: `Fruit`,
OrderDate: `2010-02-17`,
Units: 371,
UnitPrice: 3.66,
Price: 1357.86,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 103,
ParentID: 1,
Name: `Butter`,
Category: `Diary`,
OrderDate: `2010-02-17`,
Units: 260,
UnitPrice: 3.45,
Price: 897,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 104,
ParentID: 1,
Name: `Potato Chips`,
Category: `Snack`,
OrderDate: `2010-02-17`,
Units: 118,
UnitPrice: 1.96,
Price: 231.28,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 105,
ParentID: 1,
Name: `Orange Juice`,
Category: `Beverages`,
OrderDate: `2010-02-17`,
Units: 261,
UnitPrice: 5.38,
Price: 1404.18,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 2,
ParentID: -1,
Name: `Order 2`,
Category: ``,
OrderDate: `2022-05-27`,
Units: 1831,
UnitPrice: 8.23,
Price: 15062.77,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 201,
ParentID: 2,
Name: `Frozen Shrimps`,
Category: `Seafood`,
OrderDate: `2022-05-27`,
Units: 120,
UnitPrice: 20.45,
Price: 2454,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 202,
ParentID: 2,
Name: `Ice Tea`,
Category: `Beverages`,
OrderDate: `2022-05-27`,
Units: 840,
UnitPrice: 7,
Price: 5880,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 203,
ParentID: 2,
Name: `Fresh Cheese`,
Category: `Diary`,
OrderDate: `2022-05-27`,
Units: 267,
UnitPrice: 16.55,
Price: 4418.85,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 204,
ParentID: 2,
Name: `Carrots`,
Category: `Vegetables`,
OrderDate: `2022-05-27`,
Units: 360,
UnitPrice: 2.77,
Price: 997.2,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 205,
ParentID: 2,
Name: `Apple Juice`,
Category: `Beverages`,
OrderDate: `2022-05-27`,
Units: 244,
UnitPrice: 5.38,
Price: 1312.72,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 3,
ParentID: -1,
Name: `Order 3`,
Category: ``,
OrderDate: `2022-08-04`,
Units: 1972,
UnitPrice: 3.47,
Price: 6849.18,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 301,
ParentID: 3,
Name: `Skimmed Milk 1L`,
Category: `Diary`,
OrderDate: `2022-08-04`,
Units: 1028,
UnitPrice: 3.56,
Price: 3659.68,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 302,
ParentID: 3,
Name: `Bananas 5 Pack`,
Category: `Fruit`,
OrderDate: `2022-08-04`,
Units: 370,
UnitPrice: 6.36,
Price: 2353.2,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 303,
ParentID: 3,
Name: `Cauliflower`,
Category: `Vegetables`,
OrderDate: `2022-08-04`,
Units: 283,
UnitPrice: 0.95,
Price: 268.85,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 304,
ParentID: 3,
Name: `White Chocolate Cookies`,
Category: `Cookies`,
OrderDate: `2022-08-04`,
Units: 291,
UnitPrice: 1.95,
Price: 567.45,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 4,
ParentID: -1,
Name: `Order 4`,
Category: ``,
OrderDate: `2023-01-04`,
Units: 1065,
UnitPrice: 5.56,
Price: 5923.5,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 401,
ParentID: 4,
Name: `Mini Milk Chocolate Cookie Bites`,
Category: `Cookies`,
OrderDate: `2023-01-04`,
Units: 68,
UnitPrice: 2.25,
Price: 153,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 402,
ParentID: 4,
Name: `Wild Salmon Fillets`,
Category: `Seafood`,
OrderDate: `2023-01-04`,
Units: 320,
UnitPrice: 16.15,
Price: 5168,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 403,
ParentID: 4,
Name: `Diet Lemonade`,
Category: `Beverages`,
OrderDate: `2023-01-04`,
Units: 437,
UnitPrice: 0.5,
Price: 218.5,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 404,
ParentID: 4,
Name: `Potatoes`,
Category: `Vegetables`,
OrderDate: `2023-01-04`,
Units: 240,
UnitPrice: 1.6,
Price: 384,
Delivered: true
}),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrTreeGridModule } from "@infragistics/igniteui-react-grids";
import { IgrTreeGrid, IgrColumn } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, WebTreeGridDescriptionModule } from "@infragistics/igniteui-react-core";
import { OrdersTreeDataItem, OrdersTreeData } from './OrdersTreeData';
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[] = [
IgrTreeGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private treeGrid: IgrTreeGrid
private treeGridRef(r: IgrTreeGrid) {
this.treeGrid = r;
this.setState({});
}
private column1: IgrColumn
constructor(props: any) {
super(props);
this.treeGridRef = this.treeGridRef.bind(this);
this.webTreeGridSummaryFormatter = this.webTreeGridSummaryFormatter.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrTreeGrid
autoGenerate={false}
data={this.ordersTreeData}
ref={this.treeGridRef}
id="treeGrid"
primaryKey="ID"
foreignKey="ParentID"
allowFiltering={true}
filterMode="excelStyleFilter">
<IgrColumn
field="ID"
header="Order ID"
sortable={true}>
</IgrColumn>
<IgrColumn
field="Name"
header="Order Product"
sortable={true}>
</IgrColumn>
<IgrColumn
field="Category"
header="Product Category"
sortable={true}>
</IgrColumn>
<IgrColumn
field="Units"
header="Units"
dataType="number"
sortable={true}>
</IgrColumn>
<IgrColumn
field="UnitPrice"
header="Unit Price"
dataType="number"
sortable={true}>
</IgrColumn>
<IgrColumn
field="Price"
header="Price"
dataType="number"
sortable={true}>
</IgrColumn>
<IgrColumn
field="OrderDate"
header="Order Date"
dataType="date"
hasSummary={true}
sortable={true}
summaryFormatter={this.webTreeGridSummaryFormatter}
name="column1">
</IgrColumn>
<IgrColumn
field="Delivered"
header="Delivered"
dataType="boolean"
sortable={true}>
</IgrColumn>
</IgrTreeGrid>
</div>
</div>
);
}
private _ordersTreeData: OrdersTreeData = null;
public get ordersTreeData(): OrdersTreeData {
if (this._ordersTreeData == null)
{
this._ordersTreeData = new OrdersTreeData();
}
return this._ordersTreeData;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebTreeGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webTreeGridSummaryFormatter(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
Child Summaries
IgrTreeGrid
루트 노드와 각 중첩된 자식 노드 수준에 대해 별도의 요약을 지원합니다. 표시되는 요약은 속성을 사용하여 구성할 수 있습니다 summaryCalculationMode
. 자식 수준 요약은 summaryPosition
속성을 사용하여 자식 노드 앞이나 뒤에 표시할 수 있습니다. 이 두 가지 속성 IgrTreeGrid
과 함께 exposes 및 showSummaryOnCollapse
property를 사용하면 참조하는 부모 노드가 축소될 때 요약 행이 계속 표시되는지 여부를 확인할 수 있습니다.
summaryCalculationMode
속성의 사용 가능한 값은 다음과 같습니다.
RootLevelOnly
- 요약은 루트 수준 노드에 대해서만 계산됩니다.ChildLevelsOnly
- 요약은 하위 수준에 대해서만 계산됩니다.RootAndChildLevels
- 루트 및 하위 수준 모두에 대한 요약이 계산됩니다. 이것이 기본값입니다.
summaryPosition
속성의 사용 가능한 값은 다음과 같습니다.
Top
- 요약 행은 하위 행 목록 앞에 나타납니다.Bottom
- 요약 행은 하위 행 목록 뒤에 나타납니다. 이 값은 기본값입니다.
showSummaryOnCollapse
속성은 부울입니다. 기본값은 false로 설정됩니다. 즉, 상위 행이 축소되면 요약 행이 숨겨집니다. 속성이 true로 설정되면 상위 행이 축소될 때 요약 행이 계속 표시됩니다.
The summaryPosition property applies only for the child level summaries. The root level summaries appear always fixed at the bottom of the IgrTreeGrid.
export class OrdersTreeDataItem {
public constructor(init: Partial<OrdersTreeDataItem>) {
Object.assign(this, init);
}
public ID: number;
public ParentID: number;
public Name: string;
public Category: string;
public OrderDate: string;
public Units: number;
public UnitPrice: number;
public Price: number;
public Delivered: boolean;
}
export class OrdersTreeData extends Array<OrdersTreeDataItem> {
public constructor(items: Array<OrdersTreeDataItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new OrdersTreeDataItem(
{
ID: 1,
ParentID: -1,
Name: `Order 1`,
Category: ``,
OrderDate: `2010-02-17`,
Units: 1844,
UnitPrice: 3.73,
Price: 6884.38,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 101,
ParentID: 1,
Name: `Chocolate Chip Cookies`,
Category: `Cookies`,
OrderDate: `2010-02-17`,
Units: 834,
UnitPrice: 3.59,
Price: 2994.06,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 102,
ParentID: 1,
Name: `Red Apples`,
Category: `Fruit`,
OrderDate: `2010-02-17`,
Units: 371,
UnitPrice: 3.66,
Price: 1357.86,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 103,
ParentID: 1,
Name: `Butter`,
Category: `Diary`,
OrderDate: `2010-02-17`,
Units: 260,
UnitPrice: 3.45,
Price: 897,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 104,
ParentID: 1,
Name: `Potato Chips`,
Category: `Snack`,
OrderDate: `2010-02-17`,
Units: 118,
UnitPrice: 1.96,
Price: 231.28,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 105,
ParentID: 1,
Name: `Orange Juice`,
Category: `Beverages`,
OrderDate: `2010-02-17`,
Units: 261,
UnitPrice: 5.38,
Price: 1404.18,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 2,
ParentID: -1,
Name: `Order 2`,
Category: ``,
OrderDate: `2022-05-27`,
Units: 1831,
UnitPrice: 8.23,
Price: 15062.77,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 201,
ParentID: 2,
Name: `Frozen Shrimps`,
Category: `Seafood`,
OrderDate: `2022-05-27`,
Units: 120,
UnitPrice: 20.45,
Price: 2454,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 202,
ParentID: 2,
Name: `Ice Tea`,
Category: `Beverages`,
OrderDate: `2022-05-27`,
Units: 840,
UnitPrice: 7,
Price: 5880,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 203,
ParentID: 2,
Name: `Fresh Cheese`,
Category: `Diary`,
OrderDate: `2022-05-27`,
Units: 267,
UnitPrice: 16.55,
Price: 4418.85,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 204,
ParentID: 2,
Name: `Carrots`,
Category: `Vegetables`,
OrderDate: `2022-05-27`,
Units: 360,
UnitPrice: 2.77,
Price: 997.2,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 205,
ParentID: 2,
Name: `Apple Juice`,
Category: `Beverages`,
OrderDate: `2022-05-27`,
Units: 244,
UnitPrice: 5.38,
Price: 1312.72,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 3,
ParentID: -1,
Name: `Order 3`,
Category: ``,
OrderDate: `2022-08-04`,
Units: 1972,
UnitPrice: 3.47,
Price: 6849.18,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 301,
ParentID: 3,
Name: `Skimmed Milk 1L`,
Category: `Diary`,
OrderDate: `2022-08-04`,
Units: 1028,
UnitPrice: 3.56,
Price: 3659.68,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 302,
ParentID: 3,
Name: `Bananas 5 Pack`,
Category: `Fruit`,
OrderDate: `2022-08-04`,
Units: 370,
UnitPrice: 6.36,
Price: 2353.2,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 303,
ParentID: 3,
Name: `Cauliflower`,
Category: `Vegetables`,
OrderDate: `2022-08-04`,
Units: 283,
UnitPrice: 0.95,
Price: 268.85,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 304,
ParentID: 3,
Name: `White Chocolate Cookies`,
Category: `Cookies`,
OrderDate: `2022-08-04`,
Units: 291,
UnitPrice: 1.95,
Price: 567.45,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 4,
ParentID: -1,
Name: `Order 4`,
Category: ``,
OrderDate: `2023-01-04`,
Units: 1065,
UnitPrice: 5.56,
Price: 5923.5,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 401,
ParentID: 4,
Name: `Mini Milk Chocolate Cookie Bites`,
Category: `Cookies`,
OrderDate: `2023-01-04`,
Units: 68,
UnitPrice: 2.25,
Price: 153,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 402,
ParentID: 4,
Name: `Wild Salmon Fillets`,
Category: `Seafood`,
OrderDate: `2023-01-04`,
Units: 320,
UnitPrice: 16.15,
Price: 5168,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 403,
ParentID: 4,
Name: `Diet Lemonade`,
Category: `Beverages`,
OrderDate: `2023-01-04`,
Units: 437,
UnitPrice: 0.5,
Price: 218.5,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 404,
ParentID: 4,
Name: `Potatoes`,
Category: `Vegetables`,
OrderDate: `2023-01-04`,
Units: 240,
UnitPrice: 1.6,
Price: 384,
Delivered: true
}),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrPropertyEditorPanelModule } from "@infragistics/igniteui-react-layouts";
import { IgrTreeGridModule } from "@infragistics/igniteui-react-grids";
import { IgrPropertyEditorPanel, IgrPropertyEditorPropertyDescription } from "@infragistics/igniteui-react-layouts";
import { IgrTreeGrid, IgrColumn } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, PropertyEditorPanelDescriptionModule, WebTreeGridDescriptionModule } from "@infragistics/igniteui-react-core";
import { OrdersTreeDataItem, OrdersTreeData } from './OrdersTreeData';
import { IgrPropertyEditorPropertyDescriptionChangedEventArgs } from "@infragistics/igniteui-react-layouts";
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,
IgrTreeGridModule
];
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 summaryCalculationModeEditor: IgrPropertyEditorPropertyDescription
private summaryPositionEditor: IgrPropertyEditorPropertyDescription
private showSummaryOnCollapseEditor: IgrPropertyEditorPropertyDescription
private treeGrid: IgrTreeGrid
private treeGridRef(r: IgrTreeGrid) {
this.treeGrid = r;
this.setState({});
}
constructor(props: any) {
super(props);
this.propertyEditorPanel1Ref = this.propertyEditorPanel1Ref.bind(this);
this.webTreeGridChangeSummaryCalculationMode = this.webTreeGridChangeSummaryCalculationMode.bind(this);
this.webTreeGridChangeSummaryPosition = this.webTreeGridChangeSummaryPosition.bind(this);
this.treeGridRef = this.treeGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="options vertical">
<IgrPropertyEditorPanel
componentRenderer={this.renderer}
target={this.treeGrid}
descriptionType="WebTreeGrid"
isHorizontal="true"
isWrappingEnabled="false"
ref={this.propertyEditorPanel1Ref}>
<IgrPropertyEditorPropertyDescription
name="SummaryCalculationModeEditor"
label="Summary Calculation Mode"
valueType="EnumValue"
dropDownNames={["rootLevelOnly", "childLevelsOnly", "rootAndChildLevels"]}
dropDownValues={["rootLevelOnly", "childLevelsOnly", "rootAndChildLevels"]}
changed={this.webTreeGridChangeSummaryCalculationMode}>
</IgrPropertyEditorPropertyDescription>
<IgrPropertyEditorPropertyDescription
name="SummaryPositionEditor"
label="Summary Position"
valueType="EnumValue"
dropDownNames={["top", "bottom"]}
dropDownValues={["top", "bottom"]}
changed={this.webTreeGridChangeSummaryPosition}>
</IgrPropertyEditorPropertyDescription>
<IgrPropertyEditorPropertyDescription
label="Show summary row when group row is collapsed:"
propertyPath="ShowSummaryOnCollapse"
name="ShowSummaryOnCollapseEditor">
</IgrPropertyEditorPropertyDescription>
</IgrPropertyEditorPanel>
</div>
<div className="container fill">
<IgrTreeGrid
autoGenerate={false}
data={this.ordersTreeData}
ref={this.treeGridRef}
id="treeGrid"
primaryKey="ID"
foreignKey="ParentID">
<IgrColumn
field="ID"
header="Order ID"
sortable={true}>
</IgrColumn>
<IgrColumn
field="Name"
header="Order Product"
hasSummary={true}>
</IgrColumn>
<IgrColumn
field="UnitPrice"
header="Price"
dataType="number"
hasSummary={true}
editable={true}>
</IgrColumn>
<IgrColumn
field="Delivered"
dataType="boolean">
</IgrColumn>
<IgrColumn
field="OrderDate"
header="Order Date"
dataType="date">
</IgrColumn>
</IgrTreeGrid>
</div>
</div>
);
}
private _ordersTreeData: OrdersTreeData = null;
public get ordersTreeData(): OrdersTreeData {
if (this._ordersTreeData == null)
{
this._ordersTreeData = new OrdersTreeData();
}
return this._ordersTreeData;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
PropertyEditorPanelDescriptionModule.register(context);
WebTreeGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webTreeGridChangeSummaryCalculationMode(sender: any, args: IgrPropertyEditorPropertyDescriptionChangedEventArgs): void {
var treeGrid = this.treeGrid;
treeGrid.summaryCalculationMode = args.newValue;
}
public webTreeGridChangeSummaryPosition(sender: any, args: IgrPropertyEditorPropertyDescriptionChangedEventArgs): void {
var treeGrid = this.treeGrid;
treeGrid.summaryPosition = args.newValue;
}
}
// 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
Keyboard Navigation
요약 행은 다음 키보드 상호 작용을 통해 탐색할 수 있습니다.
- UP- 한 셀 위로 이동합니다.
- DOWN- 한 셀 아래로 이동합니다.
- 왼쪽- 한 셀 왼쪽으로 이동합니다.
- RIGHT- 한 셀 오른쪽으로 이동합니다.
- CTRL + LEFT 또는 HOME- 가장 왼쪽 셀로 이동합니다.
- CTRL + RIGHT 또는 END- 가장 오른쪽 셀로 이동합니다.
Styling
사전 정의된 테마 외에도 사용 가능한 CSS 속성 중 일부를 설정하여 그리드를 추가로 사용자 정의할 수 있습니다. 일부 색상을 변경하려면 먼저 그리드에 대한 클래스를 설정해야 합니다.
<IgrTreeGrid className="grid">
</IgrTreeGrid>
tsx
그런 다음 해당 클래스에 대한 관련 CSS 속성을 설정합니다.
.grid {
--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
Demo
export class OrdersTreeDataItem {
public constructor(init: Partial<OrdersTreeDataItem>) {
Object.assign(this, init);
}
public ID: number;
public ParentID: number;
public Name: string;
public Category: string;
public OrderDate: string;
public Units: number;
public UnitPrice: number;
public Price: number;
public Delivered: boolean;
}
export class OrdersTreeData extends Array<OrdersTreeDataItem> {
public constructor(items: Array<OrdersTreeDataItem> | number = -1) {
if (Array.isArray(items)) {
super(...items);
} else {
const newItems = [
new OrdersTreeDataItem(
{
ID: 1,
ParentID: -1,
Name: `Order 1`,
Category: ``,
OrderDate: `2010-02-17`,
Units: 1844,
UnitPrice: 3.73,
Price: 6884.38,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 101,
ParentID: 1,
Name: `Chocolate Chip Cookies`,
Category: `Cookies`,
OrderDate: `2010-02-17`,
Units: 834,
UnitPrice: 3.59,
Price: 2994.06,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 102,
ParentID: 1,
Name: `Red Apples`,
Category: `Fruit`,
OrderDate: `2010-02-17`,
Units: 371,
UnitPrice: 3.66,
Price: 1357.86,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 103,
ParentID: 1,
Name: `Butter`,
Category: `Diary`,
OrderDate: `2010-02-17`,
Units: 260,
UnitPrice: 3.45,
Price: 897,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 104,
ParentID: 1,
Name: `Potato Chips`,
Category: `Snack`,
OrderDate: `2010-02-17`,
Units: 118,
UnitPrice: 1.96,
Price: 231.28,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 105,
ParentID: 1,
Name: `Orange Juice`,
Category: `Beverages`,
OrderDate: `2010-02-17`,
Units: 261,
UnitPrice: 5.38,
Price: 1404.18,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 2,
ParentID: -1,
Name: `Order 2`,
Category: ``,
OrderDate: `2022-05-27`,
Units: 1831,
UnitPrice: 8.23,
Price: 15062.77,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 201,
ParentID: 2,
Name: `Frozen Shrimps`,
Category: `Seafood`,
OrderDate: `2022-05-27`,
Units: 120,
UnitPrice: 20.45,
Price: 2454,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 202,
ParentID: 2,
Name: `Ice Tea`,
Category: `Beverages`,
OrderDate: `2022-05-27`,
Units: 840,
UnitPrice: 7,
Price: 5880,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 203,
ParentID: 2,
Name: `Fresh Cheese`,
Category: `Diary`,
OrderDate: `2022-05-27`,
Units: 267,
UnitPrice: 16.55,
Price: 4418.85,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 204,
ParentID: 2,
Name: `Carrots`,
Category: `Vegetables`,
OrderDate: `2022-05-27`,
Units: 360,
UnitPrice: 2.77,
Price: 997.2,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 205,
ParentID: 2,
Name: `Apple Juice`,
Category: `Beverages`,
OrderDate: `2022-05-27`,
Units: 244,
UnitPrice: 5.38,
Price: 1312.72,
Delivered: false
}),
new OrdersTreeDataItem(
{
ID: 3,
ParentID: -1,
Name: `Order 3`,
Category: ``,
OrderDate: `2022-08-04`,
Units: 1972,
UnitPrice: 3.47,
Price: 6849.18,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 301,
ParentID: 3,
Name: `Skimmed Milk 1L`,
Category: `Diary`,
OrderDate: `2022-08-04`,
Units: 1028,
UnitPrice: 3.56,
Price: 3659.68,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 302,
ParentID: 3,
Name: `Bananas 5 Pack`,
Category: `Fruit`,
OrderDate: `2022-08-04`,
Units: 370,
UnitPrice: 6.36,
Price: 2353.2,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 303,
ParentID: 3,
Name: `Cauliflower`,
Category: `Vegetables`,
OrderDate: `2022-08-04`,
Units: 283,
UnitPrice: 0.95,
Price: 268.85,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 304,
ParentID: 3,
Name: `White Chocolate Cookies`,
Category: `Cookies`,
OrderDate: `2022-08-04`,
Units: 291,
UnitPrice: 1.95,
Price: 567.45,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 4,
ParentID: -1,
Name: `Order 4`,
Category: ``,
OrderDate: `2023-01-04`,
Units: 1065,
UnitPrice: 5.56,
Price: 5923.5,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 401,
ParentID: 4,
Name: `Mini Milk Chocolate Cookie Bites`,
Category: `Cookies`,
OrderDate: `2023-01-04`,
Units: 68,
UnitPrice: 2.25,
Price: 153,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 402,
ParentID: 4,
Name: `Wild Salmon Fillets`,
Category: `Seafood`,
OrderDate: `2023-01-04`,
Units: 320,
UnitPrice: 16.15,
Price: 5168,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 403,
ParentID: 4,
Name: `Diet Lemonade`,
Category: `Beverages`,
OrderDate: `2023-01-04`,
Units: 437,
UnitPrice: 0.5,
Price: 218.5,
Delivered: true
}),
new OrdersTreeDataItem(
{
ID: 404,
ParentID: 4,
Name: `Potatoes`,
Category: `Vegetables`,
OrderDate: `2023-01-04`,
Units: 240,
UnitPrice: 1.6,
Price: 384,
Delivered: true
}),
];
super(...newItems.slice(0));
}
}
}
tsimport React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrTreeGridModule } from "@infragistics/igniteui-react-grids";
import { IgrTreeGrid, IgrColumn } from "@infragistics/igniteui-react-grids";
import { ComponentRenderer, WebTreeGridDescriptionModule } from "@infragistics/igniteui-react-core";
import { OrdersTreeDataItem, OrdersTreeData } from './OrdersTreeData';
import { IgrColumnTemplateContext } 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[] = [
IgrTreeGridModule
];
mods.forEach((m) => m.register());
export default class Sample extends React.Component<any, any> {
private treeGrid: IgrTreeGrid
private treeGridRef(r: IgrTreeGrid) {
this.treeGrid = r;
this.setState({});
}
private column1: IgrColumn
private column2: IgrColumn
private column3: IgrColumn
private column4: IgrColumn
private column5: IgrColumn
private column6: IgrColumn
private column7: IgrColumn
constructor(props: any) {
super(props);
this.treeGridRef = this.treeGridRef.bind(this);
}
public render(): JSX.Element {
return (
<div className="container sample ig-typography">
<div className="container fill">
<IgrTreeGrid
autoGenerate={false}
data={this.ordersTreeData}
ref={this.treeGridRef}
id="treeGrid"
primaryKey="ID"
foreignKey="ParentID">
<IgrColumn
field="ID"
header="Order ID">
</IgrColumn>
<IgrColumn
field="Name"
header="Order Product"
hasSummary={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column1">
</IgrColumn>
<IgrColumn
field="Category"
header="Category"
hasSummary={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column2">
</IgrColumn>
<IgrColumn
field="Units"
header="Units"
dataType="number"
hasSummary={true}
editable={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column3">
</IgrColumn>
<IgrColumn
field="UnitPrice"
header="Unit Price"
dataType="number"
hasSummary={true}
editable={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column4">
</IgrColumn>
<IgrColumn
field="Price"
header="Price"
dataType="number"
hasSummary={true}
editable={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column5">
</IgrColumn>
<IgrColumn
field="Delivered"
header="Delivered"
dataType="boolean"
hasSummary={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column6">
</IgrColumn>
<IgrColumn
field="OrderDate"
header="Order Date"
dataType="date"
hasSummary={true}
headerTemplate={this.webTreeGridSummariesHeaderTemplate}
name="column7">
</IgrColumn>
</IgrTreeGrid>
</div>
</div>
);
}
private _ordersTreeData: OrdersTreeData = null;
public get ordersTreeData(): OrdersTreeData {
if (this._ordersTreeData == null)
{
this._ordersTreeData = new OrdersTreeData();
}
return this._ordersTreeData;
}
private _componentRenderer: ComponentRenderer = null;
public get renderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebTreeGridDescriptionModule.register(context);
}
return this._componentRenderer;
}
public webTreeGridSummariesHeaderTemplate = (props: { dataContext: IgrColumnTemplateContext }) => {
const column = (props.dataContext as any).column;
return (
<div>
<span style={{ float: 'left' }}>{column.field}</span>
<span style={{ float: 'right', color: column.hasSummary ? '#e41c77' : '' }} onPointerDown={(e: any) => this.toggleSummary(column)}>∑</span>
</div>
);
}
public toggleSummary(field: IgrColumn) {
if (field) {
field.hasSummary = !field.hasSummary;
(this as any).setState({ summary: field.hasSummary });
}
}
}
// 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 */
#treeGrid {
--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 References
Additional Resources
우리 커뮤니티는 활동적이며 항상 새로운 아이디어를 환영합니다.