Guest post: mzPivotGrid: Ext JS用ピボットテーブル
こんにちは、ゼノフィkotsutsumiです。
Guest Blog Post
At mzSolutions ではExt JSとSencha Touchのコンポーネント開発に関わっています。 このブログ投稿では、Sencha Ext JSでmzPivotGridを利用する方法を説明します。
ピボットグリッドとは何か
Ext JSのグリッドパネルは大きいデータセットを完璧に表示し、様々な種類のデータを表示することができるたくさんの機能を提供しています。 提供していないデータの表示形式の一つがピボットグリッドです。 レポートを作成する時、 ピボットグリッド を使うという手があります。 データを整理しまとめてレポートを生成できるようになりますし、その上データについてユーザーがより詳しい判断ができるようになります。
mzPivotGridとは何か
mzPivotGridはExt JSでピボットグリッドを生成できるコンポーネントです。 次のシナリオを想像しましょう。 次のようなフィールドがある売上データがあります:国、販売員、注文日、注文数量、注文ID。 このデータを編集したい場合は、単純にExt JSのGridPanelにCellEditingやRowEditingプラグインをつけるだけです。

もし次のような質問に答えなければならないとしたらどうしますか?
- 各販売員の注文数量はいくつ?
- 指定した国での各販売員の注文数量はいくつ?
- 指定した年の販売員の成績は?
mzPivotGridを使えばそういったレポートを生成する事ができます。次のように表示されます:



mzPivotGridを使う
mzPivotGridはExt JS Grid Panelコンポーネントを継承しているので、慣れ親しんだ機能のほとんどが利用できます:列のリサイズ、ロック、セルのrenderers、セルや行のイベントなど。 mzPivotGridはデフォルトのGridPanelが提供しないピボット機能や合計が欲しいときに利用できます。
データセットを販売員と年で分析するには、topAxisとleftAxisを設定するだけです:
1 2 3 4 5 6 7 8 9 10 11 | leftAxis: [{ width: 80, dataIndex: 'salesperson', header: 'Salesperson' }], topAxis: [{ dataIndex: 'year', header: 'Year', direction: 'ASC' }] |
複数のレベルに対応していますので、topAxisとleftAxisに複数のフィールドを指定できます。 行や列をグループ分けするとよい場合があるとおもいます。 その際には”enableGrouping”をtrueに設定するだけです。
これでtopAxisとleftAxisにデータセットを分析しました。 次にセルの値を集計しましょう。 sum、avarage、min、max、countなどの、いくつかの種類の集計が使えます。 これで不足なら、自前で集計関数を提供することもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | aggregate: [{ measure: 'amount', header: 'Sales', aggregator: 'sum', align: 'right', width: 85, renderer: Ext.util.Format.numberRenderer('0,000.00') },{ measure: 'orderid', header: 'Qnt', aggregator: function(records, measure, matrix, rowGroupKey, colGroupKey) { // do your own algorithm return records.length; }, align: 'right', width: 85, renderer: Ext.util.Format.numberRenderer('0,000.00') }] |
上の例でお気づきのことと思いますが、 “sales”とか”quantity”とかの複数のデータフィールドを集計できます。 これは必要になる集計を全て設定すれば簡単に取得できます。

行や列の総合計を表示する設定も非常に単純です(“enableRowGrandTotals: true”または”enableColGrandTotals: true”と設定します)。 “enableRowSummary”や”enableColSummary”コンフィグでグループの合計も取ることができます。 スタイリングも簡単でセルのrenderersも定義できます。
ピボットグリッドはExt JSで使えるどのストアも利用できるので、データフィルタリングも非常に簡単で、ストアオブジェクト上でフィルタリングします。 これによりフィルタリングを管理するプラグインを実装することができます。
Ext JSのデータModelクラスは最高なので、独自のグループ間隔でデータを分析するためには、モデルを拡張して、パワフルな”convert”機能を使うといいでしょう。 次の例をご覧ください:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | fields: [ {name: 'orderid', type: 'int'}, {name: 'salesperson', type: 'string'}, {name: 'country', type: 'string'}, {name: 'orderdate', type: 'date', dateFormat: 'd/m/Y'}, {name: 'amount', type: 'int'}, { name: 'person-range', convert: function(v, record){ if(/^[a-j]/i.test(record.get('salesperson'))) return 'A-J'; if(/^[k-s]/i.test(record.get('salesperson'))) return 'K-S'; if(/^[t-z]/i.test(record.get('salesperson'))) return 'T-Z'; return v; } },{ name: 'year', convert: function(v, record){ return Ext.Date.format(record.get('orderdate'), "Y"); } } ] |
次のように表示されます:

サンプル利用事例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | var pivotGrid = Ext.create('Mz.pivot.Grid', { title: 'Pivot grid', height: 400, width: 600, enableLocking: false, enableGrouping: true, viewConfig: { trackOver: true, stripeRows: false }, store: store, aggregate: [{ measure: 'amount', header: 'Sales', aggregator: 'sum', align: 'right', width: 85, renderer: Ext.util.Format.numberRenderer('0,000.00') }], caption: 'Sales report', leftAxis: [{ width: 80, dataIndex: 'salesperson', header: 'Sales Person' }], topAxis: [{ dataIndex: 'year', header: 'Year', direction: 'ASC' }] }); |
今後
mzPivotGridは商用製品なので、常に新たなプラグインや機能で改善され続けます。 もし何か特別なものを実装する必要があれば、我々に連絡をして下さい。
mzPivotGridのライセンスについての詳細はこちらをクリックしてください。