notebook

都内でWEB系エンジニアやってます。

ag-gridでrow grouping

row groupingを実際にやってみた時のオプションなどのメモ

実際に使ったオプションなどの覚書なので結構雑になってます

全部みたいなら下記にサンプルコード付きで丁寧に乗っているのでこちらをみた方が良さそう

Grouping by Row: Core Feature of our Datagrid

www.ag-grid.com

enterpriseですが無料でお試し用のライセンスキーを発行できるので試してみてもいいかと思います

  • 動作環境
Angular: 5.1.3
ag-grid: 16.0.0
  • Row Grouping

特定の列にオプションをつけることで自動でグルーピングしてくれる

例えば「campaignName」フィールドでグルーピングしたい場合は下記のように「campaignName」のカラム定義にrowGroup: trueを追記する

columndefs = [
.....
.....
  {
    field: 'campaignname',
    rowgroup: true,
  }
.....
.....
]

グループ化された列の定義

autoGroupColumnDef

グループ化された列のカラム定義を指定する(テーブルに追加)、複数グループ化列がある場合は全てに対して適用される

  • component.html
<ag-grid-angular .....
                 .....
                 [autoGroupColumnDef]="autoGroupColumnDef"
                 .....
                 .....
  • component.ts
    this.autoGroupColumnDef = {
      width: 200,
      cellRenderer: 'agGroupCellRenderer',
      suppressFilter: false, //グループ化したデータの列に対してフィルタを有効にできる
      filterValueGetter: this.filterValueGetter, // グループ化した後の列に対してのフィルタ対象のデータの取得方法をコールバックで渡す
      valueGetter: this.filterValueGetter,
      cellRendererParams: {
        suppressCount: true, // 神奈川県(5) のようにグループ化してそのグループが何行データがあるかを知るためにデフォルトでカウントがされるようになっているのでそれをしないようにする
        // pivotなどと組み合わせる際にはよく使う
      }
    };

Grouping by Row: Core Feature of our Datagrid

複数の列をグループ化

groupMultiAutoColumn

グループ化カラムを複数列表示するか

これがない場合は単一列に複数のグループが表示される

ファイルエクスプローラのように少しインデントがずれて表示される

  • component.html
<ag-grid-angular .....
                 .....
                 [groupMultiAutoColumn]="true"
                 .....
                 .....

Grouping by Row: Core Feature of our Datagrid

集計

Aggregation: Enterprise Grade Feature of our Datagrid

上記のサンプルのようにグループ化した元の合計数値を出したい場合などもあると思います

そういった場合に集計関数を指定して集計結果をグループの親の行に表示させることができる

colDef.aggFuncで指定する

  • カラム定義
  {
    .....
    .....
    field: 'impression',
    aggFunc: 'sum'
    .....
    .....
  }

デフォルトで用意されている関数が sum, min, max, count, avg, first, lastがあるよう

だいたいはこれで事足りると思うのですが足りない場合はカスタムできます

関数を定義してcolDef.aggFuncにその関数を指定するだけです

this.hogeAggregateFunction(values) {
  //何かしらの集計
}

this.columnDefs = [
  {
    .....
    .....
    field: 'hoge',
    aggFunc: this.hogeAggregateFunction
    .....
    .....
  }
]

わたってくる値は(values)

その列の集計元となるデータが渡ってきます

ただ、広告の話でいうとCPAとかCVRとかそこらへんの集計はCost/CV,CV/Clickだったりするので該当の列のデータだけが渡ってきても計算できません。

そこでそれを解決するための機能が次のカスタム集計関数です

カスタム集計関数

groupRowAggNodes

全ての行に対して集計を適用する関数を定義する

設定方法は下記のようにコールバックを指定する

この設定はColDefじゃなくtable全体の設定に設定する

[groupRowAggNodes]="customAggregateNodes"
this.customAggregateNodes(nodes) {
  .....
  .....
  .....
  .....

  return {
    hoge: aggregatedHoge, // 「hoge」の集計結果
    fuga: aggregatedFuga, // 「fuga」の集計結果
  }
}

引数nodesを受け取ってそれを集計していく

こちらは集計対象の全てのノードを渡してくれる(厳密にいうとフィルター後の表示されているノード(gridOptions.api.forEachAfterFilterNodeで取得できるノードと同じ))

グループ内の全ノードのデータを受け取ってカスタムするカラムを返してあげるという感じになるようですね

この機能を使うとデフォルトの関数が適用されなくなるようなのでそれまで使っていたsumなどの実装もすべて自分で集計する必要があるようです

あと当然ながらグループノードがある場合そのグループの小ノード全てを渡す処理になるのでグループ化があればあるだけ処理が走ります

まぁしょうがないですね

Aggregation: Enterprise Grade Feature of our Datagrid

www.ag-grid.com

複数のグループ化を行なっている場合集計に使うデータの取得方法が違う

例えば下記のようなデータがあって

columnDefs = [
  {
    field: 'g1',
    rowGroup: true
  },
  {
    field: 'g2',
    rowGroup: true
  },
  {
    field: 'hoge',
    aggFunc: 'sum'
  }
]
// 実際のデータ
[
  {g1: 'piyo', g2: 'fuga', hoge: 1}
  {g1: 'piyo', g2: 'fuga', hoge: 1}
  {g1: 'piyo', g2: 'moge', hoge: 1}
  {g1: 'piyo', g2: 'moge', hoge: 2}
]

通常の集計であればよく使うnode.dataからデータを取得できる

node.data.hoge // 'g2'でのグループ合計を集計時のhogeの値
// g1: 'piyo', g2: fuga, => hoge: 2
// g1: 'piyo', g2: moge, => hoge: 3

グループ化されたノードのデータを使ってさらに集計する場合は

node.aggData.hoge // 'g1'でのグループ合計を集計時のhogeの値
// 一つ下のグルーピングの集計結果を元に集計する
// g1: 'piyo' => hoge: 5

といったようにnode.aggDataからデータを参照する必要がある

感想

aggregateに関してはもう少しやりたいことさせてよって感じの感想を持ったものの使いこなせれば楽できるのかなーといった感じを受けました