268 lines
9.3 KiB
TypeScript
268 lines
9.3 KiB
TypeScript
import type { GridView, DataColumn } from "@/components/type/DataGrid.type";
|
|
|
|
// 그리드 푸터 합계 계산 함수 (계산 로직)
|
|
export const getFooterSummary = (grid: GridView, column: DataColumn) => {
|
|
// 데이터 소스에서 직접 합계 계산
|
|
const dataSource = grid.getDataSource();
|
|
const rowCount = dataSource.getRowCount();
|
|
let sum = 0;
|
|
|
|
for (let i = 0; i < rowCount; i++) {
|
|
const cellValue = dataSource.getValue(i, column.fieldName);
|
|
|
|
// 문자열인 경우 숫자로 변환
|
|
const numericValue = typeof cellValue === 'string'
|
|
? Number(String(cellValue).replace(/,/g, ''))
|
|
: Number(cellValue);
|
|
|
|
if (!isNaN(numericValue) && numericValue !== null && numericValue !== undefined) {
|
|
sum += numericValue;
|
|
}
|
|
}
|
|
|
|
return sum;
|
|
};
|
|
|
|
// 평균 계산 함수
|
|
export const getFooterAvgSummary = (grid: GridView, column: DataColumn) => {
|
|
const dataSource = grid.getDataSource();
|
|
const rowCount = dataSource.getRowCount();
|
|
|
|
let sum = 0;
|
|
let avg = 0;
|
|
|
|
for (let i = 0; i < rowCount; i++) {
|
|
const cellValue = dataSource.getValue(i, column.fieldName);
|
|
|
|
const numericValue = typeof cellValue === 'string'
|
|
? Number(String(cellValue).replace(/,/g, ''))
|
|
: Number(cellValue);
|
|
|
|
if (!isNaN(numericValue) && numericValue !== null && numericValue !== undefined) {
|
|
sum += numericValue;
|
|
}
|
|
}
|
|
|
|
avg = sum / rowCount;
|
|
|
|
return Math.floor(avg * 10) / 10;
|
|
}
|
|
|
|
// "구분" 필드의 고유값들을 찾는 함수 (첫 번째, 두 번째)
|
|
const getDivisionValues = (grid: GridView, divisionFieldName: string = '구분'): string[] => {
|
|
const dataSource = grid.getDataSource();
|
|
const rowCount = dataSource.getRowCount();
|
|
const uniqueValues = new Set<string>();
|
|
|
|
for (let i = 0; i < rowCount; i++) {
|
|
const divisionValue = dataSource.getValue(i, divisionFieldName);
|
|
if (divisionValue !== null && divisionValue !== undefined && divisionValue !== '') {
|
|
uniqueValues.add(String(divisionValue));
|
|
}
|
|
}
|
|
|
|
// Set을 배열로 변환하고 순서 유지
|
|
return Array.from(uniqueValues);
|
|
};
|
|
|
|
// "구분" 필드 값에 따라 필터링하여 합계 계산하는 함수
|
|
// divisionIndex: 0 = 첫 번째 고유값, 1 = 두 번째 고유값
|
|
export const getFooterSummaryByDivision = (
|
|
grid: GridView,
|
|
column: DataColumn,
|
|
divisionIndex: number,
|
|
divisionFieldName: string = '구분'
|
|
) => {
|
|
const dataSource = grid.getDataSource();
|
|
const rowCount = dataSource.getRowCount();
|
|
let sum = 0;
|
|
|
|
// "구분" 필드의 고유값 찾기
|
|
const divisionValues = getDivisionValues(grid, divisionFieldName);
|
|
if (divisionValues.length <= divisionIndex) {
|
|
return 0; // 해당 인덱스의 고유값이 없으면 0 반환
|
|
}
|
|
|
|
const targetDivision = divisionValues[divisionIndex];
|
|
|
|
for (let i = 0; i < rowCount; i++) {
|
|
// "구분" 필드 값 확인
|
|
const divisionValue = dataSource.getValue(i, divisionFieldName);
|
|
if (String(divisionValue) !== targetDivision) {
|
|
continue; // 해당 "구분" 값이 아니면 스킵
|
|
}
|
|
|
|
const cellValue = dataSource.getValue(i, column.fieldName);
|
|
|
|
// 문자열인 경우 숫자로 변환
|
|
const numericValue = typeof cellValue === 'string'
|
|
? Number(String(cellValue).replace(/,/g, ''))
|
|
: Number(cellValue);
|
|
|
|
if (!isNaN(numericValue) && numericValue !== null && numericValue !== undefined) {
|
|
sum += numericValue;
|
|
}
|
|
}
|
|
|
|
return sum;
|
|
};
|
|
|
|
// "구분" 필드 값에 따라 필터링하여 평균 계산하는 함수
|
|
// divisionIndex: 0 = 첫 번째 고유값, 1 = 두 번째 고유값
|
|
export const getFooterAvgSummaryByDivision = (
|
|
grid: GridView,
|
|
column: DataColumn,
|
|
divisionIndex: number,
|
|
divisionFieldName: string = '구분'
|
|
) => {
|
|
const dataSource = grid.getDataSource();
|
|
const rowCount = dataSource.getRowCount();
|
|
let sum = 0;
|
|
let count = 0;
|
|
|
|
// "구분" 필드의 고유값 찾기
|
|
const divisionValues = getDivisionValues(grid, divisionFieldName);
|
|
if (divisionValues.length <= divisionIndex) {
|
|
return 0; // 해당 인덱스의 고유값이 없으면 0 반환
|
|
}
|
|
|
|
const targetDivision = divisionValues[divisionIndex];
|
|
|
|
for (let i = 0; i < rowCount; i++) {
|
|
// "구분" 필드 값 확인
|
|
const divisionValue = dataSource.getValue(i, divisionFieldName);
|
|
if (String(divisionValue) !== targetDivision) {
|
|
continue; // 해당 "구분" 값이 아니면 스킵
|
|
}
|
|
|
|
const cellValue = dataSource.getValue(i, column.fieldName);
|
|
|
|
// 문자열인 경우 숫자로 변환
|
|
const numericValue = typeof cellValue === 'string'
|
|
? Number(String(cellValue).replace(/,/g, ''))
|
|
: Number(cellValue);
|
|
|
|
if (!isNaN(numericValue) && numericValue !== null && numericValue !== undefined) {
|
|
sum += numericValue;
|
|
count += 1;
|
|
}
|
|
}
|
|
|
|
if (count === 0) {
|
|
return 0;
|
|
}
|
|
|
|
const avg = sum / count;
|
|
return Math.floor(avg * 10) / 10;
|
|
};
|
|
|
|
// Footer 설정 객체 생성 함수
|
|
const createSumFooter = (format: string) => ({
|
|
expression: 'sum' as const,
|
|
numberFormat: format,
|
|
valueCallback: (grid: GridView, column: DataColumn) => {
|
|
return getFooterSummary(grid, column);
|
|
},
|
|
});
|
|
|
|
const createAvgFooter = (format: string) => ({
|
|
expression: 'avg' as const,
|
|
numberFormat: format,
|
|
valueCallback: (grid: GridView, column: DataColumn) => {
|
|
return getFooterAvgSummary(grid, column);
|
|
},
|
|
});
|
|
|
|
// "구분" 값에 따라 필터링하는 Footer 배열 생성 함수 (2줄)
|
|
const createSumFooterArrayByDivision = (format: string) => [
|
|
{
|
|
numberFormat: format,
|
|
valueCallback: (
|
|
grid: GridView,
|
|
column: DataColumn,
|
|
footerIndex: number,
|
|
columnFooter: unknown,
|
|
value: number | string | undefined
|
|
) => {
|
|
// footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값)
|
|
// footerIndex를 divisionIndex로 사용
|
|
return getFooterSummaryByDivision(grid, column, footerIndex);
|
|
},
|
|
},
|
|
{
|
|
numberFormat: format,
|
|
valueCallback: (
|
|
grid: GridView,
|
|
column: DataColumn,
|
|
footerIndex: number,
|
|
columnFooter: unknown,
|
|
value: number | string | undefined
|
|
) => {
|
|
// footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값)
|
|
// footerIndex를 divisionIndex로 사용
|
|
return getFooterSummaryByDivision(grid, column, footerIndex);
|
|
},
|
|
},
|
|
];
|
|
|
|
// "구분" 값에 따라 필터링하는 평균 Footer 배열 생성 함수 (2줄)
|
|
const createAvgFooterArrayByDivision = (format: string) => [
|
|
{
|
|
numberFormat: format,
|
|
valueCallback: (
|
|
grid: GridView,
|
|
column: DataColumn,
|
|
footerIndex: number,
|
|
columnFooter: unknown,
|
|
value: number | string | undefined
|
|
) => {
|
|
// footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값)
|
|
// footerIndex를 divisionIndex로 사용
|
|
return getFooterAvgSummaryByDivision(grid, column, footerIndex);
|
|
},
|
|
},
|
|
{
|
|
numberFormat: format,
|
|
valueCallback: (
|
|
grid: GridView,
|
|
column: DataColumn,
|
|
footerIndex: number,
|
|
columnFooter: unknown,
|
|
value: number | string | undefined
|
|
) => {
|
|
// footerIndex: 0 = 첫 번째 footer 행 (첫 번째 "구분" 값), 1 = 두 번째 footer 행 (두 번째 "구분" 값)
|
|
// footerIndex를 divisionIndex로 사용
|
|
return getFooterAvgSummaryByDivision(grid, column, footerIndex);
|
|
},
|
|
},
|
|
];
|
|
|
|
// 1. 정수형 : #,##0
|
|
export const footerInt = createSumFooter('#,##0');
|
|
|
|
// 2. 소수점 1자리 : #,##0.0
|
|
export const footerDecimal1 = createSumFooter('#,##0.0');
|
|
|
|
// 3. 소수점 2자리 : #,##0.00
|
|
export const footerDecimal2 = createSumFooter('#,##0.00');
|
|
|
|
// 4. 소수점 3자리 : #,##0.000
|
|
export const footerDecimal3 = createSumFooter('#,##0.000');
|
|
|
|
// "구분" 값에 따라 필터링하는 Footer 배열 (정수형, 2줄)
|
|
export const footerIntArrayByDivision = createSumFooterArrayByDivision('#,##0');
|
|
|
|
// "구분" 값에 따라 필터링하는 Footer 배열 (소수점 1자리, 2줄)
|
|
export const footerDecimal1ArrayByDivision = createSumFooterArrayByDivision('#,##0.0');
|
|
|
|
// "구분" 값에 따라 필터링하는 Footer 배열 (소수점 2자리, 2줄)
|
|
export const footerDecimal2ArrayByDivision = createSumFooterArrayByDivision('#,##0.00');
|
|
|
|
// "구분" 값에 따라 필터링하는 Footer 배열 (소수점 3자리, 2줄)
|
|
export const footerDecimal3ArrayByDivision = createSumFooterArrayByDivision('#,##0.000');
|
|
|
|
// 률(%) 평균 값(기본 소수점 1자리)
|
|
export const footerAvgDecimal = createAvgFooter('#,##0.0');
|
|
|
|
// "구분" 값에 따라 필터링하는 평균 Footer 배열 (소수점 1자리, 2줄)
|
|
export const footerAvgDecimalArrayByDivision = createAvgFooterArrayByDivision('#,##0.0'); |