2024年11月29日金曜日

バー・チャートのY軸のラベルを動的に変更する

バー・チャートにY軸のラベルを動的に変更する方法を紹介します。

以下の動画のように、選択リストでまたはドルを選択したときに、Y軸の表示を... 円または... ドルのように表示を変えます。以前に「チャートのプロパティを動的に変更する」という記事にて、Y軸の最大値の変更方法について紹介しています。今回の記事はラベルを変更するためにconverterを入れ替えています。APEXのチャートはOracle JETを使用していますが、プロパティが異なると変更の仕方も変わるようです。


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

バー・チャートのシリーズSQL問合せとして、以下を設定しています。ページ・アイテムP1_CURRENCYDOLLAR(表示値はドル)またはYEN(表示値は)のどちらかを選択する選択リストP1_RATEは1ドルに相当する円レートを設定する数値フィールドです。
with price_v as (
    select 1599 price, 'notebook' product from dual
    union all
    select 999  price, 'smart phone' product from dual
    union all
    select 1299 price, 'tablet' product from dual
)
select
    case when :P1_CURRENCY = 'YEN' then
        ceil(price * :P1_RATE)
    else
        price
    end price,
    product
from price_v

Y軸がPRICEになります。yの値のパターン# ドルとし、初期はドル表示とします。


ページ・アイテムP1_CURRENCYを変更したときに、動的アクションで以下のJavaScriptを実行します。クラスIntlNumberConverterはOracle JETが提供しているクラスです。プロパティconverterには、コンバータとなるクラス(IntlNumberConverterやIntlDataTimeConverter)のインスタンスを作成し、それをconverterに割り当てる必要があります。
let p = '# ' + apex.items.P1_CURRENCY.displayValueFor(
    apex.items.P1_CURRENCY.value
);

let currencyConverter = new oj.IntlNumberConverter({
        style: 'decimal',
        pattern: p
});
console.log('pattern is updated ', p);

let chart = apex.region("PRICE").widget();

chart.ojChart(
    'option',
    'yAxis.tickLabel.converter',
    currencyConverter
);
chart.ojChart(
    'option',
    'valueFormats.value.converter',
    currencyConverter
);
chart.ojChart(
    'option',
    'valueFormats.label.converter',
    currencyConverter
);

Y軸の表示(その他の設定はツール・チップ内での表示に使用されます)について、converterを設定すると表示が変わります。通貨が変わったことをチャート自体に反映させるため、後続の処理としてバー・チャートのリフレッシュを実行します。


Y軸のパターンの初期状態は# ドルですが、ページが再ロードされたときのP1_CURRENCYの値が(変更イベントが発生しないため)反映されません。動的アクション初期化時に実行オンにするという対処方法もありますが、今回はチャート・リージョンの初期化JavaScriptファンクションを記述することにより対応します。

以下のコードを記述します。
function( options ) {
    let p = '# ' + apex.items.P1_CURRENCY.displayValueFor(
        apex.items.P1_CURRENCY.value
    );

    let currencyConverter = {
        style: 'decimal',
        pattern: p
    };
    console.log('pattern is updated ', p);
    
    options.yAxis.tickLabel.converter    = currencyConverter;
    options.valueFormats.label.converter = currencyConverter;
    options.valueFormats.value.converter = currencyConverter;

    return options;
}


以上でアプリケーションは完成です。

チャートをカスタマイズするためには、Oracle JETのリファレンスを読み解く必要があります。今回の記事がOracle APEXのアプリケーション作成の参考になれば幸いです。