ag-grid-community 事始め

# はじめに

　高機能な表組み表示を求められ、グリッド表示ライブラリを試しております。
　AG Grid（[公式サイトのデモページ](https://www.ag-grid.com/example/)）がすごかったので、例に組み込んでみることにしました。
　使用するのは、"ag-grid-community"のバージョンは 27.3.0 です。

# 構築手順

　fetchしたjsonを加工して表示する、という前提で説明をしていきます。

## パッケージ追加

　[JavaScript Data Grid: Install AG Grid with NPM](https://www.ag-grid.com/javascript-data-grid/npm/)のページに従って、npmコマンドを駆使してパッケージ追加します。
　package.json には「"ag-grid-community": "^27.3.0",」が増えました。

> npm install --save ag-grid-community

## カラムの定義(1)：最低限必要な項目

　[JavaScript Data Grid: Column Definitions](https://www.ag-grid.com/javascript-data-grid/column-definitions/)のページ周辺の情報に従って、`const gridOptions`を定義していきます。

```javascript
const gridOptions = {
    columnDefs: [
        { headerName: '番号', field: 'num', },
        { headerName: '地域', field: 'area', },
        { headerName: '市町村', field: 'city', },
    ],
}
```
　最小限ひとつのカラムにおいて、`{headerName: '番号', field: 'num',}`などとheaderNameとfieldを定義します。
　**headerName:** はヘッダーに表示するカラム名になります。これを省いてしまうと、field: で指定したものが表示されてしまいます。
　**field:** はカラムの識別子になります。jsonでデータを与えるときにfield:でマッチングします。

## カラムの定義(2)：カラムのグルーピング

```javascript
const gridOptions = {
    columnDefs: [
        { headerName: '番号', field: 'num', },
        { headerName: '地域', field: 'area', },
        { headerName: '住所', children: [
            { headerName: '都道府県', field: 'prefecture', },
            { headerName: '市区町村', field: 'city', },
        ],},
    ],
}
```
　**children:** を使えば、カラムの定義をネストできます。

## カラムの定義(3)：右寄せ

　[JavaScript Data Grid: Cell Styles](https://www.ag-grid.com/javascript-data-grid/cell-styles/)に従って、セルでの見せ方を工夫できます。
　数値データは右寄せしたいもの。簡単に対処するには、cellStyle:を追加します。
　**cellStyle:** を使うと、対象のカラムのセルにてCSSを適用できます。

```javascript
const gridOptions = {
    columnDefs: [
        { headerName: '番号', field: 'num', cellStyle: { textAlign: 'right' }, },
        { headerName: '地域', field: 'area', },
        { headerName: '住所', children: [
            { headerName: '都道府県', field: 'prefecture', },
            { headerName: '市区町村', field: 'city', },
        ],},
    ],
}
```

　セルのデータ由来でスタイリングを切り替えたい場合には、アロー演算子で記述できますので、[該当のドキュメント](https://www.ag-grid.com/javascript-data-grid/cell-styles/)を参照してください。

　直接CSSをJSでの書き方で記述するのが cellStyle: なら、CSS定義したクラスで記述するのが cellClass: です。
　**cellClass:** を使うと、CSSにて定義済みクラス名を記述できます。上記の例なら、数字用のスタイルクラスを定義しておいて記述できますね。

## データの定義

　今回はGeoJSONデータに付帯している、FeatureごとのPropertiesをまるっと与えることにしました。

```javascript
    // json に既にパースしてあるGeoJSONデータが入っている、として
    const rowData = json.features.map(f => f.properties);
```

　FeatureごとのPropertiesに記述してあるキーを、予めcolumnDefsに方に記述してあるので、お手軽です。

## 仕上げ（カラム全体の定義ほか）

　'ag-grid-community'を使えるようにする場面は、例えばこんな感じ。

```javascript
import { Grid } from 'ag-grid-community';
import "../node_modules/ag-grid-community/dist/styles/ag-grid.scss";
import "../node_modules/ag-grid-community/dist/styles/ag-theme-material.css";
```
　'ag-grid-community'だけのimportだけじゃなく、スタイルシートの適用も忘れずに。

```javascript
    const gridOptions = {
        defaultColDef: {
            resizable: true,  // カラム幅可変に
            sortable: true,  // ソート可能に
            filter: true,  // 絞り込み可能に
        },
        columnDefs: columnDefs,
        rowData: rowData,
    };
    const gridDiv = document.querySelector('#targetElementId');
    new Grid(gridDiv, gridOptions);
    gridOptions.columnApi.autoSizeAllColumns();
```

　これで、初期表示時点で自動的にカラム幅がだいたい調整され、手動でのカラム幅調整もでき、ドラッグ操作によるカラム順序の入替えもできて、ソートもできて、絞り込みもできております。

　カラムごとにresizable:、sortable:、filter:を記述しても良いです。
　defaultColDef: にて sortable: true, にしておきつつ、個別のカラム定義で sortable: false, にすると記述が楽かも。

## カラム幅をいい感じにピッタリさせたい

　Excelで全カラムを選択してから、カラムヘッダーの境目をダブルクリックしたような、余白を最小限に抑えた表示をさせたいですよね。
　`gridOptions`に、`suppressColumnVirtualisation: true,`を加えます。　カラム表示の仮想化を無効にすることで、表示されていないカラムが処理対象から外れるのを防ぎます。
　さらに、`gridOptions`に、`onFirstDataRendered:`のイベント処理を加えます。　`columnApi.autoSizeAllColumns()`を呼ぶことでカラムごとの幅自動調整が働きます。

```javascript
    const gridOptions = {
        defaultColDef: {
            resizable: true,  // カラム幅可変に
            sortable: true,  // ソート可能に
            filter: true,  // 絞り込み可能に
        },
        columnDefs: columnDefs,
        rowData: rowData,
        suppressColumnVirtualisation: true,  // カラム仮想化をさせないことで、autoSizeAllColumns()が全カラムに効く！
        onFirstDataRendered: event => {
            event.columnApi.autoSizeAllColumns(false);  // カラムヘッダーも含めてオートサイズを実行
        },
    };
```

# さいごに

　ここでは説明を省きましたが、実際にはjsモジュール化してたり、表示先を[jsPanel v4](https://jspanel.de/)で表示されるフローティングウィンドウにしております。つい同僚にも見せびらかしてしまいました。
　'ag-grid-community'ユーザーさんとつながりたいです。情報共有していきましょう。