Tableau Web Data Connector開発ことはじめ

  • 投稿日:
  • by
  • カテゴリ:

Author

大野 智之Tomoyuki Ohno

大野 智之

リックソフトの大野です。
さて今回は、Tableauの機能の1つであるWeb Data Connectorの開発方法と、Tableau上での利用方法についてご紹介したいと思います。

はじめに

Tableauには様々なデータコネクタが用意されており、Web Data Connector(Web データコネクタ, WDC)はその中の1つとして用意されています。

はじめに

Web Data Connectorを利用することで、ユーザー自身でカスタムのデータコネクタを作成することができます。すなわち、Tableau標準のデータコネクターとして用意されていないデータソースを、Tableau上で扱うことが出来るようになります。

Web Data Connectorとは何でしょうか?

さて、皆さんは「Web Data Connector」というキーワードから、まずどのような機能を想像されますでしょうか。
例えば、インターネットやイントラネット上の(HTTP/HTTPSで公開されている)REST APIをそのまま(無加工で、URLを指定するだけで)データソースとして扱うことが出来る機能を想像される方もいらっしゃるのではないでしょうか。しかし、残念ながらWeb Data Connectorはそのような機能ではありません。
Web Data Connectorとは、すなわちTableau専用のデータ形式(データフォーマット)の1つであり、REST APIとして提供されているデータソースをTableau上で扱いたい場合は、Web Data Connectorの「形式」に合わせてTableauへ渡す必要があります。また、対応するWeb Data Connectorはユーザー側で開発する必要があります。
なお、Web Data Connectorの開発は、コツさえ掴んでしまえばそれほど難しくはありません。また、今回はREST APIを例に進めていきますが、データソースは必ずしもREST APIである必要はなく、最終的にWeb Data Connectorとして扱えるものであればどのようなものでも対応可能です。
次からは、実際にWeb Data Connectorの開発を進めていきます。

開発環境の準備

Tableau社では、開発者向けにWeb Data ConnectorのSDKをGithubで公開しています。このSDKを使用することで簡単にWeb Data Connectorを開発することができます。
必須の環境ではありませんが、導入されることを強く推奨します。特に、SDKで提供されるWeb Data Connector Simulatorは、Web Data Connectorのデバッグを行う際においてとても役立ちます。

前提条件

開発環境には、事前に次のソフトウェアをインストールしておきます。

  • Git
  • Node.js

手順

1.WDC SDKを入手する

ターミナルを開き、以下のコマンドを入力し、WDC SDKのGitリポジトリを取得(Clone)します。

[html] $ git clone https://github.com/tableau/webdataconnector.git [/html]

リポジトリの取得が完了したら、リポジトリのディレクトリに切り替えます。

[html] $ cd webdataconnector [/html]

2.依存関係のインストール

npmで依存関係をインストールします。(スーパーユーザーで実行します)

[html] # npm install --production [/html]

3.テスト用のWebサーバの起動

以下のコマンドを入力し、テスト用のWebサーバを起動します。

[html] $ npm start [/html]

次のURLをWebブラウザで開きます。
(ローカル環境以外でWebサーバを起動している場合、「localhost」およびポート番号の値は環境に応じて変更します)

[html] http://localhost:8888/Simulator/index.html [/html]

Web Data Connector Simulator が表示されます。

Web Data Connector Simulator

Web Data Connectorの作成

開発環境を準備したら、次にWeb Data Connectorの作成に進みます。
今回は、JiraのREST APIをもとに、Web Data Connectorの作成を進めていきます。

前提条件

  • Webサーバ (Apache, Nginxなど)
    ※開発環境と同じホスト(ドメイン、IPアドレス)上で動作させます。
  • moment.js (https://momentjs.com/)
    以下のHTML, JavaScriptと同じディレクトリ配下に配置します。
  • PHP (cURLモジュール, JSONモジュールが有効であること)
    ※PHPについては後述しますが、同様の対応が行えればPHP以外の言語でも可能です。

手順

1.HTMLファイルの作成

まず最初にHTMLファイルを作成します。Webサーバの公開ディレクトリ上に配置します。
ここで作成したHTMLファイルは、Web Data ConnectorのエンドポイントとしてTableauで参照します。
なお、インターネットに接続されていない環境で本ファイルを運用する場合は、HTMLファイル上にてCDNやTableau社のサーバを参照しているライブラリを、ライブラリの提供元より別途ダウンロードのうえ、参照先を適宜変更してください。

[html] <index.html> <head> <title>Test Web Data Connector</title> <meta http-equiv="Cache-Control" content="no-store" /> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js" type="text/javascript"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" crossorigin="anonymous"></script> <script src="https://connectors.tableau.com/libs/tableauwdc-2.3.latest.js" type="text/javascript"></script> <script src="moment.js" type="text/javascript"></script> <script src="jiraWDC.js" type="text/javascript"></script> </head> <body> <div class="container container-table"> <div class="row vertical-center-row"> <div class="text-center col-md-4 col-md-offset-4"> <button type="button" id="submitButton" class="btn btn-success" style="margin: 10px;">Get Data</button> </div> </div> </div> </body> </html> [/html]

2.JavaScriptファイルの作成

次に、JavaScriptファイルを作成します。HTMLファイルと同じディレクトリ配下に配置します。
まず最初に、ひな形として以下のコードを入力します。

[html] (function () { var myConnector = tableau.makeConnector(); myConnector.getSchema = function (schemaCallback) { }; myConnector.getData = function (table, doneCallback) { }; tableau.registerConnector(myConnector); })(); [/html]

次に上記に対して必要なコードを追加していきます。
最終的なコードについては次の通りとなりますが、それぞれのブロックについて解説をします。

最終的なコード

①スキーマ

Web Data Connectorより出力されるデータのスキーマを定義します。
REST APIから取得されるデータのうち、必要なフィールドをスキーマとして定義します。
なお、Web Data Connectorが対応するデータ型については、Tableau Web Data ConnectorのAPIリファレンスに記載されています。

[html] myConnector.getSchema = function (schemaCallback) { var cols = [ { id: "id", dataType: tableau.dataTypeEnum.int }, { id: "key", dataType: tableau.dataTypeEnum.string }, { id: "summary", dataType: tableau.dataTypeEnum.string }, { id: "project", dataType: tableau.dataTypeEnum.string }, { id: "projectCateogory", dataType: tableau.dataTypeEnum.string }, { id: "issuetype", dataType: tableau.dataTypeEnum.string }, { id: "status", dataType: tableau.dataTypeEnum.string } { id: "prirority", dataType: tableau.dataTypeEnum.string }, { id: "creator", dataType: tableau.dataTypeEnum.string }, { id: "reporter", dataType: tableau.dataTypeEnum.string }, { id: "assignee", dataType: tableau.dataTypeEnum.string }, { id: "created", dataType: tableau.dataTypeEnum.datetime }, { id: "updated", dataType: tableau.dataTypeEnum.string }, { id: "resolutiondate", dataType: tableau.dataTypeEnum.datetime }, { id: "duedate", dataType: tableau.dataTypeEnum.datetime} ]; var tableSchema = { id: "issues", alias: "JIRA Issue list", columns: cols }; schemaCallback([tableSchema]); }; [/html]

②データの取得と代入

指定されたリソースよりJSON形式でデータを取得し、Tableauへ受け渡します。
代入を行うデータ(オブジェクト)は、JiraよりREST APIを参照した際に出力されるJSONをもとに定義します。
代入先の配列は、①で定義したスキーマに合わせます。

なお、以下のコードでは、Jiraからのデータ取得は同一サーバ上に設置したPHPで行い、JavaScriptではPHPで処理された結果を取得しています。
これは、認証情報(ユーザー名・パスワード、トークン等)の隠蔽と、AJAX通信におけるクロスドメイン制限を回避するためです。
(PHPはあくまでも一例で、その他の言語でも同様の処理を実装することで、同様の結果は得られます)

また、データの加工に係る処理(前処理的なもの)が必要となる場合も、なるべくサーバサイドで処理を行った方がトラブルも少ないためお勧めです。
(WebブラウザおよびTableauにおけるJavaScriptの互換性の影響や、デバッグのしやすさ等を考慮し、クライアントサイド側の実装は最低限とすることをお勧めします)

[html] myConnector.getData = function (table, doneCallback) { $.getJSON("jiraWDCdata.php", function(resp) { var issues = resp.issues, tableData = []; len = issues.length; for (var i = 0; i < len; i++) { tableData.push({ "id": issues[i].id, "key": issues[i].key, "summary": issues[i].fields.summary, "project": issues[i].fields.project.name, "projectCategory": issues[i].fields.project.projectCategory.name, "issuetype": issues[i].fields.issuetype.name, "status": issues[i].fields.status.name, "priority": issues[i].fields.priority.name, "creator": issues[i].fields.creator.displayName, "reporter": issues[i].fields.reporter.displayName, "assignee": issues[i].fields.assignee.displayName, "created": cnvDateTime(issues[i].fields.created), "updated": cnvDateTime(issues[i].fields.updated), "resolutiondate": cnvDateTime(issues[i].fields.resolutiondate), "duedate": issues[i].fields.duedate }); } table.appendRows(tableData); doneCallback(); }); }; [/html]

※PHPコードの例

[html] <jiraWDCdata.php> <?php $url = 'https://test.example/jira/rest/api/2/search'; $jql = "project=TESTPRJ"; $query = "jql=". urlencode($jql); $username = 'hogeuser'; $password = 'hogepassword'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url . '?' . $query); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password); $res = curl_exec($ch); curl_close($ch); header('content-type: application/json; charset=utf-8'); echo $res; [/html]

③イベントリスナ

TableauからWeb Data Connectorへアクセスする際のトリガーとなる処理を追加します。

[html] $(document).ready(function() { $("#submitButton").click(function() { tableau.connectionName = "JIRA Issues"; tableau.submit(); }); }); [/html]

④日時形式の変換

JIRA REST APIより出力される日付をTableauのdatetime型として扱えるよう、日時形式の変換処理を追加します。
なお、ここでは日時形式変換のために、Moment.js (https://momentjs.com/)を使用しています。

[html] function cnvDateTime(strDateTime) { dateFormat = "Y-MM-DD HH:mm:ss"; return moment(strDateTime).format(dateFormat); } [/html]

以上の通りコーディングを進めていくと、次のようなコードになります。

[html] <jiraWDC.js> (function () { var myConnector = tableau.makeConnector(); myConnector.getSchema = function (schemaCallback) { var cols = [ { id: "id", dataType: tableau.dataTypeEnum.int }, { id: "key", dataType: tableau.dataTypeEnum.string }, { id: "summary", dataType: tableau.dataTypeEnum.string }, { id: "project", dataType: tableau.dataTypeEnum.string }, { id: "projectCateogory", dataType: tableau.dataTypeEnum.string }, { id: "issuetype", dataType: tableau.dataTypeEnum.string }, { id: "status", dataType: tableau.dataTypeEnum.string } { id: "prirority", dataType: tableau.dataTypeEnum.string }, { id: "creator", dataType: tableau.dataTypeEnum.string }, { id: "reporter", dataType: tableau.dataTypeEnum.string }, { id: "assignee", dataType: tableau.dataTypeEnum.string }, { id: "created", dataType: tableau.dataTypeEnum.datetime }, { id: "updated", dataType: tableau.dataTypeEnum.string }, { id: "resolutiondate", dataType: tableau.dataTypeEnum.datetime }, { id: "duedate", dataType: tableau.dataTypeEnum.datetime} ]; var tableSchema = { id: "issues", alias: "JIRA Issue list", columns: cols }; schemaCallback([tableSchema]); }; myConnector.getData = function (table, doneCallback) { $.getJSON("jiraWDCdata.php", function(resp) { var issues = resp.issues, tableData = []; len = issues.length; for (var i = 0; i < len; i++) { tableData.push({ "id": issues[i].id, "key": issues[i].key, "summary": issues[i].fields.summary, "project": issues[i].fields.project.name, "projectCategory": issues[i].fields.project.projectCategory.name, "issuetype": issues[i].fields.issuetype.name, "status": issues[i].fields.status.name, "priority": issues[i].fields.priority.name, "creator": issues[i].fields.creator.displayName, "reporter": issues[i].fields.reporter.displayName, "assignee": issues[i].fields.assignee.displayName, "created": cnvDateTime(issues[i].fields.created), "updated": cnvDateTime(issues[i].fields.updated), "resolutiondate": cnvDateTime(issues[i].fields.resolutiondate), "duedate": issues[i].fields.duedate }); } table.appendRows(tableData); doneCallback(); }); }; tableau.registerConnector(myConnector); $(document).ready(function() { $("#submitButton").click(function() { tableau.connectionName = "JIRA Issues"; tableau.submit(); }); }); })(); function cnvDateTime(strDateTime) { dateFormat = "Y-MM-DD HH:mm:ss"; return moment(strDateTime).format(dateFormat); } [/html]

デバッグ

デバッグには、先に紹介しました「Web Data Connector Simulator」を利用します。

手順

1.Web Data Connector Simulatorを開きます。

ローカル環境の場合は、次のURLをWebブラウザへ入力し、Web Data Connector Simulatorを開きます。
(ローカル環境以外でWebサーバを起動している場合、「localhost」およびポート番号の値は環境に応じて変更します)

[html] http://localhost:8888/Simulator/index.html [/html]

2.Connector URLへ、今回作成したWeb Data ConnectorのURLを入力します。

Web Data ConnectorのURLを入力

3.「Start Interactive Phase」をクリックします。

Start Interactive Phase」をクリック

4.「Get Data!」をクリックします。

「Get Data!」をクリック

5.HTML, JavaScript各コードに問題なければ、設定されたスキーマが表示されます。

スキーマが表示されずエラーが表示される、スキーマの表示結果が意図した結果とは異なる場合は、コードの確認・調整を行います。

設定されたスキーマが表示

6.「Fetch Table Data」をクリックします。

「Fetch Table Data」をクリック

7.問題なくデータが取得できれば、以下のように取得結果が表示されます。

データが取得できない、あるいはエラーになる場合は、コードの確認・調整と、取得元の確認(取得元のURLが正しいこと、取得元のデータに問題ないことの確認)を行います。

取得結果が表示

作成したWeb Data ConnectorをTableauで利用する

デバッグして問題なくWeb Data Connectorが動作することを確認したら、早速Tableauで利用してみましょう。

手順

1.Tableauを開き、Web データコネクタを選択します。

Web データコネクタを選択

2.URLを入力し、Enterキーを押下します。

URLを入力し、Enterキーを押下

3.「Get Data!」をクリックします。

「Get Data!」をクリック

4.データソース画面が表示されますので、「今すぐ更新」をクリックします。

「今すぐ更新」をクリック

5.データの取得が行われ、表に一覧されます。

表に一覧

6.取得されたデータをもとに、Tableauで分析が行えるようになります。

Tableauで分析

おわりに

TableauのWeb Data Connector機能を利用すると、Tableau標準のデータコネクタとして用意されていないデータソースも扱えることがお分かりいただけたかと思います。
今回はJiraのREST APIをもとに解説を進めていきましたが、Jiraに限らずREST APIを利用できるシステムであれば同様の要領で対応いただけます。また、REST APIに対応していないシステムであっても、対応はそれほど難しくないと思います。
本内容がTableauでのWeb Data Connector利用の参考としていただけますと幸いです。

Appendix:Tableau Web Data Connectorに関するリソース

本内容ではWeb Data Connectorの基本的な機能のみを解説しましたが、Web Data Connectorにはこの他にも様々な機能が用意されています。
詳細については、Tableau社がGithub上に公開しているTableau Web Data Connectorのサイト(下記)をご参照ください。

Tableau Web Data Connectorについて

Tableau について

ご不明な点がございましたら、お気軽に弊社にお問合せください。

お問い合わせ