Kepler.glはReactのコンポーネントとして開発されていますが、GitHubのリポジトリのexamplesにumd-clientの実装が含まれています。
上記のumd-clientのindex.htmlを参考にして、Kepler.glのOracle APEXへの組み込みを行います。
Kepler.glに表示させるデータセットは、データベースへ保存できるようにします。また、データベースに保存したデータセットを表示できるようにします。これらの実装はAPI ReferenceのAdvanced usagesのSaving and Loading Maps with Schema Managerのセクションを参考に実装します。
作成したAPEXアプリケーションは以下のように動作します。データベースにロードしているサンプル・データは以下より取得しています。
https://github.com/uber-web/kepler.gl-data
https://github.com/uber-web/kepler.gl-data
create table kepler_datasets (
id number generated by default on null as identity
constraint kepler_datasets_id_pk primary key,
name varchar2(80 char) not null,
config clob check (config is json),
dataset clob check (dataset is json)
);
空白のページをベースにKepler.glを組み込みます。以下よりページ番号を2として説明を進めます。ページ番号が異なる場合は、P2といった接頭辞を置き換えてください。
ボタンは3つ作成します。ボタンLOADにより、ページ・アイテムP2_NAMEで指定したデータセットをKepler.glに読み込みます。ボタンSAVEはKepler.glで扱っているデータセットをデータベースに保存します。同名のデータセットがある場合は上書きします。ボタンDELETEで保存されているデータセットを削除します。ページ遷移が発生するとKepler.glは初期化されるため、これらはすべてページ遷移が発生しない動的アクションとして実装します(DELETEは例外で、Kepler.glを初期化するためJavaScript中でページ遷移を呼び出しています)。
https://unpkg.com/react@18.3.1/umd/react.production.min.js
https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js
https://unpkg.com/redux@4.2.1/dist/redux.js
https://unpkg.com/react-redux@8.1.3/dist/react-redux.min.js
https://unpkg.com/styled-components@6.1.13/dist/styled-components.min.js
https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js
https://unpkg.com/kepler.gl@3.1.0-alpha.1/umd/keplergl.min.js
Kepler.glの3.0以降はMapBoxの代わりにMapLibreを使います。そのため、MapLibreのライブラリをロード対象に含めています。
ファンクションおよびグローバル変数の宣言に以下を記述します。概ねindex.htmlのscript要素に記述されているコードと同じですが、MapBox関連のコードを削除しています。また、Kepler.glを表示する幅と高さは、APEXのリージョンに収まるように調整しています。
ページ・ロード時に実行に以下を記述します。Kepler.glであるReactコンポーネントを、IDがappのDIV要素に描画します。
https://d1a3f4spazzrp4.cloudfront.net/kepler.gl/uber-fonts/4.0.0/superfine.css
https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css
https://unpkg.com/kepler.gl@3.1.0-alpha.1/umd/keplergl.min.css
Kepler.glを描画する静的コンテンツのリージョンを作成します。ソースのHTMLコードに以下を記述します。
<div id="app"></div>
余計な装飾を省くために、外観のテンプレートとしてBlank with Attributes(No Grid)を選択します。
以上でKepler.glがページに描画され、単体で使えるようになります。
これから、Kepler.glとデータベースを連携させる実装を追加します。
Kepler.glが扱う構成データとデータセットを、それぞれ保持するページ・アイテムを作成します。構成データはP2_CONFIG、データセットはP2_DATASETに保持します。ブラウザのJavaScriptからデータベースにこれらの値を送信する時、逆にデータベース・サーバーから取り出した値をブラウザに送信する時に、これらのページ・アイテムに値を保存します。
これらのページ・アイテムのタイプは非表示とします。動的アクションで値を設定するため、設定の保護された値はオフにします。セッション・ステートのデータ型はCLOB、ストレージはリクエストごと(メモリーのみ)を選択します。
ボタンLOADの動的アクションとして、以下の処理が行われます。
最初のTRUEアクションで画面にスピナーを表示させ、画面操作のブロックを開始します。以下のJavaScriptを実行します。
/* スピナーを開始し、画面操作をブロックする */
spinner = apex.widget.waitPopup();
続いてボタンLOADを無効化します。
select config, dataset into :P2_CONFIG, :P2_DATASET
from kepler_datasets where name = :P2_NAME;
送信するアイテムとしてP2_NAME、戻すアイテムとしてP2_CONFIG、P2_DATASETを指定します。
ページ・アイテムP2_CONFIG、P2_DATASETに読み込んだデータを、Kepler.glに渡します。以下のJavaScriptコードを実行します。
データベースからKepler.glへの、データセットのロード処理の実装は以上です。
ボタンSAVEで実行されるTRUEアクションは、JavaScriptコードの実行のみです。以下のコードを実行します。
構成データとデータセットをデータベースに書き込むために、AjaxコールバックUPSERT_DATASETを呼び出しています。
AjaxコールバックのPL/SQLコードとして以下を記述します。
Kepler.glからデータベースへの、データセットの保存処理の実装は以上です。
ボタンDELETEの処理では、最初にPL/SQLコードとして以下を実行し、ページ・アイテムP2_NAMEのデータを削除します。
delete from kepler_datasets where name = :P2_NAME;
データを削除したのち、ページを再描画して初期化します。以下のJavaScriptコードを実行します。
const thisPage = 'f?p=' + apex.env.APP_ID + ':' + apex.env.APP_PAGE_ID + ':' + apex.env.APP_SESSION + ':::::';
apex.navigation.redirect(thisPage, true);
ボタンDELETEの実装は以上で完了です。
以上でAPEXアプリケーションへのKepler.glの組み込みは完了です。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-kepler-gl-on-apex.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完