WebOS Goodies

WebOS の未来を模索する、ゲームプログラマあがりの Web 開発者のブログ。

WebOS Goodies へようこそ! WebOS はインターネットの未来形。あらゆる Web サイトが繋がり、共有し、協力して創り上げる、ひとつの巨大な情報システムです。そこでは、あらゆる情報がネットワーク上に蓄積され、我々はいつでも、どこからでも、多彩なデバイスを使ってそれらにアクセスできます。 WebOS Goodies は、さまざまな情報提供やツール開発を通して、そんな世界の実現に少しでも貢献するべく活動していきます。
Subscribe       

Google Visualization API 詳細、および Gadgets-in-Docs の作り方

前回の Query Language の記事はたくさんの方に読んでいただけたようで、たいへん嬉しく思っております。とりあえず最もインパクトがあり、しかも他所ではあまり触れられていない機能ということで Query Language にネタを絞って書いたのですが、そのために Google Visualization API そのものや Gadgets-in-Docs について、きちんとご紹介できませんでした。

そこで、本日はそのあたりの補足も兼ねて、 Google Visualization API 全般についてご紹介しようと思います。 Google Docs 活用の参考にしていただければ幸いです。

Google Visualization API 概要

さて、まずは Google Visualization API 自体について、軽くご紹介しておきましょう。この API をひと言で言えば、「Google Spreadsheets のデータを読み込むための JavaScript ライブラリ」です。 Google Ajax APIs のひとつという位置付けになっており、使用方法も似ています。主な特徴は以下のとおりです。

  • サーバーを用意することなく、 JavaScript のみで Google Spreadsheets のデータを読み込める。
  • 非公開のシートも取得可能(ユーザーが Google Docs にログインしている必要がある)。
  • SQL に似た Query Language を利用することで、取得するデータの選別やソートなどが可能(詳細は前回の記事参照)。
  • iGoogle ガジェットでの利用を補助するヘルパーが用意されている。
  • 通信プロトコルは Google Spreadsheets に限定されない汎用的な設計になっている。

やはり Query Language が最大の特徴ではありますが、最後の「Google Spreadsheets に限定されない」という点も実は重要です。詳細は後ほど書きますが、多数用意された(そして今後も増えていくであろう) Google Spreadsheets 用のガジェットを、自分のサイトでも活用できるのです。ひと粒で二度おいしい API というわけですね!

Google Visualization API の使い方

前回とだいぶ重複しますが、少し詳しめに Google Visualiaztion API の使い方をご紹介します。例として、前回も使った県名リストのスプレッドシートから県コードと県名、地域名を表示するページを作ってみました。以下の URL に実際に動作するデモページがありますので、お試しください。

http://webos-goodies.googlecode.com/svn/trunk/blog...

それでは、このページのコードについて順を追ってご紹介します。 API リファレンスも参照しながら読んでいただくとよろしいかと思います。

Google AJAX APIs ライブラリの読み込みなど

HEAD タグの内容は API の動作に関係しない記述ばかりなので、そこは省略して BODY タグの内部からはじめましょう。コードは以下のようになっています。

<body>

<!-- Google AJAX API の共通ライブラリを読み込む(APIキーは不要) -->
<script type="text/javascript" src="http://www.google.com/jsapi"></script>

<!-- Google Visualization API でデータを読み込む一連の処理 -->
<script type="text/javascript">
  // 省略
</script>

<!-- この DIV に取得したデータを表示する -->
<div id="result">読み込み中...</div>

</body>

まず最初に行うべきことは、 Google AJAX APIs 共通ライブラリの読み込みです。これは普通に SCRIPT タグで "http://www.google.com/jsapi" を指定するだけです。その後に Google Visualization API を使ってデータを取得する処理を書くわけですが、これは以降で詳しくご紹介しますので、上記のコードでは省略しています。そして、最後に取得したデータを表示するための DIV を用意しています。ここまではなんの変哲もないコードなので、問題ないでしょう。

Google Visualization API の読み込み

いよいよ核心部分、先のコードで省略したスクリプト部分についてみていきましょう。既に Google AJAX APIs が使えるようになっているので、次は Google Visualization API のライブラリを読み込みます。これには SCRIPT タグは使わず、 Google AJAX APIsgoogle.load メソッドを利用します。

google.load("visualization", "1");

この一行でライブラリの読み込みは完了です。ここは決まり文句として覚えてしまうのが良いでしょう。

リクエストの発行

API の準備が整ったら、その機能を利用してスプレッドシートの内容を取得するリクエストを発行します。コードは以下のようになります。

// データソース URL
var dataSource = 'http://spreadsheets.google.com/tq?key=pMIBrnJ4PHK-SHF_4IqAcVQ&gid=0&pub=1';

// Query Language
var queryLanguage = 'select A, B, E';

// ページ読み込みの完了後にデータをリクエスト
google.setOnLoadCallback(function() {
  var query = new google.visualization.Query(dataSource);
  query.setQuery(queryLanguage);
  query.send(handleResponse);
});

google.setOnLoadCallback は、 onload イベントを登録するための Google AJAX APIs のメソッドです。 Google Visualization APIs の各メソッドはページの読み込みが終了した後に呼び出すことになっていますので、リクエスト発行の処理をイベントに登録しています。

リクエストを発行するためには google.visualization.Query クラスのオブジェクトが必要なので、 onload イベント処理の最初で生成しています。コンストラクタ引数に渡しているのは、取得するスプレッドシートを識別するデータソース URL です。データソース URL については前回の記事で詳しくご紹介していますので、そちらをご覧ください。

次に呼んでいる setQuery は、 Query Language (こちらも前回の記事参照)を指定するメソッドです。 Query Language が必要ない場合(データソースのすべてを読み込む場合)はこのメソッドの呼び出しを省略できます。

最後に send メソッドでリクエストを発行します。引数に渡しているのは、レスポンスを受け取った際に呼ばれるコールバック関数です。

レスポンスを処理する

レスポンスを受け取ると、その内容を格納した google.visualization.QueryResponse オブジェクトを引数にしてコールバック関数が呼ばれますので、適切に処理します。処理内容は目的に応じてさまざまですが、ここでは取得したデータを HTML のテーブルにフォーマットして、用意してある DIV に挿入することにします。

function handleResponse(response)
{
  var el = document.getElementById('result');
  if(response.isError()) {
    el.innerHTML = escapeHtml(response.getDetailedMessage());
    return;
  }

  var data = response.getDataTable();
  var html = [];
  for (var row = 0; row < data.getNumberOfRows(); row++)
  {
    var line = [];
    for (var col = 0; col < data.getNumberOfColumns(); col++)
      line.push(escapeHtml(data.getFormattedValue(row, col)));
    html.push('<tr><td>' + line.join("</td><td>") + '</td></tr>');
  }
  el.innerHTML = '<table>' + html.join('') + '</table>';
}

// HTML エスケープするヘルパー関数
function escapeHtml(text) {
  return (text || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\u0022/g, '&quot;');
}

最初の if 文では、 isError メソッドを使ってエラーが発生していないかどうかをチェックしています。もしエラーが発生した場合は isError メソッドが true を返すので、 getDetailedMessage メソッドでエラーメッセージを取得し、 DIV に挿入して終了します。

リクエストが成功していれば、 getDataTable メソッドで google.visualization.DataTable クラスのオブジェクトが取得できます。実際のデータへのアクセスはこのオブジェクトを介して行います。余談ですが、この名前からすると将来的に他の形式の取得も提供されるかもしれませんね。

さあ、いよいよスプレッドシートの内容の取得です。 DataTable クラスの getNumberOfRows, getNumberOfColumns メソッドで行数とカラム数が取得できますので、それをもとにループを回すのが良いでしょう。ループ内では getFormattedValue メソッドを使って各カラムの表示可能な文字列を取得し、 HTML コードを組み立てています。

以上がシートの内容を取得するまでの手順です。ライブラリの読み込みが少し変則的ですが、それ以外はとてもシンプルに実現されていますね。このサンプルでは使っていませんが、各カラムの表示文字列以外にもいくつか取得できる情報があります。それらの詳細はこちらの API リファレンスを参照してください。

Gadget-in-Docs 概要

ここまでで Google Visualization API の使い方はだいたいご理解いただけたと思います。これだけでも Google Spreadsheets のデータを思う存分活用できて素晴らしいのですが、 Google はさらにもうひとつ、ナイスな活用方法を用意してくれました。それが Gadget-in-Docs 、 Google Spreadsheets に統合された iGoogle ガジェットです。

この機能は、単にスプレッドシートに iGoogle ガジェットを配置できるというだけではありません。ガジェット側で Google Visualization API を用いることで、スプレッドシートのデータをさまざまな形で活用できます。公にはデータの可視化(グラフ表示など)が主目的となっていますが、もちろんそれにこだわる必要はありません。個人的には、 Web フォームの検証の条件をスプレッドシートに入力すると、そこから Rails のバリデーションコードを自動生成するガジェットとか作れないかな、とか考えています。

こんな便利な Gadget-in-Docs 機能、活用しない手はありません。以降でオリジナルのガジェットの作り方をご紹介しますので、ぜひ皆さんも作ってみてください!

Gadget-in-Docs の作り方

それでは、 Gadget-in-Docs の作り方をご紹介しましょう。例題として、先ほどと同じく県名リストのデータを表示するガジェットを実装してみようと思います。以下のページに実際に動作するデモがありますのでご覧ください。公開されたスプレッドシートではガジェットが動作しなくなってしまったようです m(_ _)m

http://spreadsheets.google.com/pub?key=pMIBrnJ4PHK...

ソースは以下です。

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Gadget-in-Docs Sample">
    <Require feature="idi"/>
    <Require feature="locked-domain"/>
  </ModulePrefs>
  <UserPref name="_table_query_url" display_name="Data source URL" required="true"/>
  <Content type="html">
    <![CDATA[

<!-- Google AJAX API の共通ライブラリを読み込む(APIキーは不要) -->
<script type="text/javascript" src="http://www.google.com/jsapi"></script>

<!-- Google Visualization API でデータを読み込む一連の処理 -->
<script type="text/javascript">

  // Google Visualization API のライブラリを読み込む
  google.load("visualization", "1");

  // Query Language
  var queryLanguage = 'select A, B, E';

  // ヘルパーオブジェクトを格納する変数
  var helper = null;

  // ページ読み込みの完了後にデータをリクエスト
  google.setOnLoadCallback(function() {
    helper = new google.visualization.GadgetHelper();
    var query = helper.createQueryFromPrefs(new _IG_Prefs());
    query.setQuery(queryLanguage);
    query.send(handleResponse);
  });

  // データを取得できると、この関数が呼ばれる
  function handleResponse(response)
  {
    // エラー処理
    if(!helper.validateResponse(response))
      return;

    var el   = document.getElementById('result');
    var data = response.getDataTable();
    var html = [];
    for (var row = 0; row < data.getNumberOfRows(); row++)
    {
      var line = [];
      for (var col = 0; col < data.getNumberOfColumns(); col++)
        line.push(escapeHtml(data.getFormattedValue(row, col)));
      html.push('<tr><td>' + line.join("</td><td>") + '</td></tr>');
    }
    el.innerHTML = '<table>' + html.join('') + '</table>';
  }

  // HTML エスケープするヘルパー関数
  function escapeHtml(text) {
    return (text || '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\u0022/g, '&quot;');
  }

</script>

<!-- この DIV に取得したデータを表示する -->
<div id="result">読み込み中...</div>

    ]]>
 </Content>
</Module>

前述のとおり Gadget-in-Docs の実体は iGoogle ガジェットですので、その作成には iGoogle ガジェットの知識が必要です。しかし、それらすべてを網羅するのは難しいので、ここでは Gadget-in-Docs に特有な事柄を中心にご紹介しようと思います。 iGoogle ガジェットを作ったことのない方は、過去の関連記事のほうをぜひご覧ください。

メタ情報の定義

Gadget-in-Docs といっても、基本的には通常の iGoogle ガジェットとなにも変わりません。実際、ほぼすべての iGoogle ガジェットを Google Spreadsheets に配置することが可能です。しかし、スプレッドシートのデータソース URL を取得したり、データが変更された際に自動的にリロードしたりといった機能を実現するには、わずかながら特別な記述が必要になりますので、まずはそれらをご紹介しましょう。

以下は今回のサンプルの XML 部分を抜き出したものです。この中の Content 要素が HTML でいう BODY 要素にあたるもので、その中に記述された HTML がガジェット内にほぼそのままレンダリングされます。

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Simple Table Gadget">
    <Require feature="idi"/>
    <Require feature="locked-domain"/>
  </ModulePrefs>
  <UserPref name="_table_query_url" display_name="Data source URL" required="true"/>
  <Content type="html">
    <![CDATA[

      <!-- ガジェット内に表示する HTML コード -->

    ]]>
 </Content>
</Module>

このなかで、最も重要なのが "_table_query_url" というユーザー設定項目です。この名前の設定項目があると Google Spreadsheets が自動的に認識し、そこに現在のシートのデータソース URL を設定してくれます。また、ガジェットの設定画面にてシート上の範囲選択でガジェットへの読み込み範囲を指定するインターフェースも提供されます。すべての Gadget-in-Docs がこの設定項目を持つべきです。

もうひとつ見慣れないのが、 "idi", "locked-domain" という 2 つのライブラリを読み込む Require 要素ですね。これらを指定しておくと、データが変更されたときに自動的にガジェットがリロードされ、最新のデータを反映できます。たった 2 行でリアルタイムの反映が実現されるのは素晴らしいですね。もし勝手にリロードされると都合が悪い場合は、これらの指定を省略すれば OK です。

なお、残念ながらこの自動リロードの機能は type="html" のガジェットでのみ有効で、 type="url" では動作しません。次善の策として、定期的にデータを更新するように指定することもできます。それには、以下のようなユーザー設定項目を追加します。

<UserPref name="_table_query_refresh_interval" display_name="Data refresh interval (minutes)" default_value="0" datatype="enum" required="false">
  <EnumValue value="0" display_value="None"/>
  <EnumValue value="60" display_value="1"/>
  <EnumValue value="300" display_value="5"/>
  <EnumValue value="1800" display_value="30"/>
</UserPref>

これを記述するとリフレッシュ間隔を指定する設定項目が追加され、そこで指定した間隔でデータが更新されます。実際には google.visualization.Query クラスの setRefreshInterval メソッド(詳細は API リファレンス参照)に、この設定値がそのまま渡されるようです。

これら以外にも、 iGoogle ガジェットにはさまざまなメタ情報があります。詳細は前述の過去記事をご覧くださいませ。

ヘルパーオブジェクトを使う

メタ情報の定義ができたら、次はいよいよガジェット本体の HTML を記述します。と言っても、これは Web ページ版の BODY 内の記述ほぼそのままです。相違点は 2 つありますが、まず最初は google.visualization.Query オブジェクトを直接生成する代わりに、ヘルパーを利用していることです。

google.setOnLoadCallback(function() {
  var helper = new google.visualization.GadgetHelper();
  var query  = helper.createQueryFromPrefs(new _IG_Prefs());
  query.setQuery(queryLanguage);
  query.send(handleResponse);
});

google.visualization.GadgetHelper クラスが iGoogle ガジェット用のヘルパーです。その createQueryFromPrefs メソッドに _IG_Prefs オブジェクト(ユーザー設定項目にアクセスするためのオブジェクト)を渡すことにより、前述のユーザー設定項目を反映させた GadgetHelper オブジェクトが取得できます。データソース URL も前述の "_table_query_url" から取得されるため、コード内では指定していません。

もうひとつは、レスポンスのエラー処理をヘルパーに任せている点です。

function handleResponse(response)
{
  // エラー処理
  if(!helper.validateResponse(response))
    return;

このように validateResponse メソッドを使うと、エラーが発生した場合にガジェットの左上にメッセージを表示してくれます。インターフェースの統一という意味でも、とくに理由がない限りこのメソッドを利用するのが良いでしょう。

以上、 Gadget-in-Docs 特有の知識はこれだけです。 iGoogle ガジェット APIGoogle Visualization API を駆使して、素晴らしいガジェットを作ってください!

Google Spreadsheets に配置する

ガジェットが完成したら、さっそくスプレッドシートに配置しましょう。 Google Spreadsheets の編集画面で簡単に配置できます。

まずは適当なスプレッドシートを Google Docs で開いてください。そしてツールバーにある アイコンをクリックし、メニューから「ガジェット」を選択します。すると「ガジェットを追加」ダイアログが表示されますので、左側のメニューの「カスタム…」をクリックします。これで以下のようなガジェットの URL を指定する画面になります。

「ガジェットの URL」にガジェットのソースファイルの URL を指定し、「追加」ボタンをクリックすると、ダイアログが閉じてシートにガジェットが配置されます。必要に応じて設定項目を変更し、「保存して閉じる」ボタンをクリックして完了です。ガジェット右上の▽メニューを使えば、ガジェットを iGoogle に配置したり、任意の Web ページに埋め込むための HTML コードを取得したりできますので、試してみてください。

Gadget Gallery に登録しよう

これはというガジェットができたなら、 Gadget-in-Docs 専用のガジェットギャラリーに投稿して世界中のユーザーに使ってもらいましょう。英語ですが、以下のページから投稿できます。

http://code.google.com/apis/visualization/document...

投稿するためにはガジェットソースファイルの ModulePrefs 要素に規定の属性を記述しておかなくてはなりません。必要な属性に関してはこちらの記事でご紹介していますので、参照してください。

iGoogle ガジェットのときはガジェットソースファイルの URL を送信するだけでよかったのですが、 Gadget-in-Docs の投稿フォームは、いろいろ項目が増えていますね。英語なので厳しいですが、頑張って記入してください。もしかしたら日本語でも受け付けてくれるかもしれませんので、試して成功したら教えてください(笑)。

これまでのパターンからすると、フォームを送信後、数週間経ってからキャラリーに登録されます。気長に待ちましょう。たまにスルーされてしまうこともありますが・・・。

Gadgets-in-Docs を自分のサイトで利用する

記事の最初でも少し触れましたが、本来 Google Visualization API は Google Spreadsheets 専用のものではありません。残念ながらサーバー側の実装は公開されていませんが、通信プロトコル自体は Google に依存していません。前回の記事でも軽くご紹介したとおり、ごくシンプルな REST + JSONP です。さすがに Query Language を完全に実装するのは大変でしょうが、それが未サポートでも大半のガジェットは動作するのではないかと思います。

それでは、 Google Visualization API を実装してなにが得なのかというと、 Google Spreadsheets に用意されている多数のガジェットを、自サイトのデータのビジュアライゼーションに利用できるのです。公開サイトではもちろん、社内用の Web サイトでも(クライアントがインターネットにアクセスできれば)動作するはずです。今後ガジェットは増える一方でしょうから、それらの資産が利用できるのは大きなメリットではないでしょうか。誰か Ruby で実装してくれないかなぁ(w

以上、本日は Google Visualization API の詳細と Gadget-in-Docs の作り方をご紹介しました。これらの機能は Google Spreadsheets の新機能としても画期的ですが、それ以上に従来よりも格段に実用性の高いマッシュアップの形を示したという点で意義深いと思います。これもまた WebOS への大きな一歩ですね。今後はこのような形でデータを開放していく動きが他のサービスにも広まってほしいと願うばかりです。まあ、とりあえずはこれらの API でとことん遊んでみるのが先決ですかね!(・∀・)

参考

関連記事

この記事にコメントする

Recommendations
Books
「Closure Library」の入門書です。
詳しくはこちらの記事をどうぞ!
Categories
Recent Articles