オープンソースのチャート描画ライブラリであるChart.jsを、Oracle APEXのアプリケーションに組み込んでみます。Chart.jsの使い方自体には、ほとんど触れません。
前回の記事で、Oracle JETのチャートを直接Oracle APEXに組み込む方法を紹介しています。そのOracle JETのチャートと同じチャートを、Chart.jsで表示してみます。
作業にあたって、空のAPEXアプリケーションを作成します。名前はIntegrating Chart.jsとします。
直接Chart.jsで描画
Chart.jsに案内のあるjsDelivrのページを開き、ページに組み込むスクリプトを選択します。
https://www.jsdelivr.com/package/npm/chart.js?path=dist
TypeはDefault、VersionはLatest Majorを選び、Copy URLを実行します。以下のURLがクリップボードにコピーされます。
このURLをページ・プロパティのJavaScriptのファイルURLに記述します。
チャートに描画するデータを保持するページ・アイテムとしてP1_GROUPS、P1_VALUEを作成します。タイプは非表示です。
ページ・アイテムP1_GROUPSに計算を作成し、ページの描画前にデータを設定します。計算のタイプとしてSQL問合せ(単一の値を返す)を選択し、SQL問合せに以下を記述します。
select
json_arrayagg(
ename
order by empno asc )
from emp where deptno = 10
バー・チャートのそれぞれの棒に当たる従業員名をJSON配列にして、ページ・アイテムに保持します。(Oracle JETのときはJSONオブジェクトの配列だったので、保持する値は変わっています。)
ページ・アイテムP1_VALUEにも計算を作成し、ページ描画前に値を設定します。SQL問合せに以下を記述します。
select
json_arrayagg(
sal
order by empno asc )
from emp where deptno = 10
チャートを描画するリージョンを作成します。
名前はChart.jsとします。タイプに静的コンテンツを選択し、ソースのHTMLコードとして以下を記述します。
<canvas id="myChart"></canvas>
Chart.jsは、指定したCanvas要素にチャートを描画するため、Canvas要素をあらかじめ用意しています。
チャートを描画するJavaScriptのコードを、ページ・プロパティのJavaScriptのページ・ロード時に実行に記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const ctx = document.getElementById('myChart'); | |
new Chart(ctx, { | |
type: 'bar', | |
data: { | |
labels: JSON.parse(apex.items.P1_GROUPS.value), | |
datasets: [{ | |
data: JSON.parse(apex.items.P1_VALUE.value), | |
backgroundColor: '#309fdb', | |
borderWidth: 1 | |
}] | |
}, | |
options: { | |
plugins: { | |
legend: { | |
display: false | |
} | |
}, | |
indexAxis: 'y' | |
} | |
}); |
以上で実装は完了です。ページを実行すると以下のように表示されます。
テンプレート・コンポーネントの作成
JavaScriptの記述による手続的なアプリケーションの実装は、あまりOracle APEXのアプリケーション開発に合っていません。テンプレート・コンポーネントを作成し、Chart.jsによるチャート描画を宣言的に実装できるようにします。
テンプレート・コンポーネントは、こちらの記事で紹介したOracle JETのテンプレート・コンポーネントとおおむね同じ手順で作成します。そのため、設定内容に絞って説明します。
テンプレート・コンポーネントの名前はChart.js Bar Chartとしました。テンプレートの部分には以下を記述しています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div class="#CSS_CLASSES#"> | |
<a-chart-js-bar-chart id="#APEX$DOM_ID#" groups="#GROUPS#" value="#VALUE#" color="#COLOR#" orientation="#ORIENTATION#"></a-chart-js-bar-chart> | |
</div> |
カスタム要素名をa-chart-js-bar-chartとしています。カスタム属性はOracle JETを使ったテンプレート・コンポーネントと同じにしています。
カスタム属性の設定はOracle JETのテンプレート・コンポーネントとほぼ同じですが、orientationに限り静的LOVの戻る(戻り値)を変更しています。Chart.jsではoptionsのindexAxisによってバー・チャートの方向が決まります。indexAxisへはhorizontalのときにy、verticalのときにxを与えます。
テンプレート・コンポーネントのファイルとして、Chart.jsの実体となるファイルchart.umd.min.jsをアップロードします。アップロードするディレクトリとして、jsを指定しています。
ディレクトリをjs、ファイル名をscript.jsとして、カスタム要素a-chart-js-bar-chartの実装を記述します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function (debug) { | |
"use strict"; | |
class ChartJSBarChart extends HTMLElement { | |
chart; | |
chartId; | |
constructor() { | |
super(); | |
this.chartId = new Date().getTime(); | |
debug.info("%s, constructor", this.chartId); | |
} | |
connectedCallback() { | |
debug.info("%s, %s, connectedCallback, %s", this.chartId, new Date().getTime(), this.isConnected); | |
if (this.isConnected) { | |
/* append canvas as a first Child */ | |
const canvas = document.createElement("canvas"); | |
this.appendChild(canvas); | |
/* configuration for Chart.js */ | |
let config = { | |
type: 'bar', | |
data: { | |
labels: JSON.parse(this.getAttribute("groups")), | |
datasets: [{ | |
data: JSON.parse(this.getAttribute("value")), | |
backgroundColor: this.getAttribute("color"), | |
borderWidth: 1 | |
}] | |
}, | |
options: { | |
plugins: { | |
legend: { | |
display: false | |
} | |
}, | |
indexAxis: this.getAttribute("orientation") | |
} | |
}; | |
/* draw chart */ | |
debug.info(config); | |
this.chart = new Chart(canvas,config); | |
} | |
} | |
disconnectedCallback() { | |
debug.info("%s, %s, disconnectedCallback", this.chartId, new Date().getTime()); | |
if (this.firstChild) { | |
this.removeChild(this.firstChild); | |
} | |
} | |
} | |
document.addEventListener('DOMContentLoaded', () => { | |
if ( window.customElements.get("a-chart-js-bar-chart") === undefined ) { | |
debug.info("define custom element"); | |
window.customElements.define("a-chart-js-bar-chart", ChartJSBarChart); | |
}; | |
}); | |
})(apex.debug); |
ロードするファイルURLのJavaScriptに以下を記述します。
#PLUGIN_FILES#js/chart.umd.min.js
#PLUGIN_FILES#js/script#MIN#.js
以上でテンプレート・コンポーネントは完成です。
Chart.jsで直接チャートを描画するページのコピーを作成し、テンプレート・コンポーネントを使った実装に変更します。
Chart.jsのロードや描画の実行はテンプレート・コンポーネントが行うため、ページ・プロパティのJavaScriptのファイルURLおよびページ・ロード時に実行は空白にします。
Canvas要素を含んでいた静的コンテンツのリージョンのタイプを、作成したテンプレート・コンポーネントChart.js Bar Chartに変更します。
リージョンの属性を開き、設定のGroupsとしてP2_GROUPS、ValueとしてP2_VALUE、Colorとして#309fdb、Orientationとしてhorizontalを設定します。
以上で実装は完了です。ページを実行すると以下のように表示されます。
対話モード・レポートへの組み込み
対話モード・レポートにテンプレート・コンポーネントChart.js Bar Chartを組み込みます。
対話モード・レポートのソースのSQL問合せとして、以下を記述します。
select
dname,
json_arrayagg(
ename
order by empno asc ) groups,
json_arrayagg(
sal
order by empno asc) value,
'' chart
from emp_dept_v group by dname
列CHARTを選択し、タイプをChart.js Bar Chartへ変更します。設定のCSS Classesにw400、Groupsに列GROUPS、ValueにVALUE、Colorに#309fdb、Orientationにhorizontalを指定します。
今回の記事は以上になります。
作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/integrating-chart-js.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完