数年前、私は広範なスポーツ関連のデータ・フィードを生成しているクライアントの仕事をしました。私たちは、このクライアントのデータ・サービス製品がカバーする範囲の広さとその詳細さを明らかにする手段を模索しましたが、結局、クライアントの Web サイトに「得点表」のようなウィジェットを配置することにしました。「サッカーの試合の得点」、「競馬のレース結果」、「クリケットの試合の得点」などの主要なスポーツの最新情報をすべてリアルタイムで表示すれば、目的の効果を得られて、潜在顧客にクライアントのデータ・サービスの素晴らしさが伝わるだろうと考えたわけです。
しかし、この記事の目的は、この特定の得点表をどのように開発したのかを説明することではありません。ここでこの話を持ち出したわけは、ウィジェットをデプロイした後に奇妙なことになってきたからです。
得点表を使用するようになった後、クライアントの最高経営層から、得点表に表示される数値について質問を受けるようになりました。初めのうちは結果の正確さに関する質問でしたが、そのうち内省的な質問になってきました。例えば「サッカーの得点をもっと表示したほうが良かったのでは」といった質問や、「試合やレースが多い日に更新の速度が遅くなる」といった質問です。私たちが表示していたさまざまな数値は実質的に、クライアントのスポーツ関連データ・フィードの品質、そして全体的な正常性のベンチマークとなったわけです。
得点表アプリケーションが 1、2 秒ごとに更新されると、それは企業のハートビートとして最高経営層に伝わります。彼らはそこに異常があればすぐに気付きます。もちろん、私たちは何も新しいことを行ったわけではありません。KPI のダッシュボードを作成するにあたっての考え方を変え、マーケティングを率先しただけのことです。
エンタープライズ開発業界ではある時期、ダッシュボードは大々的な誇大宣伝の対象となりました。そこで、まずはこの記事で使用するダッシュボードの意味を定義させてください。
ダッシュボードとは、1 つまたはそれ以上の目的を達成する上で必要となる重要な情報を、できれば 1 つの画面にまとめて配置することで、情報を一目で把握できるようにするためのビジュアル・ディスプレイのことです。
ダッシュボードで表現されるデータの目的とタイプは、以下の 3 つのカテゴリーに分類することができます。
- 戦略上のデータ。戦略を立てることを目的としたデータは、どちらかと言えば、企業の経営陣や重要な決定権を持つ人々が興味を引くような内容です。彼らは企業全体の正常性を直観的に判断するために、現場で何が起こっているのかを十分に把握しようと常に努めているからです。
- 解析用データ。傾向を推測したり特定したりすることを目的としたデータは、その性質上、より解析的なものになります。
- 運用上のデータ。運用上のデータは、プロセスの状態を直接監視することで取得されるデータで、「Web サイトが動作しているか」、あるいは「連絡先 E メールのフォームは機能しているか」といった運用に関する内容のデータです。
上記のカテゴリーのほかにも、私が実際に携わったり、目にしたことのあるダッシュボードのデータには、ダッシュボードに特有のカテゴリーがいくつかあります。それは例えば、どれくらいの頻度でデータの自動更新が行われるのかとか、そのデータが量を表すデータなのか、質を表すデータなのか、その両方を表すデータなのか、といったもので、こうしたカテゴリーがデータを辿って詳細まで掘り下げていく出発点になる場合もあります。
ダッシュボードに表示されるのは一般に、測定可能な内容です。通常、これはビジネスの世界では重要業績評価指標 (KPI) と呼ばれています。測定することが可能で、企業のビジネス・プロセスの状態や健全性に関する情報を伝えるメトリックは、いずれも KPI です。したがって優れた KPI は、組織内において、戦略を立てる、解析を行う、運用を行うなどの目的を達成したかどうかを適切に測定できるものでなければなりません。
囲み記事「KPI の例」に、業務で役に立つ可能性のある KPI の例をほんの一部ですが紹介しています。これらの KPI は、あらゆる種類の企業で使える一般的なものです。前述の得点表での場合もそうでしたが、私は常に、それぞれのビジネスに固有のプロセスの健全性を端的に特徴付ける KPI を特定しようと努めています。企業の活動内容に密接に関連していればしているほど、適切なメトリックとなります。
KPI を定義するもっと適切な方法がわかってきたり、KPI を使ってどのような質問に対する答えを出したいのかが見えてくるにつれて、KPI の定義が変わる可能性があることを覚悟しておいてください。結局のところ、KPI の用途として最も有効なのは、ビジネスに関する質問に対して答えを知るための手段とすることです。
そうは言っても、KPI を恐れることはありません。KPI は随意、高度なものにすることも、単純なものにすることもできます。そして独自の KPI を作成する際に参考にできる資料も Web には豊富に揃っています。私が思うに、KPI を作成する上で最も重要なことは、使用できるデータを確保することです。
優れた Web ダッシュボードは、利用者ができるだけ理解しやすい方法で KPI を表示します。つまり、データを最大限活用するとともに、情報の表示とは無関係なグラフィック表示を可能な限り減らします。ダッシュボードに表示するアイテムをどのようにグループ化するかを決めるには、まず始めに戦略を立てる、解析を行う、運用を行うといった目的に沿って表示要素を構成すると有益です。比較を行いたいアイテムをグループ化するときには、その比較が適切かつ有効であり、過去に何が起こったかを説明するというよりは、有益なフィードバックをビジネスに提供することを確認してください。特定の出来事がどのようにして起こったかを示すことも役には立ちますが、ダッシュボードの役割は現状を説明することです。現状を説明するために履歴が必要な場合には、ダッシュボードまたはダッシュボードで利用するデータが定期的に保存されるようにダッシュボードを作成してください。
ダッシュボードの形態として、最初に示すのは極めてわかりやすく要約された形のデータで、それから徐々に公開する情報の量を増やしていくようなダッシュボードは、情報をナビゲートするためのツールとなります。ただし、データのドリルダウンやナビゲーション UI などの要素を提供する場合には、ダッシュボードを特定のユーザー・ロールに対応させる必要があることも認識しておく必要があります。その場合のベスト・プラクティスは、特定のロールごとに対応するダッシュボードを 1 つ用意することです。
最後に言っておく点として、優れた Web ダッシュボードでは複雑すぎるグラフは使用しません。その典型的な例は、3 次元 (3D) 円グラフの使用です。このような円グラフで詳細が追加されると、全体に占める個々の部分の割合が視覚的に判断しにくくします。グラフの見やすさについてさらに掘り下げた多岐にわたる考察 (詳細は、「参考文献」のリンクを参照) では、円グラフの使用を完全に否定しています。
効果的でないダッシュボードでは、ここで説明したアドバイスのすべての対極の形になっています。私がこれまで目にしてきた不十分な設計のダッシュボードにお決まりの特徴をいくつか以下に挙げます。
- 色を使い過ぎていること。データを色分けして整理するのはいいことですが、やりすぎてしまう場合が多いようです。
- ユーザーがスクロールしたり、タブを使用したりしなければならないこと。データが複数のページにまたがっていると、ユーザーが余計に頭を使わなければならなくなります。
- あまりにも詳細であること。要約されていなければ、ユーザーがデータを総合的に捉え、具体的なアクションを取ることがほとんど不可能になります。
- 正確過ぎること。数値の小数位が多過ぎたり、グラフ上にデータ・ラベルがあり過ぎたりするなどです。
- 重大な例外が見過ごされてしまうこと。目標から大きく外れていたり、目標を達成していなかったりといった例外が強調されていなければ、時機を得たアクションを取れないなど、ダッシュボードが効果的に機能しません。
- 不完全、あるいは十分でないメトリックを採用すること。適切なメトリックと計算式を使い、KPI が適切な指標になることを確実にするのは当然のことのように思えますが、上記の悪い特徴と同じく、このことは一般的に見過ごされがちです。ダッシュボード・アプリケーションのなかで KPI を正式に決める前に、メトリックを手動で生成するか、またはスプレッドシートを使用してサンプル計算のテストに役立ててください。
データ・インクの基本概念には、ダッシュボードの良し悪しを決定する条件を記述するもう 1 つの方法が要約されています。情報およびデータ設計の基本理念であるデータ・インクは、文字通り、データを表現するもの (数値やグラフ上でデータを表す線) をページに印刷するために使用されるインクの総量ですが、これはコンピューター画面にも当てはまります。コンピューター画面では、データの表現に使われているデータ・ピクセルはデータ・インクに相当し、それ以外のピクセルはいずれもデータ・インクには相当しません。情報の設計でデータ・ピクセルを最大限にするということは、余分なグラフィック要素をできるだけ取り除き、控えめなカラー・スキームを使用し、手の込んだフォントを使わないようにすることを意味します。
サンプル・ダッシュボードを作成する手順に移る前に、「ダウンロード」セクションからソース・ファイルを入手してダッシュボードをインストールするとよいかもしれません。その場合には、.zip ファイルを解凍して、このファイルに付属の README ファイルの説明に従ってください。
すべてがインストールされた状態になると、Web ブラウザーと以下の URL を使って eXist データベースの dashboard.xq にアクセスすることで、サンプル・ダッシュボードを表示できるようになります。
http://localhost:8080/exist/rest/db/dashboards_with_xquery/xquery/dashboard.xq |
XQuery ファイルを eXist 以外の場所にインストールした場合には、該当する場所に合わせて上記の URL を変更してください。
サンプル・ダッシュボードは、オンライン Web サービスに対して大量のテスト・データとクレデンシャルを使用することにも注意してください。これらのリソースはいずれもインターネット上に存在するので、いつでも入手できるはずですが、問題が発生した場合には、サンプル・データとして独自のクレデンシャルとテスト・データを使用することをお勧めします。
ここまでで、ダッシュボードとは何であるかを理解できたことと思います。また、ダッシュボードの主な目的は人を引きつける方法を使って KPI を表示することであり、それによってビジネスに関する重要な疑問点を見つけ、それに答えられるようにすることである、ということも理解できたことと思います。そこで今度は、実際にサンプル・ダッシュボードを作成する手順に移ります。eXist XML データベースや XQuery などの XML 技術を利用すると、XML データを集約して利用できるようになり、ダッシュボードの HTML 表現を作成することが可能になります。
図 1 に、完成した形のサンプル・ダッシュボードを示します。
図 1. サンプル・ダッシュボード
この Web ページには、注意をそらすような余計な設計要素はほとんどありません。これは、他の何よりもデータ・ピクセルを増やすという前のセクションのアドバイスに忠実に従った成果の表れだと思います。CSS ファイルでは、私が読みやすいと思う控えめな色の背景とフォントを定義しています。
このダッシュボードには、XQuery がデータの統合にいかに優れているかを示すために、すぐに使用できる KPI を選びました。
- 滞納請求書 (Aging Invoices): 企業がそのサービスの料金を請求するときには一般に、標準的な条件 (顧客が支払うまでの日数など) に基づいて支払いが行われます。
- 販売パイプライン (Sales Pipeline): 企業は販売機会をいくつかの段階に分類します。それぞれの段階が、実際に仕事を受注して請求できる可能性の大きさを定義します。
- 週間タイムシート (Weekly Timesheets): 従業員の週間タイムシートが表示されます。勤務時間が標準の週 40 時間を超えている従業員は強調表示されます。
- Web サイト稼働状況 (Website Operation): このモニターは、Web サイトが稼働中であるかどうかを示します。
- リマインダー (Reminders): 企業で予定している作業です。
- 競合他社の Web サイト (Competitor Website): このグラフには、競合他社の Web サイトの実績の比較が示されます。
このダッシュボードは本格的なアプリケーションというよりは、XQuery の eXist XML データベース実装ならではの機能を利用したマッシュアップです。これから作成するダッシュボードは、たった 3 つの XQuery ファイルを使用して実装します。そのうちの 1 つは XQuery モジュールで、他の 2 つの XQuery ファイルから利用されます (図 2 を参照)。
図 2. ダッシュボードの XQuery コンポーネント
XQuery モジュール utility.xqm には、data.xq と dashboard.xq の両方が使用する関数が含まれています。XQuery ファイル data.xq の役割は、KPI 関連のすべてのデータが含まれる XML ドキュメントを生成することです。もう一方の dashboard.xq ファイルの役割は、このデータを表示するためにブラウザーで表示できる HTML ファイルを作成することです。
私がソフトウェアを開発するときには、何よりもまず、アプリケーションのデータ層を具体化するように努めています。有益なアプリケーションはほとんど例外なく、ある種のデータに依存します。これから作成するのはデータを表示するダッシュボードなので、最初にデータ・ソースを識別するのは当然のことです。
ダッシュボードの最終目標は KPI を表示することなので、データ・ソースは KPI 自体に統合するか、あるいは KPI の計算に使われるようにする必要があります。KPI が質的なものを表すか、量的なものを表すかに関わらず、すべての KPI はビジネスの運営に有益な情報を提供しなければなりません。このサンプル・ダッシュボードでは、XQuery を利用して統合シナリオを扱う方法を説明するために、一般に公開されているデータを使用します。さらに、よく利用されている人気の Web サービスをデータ・ソースに選び、Web サービスの内部、外部、およびビジネスの末端で生成された XML データを取り込めるようにしました。
図 3 に、選択したデータ・ソースを示します。いずれのデータ・ソースにしても、Google™ などのよく利用されている Web サービスや、リレーショナル・データベースなどの平凡な技術から入手することができます。
図 3. 使用可能なデータ・ソースの図
それぞれのデータ・ソースは、以下の目的のために、Web サービス、XML データ、または XQuery によって生成されるデータと何らかの形で統合する必要があります。
- Web サイト稼働状況: XQuery 自体が拡張性のある言語であることを明らかにします。
- 滞納請求書: XQuery を使用して MySQL にアクセスする方法を説明します。
- 販売パイプライン: XQuery を使用して Google ドキュメントのスプレッドシートにアクセスする方法を説明します。
- 週間タイムシート: ローカルの Microsoft® Office Excel® スプレッドシートにアクセスする方法を説明します。
- リマインダー: 人気の Backpack Web サービスを統合します。
- 競合他社の Web サイト: グラフに競合他社の Web サイトの実績の比較を示します。
data.xq を処理すると、必要なすべてのデータが含まれる 1 つの XML ドキュメントが生成されます。データを XQuery 内で統合するのに最も簡単な方法は、doc() 関数を使って Web URL のサイトから XML を取得するというものです。この関数に、(XML の観点では) 整形式ではないデータを返すリソースの URL を指定すると、エラーを受け取ることになります。
リスト 1 のコード・セクションに、data.xq での実際の処理方法を示します。
リスト 1. data.xq での処理
<sales_pipeline desc="example accessing published Google spreadsheet">
{doc("http://spreadsheets.google.com/feeds/list/
pZDPqHJcLzxKntsQv2tuIMQ/1/public/basic")}
</sales_pipeline>
...
<backpack desc="example accessing simple web service">
{doc("http://dashboardwithxquery.backpackit.com/
69babcbce8aa212fc83464088b45f7a97a9f3dce/reminders.xml")}
</backpack>
...
<timesheet desc="example accessing local MS Excel file">
doc("file:///Users/jimfuller/Source/Writing/1_articles/1_ibm/
3_dashboards_with_xquery/working/src/data/MSOFFICE-timesheet.xls")
</timesheet>
|
sales_pipeline 要素がアクセスするのは、私が公開した Google ドキュメントで、URL を指定すればアクセスできるようになっています。Google ドキュメントはこのようにして Atom XML フィードとして公開されます (「参考文献」にリンクを記載)。Backpack URL は、私が http://www.backpackit.com にセットアップしたリマインダーを表す XML フィードを返します。一方、timesheet 要素はこれとは異なり、ローカルにホストされる Excel ファイルにアクセスします。数年前から Excel では、Microsoft 固有の XML フォーマットで生成された Excel スプレッドシートを使用できるようになっています。
データ統合の次のステップは、XQuery を使用して一連のヘルパー関数を作成することです。作成するすべてのヘルパー関数は、utility.xqm XQuery モジュールに配置します。以下ではこれらの関数について、コアとなる具体的な点を強調した上で簡単に説明します。
- utility:check_site(): XQuery コードのこの部分では、Web URL がアクセス可能かどうかをチェックし、Web サーバーが応答するまでにかかった時間を測定します。リスト 2 に、この関数を示します。
リスト 2. utility:check_site() 関数declare function utility:check_site($uri) { let $start := util:system-time() let $response := httpclient:get(xs:anyURI($uri),false(),()) let $end := util:system-time() let $response-time := (($end - $start) div xs:dayTimeDuration('PT1S')) * 1000 let $status-code := string($response/@statusCode) return <test xmlns="" ts="{current-dateTime()}" status="{$status-code}" response="{$response-time}" /> };
dashboard.xq は、この関数が返すテスト要素を使って Web サイトの状況を表示します。
- utility:get-aged-invoices(): エンコードされてリレーショナル・データベース内に保管されるデータは想像できないほどの量です。そこで、MySQL® コミュニティー・サーバーと対話する eXist XML データベースを統合する例を説明しておきます。XQuery にはネイティブに組み込まれた RDBMS (リレーショナル・データベース管理システム) 機能はありませんが、よく使用されている XQuery プロセッサーの多くには拡張関数があります。eXist XML データベースには、オプション・モジュールという形で SQL (構造化問い合わせ言語) 拡張関数が用意されているので、これを必ず有効にしてください。有効にするには、eXist conf.xml ファイルの該当するセクションのコメントを外します (サンプル・コードに含まれている README ファイルを参照)。リスト 3 に、
utility:get-aged-invoices()関数を記載します。
リスト 3. utility:get-aged-invoices() 関数declare function utility:get-aged-invoices(){ let $connection := sql:get-connection("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", "root", "") let $data := sql:execute($connection, "select * from invoices;", fn:true()) return <invoices> <total>{sum($data/sql:row/sql:invoice_amount)}</total> <age amt="15"> {sum($data/sql:row/sql:invoice_amount[../sql:invoice_terms='15'])}</age> <age amt="30"> {sum($data/sql:row/sql:invoice_amount[../sql:invoice_terms='30'])}</age> <age amt="60"> {sum($data/sql:row/sql:invoice_amount[../sql:invoice_terms='60'])}</age> </invoices> };
この関数はまず、eXist SQL 拡張モジュールの
sql:get-connection()関数を使って JDBC (Java™ Database Connectivity) スタイルの接続を確立します。次に、データベースからデータを選択するための SQL 文を定義し、その文をsql:executeによって実行します。この関数の結果が保管されるのは、$data変数です。この変数は、後で XPath を使って関連データを抽出するときに使用します。
以下に記載するのは、Google ベースの各種 Web サービスと統合する関数です (詳細は、「参考文献」のリンクを参照)。Google の Web サービスの多くは同じような手法でサービスを公開し、そのサービスに接続するので、いくつかの例を追加で記載しておきます (サンプル・ダッシュボードで実際に使用するわけではありませんが、参考として役に立つと思います)。
- utility:get-google-token($Email,$Passwd,$accountType,$source,$service): Google Web サービスには数種類の認証メカニズムがあり、どの程度の統合が必要かに応じて選択することができます。私が選んだのは、この例の目的にふさわしい使い捨て認証トークンを作成する
ClientTokenバージョンです (リスト 4 を参照)。
リスト 4. Google の utility:get-google-token($Email,$Passwd,$accountType,$source,$service) サービスdeclare function utility:get-google-token($Email,$Passwd,$accountType,$source,$service){ let $params := concat("Email=",$Email, "&Passwd=",$Passwd, "&source=",$source, "&accountType=",$accountType, "&service=",$service) let $uri := concat("https://www.google.com/accounts/ClientLogin?",$params) let $response := httpclient:get(xs:anyURI($uri),false(),()) let $token := substring-after(xmldb:decode($response),"Auth=") return string($token) };
この関数が返すのは、XML ではなくストリングであることに注意してください。XQuery では、関数の入力と出力を制約してデータ型を指定することができます。
- utility:get-google-spreadsheet-feed($Email,$Passwd): この関数 (リスト 5 を参照) は、所有している (または他人の) Google ドキュメント内のドキュメント・リストを Atom フィードとして返します。この関数を例に挙げた理由は、私が使用したのは一般公開されているスプレッドシートなので、XQuery で Google ドキュメントに接続してそのドキュメントを使用する方法を知りたいという開発者もいるだろうと思ったからです。
リスト 5. utility:get-google-spreadsheet-feed($Email,$Passwd) 関数declare function utility:get-google-spreadsheet-feed($Email,$Passwd){ let $accountType := "HOSTED_OR_GOOGLE" let $source := "Dashboards-XQUERY-Example" let $service := "wise" let $token := utility:get-google-token($Email,$Passwd,$accountType,$source,$service) let $headers := <headers> <header name="Authorization" value="GoogleLogin auth={$token}"/> </headers> let $uri := xs:anyURI('http://spreadsheets.google.com/feeds/spreadsheets/private/full') return httpclient:get($uri, false(), $headers) };
この関数は、Google ドキュメント内のドキュメント・リストを取得するための適切な HTTP リクエストを作成します。取得したリストは、Google ドキュメント内のドキュメントを開くために使用することができます。
- utility:get-google-atom-feed(): もう 1 つの興味深いデータ・ソースとしては、Google の E メール・アドレスがあります。リスト 6 を見るとわかるように、データは Atom データ・フィードとして Gmail で公開されます (このサンプル・ダッシュボードで実際にこのソースを使うわけではありませんが、E メールを操作するためのデータ・ソースの一例として覚えておくと便利です)。
リスト 6. utility:get-google-atom-feed() 関数declare function utility:get-google-atom-feed($user,$pass,$label){ let $token := util:string-to-binary(concat($user,':',$pass)) let $headers := <headers> <header name="Authorization" value="Basic {$token}"/> </headers> let $uri := xs:anyURI(concat('https://mail.google.com/mail/feed/atom/',$label)) return httpclient:get($uri, false(), $headers) };
- utility:get-google-cal-feed($Email,$Passwd): 人気の高い Google サービスには、カレンダーのイベント・データを表示する Google Calendar もあります (data.xq では使用していません)。リスト 7 に、このサービスに対応する関数を記載します。
リスト 7. utility:get-google-cal-feed($Email,$Passwd) 関数declare function utility:get-google-cal-feed($Email,$Passwd){ let $accountType := "HOSTED_OR_GOOGLE" let $source := "Dashboards-XQUERY-Example" let $service := "cl" let $token := utility:get-google-token($Email,$Passwd,$accountType,$source,$service) let $headers := <headers> <header name="GData-Version" value="2"/> <header name="Authorization" value="GoogleLogin auth={$token}"/> </headers> let $uri := xs:anyURI( concat('http://www.google.com/calendar/feeds/', string($Email), '/private/full') ) return httpclient:get($uri, false(), $headers) };
data.xq は以上の関数を使って、デジタル・ダッシュボードのソース・ドキュメントとなる壮大な XML ドキュメントを作成します。コードをすでにインストールしている場合は、ブラウザーで data.xq にアクセスしてみてください。図 4 のような画面が表示されるはずです。
図 4. data.xq の取得
上記のマークアップの構造は任意なので、どのような構造にしても構いません。
dashboard.xq XQuery ファイルはその出力として、eXist XML データベース固有の、ダッシュボードを表すシリアライズ・オプションに基づいた HTML ドキュメントを生成します。
declare option exist:serialize
"method=xhtml media-type=text/html indent=yes omit-xml-declaration=no";
|
サンプル・ダッシュボードを作成するには、集約された XML ドキュメントを取得し、utility.xqm に定義された XQuery 関数を使って、Web ページを構成するそれぞれの特定エリアを作成します (図 5 を参照)。
図 5. 関数とダッシュボードとの関連付け
KPI は、特定のメトリックの状態を示す棒グラフと HTML の組み合わせを使って表示します。棒グラフを使用するエリアには、Google Chart API を採用することにしました。この賢い API が作成するのは、販売パイプライン、滞納請求書、タイムシートで使用しているグラフです。
- 滞納請求書: 標準的な条件 (15 日間、30 日間、60 日間) を表す 3 つの個別の棒グラフを用いて、未払いの請求書の状況を示します。
- 販売パイプライン: 6 つの棒グラフで、販売ワークフローのそれぞれの状態に置かれた見込み販売件数を示します。棒グラフの範囲は、パイプラインの各段階で目的とされる件数を表します。
- タイムシート: 棒グラフは従業員ごとに生成されます。従業員の週間勤務時間が 40 時間を超えると、棒の色が赤に変わります。
グラフを作りやすくするため、utility:graph() という XQuery 関数を作成しました。この関数は、utility.xqm に定義されています (リスト 8 を参照)。
リスト 8. utility:graph() 関数
(: Wrap up Google Charting API :)
declare function utility:graph($type,$colors,$size,$markers,$data,$alt){
let $src
:=concat('http://chart.apis.google.com/chart?chf=bg,s,F7F5E6&chco=',$colors,
'&chs=',$size,
'&cht=',$type,
'&chl=',$markers,
'&chd=t:',$data
)
return <img alt="{$alt}"src="{$src}"/>
};
|
utility:graph() 関数は URL を組み立て、その結果として img 要素を返します。Google Chart API のオプションについての詳細は、「参考文献」を参照してください。
サンプル・ダッシュボードには操作対象のデータが必要です。そこで、data.xq が doc() 関数を使用して生成した集約データを取り込み、結果を以下のように $data 変数に保管します。
let $data :=
doc('http://localhost:8080/exist/rest/db/dashboards_with_xquery/xquery/data.xq')
|
$data 変数にこの XML ドキュメントを組み込むということは、すべてのメトリックが同時に測定されることを意味します。すべてのメトリックを同時に測定する必要はありませんが、こうすると、すべてのメトリックで「ハートビート」が統一されることになるため、定期的に結果を保存してパフォーマンスの履歴を表示する場合に便利です。
これから記載するリストで、それぞれの表示エリアを取り上げ、XQuery の実行内容の中心となる基本部分を説明します。これらのリストでは、HTML マークアップと区別しやすいように XQuery コードを太字で強調表示します。
リスト 9 に記載する XQuery コードが表示するのは 3 つの棒グラフです。これらの棒グラフは、比較できるように正規化しなければなりません。範囲として 10,000 を使用していることからわかるように、値を同じ数量で割ってから 100 を掛けることで、棒の使用率を取得しています。
リスト 9. 滞納請求書の棒グラフのコード
<h3>Aging Invoices<sup>(mysql)</sup></h3>
<table>
<tr>
<td>£{$data/data/strategic/financial/invoices/age[@amt='15']}</td>
<td>
{ let $amt :=(xs:float($data/data/strategic/financial/invoices/age[@amt='15'])
div 10000) * 100
return
utility:graph("bhs","4D89F9",
"150x30", "0|10000",$amt, '15 day')
}
</td>
<td>15 Day</td> </tr>
<tr>
<td>£{$data/data/strategic/financial/invoices/age[@amt='30']}</td>
<td>{ let $amt :=
(xs:float($data/data/strategic/financial/invoices/age[@amt='30'])
div 10000) * 100
return
utility:graph("bhs",
"4D89F9",
"150x30",
"0|10000",
$amt,
'30 day')
} </td>
<td>30 Day</td> </tr>
<tr>
<td>£{$data/data/strategic/financial/invoices/age[@amt='60']}</td>
<td>{ let $amt := (xs:float($data/data/strategic/financial/invoices/age[@amt='60'])
div 10000) * 100
return
utility:graph("bhs","4D89F9", "150x30",
"0|10000", $amt, '60 day') } </td>
<td>60 Day</td> </tr>
</table>
|
表の各行では正しいデータを選択しなければなりません。そのために使用しているのが、合計値を表す amt 属性です。このデータは、元々は MySQL データベースから生成されたものなので、MySQL サーバーが稼働中であること、そしてサーバーにサンプル・データ・セットがロードされていることを確認してください。また、設定を指示する README ファイルの説明に従って、data.xq コードのコメントを外す必要もあります。
販売パイプラインのデータは、一般公開されている Google ドキュメントのスプレッドシートから取得します。つまり、事実上 Atom フィードからデータを選択するということです。このデータを表示する際に唯一奇異に映る点は、(Google スプレッドシートからの) Atom フィードが提供するデータは、リスト 10 に示すように何行にもわたる、カンマで区切られたデータになっていることです。
リスト 10. 販売パイプラインのコード
<h3>Sales Pipeline
<sup>(google spreadsheet)</sup></h3>
<table>
{for $item in $data/data/strategic/sales_pipeline/atom:feed/atom:entry/atom:content
return
let $cols := tokenize($item,',')
return
<tr>
<td>£{substring-after($cols[2],':')}</td>
<td>{
let $amt := (xs:float(substring-after($cols[2],':'))
div 10000) * 100 return
utility:graph("bhs",
"4D89F9,C6D9FD",
"150x30",
"0|10000",
$amt,
substring-after($cols[1],':'))
}</td>
<td>{
substring-after($cols[1],':')
}</td>
</tr> }
</table>
|
カンマで区切られたデータが混在する XML は多少奇妙に見えますが、XQuery にはこのような XML を構文解析するためのオプションが豊富に揃っています。私は tokenize() 関数を使用して各列を区分してから、substring-after() 関数を使ってデータ値を取得しています。
タイムシート・データを収集する最適の方法が、単にローカル・スプレッドシートを開くだけという場合もあります。現在、Excel が XML フォーマットをサポートするようになっているので、スプレッドシートの構造を知るだけで、リスト 11 に記載するコードのようにスプレッドシートを操作することができます。
リスト 11. Excel スプレッドシート・データの操作
<h3>Weekly Timesheets <sup>(MS Excel)</sup></h3>
<table> {
for $item in $data/data/operational/project/timesheet/
ss:Workbook/ss:Worksheet/ss:Table/ss:Row[not(position()=1)]
return
<tr> <td>{$item/ss:Cell[1]}</td>
<td>{$item/ss:Cell[2]}</td> <td>
{
let $hours := xs:decimal(($item/ss:Cell[3] div 40 ) * 100)
return
if ($hours < 100) then
utility:graph("bhs",
"4D89F9,C6D9FD",
"150x30",
"0|40",
$hours,
$item/ss:Cell[3])
else
utility:graph("bhs",
"FF5858,C6D9FD",
"150x30",
"0|40",
$hours,
$item/ss:Cell[3]) }
</td> </tr>
}
</table>
|
XQuery を使うと、列のラベルが含まれる最初の行を使用しないようにすることができます。その他に考慮しなければならないのは、従業員の勤務時間が週 40 時間を超えた場合に棒グラフを赤で表示する機能だけです。XQuery の if|then|else 文では、$hours 変数が 40 より大きいかどうかの判断に基づいて、棒グラフを選択することができます。
Microsoft がオープン・スタンダード・ベースの XML ソース・フォーマットを提供するようになったということは、長年使っていたバイナリー・フォーマットからの卒業を意味します。バイナリー・フォーマットは速さの点では実に優れていますが、閉鎖的であるため、ここで説明するような統合を実現するのが困難です。スプレッドシートを表す Excel XML フォーマットはおおむね合理的と言えますが、その特有の構造に伴う利点についての議論は、他の人の判断に委ねることにします。
data.xq が生成するテスト要素によって、Web サイトがオンライン状態であるかどうか、そして Web サーバーが応答するまでにどれだけの時間がかかったのかがわかります。私は巧妙なものを使う代わりに、単純に status 属性を使って判断をするテストを実行しました (リスト 12 を参照)。
リスト 12. Web サイトのテスト
<h3>Website Operation <sup>(xquery logic)</sup></h3>
<table> {
for $item in $data//website_ok/website
return
<tr>
<td>{$item/@title/string()}</td>
<td>
{
if ( $item/test/@status = '200' ) then
attribute style{'background-color:green'}
else
attribute style{'background-color:red'
}
}  </td>
<td>{
$item/test/@response/string()
} ms</td>
</tr>
}
</table>
|
同じような関数を使って、存在の有無をテストする以上の機能に拡張することは可能です。例えば、連絡先フォームが機能しているかどうかをテストすることなどが考えられます。
リマインダーでは、別の Web アプリケーション (http://www.backpackit.com/) からデータを取得し、XQuery FLWR (for、let、where、return) 式を使って XML Web サービスを繰り返し処理しているだけに過ぎません (リスト 13 を参照)。
リスト 13. XML Web サービスでの繰り返し処理
<h3>Reminders <sup>(simple webservice)</sup></h3> <table> {
for $item in $data/data/operational/project/backpack/reminders/reminder
return
<tr>
<td>{
string($item/creator/@name)
}:</td>
<td> {
$item/content
}</td>
</tr>
}
</table>
|
読者の刺激となるように、外部ウィジェットを組み込むと面白いことになると考えました。この点から、ダッシュボードはマッシュアップにより近いものとなっています。compete.com Web サイトは、複数の Web サイトの実績を比較して表示する上で素晴らしい成果をあげています。
この記事でサンプル・ダッシュボードを作成した目的は、何かを素早く作成したり、極めて再利用しやすいものを作成したりすることではなく、XQuery の使い方を説明することでした。このダッシュボードを最適化するには、例えば以下の提案があります。
cron(およびwgetまたはcurl) を使用して dashboard.xq の実行をスケジューリングするという方法で、dashboard.html を生成する。- または、eXist XML データベースのスケジューラーを使用して dashboard.html の作成をスケジューリングする。
- 各データ・ソースからの結果をそれぞれ単独で XML データベース内に保管する。
- 各 KPI をモジュール化し、例えば XSLT を使用してデータの表示を管理する。
今回 3 つの単純な XQuery ファイルを使用して Web ダッシュボードを実装しました。このダッシュボードでは、データを集約して表示する XQuery と XML データベースの威力を明らかにすることができました。
| 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|---|---|---|
| Source files for the example dashboard | src.zip | 13KB | HTTP |
学ぶために
- 情報ダッシュボードの設計: Stephen Few がわかりやすく簡潔にまとめている、ダッシュボードを設計する際の必須事項を読んでください。
- XQuery 1.0: An XML Query Language: XQuery 言語について概説している主要な資料です。
- XML Path Language (XPath) 2.0: 関連する XPath 2.0 仕様を読んでください。
- eXist XML データベース: XML データ・モデルに応じて XML データを保管し、効率的な索引ベースのXQuery 処理機能を備えたこのオープンソースのデータベース管理システムについての詳細を調べてください。
- Atom フィード仕様: Atom フィードの XML マークアップ・フォーマットに関する IETF (Internet Engineering Task Force) による仕様を読んでください。
- Google API Web サービス: すべての Google API を網羅した主要なリストを参照してください。
- Google ClientLogin 認証: 大半の Google API で使われている ClientLogin 認証の要求方法および使用方法を学んでください。
- Google カレンダー Web サービス: Google カレンダー・サービスの API 資料を読んでください。
- Google ドキュメント Web サービス: Google ドキュメント・リスト・サービスの API 資料を読んでください。
- Google スプレッドシート Web サービス: Google スプレッドシート・サービスの API 資料を読んでください。
- 汎用 Google Atom フィード: Atom フィードを発行する Google Web サービスの概要を読んでください。
- Google Chart API: Google Chart サービスの API 資料を読んでください。
- 37 Signals の Backpack API Web サービス: イントラネット・グループウェアとしてよく使用されている 37 Signals Backpack サービスの API を参照してください。
- データ・インク: 1983年に Tufte が考案した概念、データ・インク比について詳しく調べてください。データ・インク比は、情報設計のなかでは何よりもまずデータを利用するという考えを中心に展開しています。
- 情報ダッシュボードの設計: Stephen Few が説明する、円グラフの使用を再考すべきもっともな理由を読んでください。
- IBM XML 認定: XML や関連技術の IBM 認定技術者になる方法について調べてください。
- XML Technical library: 広範な技術に関する記事とヒント、チュートリアル、標準、そして IBM Redbooks については、developerWorks XML ゾーンを参照してください。
- developerWorks の Technical events and webcasts: これらのセッションで最新情報を入手してください。
- developerWorks podcasts: ソフトウェア開発者向けの興味深いインタービューとディスカッションを聞いてください。
製品や技術を入手するために
- MySQL Community データベース・サーバー: MySQL データベースをダウンロードしてサンプル・ダッシュボードと統合してみてください。
- MySQL JDBC コネクター: eXist データベースに必要な JDBC コネクターをダウンロードしてください。
- IBM 製品の評価版: DB2®、Lotus®、Rational®、Tivoli®、および WebSphere® のアプリケーション開発ツールとミドルウェア製品を体験するには、IBM SOA Sandbox のオンライン・トライアルをダウンロードするか、検討してみてください。
議論するために
- XML ゾーンのディスカッション・フォーラム: XML 関連のフォーラムに参加してください。
- developerWorks blogs: developerWorks blogs から developerWorks コミュニティーに加わってください。

Jim Fuller はプロとして 15 年の経験を持つ開発者で、自国のアメリカ、そしてイギリスの両方で数々の一流ソフトウェア会社と協力しています。技術関連の本を共同で執筆した経験があり、XML 技術をテーマとした講演、記事の執筆活動は定期的に行っています。彼は、XML Prague 設立時の委員会メンバーで、EXSLT の責任者の 1 人でもありました。余暇は、XML データベースと XQuery をいじって過ごしています。いくつかの会社 (FlameDigital、Webcomposite s.r.o.) で技術ディレクターを務めています。