LoginSignup
2
2

More than 3 years have passed since last update.

QlikView Extensionをつくってみる

Posted at

QlikView Extensionの作り方について。日本語の紹介サイトがあまりなく、情報収集に困る方も多いであろうから参考になれば幸いである。

対象

本稿ではQlikView(v11以上)を扱っている。Qlik SenseもExtensionと呼ばれる技術があるらしいが、本稿では取り扱っていない。

QlikView Extension

概説

QlikViewではビルトインのいくつかのチャートがある。しかしながら、定型的で表現には限界がある。Extensionを使うことで、CSSとJavaScriptにより自由な表現を行うことができる。

制約

WebViewモードでしか使えない。表現をWebブラウザーのレンダリングに頼っているためである。

活用例

運送会社の案件で、ドライバーごとの移動を視覚化したいとの依頼があった。それに応じ移動経路を地図にプロットするExtensionを開発した。

QlikView Extensionの作り方

フォルダー構成

基本的な構成は次の通りとなる。

 エクステンション名/
  ├ Definition.xml
  ├ icon.png
  ├ Script.js
  ├ DynProperties.qvpp
  ├ css/
  │ ├ Definition.xml
  │ ├ a.css
  │ └ b.css
  └ js/
    ├ Definition.xml
    ├ c.js
    └ d.js

css/やjs/といったサブフォルダーは設けず、単一のフォルダー(エクステンション名/)に全てまとめても良い。フォルダー毎にDefinition.xmlが必要となるため、サブフォルダーを作るのであれば同ファイルが必要となる。

Definition.xml

概要

ファイル名は固定。その名の通りExtensionのプロパティ定義ファイルである。日本語を含むときはBOM付きでないと文字化けするかもしれない。次のリンクに設定項目は網羅される。

エクステンション名/Definition.xml

デフォルトのPageHeightは40。値を大きくすればロードするレコードの量が増える。

Definition.xml
<?xml version="1.0" encoding="UTF-8" ?>
<ExtensionObject Path="エクステンション名"
                 Label="エクステンション日本語名"
                 Description="エクステンションの説明"
                 PageHeight="100"
                 Type="object">

  <Dimension Label="軸" Initial="" TargetName="軸" />
  <Measurement Label="メジャーA" Initial="" />
  <Measurement Label="メジャーB" Initial="" />

  <Initiate Name="Chart.Dimension.0.Field" Value="軸" />
  <Initiate Name="Chart.Expression.0.0.Definition" Value="メジャーA" />
  <Initiate Name="Chart.Expression.0.0.Definition" Value="メジャーB" />

  <Initiate Name="Chart.Dimension.0.SuppressNull" Value="1" /> 
  <Initiate Name="Chart.Dimension.0.Sort.PrimarySortOrder" Value="1" /> 
</ExtensionObject>

前述の通りプロパティはいろいろあるので、例えばExtensionの枠が鬱陶しいなと思ったら、このように追記すれば消せる。

Definition.xml(一部)
  <Initiate Name="Caption.Show" Value="0" />
  <Initiate Name="Caption.Icon.SendToExcel" Value="0" />
  <Initiate Name="Caption.Allow.Maximize" Value="0" />
  <Initiate Name="Caption.Allow.Minimize" Value="0" />
  <Initiate Name="Caption.Text" Value="エクステンション日本語名" />
  <Initiate Name="Layout.Allow.MoveSize" Value="0" />
  <Initiate Name="Layout.Border.Use" Value="0" />

エクステンション名/サブフォルダー名/Definition.xml

これ以上の情報はいらない。このDefinition.xmlをサブフォルダー毎に格納すればよい。

Definition.xml
<?xml version="1.0" encoding="UTF-8" ?>
<ExtensionObject Type="object">
</ExtensionObject>

icon.png

概要

ファイル名は固定。本Extensionのアイコン。32 x 32px位でよいと思う。

Script.js

概要

ファイル名は固定。initialのスクリプト。日本語を含むときはBOM付きでないと文字化けするかもしれない。

ネットに転がっているExtensionのコードを探したが、後述のパターンAかパターンBの書き方が多いように見受けられた。何を隠そうQv.AddExtensionの呼び出し順が異なるだけである。留意したいのは、Qv.AddExtensionのコールバックでthis.Dataオブジェクトにアクセスできるようになるということだ。

エクステンション名/Script.js:パターンA

Script.js(パターンA)
function ExtensionInit() {
  var _this = this;

  var cssFiles = [];
  var QV_LOAD_URL = Qva.Remote + (Qva.Remote.indexOf("?") >= 0 ? "&" : "?") + "public=only" + "&name=";
  cssFiles.push("Extensions/" + QV_LOAD_URL + "/css/a.css");
  cssFiles.push("Extensions/" + QV_LOAD_URL + "/css/b.css");
  for (var i = 0; i < cssFiles.length; i++) {
    Qva.LoadCSS(QV_LOAD_URL + cssFiles[i]);
  }

  var jsFiles = [];
  jsFiles.push("Extensions/" + QV_EXTENSION_NAME + "/js/c.js");
  jsFiles.push("Extensions/" + QV_EXTENSION_NAME + "/js/d.js");

  Qv.LoadExtensionScripts(jsFiles,
    function () {
      alert(Object.keys(_this.Data.Rows));
      subA();
      subB();

      function subA() {
        // サブルーチンA
      }

      function subB() {
        // サブルーチンB
      }
    });
}

var QV_EXTENSION_NAME = "エクステンション名";
Qv.AddExtension(QV_EXTENSION_NAME, ExtensionInit);

エクステンション名/Script.js:パターンB

Script.js(パターンB)
function ExtensionInit() {
  var QV_EXTENSION_NAME = "エクステンション名";

  var cssFiles = [];
  var QV_LOAD_URL = Qva.Remote + (Qva.Remote.indexOf("?") >= 0 ? "&" : "?") + "public=only" + "&name=";
  cssFiles.push("Extensions/" + QV_LOAD_URL + "/css/a.css");
  cssFiles.push("Extensions/" + QV_LOAD_URL + "/css/b.css");
  for (var i = 0; i < cssFiles.length; i++) {
    Qva.LoadCSS(QV_LOAD_URL + cssFiles[i]);
  }

  var jsFiles = [];
  jsFiles.push("Extensions/" + QV_EXTENSION_NAME + "/js/c.js");
  jsFiles.push("Extensions/" + QV_EXTENSION_NAME + "/js/d.js");

  Qv.LoadExtensionScripts(jsFiles,
    function () {
      Qv.AddExtension(QV_EXTENSION_NAME,
        function () {
          var _this = this;

          alert(Object.keys(_this.Data.Rows));
          subA();
          subB();

          function subA() {
            // サブルーチンA
          }

          function subB() {
            // サブルーチンB
          }
        });
    });
}

ExtensionInit();

データへのアクセス

Rowsオブジェクトにアクセスするだけ。とてもかんたん。

Script.js(一部)
alert(this.Data.Rows[0][0].text);

ページサイズを可変にする例

Definition.xmlに次の通り追加することで、プロパティダイアログにテキストボックスができる。

Definition.xml(一部)
<Text Label="ページサイズ" Type="text" Expression="500" />

Script.jsで同テキストボックスを参照するようにすれば、それに応じてページサイズを変更できる。

Script.js(一部)
Data.SetPagesizeY(_this.Layout.Text0.text.toString());

DynProperties.qvpp

概要

ファイル名は固定。DynProperties.qvppはプロパティダイアログの表示(見た目)を管理している。Extensionをインストールするか、当該Extensionの埋め込まれたドキュメントを開くと自動的に生成される。

パッケージング

概要

qarファイルがExtensionのファイルとなる。実態はただのzipファイル。拡張子を除けばファイル名に制約はない。

作り方

zipで固めて、拡張子をqarとするだけ。

 1. フォルダー エクステンション名/をzipで固める(例:エクステンション名.zip)
 2. 同ファイルをの拡張子をzipからqarへ変更する(例:エクステンション名.qar)

インストール

qarファイルはQlikViewに関連付けられていることを前提にダブルクリックするだけ。インストールが上手く行けばQlikViewのダイアログが表示される。

再インストールの際は、QlikViewのドキュメントからも一度削除し、再配置すのが無難。

アンインストール

次のフォルダから当該Extension名のフォルダを削除すればよい。

 %AppData%\Local\QlikTech\QlikView\Extensions\Objects\エクステンション名

その他

QVとQVAの名前空間について

提供されるAPIは、Qv.ExtensionやQva.AddExtensionといったように、QvとQvaの名前空間(?)が混在している。QlikView v10とv11以降の違いとも言われるが、Qvに集約されたコードを見た試しがない。

参考

GitHubにもいくつか例はあるし、それらを参考にできると思う。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2