2023年8月29日火曜日

Oracle JETのTag CloudをOracle APEXで扱う

 最近の記事でOracle JETのTreemapをOracle APEXで扱う方法を紹介しました。手順としてはほぼ同じですが、今回はOracle JETのTag CloudをOracle APEXで扱ってみます。

作成するアプリケーションは以下のように動作します。


Oracle JET Cookbookで紹介されているTag CloudのBasicを実装しています。


以下より実装手順を説明します。

Oracle JET CookbookではJSON形式のファイルsocialNetworks.jsonをデータソースとしています。Oracle APEXのアプリケーションでは、データベースの表をデータソースとして使用します。

socialNetowrks.jsonにはソーシャルネットワークの名前、年齢層ごとと全体の使用率、URL
が記載されています。今回のタグクラウドの実装で使用するのは、全体の使用率のみです。このJSONデータは後ほど、データ・ロード定義を作成する際にサンプルとして使うため、手元のPCにファイルとしてダウンロードしておきます。

以下のクイックSQLのモデルより、表TCLD_SOCIAL_NETWORKSを作成します。元のJSONデータでは属性idがソーシャルネットワーク名になっていますが、表TCLD_SOCIAL_NETWORKSでは列IDは主キー(サロゲート・キー)とし、ソーシャル・ネットワーク名は列NAMEに保存します。
# prefix: tcld
social_networks
    name vc20 /nn /unique
    c14_17 num
    c18_34 num
    c35_54 num
    total num
    url vc200
SQLの生成SQLスクリプトを保存レビューおよび実行を順次実施します。表の作成までを実施し、アプリケーションは作成しません。


タグクラウドを組み込むAPEXのアプリケーションを作成します。

アプリケーション作成ウィザードを起動します。アプリケーションの名前JET Tag Cloudとします。

デフォルトで作成されているホーム・ページを削除し、表TCLD_SOCIAL_NETWORKSをデータソースとした対話グリッドをページとして追加します。


対話グリッドページ名Tag Cloud表またはビューとしてTCLD_SOCIAL_NETWORKSを選択します。編集を許可を選択します。

以上でアプリケーションの作成を実行します。


アプリケーションが作成されます。タグクラウドはページ番号Tag Cloudのページに実装します。


socialNetworks.jsonを表TCLD_SOCIAL_NETWORKSにロードする際に使用する、データ・ロード定義を作成します。

共有コンポーネントデータ・ロード定義を開きます。


作成済みのデータ・ロード定義が一覧されます。作成をクリックします。


データ・ロードの作成として最初からを選択します。

へ進みます。


データ・ロード定義の名前Tag Cloudとします。ターゲット・タイプ表名としてTCLD_SOCIAL_NETWORKSを選択します。

へ進みます。


サンプル・データのソース・タイプとしてファイルのアップロードを選択し、すでにダウンロードしているsocialNetworks.jsonサンプル・ファイルとして選択します。

へ進みます。


ソース列ID(Varchar2(50))マップ先Name(Varchar2)に変更します。それ以外は、デフォルトでソース列データベースの列名が一致しているため、ソース列に適切なマップ先が選択されています。

以上の設定でデータ・ロードの作成をクリックします。


データ・ロード定義Tag Cloudが作成されます。設定を調整するためにTag Cloudを開きます。


静的IDをtag_cloudからTAG_CLOUDに変更します。PL/SQLのコード中で使用するIDは大文字にしたいという理由なので、必ずしも必要な作業ではありません。設定ロード・メソッド置換に変更します。

以上の変更を行い、変更の適用をクリックします。


以上でデータ・ロード定義の作成は完了です。

ページ・デザイナでページTag Cloudを開きます。

Breadcrumb BarにあるJET Tag Cloudを削除します。JET Tag Cloudの上でコンテキスト・メニューを表示させ、削除を実行します。


表TCLD_SOCIAL_NETWORKSに初期データを投入するボタンを作成します。

識別ボタン名INITラベルInitとします。対話グリッドTcld Social Networksの上に配置します。外観テンプレート・オプションWidthStretchに変更し、画面の横幅いっぱいにボタンを表示させます。

動作アクションはデフォルトのページの送信のまま変更しません。


左ペインでプロセス・ビューを開き、ボタンINITを押した時に実行するプロセスを作成します。

識別名前初期化タイプとしてコードを実行を選択します。ソースPL/SQLコードとして以下を記述します。

declare
l_load_result apex_data_loading.t_data_load_result;
begin
l_load_result := apex_data_loading.load_data (
p_static_id => 'TAG_CLOUD'
,p_data_to_load => apex_web_service.make_rest_request_b(
p_url => 'https://www.oracle.com/webfolder/technetwork/jet/cookbook/dataVisualizations/tagCloud/resources/socialNetworks.json'
,p_http_method => 'GET'
)
);
apex_debug.info( 'Processed Row(s): ' || l_load_result.processed_rows);
end;

サーバー側の条件ボタン押下時INITを設定します。


この状態でアプリケーションを実行し、ボタンInitをクリックします。

表TCLD_SOCIAL_NETWORKSにデータが投入され、対話グリッドで編集できるようになります。


タグクラウドを表示するリージョンを作成します。

識別タイトルTag Cloudとします。タイプとして静的コンテンツを選択します。ボタンINITと対話グリッドの間にリージョンを配置します。

ソースHTMLコードとして以下を記述します。Oracle JET Cookbookのdemo.htmlとほぼ同じです。

<div
class="
oj-flex oj-sm-flex-direction-column oj-sm-align-items-center
demo-tagCloud-default-max-width
">
<p class="oj-flex-item oj-typography-bold">
Social Networks Used by US Internet Users (Ages 14-54)
</p>
<oj-tag-cloud id="tagcloud1" layout="cloud" data="[[dataProvider]]">
<template slot="itemTemplate" data-oj-as="item">
<oj-tag-cloud-item
label="[[item.data.id]]"
value="[[item.data.total]]"
short-desc='[[item.data.id + ": " + item.data.total + "% of respondents"]]'></oj-tag-cloud-item>
</template>
</oj-tag-cloud>
</div>
view raw tagcloud.html hosted with ❤ by GitHub

余計な装飾を除くため、外観テンプレートとしてBlank with Attributes (No Grid)を選択します。


タグクラウドのデータはAjaxコールバックを呼び出して取得します。

プロセス・ビューを開き、Ajaxコールバックにプロセスを作成します。Ajaxコールバックは、表TCLD_SOCIAL_NETWORKSの内容をJSONの配列として返します。

識別名前GET_DATAタイプとしてコードを実行を選択します。ソースPL/SQLコードとして以下を記述します。

declare
l_response clob;
begin
select json_arrayagg(
json_object(
key 'id' value name
,key '14-17' value C14_17
,key '18-34' value C18_34
,key '35-54' value C35_54
,key 'total' value total
,key 'url' value url
)
) into l_response
from tcld_social_networks;
htp.p(l_response);
end;


ページ・プロパティJavaScriptファイルURLに以下を記述します。

[require jet]

ファンクションおよびグローバル変数の宣言に以下を記述します。

var tagCloud;

ページ・ロード時に実行に以下を記述します。タグクラウドのモデルとなるクラスTagcloudModelと、タグクラウドを更新するapex.actionのupdate-tagcloudを定義しています。内容は概ねOracle JET Cookbookのdemo.jsを踏襲しています。

require(["require", "exports", "knockout", "ojs/ojbootstrap", "ojs/ojarraydataprovider", "ojs/ojknockout", "ojs/ojtagcloud"], function (require, exports, ko, ojbootstrap_1, ArrayDataProvider) {
"use strict";
class TagcloudModel {
/*
* Tag Cloudで表示するデータを更新する。
*/
update(data) {
this.dataProvider(new ArrayDataProvider(data, {
keyAttributes: "id",
}));
}
constructor() {
/*
* this.dataProviderはknockoutのobservableArrayに変更し、
* データはコンストラクタの外から設定する。
*/
this.dataProvider = ko.observableArray();
/*
this.socialNetworks = JSON.parse(jsonData);
this.dataProvider = new ArrayDataProvider(this.socialNetworks, {
keyAttributes: "id",
});
*/
}
}
(0, ojbootstrap_1.whenDocumentReady)().then(() => {
tagCloud = new TagcloudModel();
ko.applyBindings(tagCloud, document.getElementById("tagcloud1"));
/* ページ・ロード時の表示 */
apex.actions.invoke("update-tagcloud");
});
});
/*
* Tag Cloudを更新する。
*/
apex.actions.add([
{
name: "update-tagcloud",
action: () => {
apex.server.process ( "GET_DATA", {},
{
success: (data) => {
// console.log(data);
tagCloud.update(data);
}
}
);
}
}
]);
CSSファイルURLに以下を指定します。

#JET_CSS_DIRECTORY#redwood/oj-redwood-notag-min.css

インラインに以下を記述します。Oracle JET Cookbookのdemo.cssの内容です。
.demo-tagCloud-default-max-width {
    max-width: 50rem;
}

対話グリッドでデータを変更し保存したときに、タグクラウドを更新する動的アクションを作成します。

識別名前変更の保存とします。タイミングイベントとして保存[対話グリッド]を選択し、選択タイプリージョンリージョンとしてTcld Social Networksを指定します。


TRUEアクションとしてJavaScriptコードの実行を選択し、設定コードに以下の1行を記述します。

apex.actions.invoke("update-tagcloud");


以上でアプリケーションは完成です。アプリケーションを実行すると、記事の先頭のGIF動画のように動作します。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/jet-tag-cloud.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。