AG Grid
JavaScript 기반으로 그리드를 손쉽게 그려주는 라이브러리입니다.
react, vue, angular를 모두 지원하고, 복잡한 그리드를 비교적 쉽게 그릴 수 있게 도와줍니다.
AG Grid사용해보기
다음의 명령어로 ag-grid 디펜던시를 설치합니다.
npm install --save ag-grid-community
npm install --save ag-grid-react
package.json에서 디펜던시가 설치된 모습을 확인할 수 있습니다.
"dependencies": {
"ag-grid-community": "29.0.0",
"ag-grid-react": "29.0.0",
...
ag-grid-community는 그리드 코어 로직이며
ag-grid-react는 리액트 렌더링 엔진입니다. 리액트 기반으로 ag grid를 그리기 위해서 두 디펜던시 모두 필요하며 두개 버전이 꼭 같아야 합니다.
AG Grid 예제
다음은 AG Grid 공식문서에서 가져온 예제 코드와 렌더링된 결과입니다. 주요 개념 위주로 살펴보겠습니다.
import React, { useState, useRef, useEffect, useMemo, useCallback} from 'react';
import { render } from 'react-dom';
import { AgGridReact } from 'ag-grid-react'; // the AG Grid React Component
import 'ag-grid-community/styles/ag-grid.css'; // Core grid CSS, always needed
import 'ag-grid-community/styles/ag-theme-alpine.css'; // Optional theme CSS
const App = () => {
const gridRef = useRef(); // Optional - for accessing Grid's API
const [rowData, setRowData] = useState(); // Set rowData to Array of Objects, one Object per Row
// Each Column Definition results in one Column.
const [columnDefs, setColumnDefs] = useState([
{field: 'make', filter: true},
{field: 'model', filter: true},
{field: 'price'}
]);
// DefaultColDef sets props common to all Columns
const defaultColDef = useMemo( ()=> ({
sortable: true
}));
// Example of consuming Grid Event
const cellClickedListener = useCallback( event => {
console.log('cellClicked', event);
}, []);
// Example load data from sever
useEffect(() => {
fetch('https://www.ag-grid.com/example-assets/row-data.json')
.then(result => result.json())
.then(rowData => setRowData(rowData))
}, []);
// Example using Grid's API
const buttonListener = useCallback( e => {
gridRef.current.api.deselectAll();
}, []);
return (
<div>
{/* Example using Grid's API */}
<button onClick={buttonListener}>Push Me</button>
{/* On div wrapping Grid a) specify theme CSS Class Class and b) sets Grid size */}
<div className="ag-theme-alpine" style={{width: 500, height: 500}}>
<AgGridReact
ref={gridRef} // Ref for accessing Grid's API
rowData={rowData} // Row Data for Rows
columnDefs={columnDefs} // Column Defs for Columns
defaultColDef={defaultColDef} // Default Column Properties
animateRows={true} // Optional - set to 'true' to have rows animate when sorted
rowSelection='multiple' // Options - allows click selection of rows
onCellClicked={cellClickedListener} // Optional - registering for Grid Event
/>
</div>
</div>
);
};
export default App;
스타일 셋팅
임포트 문에서 ag-grid.css 는 꼭 필요한 css파일이고, ag-theme-alpine.css는 옵셔널한 그리드의 테마입니다.
https://www.ag-grid.com/react-data-grid/themes/
React Data Grid: Themes
The grid is styled with CSS, and a theme is simply a CSS class that applies styles to the grid. Download v29 of the best React Data Grid in the world now.
www.ag-grid.com
위 링크에서 적용 가능한 테마를 더 확인할 수 있습니다.
AgGridReact의 부모 div에 className 프롭스로 ag-theme-alpine을 주고, 스타일 프롭스도 주어서 그리드의 테마와 스타일을 설정할 수 있습니다.
AG Grid의 필수 프롭스
AgGridReact 컴포넌트로 그리드를 그릴 수 있는데 필수 프롭스는 다음과 같습니다.
- rowData
- columnDefs
데이터 셋팅(rowData 프롭스)
보통 위의 예제와 같이 useEffect에서 그리드에서 필요한 데이터를 미리 가져온 후 useState 훅으로 데이터를 변수에 셋해줍니다.
그리고 AgGridReact 컴포넌트 프롭의 rowData에 셋해준 데이터를 넘겨줍니다.
// Example load data from sever
useEffect(() => {
fetch('https://www.ag-grid.com/example-assets/row-data.json')
.then(result => result.json())
.then(rowData => setRowData(rowData))
}, []);
return (
...
<AgGridReact
...
rowData={rowData} />
...
);
열 정의(columnDefs 프롭스)
위의 예제에 headerName을 추가했습니다.
// Each Column Definition results in one Column.
const [columnDefs, setColumnDefs] = useState([
{headerName: 'Make', field: 'make', filter: true},
{headerName: 'Model', field: 'model', filter: true},
{headerName: 'Price', field: 'price'}
]);
columnDefs는 배열이고 각 원소들은 Object로 되어있습니다. 각각의 object는 headerName, field와 filter를 키로 가지고 있습니다.
headerName은 열의 이름으로, 화면에 표시됩니다.
field는 rowData 프롭에 넘겨준 데이터에서 표시할 key 입니다.
예를 들어, rowData가 다음과 같고 메달의 골드 갯수를 열에 표시하고 싶다면
const rowData = [
{
athlete: 'Michael Phelps',
medals: {
gold: 8, silver: 1, bronze: 0
}
}
];
아래와 같이 field에 밸류로 'medals.gold'를 주면됩니다.
const columnDefs = [
{ field: 'athlete', headerName: 'Name' },
// Using dot notation to access nested property
{ field: 'medals.gold', headerName: 'Gold' },
];
다음은 렌더링된 결과입니다.
그리드 API 사용
Ref를 이용해서 AG Grid의 API에 접근할 수 있습니다.
const gridRef = useRef(); // Ref for accessing Grid's API
// Example using Grid's API
const buttonListener = useCallback( e => {
gridRef.current.api.deselectAll();
}, []);
return (
...
<button onClick={buttonListener}>Push Me</button>
<AgGridReact
...
rowData={rowData} />
...
);
gridRef.current.api.deselectAll();
위와 같이 gridRef를 이용하여 그리드 API를 호출할 수 있습니다.
deselectAll을 공식문서에서 검색해보면 필터링 여부와 상관없이 셀렉션을 모두 초기화하는 함수라는 것을 알 수 있습니다.
공식 문서에서는 이 외에도 컬럼 정의, 컬럼 헤더, 이벤트, 필터링, 페이지네이션, Row, 스크롤링, 셀렉션, 소팅 등
그리드를 컨트롤할 수 있는 다양한 API를 제공하고 있습니다.
Column에 대해서 더욱 디테일하게 컨트롤할 수 있는 columnApi도 별도로 제공하고 있습니다.
gridRef.current?.columnApi.getColumns();
공식 문서에서 어떤 인자를 받고 리턴형은 무엇이고 함수에 대한 설명까지 정리가 잘 되어 있습니다.
예를 들어 getColumns 함수의 경우 그리드의 모든 컬럼들을 Column 타입의 배열로 리턴하는 것을 알 수 있습니다.
이 뿐만 아니고 columnApi로 접근하여 Column Keys, Column Groups, Moving, Pinning, Pivoting, Sizing 등을 컨트롤 할 수 있습니다.
그리드의 다양한 옵션들
AgGridReact 컴포넌트의 프롭스를 어떻게 주냐에 따라서 그리드에 다양한 옵션들을 설정할 수 있습니다.
주로 쓰이는 <AgGridReact> 컴포넌트 관련되 프롭스는 다음과 같습니다.
rowSelection : 한번에 셀랙할 수 있는 갯수로, 'single'은 1개 'multiple'은 다중선택 의미
onCellClicked : 행 클릭시의 콜백함수
onRowDoubleClicked
ref : gird를 참조하는 ref로 추후에 이 ref를 이요해서 griddata api 호출 가능
트리 구조로 ag-grid 사용하기
girOptions을 선언해서
const gridOptions = useMemo(() => {
return {
gridRef,
rowData: [],
// defaultColDef,
//columnDefs
// defaultColDef: columnDefs,
autoGroupColumnDef: autoGroupColumnDef,
treeData: true,
//suppressCopyRowsToClipboard: true,
//enableRangeSelection: true,
//tooltipShowDelay: 100,
groupDefaultExpanded: 1,
rowSelection: "single",
getDataPath: (data: any) => data.treePath,
// onComponentStateChanged,
// onGridReady,
onCellClicked: onCellClicked,
// onSelectionChanged: onSelectionChanged,
getContextMenuItems,
// onRowDoubleClicked,
};
}, [isAdminMode]);
return (
<>
<DataGrid {...gridOptions} gridSize={{ height: "100%" }} />
</>
);
ag-grid 트리로 구현하기
트리 구조로도 ag-grid를 사용할 수 있습니다.
<AgGridReact
ref={gridRef} // Ref for accessing Grid's API
rowData={rowData} // Row Data for Rows
onCellClicked={cellClickedListener} // Optional - registering for Grid Event
treeData={true}
getDataPath: {(data: any) => data.treePath}
/>
treeData = true,
getDataPath는 데이터의 트리 구조를 배열에 담아 리턴합니다.
예를 들어
음식(0 depth)
-한식(1 depth)
--불고기(2 depth)
--비빔밥(2 depth)
--갈비찜(2 depth)
-양식(1 depth)
-중식(1 depth)
위와 같은 트리 구조에서 getDataPath는 아래와 같이 리턴합니다.
["음식"], ["음식", "한식"], ["음식", "한식", "불고기"], ["음식", "한식", "비빔밥"], ...,
ag-grid에서 컨텍스트 메뉴 구현하기
그리드 셀에서 우클릭하여 컨텍스트 메뉴를 보여줄 수도 있습니다.
<AgGridReact
...
getContextMenuItems={getContextMenuItems}
/>
GetContextMenuItemsParams와 MenuItemDef를 임포트합니다.
import {GetContextMenuItemsParams, MenuItemDef} from "ag-grid-community";
...
const getContextMenuItems = useCallback(
(params: GetContextMenuItemsParams): (string | MenuItemDef)[] => {
const result: (string | MenuItemDef)[] = [
{
name: "Create",
action: () => handleCreate(params.node ? params.node : null),
},
{
name: "Modify",
action: () => handleModify(params.node ? params.node : null),
},
{
name: "Delete",
action: () => handleDelete(params.node ? params.node : null),
},
];
return result;
},
);
다음과 같이 컨텍스트 메뉴를 생성할 수 있습니다.
'Front-End' 카테고리의 다른 글
[html]개행 표시하기 (0) | 2023.12.02 |
---|---|
[끄적끄적] CSS 스타일링 고민 (0) | 2023.11.20 |
vite 로컬에서 https 설정 (0) | 2023.08.20 |