5. 가상 필드와 그룹화
집계는 여러 원본을 하나의 숫자로 줄이는 계산입니다. 파생 필드는 각 원본 행에 사용할 값을 먼저 계산하고, 그룹화는 같은 차원 키를 묶는 작업입니다. 파생 필드로 판매금액을 만든 뒤 SUM으로 합산할 수 있습니다.
5.1 물리 필드로 그룹화
REGION, NAME, MODEL을 Rows에 놓으면 지점 아래 차종, 모델 계층이 생깁니다. Columns는 같은 방식으로 교차축을 구성합니다. 필드 순서와 해당 필드의 값 순서는 별개입니다.
// 지점, 차종별로 묶고 색상별 판매를 교차 비교합니다.
AUIPivot.setRowFields(pid, ["REGION", "NAME"]);
AUIPivot.setColumnFields(pid, ["COLOR"]);
AUIPivot.setValueFields(pid, [{dataField: "TOTAL", operation: "SUM"}]);
5.2 날짜 가상 필드
setDateTypeField에 DATE를 지정하면 DATE_YEAR, DATE_HALF, DATE_QTR, DATE_MONTH를 사용할 수 있습니다. 일(day)까지 표현된 날짜 자료를 사용하고 표시 라벨과 실제 날짜 차원 키를 구분합니다.
// 날짜 기준을 지정한 뒤 연도와 월을 열 차원으로 사용합니다.
AUIPivot.setDateTypeField(pid, "DATE");
AUIPivot.setColumnFields(pid, ["DATE_YEAR", "DATE_MONTH"]);
기본 정렬은 시간 순서입니다. 날짜의 표시 형식만 바꾸는 formatter와 날짜 단위로 묶는 이 설정은 서로 다릅니다. 자동차 판매 데모
5.3 일반 파생 필드와 의존성
setDerivedFields는 JSON 선언으로 add/subtract/multiply/divide 사칙연산을 등록합니다. operands는 정확히 두 개의 필드명 또는 유한 숫자 상수입니다. 다른 파생 필드를 참조할 수 있고 선언 순서는 관계없지만 순환 참조는 오류입니다.
// 자동차 원본에 없는 할인 가정은 원본 변경 대신 선언으로 계산합니다.
AUIPivot.setDerivedFields(pid, [
{dataField: "GROSS", labelText: "계산 판매금액",
expression: {operator: "multiply", operands: ["PRICE", "COUNT"]}},
{dataField: "DISCOUNT", labelText: "가정 할인액",
expression: {operator: "multiply", operands: ["GROSS", 0.05]}},
{dataField: "NET", labelText: "할인 후 금액",
expression: {operator: "subtract", operands: ["GROSS", "DISCOUNT"]}}
]);
AUIPivot.setValueFields(pid, [{dataField: "NET", operation: "SUM"}]);
0.05는 설명을 위한 할인 가정이며 실제 할인 실적이 아닙니다. 원가 COST가 있는 자료라면 PROFIT = TOTAL − COST를 같은 방식으로 정의할 수 있습니다.
- 원본 객체에 새 속성을 삽입하지 않습니다. 내부 행 뷰에서 필요한 파생값을 처음 읽을 때 계산, 캐시하고 재계산 때 새로 구성합니다.
- Rows, Columns, Values, Filters에서 등록한 dataField를 사용합니다. SUM/AVG/MEDIAN/분산 등은 같은 필드 값으로 집계됩니다.
- 유한 숫자와 비어 있지 않은 숫자 문자열만 계산합니다. null, 공백, boolean, Date, 객체, 비유한 수는 invalid이며 계산 invalid, 0 나누기, overflow는 null입니다. 기존 SUM의 변환 규칙과는 다릅니다.
- 물리/날짜 필드 이름 충돌, 중복, 예약 이름, 없는 참조, 순환 의존성은 오류입니다. eval, 문자열 수식, callback은 지원하지 않습니다.
- getSourceData/getCellDetailList는 원본 행을 반환하며 파생 속성을 추가한 객체를 반환하지 않습니다. 정의를 삭제하면 다음 재계산에서 관련 축, 값, 필터가 정리됩니다. 남은 파생 의존성도 함께 갱신하세요.
5.4 숫자 구간과 경계
PRICE를 가격대로 묶어 비교합니다. 아래 단위와 경계는 예제용이며 실제 사업의 가격 기준으로 바꾸세요.
// 가격은 [min, max)로 분류하며 필터, 업무 순서에는 labelText 대신 id를 사용합니다.
AUIPivot.setDerivedFields(pid, [{
dataField: "PRICE_BAND", labelText: "차량 가격대", sourceField: "PRICE",
ranges: [
{id: "low", min: 0, max: 2000000, labelText: "200만원 미만"},
{id: "mid", min: 2000000, max: 3000000, labelText: "200~300만원"},
{id: "high", min: 3000000, max: null, labelText: "300만원 이상"}
],
fallback: {id: "other", labelText: "기타"}
}]);
AUIPivot.setRowFields(pid, ["PRICE_BAND"]);
AUIPivot.setColumnFields(pid, ["REGION"]);
AUIPivot.setFilterFields(pid, ["PRICE_BAND"]);
AUIPivot.setValueFields(pid, [{dataField: "TOTAL", operation: "SUM"}]);
// 원본 입력 뒤 특정 가격대를 선택할 때 사용합니다.
// AUIPivot.setFilterCache(pid, {PRICE_BAND: ["mid"]});
| 경계 | 결과 |
|---|---|
| 1,999,999 | low |
| 2,000,000 | mid |
| 3,000,000 | high |
| 음수, invalid | other (fallback) |
하한은 포함하고 상한은 제외하는 [min,max)입니다. null/생략 경계는 열린 끝입니다. 겹치는 구간은 오류, gap은 허용하며 fallback이 없으면 null입니다. 숫자 판정은 일반 파생 계산과 같으므로 빈 문자열, null이 자동으로 0 구간에 들어가지 않습니다.
id는 중복 없는 식별자이며 같은 labelText라도 서로 다른 그룹입니다. 기본 정렬은 구간 정의 순서입니다. 단순 문자열 표시순에 의존하지 않습니다. 실제 필터 선택과 JSON에는 id를 저장합니다.
5.5 업무 기준 순서와 결과 정렬
// 명시한 가격대가 먼저 나오고 나머지는 기존 상대 순서를 유지합니다.
AUIPivot.setCustomValueOrders(pid, [
{dataField: "PRICE_BAND", values: ["high", "mid", "low"]}
]);
AUIPivot.updatePivot(pid);
우선순위는 Custom Value Order, 유효 Display Order Rule, Range 정의 순서, 기본 차원 순서입니다. 미지정 값은 뒤에 오며 기존 상대 순서를 보존합니다. 중복은 오류이고 []로 설정하면 해제됩니다. Rows, Columns의 각 부모와 필터 후보에 적용합니다.
업무 순서는 실제 raw key 또는 Range id로 지정합니다. 문자열, 유한 숫자, boolean, null을 지원하고 Date/undefined/객체는 지원하지 않습니다. 기존 그룹이 합치는 타입은 새 순서 기능이 분리하지 않습니다. 날짜 synthetic의 업무 순서에는 실제 키(월 예: _$M_01)를 사용합니다.
setDisplayOrderRules는 displayAutoAscending=false에서 source의 정렬 키를 지정합니다. setSorting은 완성된 결과 행 정렬이므로 적용 후 그 순서가 우선합니다. 집계 숫자와 원본 집합은 바뀌지 않습니다.
setCustomValueOrders, setDisplayOrderRules, setSorting, 자동차 판매 데모
5.6 필터, 패널, 저장과 복원
setDerivedFields는 전체 정의를 교체합니다. 계산, Range를 함께 쓰려면 한 배열에 모두 넣으세요. source/정의/필터 변경 후 재계산에서 파생 캐시를 새로 만듭니다. getDerivedFields는 깊은 사본이며 JSON으로 저장할 수 있습니다.
개별 API를 사용할 때는 파생 정의, 업무 순서, 날짜, 행, 열, 값, 필터, source, 필터 선택 순서를 사용합니다. getReportDefinition / setReportDefinition을 사용하면 정의, 순서, 필터가 보고서에 저장되고 의존 순서와 원자적 검증을 처리합니다. 원본 자료와 callback은 보고서에 포함되지 않습니다. 수식 정의가 있으면 V4, 없으면 V3로 저장합니다. 2.8.0부터 집계 후 자유 수식을 정의하고 표시할 값과 별도로 저장할 수 있습니다.
패널에서 API로 등록한 필드를 이동, 제거, 재추가할 수 있습니다. 전용 계산식/구간 편집기는 제공하지 않습니다. 별칭 setFieldAlias가 labelText보다 우선합니다. 파생, 구간 통합 예제
5.7 보고서 설정 저장과 복원
getReportDefinition은 현재 설정의 독립 사본을 반환합니다. 사본을 수정해도 화면은 바뀌지 않으며 setReportDefinition으로 적용합니다.
| 항목 | 저장 내용 |
|---|---|
| rows, columns, values, filters | 행, 열, 값, 필터 배치 |
| filterSelections | 선택한 필터값. 슬라이서 선택도 같은 항목에 저장합니다. |
| derivedFields, customValueOrders | 파생 필드, 숫자 구간 정의와 항목 순서 |
| options 등 보고서 옵션 | 날짜, 정렬, 레이아웃, 서식과 별칭 등의 설정 |
원본 데이터, 함수, 셀 선택, 스크롤과 시각화 설정은 포함하지 않습니다. 사용자 집계는 ID, 버전, 옵션을 저장하므로 복원 대상에도 같은 계산 정의를 먼저 등록합니다. 시각화는 별도로 저장합니다.
다른 피벗에 복원할 때는 보고서에서 사용하는 필드가 있는 데이터를 준비합니다. 설정을 먼저 복원한 뒤 setGridData로 원본을 넣거나, 원본이 있는 피벗에 설정을 복원할 수 있습니다. 설정 전체를 교체하며 잘못된 버전, 필드, 연산 등의 검증에 실패하면 기존 설정을 유지합니다.