2024年8月14日水曜日

Google ChartsをOracle APEXのアプリケーションに組み込む

Google Chartsを、Oracle APEXのアプリケーションに組み込んでみます。Google Chartsの使い方自体には、ほとんど触れません。

今までにOracle JET, Chart.jsおよびApexChartsをOracle APEXに組み込む方法を紹介しています。それと同じチャートを、Google Chartsで表示してみます。


直接Google Chartsで描画



Google ChartsのQuickstartを参考にして、div要素にチャートを描画します。

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

https://www.gstatic.com/charts/loader.js


静的コンテンツのリージョンの名前Google Chartsとし、ソースHTMLコードに以下を記述します。

<div id="myChart"></div>


タイプ非表示のページ・アイテムP1_VALUEを作成し、計算を作成します。実行ポイントリージョンの前計算タイプSQL問合せ(単一の値を返す)を選択し、SQL問合せとして以下を記述します。
select
    json_arrayagg(
        json_array( ename, sal )
        order by empno
    )
from emp where deptno = 10

チャートを描画するJavaScriptのコードを、ページ・プロパティページ・ロード時に実行に記述します。

google.charts.load('current', {packages: ['bar']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
const groups = [ "ENAME", "SAL" ];
const value = JSON.parse(apex.items.P1_VALUE.value);
value.unshift(groups);
var data = new google.visualization.arrayToDataTable(
value
);
var options = {
series: {
0: { color: '#309fdb' }
},
legend: { position: 'none' },
bars: 'horizontal',
axes: {
x: {
all: {
format: {
pattern: 'decimal'
}
}
},
y: {
all: {
label: ''
}
}
}
};
var chart = new google.charts.Bar(document.getElementById('myChart'));
chart.draw(data, options);
}

以上で実装は完了です。ページを実行すると以下のように表示されます。




テンプレート・コンポーネントの作成



Google Chartsのバー・チャートを描画するテンプレート・コンポーネントについて、設定内容を説明します。

テンプレート・コンポーネントの名前Google Charts Bar Chartとしました。テンプレート部分には以下を記述しています。カスタム要素a-google-charts-bar-chartです。

<div class="#CSS_CLASSES#">
<a-google-charts-bar-chart id="#APEX$DOM_ID#" groups="#GROUPS#" value="#VALUE#" color="#COLOR#" orientation="#ORIENTATION#" width="#WIDTH#" height="#HEIGHT#"></a-google-charts-bar-chart>
</div>


カスタム属性としてCSS ClassesGroupsValueColorOrientationに加えてWidthHeightをカスタム属性に加えています。レポートの列にチャートを表示する際に、幅の自動調整がいまひとつだったため、チャートの描画領域のWidthとHeightを指定できるようにしました。両方とも整数を指定します。


チャートの向きの指定であるOrientationは、Google Chartsに与えるオプションのbars属性の値になります。静的LOVhorizontalの戻り値はhorizontalverticalの戻り値はverticalとします。


テンプレート・コンポーネントのファイルとして、Google Chartsの実体となるloader.jsをアップロードします。JavaScriptディレクトリjsとします。

ディレクトリjsファイル名script.jsとして、カスタム要素a-google-charts-bar-chartの実装を記述します。

(function (debug) {
"use strict";
class GoogleChartsBarChart extends HTMLElement {
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 div as a first Child */
const div = document.createElement("div");
this.appendChild(div);
const groupsStr = this.getAttribute("groups");
let groups =groupsStr.split(',');
let value = JSON.parse(this.getAttribute("value"));
/* put the header on top of the value array */
value.unshift(groups);
var options = {
legend: { position: 'none' },
axes: {
x: {
all: {
format: {
pattern: 'decimal'
}
}
},
y: {
all: {
label: ''
}
}
}
};
const bars = this.getAttribute("orientation");
if ( bars ) {
options.bars = bars;
};
const color = this.getAttribute("color");
if ( color ) {
options.series = { 0: { color: color } };
};
const width = this.getAttribute("width");
if ( width ) {
options.width = width;
};
const height = this.getAttribute("height");
if ( height ) {
options.height = height;
};
/*
  * Since google.charts.load returns a Promise, you can use the then method
* to execute the chart drawing process after the library has finished loading.
*/
debug.info(options);
google.charts.load('current', {'packages':['bar']}).then(
function () {
var data = new google.visualization.arrayToDataTable(
value
);
let chart = new google.charts.Bar(div);
chart.draw(data, options);
});
}
}
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-google-charts-bar-chart") === undefined ) {
debug.info("define custom element");
window.customElements.define("a-google-charts-bar-chart", GoogleChartsBarChart);
};
});
})(apex.debug);
view raw script.js hosted with ❤ by GitHub

ロードするファイルURLJavaScriptに以下を記述します。

#PLUGIN_FILES#js/loader#MIN#.js
#PLUGIN_FILES#js/script#MIN#.js


以上でテンプレート・コンポーネントは完成です。

リージョンにGoogle Chartsのテンプレート・コンポーネントを実装します。

タイプ非表示のページ・アイテムP2_VALUEを作成し、計算を設定します。計算の設定は前出のP1_VALUEと同じです。


識別名前Google ChartsタイプGoogle Charts Bar Chartとします。


リージョンの属性を開き、GroupsとしてENAME, SALValueとしてP2_VALUEColorとして#309fdbOrientationとしてhorizontalを設定します。


以上で実装は完了です。ページを実行すると以下のように表示されます。



対話モード・レポートへの組み込み



対話モード・レポートソースSQL問合せとして以下を記述します。
select
    dname,
    json_arrayagg(
        json_array( ename, sal )
        order by empno asc
    ) value,
    '' chart
from emp_dept_v group by dname

対話モード・レポートの列CHARTを選択し、識別タイプGoogle Charts Bar Chartに変更します。

設定CSS Classesw400GroupsENAME,SALValueに列VALUEColor#309fdbOrientationhorizontalを設定します。


以上で実装は完了です。ページを実行すると以下のように表示されます。


今回の記事は以上になります。

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

Google ChartsのJavaScriptファイルはテンプレート・コンポーネントには含めず、
https://www.gstatic.com/charts/loader.js
を参照するようにしています。

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