Google Chart Tools - 表とデータの扱い
今回は Google Chart Tools を使った表の作成と Google Chart でデータ(DataTable)の扱いについて説明します。
html で表が書けるのになぜわざわざ Google Chart Tools で表を書くの ? と思われるかも知れませんが、 Google Chart Tools の表では次のことが簡単にできます。
- ソート
- テーブル内に割合のバーなどを表示
- ページ分割(ページネーション)
- 他のグラフと連携
- フィルタリング
特にソートやフィルターでは、データを値と表示文字を分けて管理できるので、 文字列の比較ではなく、実際の値での比較ができるようになっています。
なお、他のグラフとの連携やフィルタリングについては次回以降に説明する予定です。 また、 Google Chart では DataTable を元にグラフを描画します。
表(のグラフ)は DataTable をそのまま表示しているようなものです。 Google Chart のデータの扱いの理解に表はちょうどいいのではないかと思います。
基本的な表の作成
まずは基本的な表の書き方を説明します。<html> <head> <script type='text/javascript' src='https://www.google.com/jsapi'></script> <script type='text/javascript'> google.load('visualization', '1', {packages:['table']}); google.setOnLoadCallback(drawTable); function drawTable() { var data = new google.visualization.DataTable(); data.addColumn('string', '名前'); data.addColumn('number', '給料'); data.addColumn('boolean', 'フルタイム'); data.addRows([ ['Mike', {v: 10000, f: '$10,000'}, true ], ['Jim', {v: 8000, f: '$8,000'}, false], ['Alice', {v: 12500, f: '$12,500'}, true ], ['Bob', {v: 7000, f: '$7,000'}, true ] ]); var table = new google.visualization.Table(document.getElementById('table_div')); table.draw(data, {showRowNumber: true}); } </script> </head> <body> <div id="table_div" style="width: 80%; "></div> </body> </html>前回の折れ線グラフと書き方はほぼ同じです。 違いは次のところです。
- ロードパッケージが 'table'
- 描画用クラスが google.visualization.Table
データを値と表示文字を分ける場合には、オブジェクトで指定します。 この場合 v が値で f が表示文字列です。
これ以外にも p で装飾を指定することもできます。 装飾に関しては 'className' で html タグのクラス名を指定できるので、 CSS で指定することもできます。
'style' で直接 CSS のスタイルも書けます。
データテーブル(DataTable)
Google Chart Tools で扱うデータは google.visualization.DataTable オブジェクトです。これは 2 次元のデータと列情報の配列を持ちます。 列情報ではラベルや列に格納するデータの型を保持します。
列情報にデータ型情報を持っているので、 同一の列では同じ型のみ格納できます。
データテーブルの作成は 3 つの方法があります。
- 空のオブジェクトを作成し、addColumn, addRows などでデータを格納
- JSON 形式で定義したデータから作成
- 2 次元配列から作成
2 番目は JSON スタイルでオブジェクトを作成し、 それを元に DataTable を作成する方法です。
記述が面倒なので、この形式でコード内に直接記述することはあまりないかもしれません。 ただし、 1 番目の方法に比べるとロードが速いので、 データの量が多い場合などではこちらの方がいいでしょう。
var dataAsJson = {cols:[ {id:'A',label:'名前',type:'string'}, {id:'B',label:'給料',type:'number'}, {id:'C',label:'フルタイム',type:'boolean'}], rows:[ {c:[{v:'Mike'},{v:10000,f:'$10,000'},{v:true,f:'TRUE'}]}, {c:[{v:'Jim'},{v:8000,f:'$8,000'},{v:false,f:'FALSE'}]}, {c:[{v:'Alice'},{v:12500,f:'$12,500'},{v:true,f:'TRUE'}]}, {c:[{v:'Bob'},{v:7000,f:'$7,000'},{v:true,f:'TRUE'}]}] }; var data = new google.visualization.DataTable(dataAsJson);前回の折れ線グラフの例では arrayToDataTable を使った二次元配列から作成する 3 番目の方法でした。
この場合、 1 列目からラベルを取得し、各列のデータから自動的に型を判定しています。 今回のサンプルを arrayToDataTable を使って作成すると次のようになります。
var data = new google.visualization.arrayToDataTable([ ['名前', '給料', 'フルタイム'], ['Mike', 10000, true ], ['Jim', 8000, false], ['Alice', 12500, true ], ['Bob', 7000, true ] ]);
ただし、表示文字と値を分けていません。 これは arrayToDataTable ではオブジェクトによる指定はできないためです。
二次元配列から作成するのが一番簡単ですが、 値と表示文字を分ける場合には addColumn, addRows 等を使うか JSON スタイルで作成する必要があります。
なお、 arrayToDataTable でもデータの先頭列(2 列目)以降であれば、 オブジェクトによる指定も可能です。
フォーマット
{v: 10000, f: '$10,000'}
のように似たものを
2 回書いたり、配列から DataTable が作れないのは面倒だなと感じたかもしれません。
こういった場合は Format の機能を使えます。また、 Format ではデータの表示を国際化することもできます。
国際化の言語はブラウザーの設定がデフォルトです。 これはパッケージロード時に明示的に変更することも可能です。
数値フォーマット
数値の場合には NumberFormat を使用します。var data = new google.visualization.arrayToDataTable([ ['名前', '給料', '到達率'], ['Mike', 10000, 0.2 ], ['Jim', 8000, 1.0], ['Alice', 12500, 0.9 ], ['Bob', 7000, 0.7 ] ]); var table = new google.visualization.Table(document.getElementById('gct_table_number_format')); // 2 列目のフォーマッター var formatter1 = new google.visualization.NumberFormat({pattern: '$#,###'}); formatter1.format(data, 1); // 3 列目のフォーマッター var formatter2 = new google.visualization.NumberFormat({pattern: '###%'}); formatter2.format(data, 2); table.draw(data, {showRowNumber: true});NumberFormat のインスタンス作成時に渡すオブジェクトで表示形式を指定します。
prefix や suffix といった要素もあるのですが、 pattern が指定されているとこちらが使用されます。 ここには 数値用の ICU のパターンを指定します。
日付フォーマット
日付の場合には DateFormat を使用します。var data = new google.visualization.DataTable(); data.addColumn('string', '雇用者名前'); data.addColumn('date', '開始日 (Long 表記)'); data.addColumn('date', '開始日 (Short 表記)'); data.addRows([ ['Mike', new Date(2008, 1, 28, 0, 31, 26), new Date(2008, 1, 28, 0, 31, 26)], ['Bob', new Date(2007, 5, 1, 0), new Date(2007, 5, 1, 0)], ['Alice', new Date(2006, 7, 16), new Date(2006, 7, 16)] ]); // フォーマッターの作成 var formatter_long = new google.visualization.DateFormat({formatType: 'long'}); var formatter_short = new google.visualization.DateFormat({formatType: 'short'}); // データを整形 formatter_long.format(data, 1); formatter_short.format(data, 2); // データを描画 var table = new google.visualization.Table(document.getElementById('gct_table_date_format')); table.draw(data, {showRowNumber: true});データには JavaScript の Date オブジェクトを格納し、 DateFormat で表示形式を指定します。
formatType には "long", "short" の他に "medium" もあります。 ただし、日本語では short と medium は同じです。
DateFormat を使わずにそのまま表示した場合も short です。
また、pattern で出力形式を詳細に設定することもできます。 この場合には 日付用の ICU のパターンを指定します。
ちなみに Google Chart Tools というよりも JavaScript の注意点があります。
日付は Date(年, 月, 日) と指定します。 この際、 年、日は一般的な 2012 や 1 - 31 といった数値を指定しますが、 月は 0(1 月) - 11(12 月) で指定します。
パターンフォーマット
複数の列から新しい列を作成する場合には PatternFormat を使用します。var data = new google.visualization.DataTable(); data.addColumn('string', '名前'); data.addColumn('string', 'E-Mail'); data.addRows([ ['John Lennon', 'john@beatles.co.uk'], ['Paul McCartney', 'paul@beatles.co.uk'], ['George Harrison', 'george@beatles.co.uk'], ['Ringo Starr', 'ringo@beatles.co.uk'] ]); var table = new google.visualization.Table(document.getElementById('gct_table_pattern_format_div')); var formatter = new google.visualization.PatternFormat('<a href="mailto:{1}">{0}</a>'); // フォーマッターで、 0, 1 の列のデータから作ったデータを 0 列に格納 formatter.format(data, [0, 1]); // 先頭(0)列のみ表示するように DataView を作成 var view = new google.visualization.DataView(data); view.setColumns([0]); // 渡すのは data ではなく、 view // allowHtml はテーブル内での html 記述許可の設定 table.draw(view, {allowHtml: true, showRowNumber: true});PatternFormat を使い、 2 つの列から新しいデータを作成し、 1 列目に格納しています。
PatternFormat::format(データ, 利用する列の列番号配列 [, 格納先の列番号]); // 格納先を省略した場合には利用した列に格納されますテーブルの描画には通常は DataTable を直接渡しますが、 表示する列を指定するために DataView を作成し、それを介して描画しています。
装飾系フォーマット
前章は表示文字を変更するための Format でしたが、 テーブル内にバーを表示するといった装飾的な機能も Format で実現します。バーフォーマット
テーブル内にバーを表示する場合には BarFormat を使用します。var data = new google.visualization.DataTable(); data.addColumn('string', '分類'); data.addColumn('number', '収入'); data.addRows([ ['靴', 10700], ['スポーツ', -15400], ['おもちゃ', 12500], ['電化製品', -2100], ['食品', 22600], ['美術品', 1100] ]); var table = new google.visualization.Table(document.getElementById('gct_table_bar_format')); // バーの幅を 120pt に設定。(デフォルトは 100) var formatter = new google.visualization.BarFormat({width: 120}); formatter.format(data, 1); // 2 番目の列に適用 table.draw(data, {allowHtml: true, showRowNumber: true});
矢印フォーマット
テーブル内に矢印を表示する場合には ArrowFormat を使用します。var data = new google.visualization.arrayToDataTable([ ['分類', '収益率'], ['靴', 0.12], ['スポーツ', -0.073], ['おもちゃ', 0], ['電化製品', -0.21], ['食品', 0.22] ]); var table = new google.visualization.Table(document.getElementById('gct_table_number_format')); // 数値フォーマットも使用 var num_formatter = new google.visualization.NumberFormat({pattern: '###.#%'}); num_formatter.format(data, 1); // 矢印フォーマット var formatter = new google.visualization.ArrowFormat(); formatter.format(data, 1); var table = new google.visualization.Table(document.getElementById('gct_table_arrow_format')); table.draw(data, {allowHtml: true, showRowNumber: true});
カラーフォーマット
セルの値に応じて色を変更する場合には ColorFormat を使用します。var data = new google.visualization.arrayToDataTable([ ['名前', '点数'], ['Mike', 38 ], ['Jim', 85], ['Alice', 52 ], ['Bob', 70 ] ]); var table = new google.visualization.Table(document.getElementById('gct_table_number_format')); // 数値のフォーマッターも使用 var formatter1 = new google.visualization.NumberFormat({suffix:'点'}); formatter1.format(data, 1); var formatter = new google.visualization.ColorFormat(); // 0 - 40 は白字に赤 formatter.addRange(0, 40, 'white', 'red'); // 40 - 80 は黄色から白への段階 formatter.addGradientRange(40, 80, null, 'yellow', 'white'); // 80 - 100 は青字 formatter.addRange(80, 100, 'blue', null); formatter.format(data, 1); table.draw(data, {allowHtml: true, showRowNumber: true});色と範囲の設定は次の関数を使います。
- addRange(開始値, 終了値, 文字色, 背景色)
- addGradientRange(開始値, 終了値, 文字色, 開始背景色, 終了背景色)
ちなみに段階的に文字色(前景色)を指定する関数はありません。
ページ分割
ページ分割(ページネーション, ページング) というのは、データがたくさんある場合に 一定数づつ分割して表示することを言います。個人的には一度に表示してスクロールで見る方が好きなのですが、 海外ではページ分割して表示するのが主流っぽいです。
ページ分割するにはテーブル描画のオプションでページ分割の設定を有効にします。
var data = new google.visualization.arrayToDataTable([ ['名前', '身長', '出席'], ['Dave', 159, true ], ['Peter', 185, false], ['John', 145, true ], ['Moshes', 198, true ], ['Karen', 169, true ], ['Phil', 169, false], ['Gori', 159, true ], ['Bill', 155, false], ['Valery', 199, true ], ['Joey', 187, true ], ['Karen', 190, true ], ['Jin', 169, false], ['Gili', 178, true ], ['Harry', 172, false], ['Handerson', 175, true ], ['Vornoy', 170, true ] ]); // ページ分割の設定 var options = { page: 'enable', // ページ分割を有効 pageSize: 5, // 1 ページの項目数 pagingSymbols: {prev: '前', next: '次'}, // ラベル }; options['showRowNumber'] = true; var table = new google.visualization.Table(document.getElementById('gct_table_pagenation')); table.draw(data, options);
Google Chart Tools - 動的なグラフの変更
Google Chart Tools では基本的にページのロード時にグラフの作成を行います。 今回は一度作成したグラフを動的に変更する方法についてです。
再描画(ブラウザーのリサイズへの対応)
Google Chart Tools では、 100%, 80% といったページサイズに合わせたグラフの作成が可能です。しかし、ブラウザーのサイズを変更した場合には、それに追従して再描画するところまでは行いません。
動的なグラフの変更の手始めとして、このブラウザーへのリサイズに合わせて再描画できるグラフを作成します。
ブラウザーのサイズを変更すると <body> で onresize イベントが発生します。
ここでグラフの再描画を行います。
<html> <head> <title> リサイズするグラフのサンプル </title> <script type="text/javascript" src="http://www.google.com/jsapi"></script> <script type="text/javascript"> google.load("visualization", "1", {packages:["corechart"]}); var resizable_chart; var resizable_options; var resizable_data; google.setOnLoadCallback( function () { resizable_data = google.visualization.arrayToDataTable([ [ '', '売上高', '営業利益', '経常利益'], ['2004', 1000, 400, 380], ['2005', 1170, 460, 400], ['2006', 660, 1120, 900], ['2007', 1030, 540, 480], ['2008', 1350, 750, 800], ['2009', 1205, 1010, 805], ['2010', 880, 585, 500], ['2011', 1450, 1300, 1005], ['2012', 1105, 770, 650], ]); resizable_options = { title: '会社業績' }; resizable_chart = new google.visualization.LineChart(document.getElementById('gct_resizable_chart')); resizable_chart.draw(resizable_data, resizable_options); } ); </script> </head> <body onresize="resizable_chart.draw(resizable_data, resizable_options);"> <div id='gct_resizable_chart' style="width=100%; height=200pt"></div> </body> </html>ここでポイントはデータ、グラフ、オプションの変数をグラフの作成関数の外で宣言しているところです。 これらの変数を使って onresize 時にグラフを描画しています。
オプションの変更(表のページ分割量の変更)
以前の記事で表のページ分割方法について説明しました。この際、 1 ページの項目数は固定でした。 項目数を変更できた方がユーザーは使いやすいでしょう。
グラフのオプションの変更のサンプルとして、このページ分割量を変更できるテーブルを作成します。
<script type="text/javascript" src="http://www.google.com/jsapi"></script> <script type="text/javascript"> google.load('visualization', '1', {packages: ['table']}); // 関数外で宣言 var visualization; var paging_data; var paging_options = {'showRowNumber': true}; function create_paging_table () { var dataAsJson = {cols:[ {id:'A',label:'名前',type:'string'}, {id:'B',label:'身長',type:'number'}, {id:'C',label:'出席',type:'boolean'}, {id:'D',label:'時刻',type:'timeofday'}], rows:[ {c:[{v:'Dave'},{v:159.0,f:'159'},{v:true,f:'TRUE'},{v:[12,25,0,0],f:'12:25:00'}]}, {c:[{v:'Peter'},{v:185.0,f:'185'},{v:false,f:'FALSE'},{v:[13,15,0,0],f:'13:15:00'}]}, {c:[{v:'John'},{v:145.0,f:'145'},{v:true,f:'TRUE'},{v:[15,45,0,0],f:'15:45:00'}]}, {c:[{v:'Moshes'},{v:198.0,f:'198'},{v:true,f:'TRUE'},{v:[16,32,0,0],f:'16:32:00'}]}, {c:[{v:'Karen'},{v:169.0,f:'169'},{v:true,f:'TRUE'},{v:[19,50,0,0],f:'19:50:00'}]}, {c:[{v:'Phil'},{v:169.0,f:'169'},{v:false,f:'FALSE'},{v:[18,10,0,0],f:'18:10:00'}]}, {c:[{v:'Gori'},{v:159.0,f:'159'},{v:true,f:'TRUE'},{v:[13,15,0,0],f:'13:15:00'}]}, {c:[{v:'Bill'},{v:155.0,f:'155'},{v:false,f:'FALSE'},{v:[7,40,48,0],f:'7:40:48'}]}, {c:[{v:'Valery'},{v:199.0,f:'199'},{v:true,f:'TRUE'},{v:[6,0,0,0],f:'6:00:00'}]}, {c:[{v:'Joey'},{v:187.0,f:'187'},{v:true,f:'TRUE'},{v:[5,2,24,0],f:'5:02:24'}]}, {c:[{v:'Karen'},{v:190.0,f:'190'},{v:true,f:'TRUE'},{v:[6,14,24,0],f:'6:14:24'}]}, {c:[{v:'Jin'},{v:169.0,f:'169'},{v:false,f:'FALSE'},{v:[5,45,36,0],f:'5:45:36'}]}, {c:[{v:'Gili'},{v:178.0,f:'178'},{v:true,f:'TRUE'},{v:[6,43,12,0],f:'6:43:12'}]}, {c:[{v:'Harry'},{v:172.0,f:'172'},{v:false,f:'FALSE'},{v:[6,14,24,0],f:'6:14:24'}]}, {c:[{v:'Handerson'},{v:175.0,f:'175'},{v:true,f:'TRUE'},{v:[6,57,36,0],f:'6:57:36'}]}, {c:[{v:'Vornoy'},{v:170.0,f:'170'},{v:true,f:'TRUE'},{v:[13,12,0,0],f:'13:12:00'}]}]}; paging_data = new google.visualization.DataTable(dataAsJson); paging_options['page'] = 'enable'; paging_options['pageSize'] = 5; paging_table = new google.visualization.Table(document.getElementById('gct_paging_table')); draw_paging_table(); } // テーブルの描画 function draw_paging_table() { paging_table.draw(paging_data, paging_options); } google.setOnLoadCallback(create_paging_table); // ページ分割時の項目数を設定 function setNumberOfPages(value) { if (value) { paging_options['pageSize'] = parseInt(value, 10); paging_options['page'] = 'enable'; } else { paging_options['pageSize'] = null; paging_options['page'] = null; } draw_paging_table(); } </script> <form action="" style="margin-top: 10px; margin-bottom: 5px; padding: 5px; border: 1px solid gray; background-color: buttonface;"> <span style="font-size:10pt;">表示する行数:</span> <select style="font-size:10pt;" onchange="setNumberOfPages(this.value)"> <option value="">すべて表示</option> <option value="3">3</option> <option selected="selected" value="5">5</option> <option value="7">7</option> <option value="10">10</option> </select> </form> <div id="gct_paging_table" style="width:400px; height:220px;"></div>リサイズ時の方法と同様に必要な変数をグラフ作成関数外で宣言し、 メニューの変更イベントで、オプションを変更して再描画しています。
データの変更(インタラクティブな計器図)
データテーブルは作成後も setValue() などのメソッドで値を変更することができます。DataTable::setValue(行番号, 列番号, 新しい値)データを変更して再描画を行うことによって、 動的にグラフを変更することが可能です。
// 行番号には列情報の行は含みません
サンプルとして動的に値を変更できる計器図の例を挙げます。
<script type="text/javascript" src="http://www.google.com/jsapi"></script> <script type="text/javascript"> google.load('visualization', '1', {packages: ['gauge']}); var dynamicGauge; var dynamicGaugeData; var dynamicGaugeOptions; // グラフの作成関数 function drawDynamicGauge() { dynamicGaugeData = google.visualization.arrayToDataTable([ ['Speed'], [70] ]); dynamicGauge = new google.visualization.Gauge(document.getElementById('gct_dynamic_gauge')); dynamicGaugeOptions = { max: 160, greenFrom: 40, greenTo: 60, yellowFrom: 60, yellowTo: 100, redFrom: 100, redTo: 160, minorTicks: 8 }; dynamicGauge.draw(dynamicGaugeData, dynamicGaugeOptions); } // データを変更する関数 function changeSpeed(dir) { var diff = dir * 25; var newvalue = dynamicGaugeData.getValue(0, 0) + diff; if (newvalue < 0) newvalue = 0; // データの値を変更 dynamicGaugeData.setValue(0, 0, newvalue); dynamicGauge.draw(dynamicGaugeData, dynamicGaugeOptions); } google.setOnLoadCallback(drawDynamicGauge); </script> <div id="gct_dynamic_gauge" style="width: 160px; height: 160px;"></div> <input type="button" value="Down" onclick="changeSpeed(-1)" /> <input type="button" value="Up" onclick="changeSpeed(1)" />
Google Chart Tools - グラフと表の連携
今回は Google Chart Tools のグラフと表との連携です。
この表との連携や次回説明するフィルタリングが比較的簡単にかけることが Google Chart Tools
の大きな利点の一つだと思います。
- Google Code Playground # Interaction Using Events
- Code Examples - Google Chart Tools — Google Developers
表とグラフでのデータの共有
連携の第一歩として同じデータで表とグラフを作成します。<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(列番号の配列)

この 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 つです。
- 表のソート
- 選択
Google Chart Tools のグラフ(テーブル)では選択などの何らかのアクションを起こした時にイベントが発生します。 このイベントには addListener 関数を使ってコールバック関数の登録ができます。
登録されたコールバック関数はイベント発生時に呼び出されるので、 ここで連携用の処理を行います。
- Handling Events - Google Chart Tools — Google Developers
- Interacting With the Chart - Google Chart Tools — Google Developers
ソート
表をソートすると '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); });