그룹 · 집계 플러그인
그룹 · 집계 · groupingPlugin
표시 중인 행을 지정한 필드 순서로 묶고 각 그룹의 행 수와 합계·평균·최소·최대를 표시합니다.
설치 함수: groupingPlugin(config) · 해제 이름: grouping
설정 속성 · 기본값
필수값은 해당 입력에서 반드시 제공하는 값입니다. 조건부 필수값은 설명에 적힌 기능을 사용할 때 필요합니다. 표시가 없는 옵션은 생략할 수 있으며 기본값을 사용합니다. 빈 문자열·누락과 0·false를 혼동하지 마세요.
| 설정 | 기본값 | 설명 |
|---|---|---|
fields 조건부 필수값 | [] | 그룹 필드 배열입니다. 첫 필드가 상위 그룹이며 다음 필드가 하위 그룹입니다. 그룹을 표시할 때 그룹 기준 필드를 1개 이상 지정합니다. []이면 그룹 없이 원래 행을 표시합니다. |
aggregates | [] | {field,type,label} 배열입니다. field는 집계할 데이터 컬럼입니다. |
aggregates[].field 조건부 필수값 | 없음 | 집계할 데이터 컬럼의 field입니다. aggregates에 집계 항목을 추가하면 각 항목에 대상 field를 지정합니다. aggregates 자체는 생략할 수 있습니다. |
aggregates[].type | sum | sum/avg/min/max 중 하나입니다. 숫자로 변환할 수 있는 값을 집계합니다. |
aggregates[].label | field 값 | 그룹 행에 표시할 집계 제목입니다. |
사용 순서
- 그룹 대상 컬럼과 숫자 집계 컬럼을 구성합니다.
- fields에 그룹 순서, aggregates에 집계 항목을 지정합니다. 초기에는 그룹을 펼쳐 표시합니다.
- 그룹의 +/− 버튼으로 전환하고 검색·필터 뒤 표시 행을 기준으로 바뀌는 집계를 확인합니다.
연결 API
| 호출 / 인수 | 반환값 | 동작 | 사용 예 |
|---|---|---|---|
grid.toggleGroup(key) | undefined | 그룹을 접거나 펼칩니다. key는 해당 그룹 값 경로를 JSON.stringify한 문자열입니다. 예: JSON.stringify(["제품","서울"]). | grid.toggleGroup(key) 필수값 |
설치 · 해제 · Vue 3 수명주기
생성 시 plugins에 등록하거나, 아직 설치하지 않은 인스턴스에서 grid.install을 호출합니다. 같은 name은 중복 설치할 수 없습니다. 설정에 쓰는 데이터·함수는 아래 전체 예제 소스를 참고하세요.
grid.install(groupingPlugin({
fields: ['category', 'region'],
aggregates: [{ field: 'qty', type: 'sum', label: '수량 합계' }],
}));
grid.uninstall('grouping'); // 플러그인 해제
// Vue 3 컴포넌트가 종료될 때
onBeforeUnmount(() => grid.destroy());그룹 view 변환을 제거하고 설치 전 toggleGroup을 복원합니다. 실제 데이터에 그룹 합계 행을 삽입하지 않습니다.
관련 이벤트
- render
이벤트 구독은 grid.on(name, (detail, grid) => {})를 사용합니다. 해제 함수 또는 grid.off로 구독을 정리하세요.
실행 예제 · 실제 원본
아래 소스는 examples/features/group.js와 Vue 원본입니다. 해당 예제 경로를 기준으로 import하며, 행 데이터는 별도 파일을 함께 사용합니다.
JavaScript 예제 실행 ↗ · Vue 3 예제 실행 ↗ · 행 데이터 원본
JavaScript 전체 소스 · group.js
import { ZixoGrid, groupingPlugin } from '../../src/index.js';
import { rows } from './group.data.js';
const host = document.querySelector('#grid'),
report = document.querySelector('#report');
const options = {
rowKey: 'id',
height: 360,
rows: rows,
columns: [
{ field: 'category', title: '분류' },
{ field: 'region', title: '지역' },
{ field: 'name', title: '주문' },
{ field: 'qty', title: '수량' },
{
field: 'scrollRowKey',
title: '참조 · 행 키',
width: 360,
editable: false,
sortable: false,
format: (_value, row) => String(row.id ?? row.code ?? row.name ?? ''),
},
{
field: 'scrollName',
title: '참조 · 이름',
width: 360,
editable: false,
sortable: false,
format: (_value, row) => String(row.name ?? ''),
},
{
field: 'scrollCategory',
title: '참조 · 분류 / 지역',
width: 360,
editable: false,
sortable: false,
format: (_value, row) =>
String(row.category ?? row.region ?? row.status ?? ''),
},
{
field: 'scrollNote',
title: '참조 · 상세 문구',
width: 360,
editable: false,
sortable: false,
format: (_value, row) =>
String(row.note ?? row.description ?? row.name ?? ''),
},
],
plugins: [
groupingPlugin({
fields: ['category', 'region'],
aggregates: [{ field: 'qty', type: 'sum', label: '수량 합계' }],
}),
],
};
const grid = new ZixoGrid(host, options);
window.addEventListener('pagehide', () => grid.destroy(), { once: true });
grid.on(
'validationerror',
(detail) => (report.textContent = detail.error.message),
);
report.textContent =
'분류→지역별로 묶고 각 그룹 합계를 표시합니다. +/−로 접고 펼칩니다.';
Vue 3 전체 소스 · vue-group.vue
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { ZixoGrid, groupingPlugin } from '../../src/index.js';
import { rows } from './group.data.js';
// Instance and DOM belong to this component, never to window or a global ID.
const gridHost = ref(null);
const message = ref('');
let grid;
let alive = true;
onMounted(() => {
const options = {
rowKey: 'id',
height: 360,
rows: rows,
columns: [
{ field: 'category', title: '분류' },
{ field: 'region', title: '지역' },
{ field: 'name', title: '주문' },
{ field: 'qty', title: '수량' },
{
field: 'scrollRowKey',
title: '참조 · 행 키',
width: 360,
editable: false,
sortable: false,
format: (_value, row) => String(row.id ?? row.code ?? row.name ?? ''),
},
{
field: 'scrollName',
title: '참조 · 이름',
width: 360,
editable: false,
sortable: false,
format: (_value, row) => String(row.name ?? ''),
},
{
field: 'scrollCategory',
title: '참조 · 분류 / 지역',
width: 360,
editable: false,
sortable: false,
format: (_value, row) =>
String(row.category ?? row.region ?? row.status ?? ''),
},
{
field: 'scrollNote',
title: '참조 · 상세 문구',
width: 360,
editable: false,
sortable: false,
format: (_value, row) =>
String(row.note ?? row.description ?? row.name ?? ''),
},
],
plugins: [
groupingPlugin({
fields: ['category', 'region'],
aggregates: [{ field: 'qty', type: 'sum', label: '수량 합계' }],
}),
],
};
grid = new ZixoGrid(gridHost.value, options);
grid.on(
'validationerror',
(detail) => (message.value = detail.error.message),
);
message.value =
'분류→지역별로 묶고 각 그룹 합계를 표시합니다. +/−로 접고 펼칩니다.';
});
onBeforeUnmount(() => {
alive = false;
grid?.destroy(); // Cancels grid requests, removes events and releases plugins.
grid = undefined;
});
defineExpose({ getGrid: () => grid });
</script>
<template>
<main>
<h1>다단 그룹 · 그룹 집계</h1>
<div ref="gridHost" class="vue-grid-host"></div>
<div class="notes result" aria-live="polite">{{ message }}</div>
</main>
</template>
제약 사항 · 주의할 동작
- tree와 동시에 설치할 수 없습니다.
- sum/avg/min/max를 지원하며 사용자 지정 집계 함수와 Pivot은 제공하지 않습니다.
- 그룹 키는 행 rowKey가 아니라 그룹 값 경로입니다. 집계 대상은 현재 view의 행이며 전체/선택 Summary와 별개입니다.