Google Chart Tools - グラフと表の連携

今回は Google Chart Tools のグラフと表との連携です。
この表との連携や次回説明するフィルタリングが比較的簡単にかけることが Google Chart Tools の大きな利点の一つだと思います。

表とグラフでのデータの共有

連携の第一歩として同じデータで表とグラフを作成します。
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">

  google.load('visualization', '1', {packages:['corechart', 'table']});
  google.setOnLoadCallback(
      function() {
          // データ定義
           var data = new google.visualization.arrayToDataTable([
               ['名前', '給料'],
               ['Mike',  10000],
               ['Jim',   8000 ],
               ['Alice', 12500],
               ['Bob',   7000 ]
           ]);
   
           // テーブルの作成
           var formatter = new google.visualization.NumberFormat(
               {pattern: '$#,###'});
           formatter.format(data, 1);
   
           var table = new google.visualization.Table(
               document.getElementById('gct_combo_sample1_table'));
           table.draw(data, {showRowNumber: true});
   
   
           // グラフの作成
           var chart_option = {hAxis:{format:'$#,###'}};
           var chart = new google.visualization.BarChart(
               document.getElementById('gct_combo_sample1_chart'));
           chart.draw(data, chart_option);
       }
   );

</script>
<table>
  <tr><td>
        <div id="gct_combo_sample1_table" style="width:150pt;" ></div>
    </td><td>
        <div id="gct_combo_sample1_chart" style="width:250pt; height:120pt;" ></div>
  </td></tr>
</table>
サンプルでは一つのデータから表とグラフを作成しています。

注意点としては、パッケージはグラフ用の "corechart""table" を両方をロードしています。

また、 NumberFormat をデータに適用していますが、 テーブルの値にしか影響はありません。 グラフの表示には別途 format オプションを使っています。

DataView による表の特定列とグラフとのデータ共有

表とグラフのデータを共有する際、テーブル全体ではなく、 テーブル内の特定の列のみ利用したい場合があります。
こういう時には DataView を使用します。

DataView は DataTable を渡して生成し、 setColumns() メソッドで利用したい列を指定します。
DataView::setColumns(列番号の配列)
js_gct_dataview.png
この DataView のオブジェクトを指定された列を抜き出した DataTable として使うことができます。
// データ定義
var data = new google.visualization.arrayToDataTable([
    ['名前', '給料', 'フルタイム', '入社年度'],
    ['Mike',  10000, true,         2000],
    ['Jim',   8000,  false,        2002],
    ['Alice', 12500, true,         1998],
    ['Bob',   7000,  true,         2001]
]);


// テーブルの作成
var formatter = new google.visualization.NumberFormat(
    {pattern: '$#,###'});
formatter.format(data, 1);
var formatter_year = new google.visualization.NumberFormat(
    {pattern: '#### 年'});
formatter_year.format(data, 3);

var table = new google.visualization.Table(
    document.getElementById('gct_combo_sample2_table'));
table.draw(data, {showRowNumber: true});


// DataView の作成
var vdata = new google.visualization.DataView(data);
vdata.setColumns([0, 1]);


// グラフの作成
var chart_option = {hAxis:{format:'$#,###'}};
var chart = new google.visualization.BarChart(
    document.getElementById('gct_combo_sample2_chart'));
chart.draw(vdata, chart_option);
以前紹介したグラフ作成を簡易化する ChartWrapper を使うと、 DataView の作成を省略して記述することもできます。
var chart = new google.visualization.ChartWrapper({
    'chartType': 'BarChart',
    'containerId': 'gct_combo_sample2_chart',
    'options': {hAxis:{format:'$#,###'}},
    'dataTable': data,
    // DataView の設定
    'view': {
        'columns': [0, 1]
    }
});
chart.draw();

連携

データを共有しただけでは、まだ連携とまでは言えません。 ここから表とグラフを連携させていきましょう。
連携できるのは次の 2 つです。
  1. 表のソート
  2. 選択
これらの連携には Google Chart Tools のイベント機能を利用します。
Google Chart Tools のグラフ(テーブル)では選択などの何らかのアクションを起こした時にイベントが発生します。 このイベントには addListener 関数を使ってコールバック関数の登録ができます。
登録されたコールバック関数はイベント発生時に呼び出されるので、 ここで連携用の処理を行います。

ソート

表をソートすると 'sort' イベントが発生します。
このイベントのコールバック関数内で表に合わせてデータをソートし、グラフを再描画します。
// データ定義
var data = new google.visualization.arrayToDataTable([
    ['名前', '給料', 'フルタイム', '入社年度'],
    ['Mike',  10000, true,         2000],
    ['Jim',   8000,  false,        2002],
    ['Alice', 12500, true,         1998],
    ['Bob',   7000,  true,         2001]
]);

// テーブルの作成
var formatter = new google.visualization.NumberFormat(
    {pattern: '$#,###'});
formatter.format(data, 1);
var formatter_year = new google.visualization.NumberFormat(
    {pattern: '#### 年'});
formatter_year.format(data, 3);

var table_option = {showRowNumber: true};
var table = new google.visualization.Table(
    document.getElementById('gct_combo_sample3_table'));
table.draw(data, table_option);


// DataView の作成
var vdata = new google.visualization.DataView(data);
vdata.setColumns([0, 1]);


// グラフの作成
var chart_option = {hAxis:{format:'$#,###'}};
var chart = new google.visualization.BarChart(
    document.getElementById('gct_combo_sample3_chart'));
chart.draw(vdata, chart_option);


// テーブルの sort イベントでグラフをソートする関数を呼び出す。
google.visualization.events.addListener(table, 'sort', function(event) {
    // イベントが発生した列でデータをソート(DataView ではない)
    data.sort([{column: event.column, desc: !event.ascending}]);
    // 再描画
    chart.draw(vdata, chart_option);
    
    // テーブルの選択状態をクリア
    table.setSelection(null);
});

なお、表の項目を選択したままソートするとデータだけ順番を変えるため、 選択対象がずれてしまいます。
これを保持するには対象の位置を調べて選択し直す必要があります。 ちょっと手間がかかるので、ソート後は選択状態を解除しています。

選択

選択の連携ではわかりやすいように、 まず組織図のサンプルで説明したいと思います。
Google Chart Tools で図を選択状態にするためには、setSelection() メソッドを実行します。
表を選択すると 'select' イベントが発生するので、 このとき、表の選択情報を getSelection() で取得し、グラフの setSelection() メソッドを呼び出します。
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
</script>

google.load('visualization', '1', {packages: ['orgchart', 'table']});
google.setOnLoadCallback(
    function () {
        var data = new google.visualization.DataTable();
        data.addColumn('string', '名前');
        data.addColumn('string', '管理者');
        data.addColumn('number', '給料');
        data.addColumn('boolean', 'フルタイム');
        data.addRows([
            ['Mike',  null,   {v: 20000, f: '$20,000'}, true ],
            ['Jim',   'Mike', {v: 8000,  f: '$8,000'},  true ],
            ['Alice', 'Mike', {v: 12500, f: '$12,500'}, false],
            ['Bob',   'Jim',  {v: 7000,  f: '$7,000'},  true ]
        ]);

        var org_view = new google.visualization.DataView(data);
        org_view.setColumns([0, 1]);
        
        var orgchart = new google.visualization.OrgChart(
            document.getElementById('gct_sample_orgchart_demo'));
        orgchart.draw(org_view, null);

        var table_view = new google.visualization.DataView(data);
        table_view.setColumns([0, 2, 3]);
        
        var table = new google.visualization.Table(
            document.getElementById('gct_sample_orgchart_demo_table'));
        table.draw(table_view, null);
        
        // テーブル選択時に組織図を選択
        google.visualization.events.addListener(table, 'select', function() {
            orgchart.setSelection(table.getSelection());
        });
        
        // 組織図選択時にテーブルを選択
        google.visualization.events.addListener(orgchart, 'select', function() {
            table.setSelection(orgchart.getSelection());
        });
    }
);

<div style="overflow-x: auto; padding:1px; margin-bottom: 1.2em;"><table>
  <tr>
    <td>
      <div id="gct_sample_orgchart_demo" style="width: 220px;"></div>
    </td>
    <td>
      <div id="gct_sample_orgchart_demo_table" style="width: 250px;"></div>
    </td>
  </tr>
</table></div>

最初のサンプルに戻りましょう。
先に別のサンプルを使ったのは、 棒(Bar)グラフと表の選択に対する連携では簡単にはいかない点があるためです。
組織図の場合と同じように書くと 表 → グラフ の連携はうまくいくのですが、 グラフ → 表 は連携しません

この原因は選択情報がグラフと表で少し違うためです。
棒(Bar)グラフのような多くのグラフでは、 getSelection() で取得される選択情報はデータテーブル上の行と列の番号を持ったオブジェクトの配列です。 これに対し、表は行のみの情報を持ったオブジェクトの配列です。

このため、表の選択時にはそのまま渡すのではなく、 一度列情報を消してからデータを渡すようにします。
 // テーブルで選択された時にグラフを選択する
 google.visualization.events.addListener(table, 'select', function() {
     chart.setSelection(table.getSelection());
 });
 
 // グラフで選択された時にテーブルを選択する
 google.visualization.events.addListener(chart, 'select', function() {
     var selection = chart.getSelection();
     for (var i = 0; i < selection.length; i++) {
        // 列情報を除去
        selection[i].column = null;
     }    
     table.setSelection(selection);
 });
ちなみに組織図は表と同じ行のみの情報なので、この場合はそのまま渡すことができます。
また、選択情報が配列になっているのは、 Google Chart Tools の図が Ctrl や Shift キーによって複数選択ができるようになっているためです。

ソートと選択を同時に連携

ソートと選択を同時に連携しようとした場合、少し問題が生じます。
ソート時にデータをソートしてグラフを再描画するため、 表とグラフで選択した項目が一致しないようになります。

これを解決するためには、 データのソート後にグラフだけでなく、表も再描画します。


しかし、表を再描画すると今度は別の問題が発生します。
再描画するため、ソートの矢印マークが消えてしまいます

これを回避するためには、再描画時に矢印を表示するようにオプションで指定します。
// データ定義
var data = new google.visualization.arrayToDataTable([
    ['名前', '給料', 'フルタイム', '入社年度'],
    ['Mike',  10000, true,         2000],
    ['Jim',   8000,  false,        2002],
    ['Alice', 12500, true,         1998],
    ['Bob',   7000,  true,         2001]
]);


// テーブルの作成
var formatter = new google.visualization.NumberFormat(
    {pattern: '$#,###'});
formatter.format(data, 1);
var formatter_year = new google.visualization.NumberFormat(
    {pattern: '#### 年'});
formatter_year.format(data, 3);

var table_option = {showRowNumber: true};
var table = new google.visualization.Table(
    document.getElementById('gct_combo_sample5_table'));
table.draw(data, table_option);


// DataView の作成
var vdata = new google.visualization.DataView(data);
vdata.setColumns([0, 1]);


// グラフの作成
var chart_option = {hAxis:{format:'$#,###'}};
var chart = new google.visualization.BarChart(
    document.getElementById('gct_combo_sample5_chart'));
chart.draw(vdata, chart_option);


// テーブルで選択された時にグラフを選択する
google.visualization.events.addListener(table, 'select', function() {
    chart.setSelection(table.getSelection());
});

// グラフで選択された時にテーブルを選択する
 google.visualization.events.addListener(chart, 'select', function() {
     var selection = chart.getSelection();
     for (var i = 0; i < selection.length; i++) {
        // 列情報を除去
        selection[i].column = null;
     }    
     table.setSelection(selection);
 });
 
 // テーブルの sort イベントでグラフをソートする関数を呼び出す。
 google.visualization.events.addListener( table, 'sort', function(event) {
     // イベントが発生した列でデータをソート(DataView ではない)
     data.sort([{column: event.column, desc: !event.ascending}]);
 
     // グラフの再描画
     chart.draw(vdata, chart_option);
 
     // テーブルの再描画
     table_option['sortAscending'] = event.ascending; // ソート昇降順
     table_option['sortColumn'] = event.column; // ソート列
     table.draw(data, table_option);
 
     // テーブルの選択状態をクリア
     table.setSelection(null);
 });
関連記事
スポンサーサイト
Prev.    Category    Next 

Facebook コメント


コメント

コメントの投稿

Font & Icon
非公開コメント

このページをシェア
アクセスカウンター
アクセスランキング
[ジャンルランキング]
コンピュータ
24位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
3位
アクセスランキングを見る>>
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

02月 | 2017年03月 | 03月
- - - 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 -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。