ラベル Chart の投稿を表示しています。 すべての投稿を表示
ラベル Chart の投稿を表示しています。 すべての投稿を表示

2025年5月9日金曜日

ピラミッド・チャートのラベルをカスタマイズする

Orale APEXのチャートのタイプピラミッドがあります。ピラミッド・チャートではラベルは列のマッピングに指定した数値が表示され、列のマッピングラベルに指定した文字列は表示されません。

初期化JavaScriptファンクションを記述することにより、ピラミッド・チャートに以下のようにラベルを表示させてみます。


何もカスタマイズしていないと、以下のように表示されます。


以下より、実施したカスタマイズについて紹介します。チャートの表示には、サンプル・データセットEMP/DEPTに含まれる表EMPデータ・ソースとして使用しています。

識別名前Pyramidタイプチャートとしたリージョンを作成しています。ソース表名EMPです。


シリーズの名前Salaryソース位置リージョン・ソースを選択します。列のマッピングラベルは列JOB値集計合計は列SALを指定します。そしてラベルの表示オンにします。

デフォルトではこの設定で、ラベルに列SALの値が表示されます。


チャート・リージョンの属性を開き、チャートタイプピラミッドを選択します。今回の実装には関係しませんが、ツールチップ凡例表示オンにしておきます。

そして本記事のテーマであるラベルをカスタマイズするコードを、初期化JavaScriptファンクションに記述します。



以上でカスタマイズは完了です。

チャートの初期化JavaScriptファンクションで設定しているoptions.dataFilterについては、Plamen Mushkovさんのブログ記事から、その存在を見つけました。

Taking your APEX JET charts style to the next level

dataFilterに渡されるデータを確認したところ、labelにvalueと同じ数値が割当たっていたので、これを変更しています。
{
  "series": [
    {
      "name": "PRESIDENT",
      "displayInLegend": "on",
      "items": [
        {
          "id": "1",
          "value": 5000,
          "label": 5000,
          "name": "PRESIDENT"
        }
      ]
    },
    {
      "name": "MANAGER",
      "displayInLegend": "on",
      "items": [
        {
          "id": "2",
          "value": 8275,
          "label": 8275,
          "name": "MANAGER"
        }
      ]
    },
    ...
 }
デフォルトでは、ラベルに列SALの値が表示されますが、その際に数値に書式が適用されます。


dataFilterに渡されるvalueはフォーマット後の文字列ではなく数値そのものであるため、書式が適用されません。そのため、例えば単位が必要であれば、その処理も初期化JavaScriptファンクションで行う必要があります。

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

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

2025年5月2日金曜日

チャートのタイトルを動的に変更する

Oracle APEXのチャートのタイトルを動的に変更する方法について調べてみました。設定を確認するために、以下のように動作するAPEXアプリケーションを作成しています。

表EMPをソースとしたバー・チャートを作成しています。選択リストのページ・アイテムで、バー・チャートの表示条件となるJOBを選択し、チャートを更新します。同時にチャートのタイトルを選択したJOBに変更しています。


このアプリケーションのエクスポートは以下に置いてあります。
https://github.com/ujnak/apexapps/blob/master/exports/update-chart-title.zip

チャートのタイトルの変更自体は簡単ですが、その実装方法はOracle APEXの公式なドキュメントに記載されていません。ただし、ChatGPTに聞くと大体教えてくれます。

ChatGPTに「Oracle APEXでJavaScriptでchart widgetを取得する手順を教えて」と聞いたところ、以下のコードを教えてくれました。
var chartWidget = apex.region("myChart").widget();
最後にChatGPTから「何を操作したいか(例:データ更新、再描画、ハイライトなど)も教えていただけますか?」と聞かれたので、「ChartのTitleを更新したい」と伝えたところ、以下のコードを教えてくれました。
var chart = apex.region("myChart").widget();
var currentOptions = chart.ojChart("option");

// タイトルを変更する
chart.ojChart("option", "title.text", "新しいタイトル");

// 必要に応じて再描画(通常は自動で反映されます)
Oracle JETのチャートのリファレンスは以下ですが、Oracle APEXのojChartインターフェース経由でどう使えるのかについては説明されていません。

カード・リージョン、ファセット・リージョン、対話グリッド、マップ・リージョンおよびテンプレート・コンポーネントといったJavaScriptの部分をOracle APEXの開発チームが実装しているコンポーネントについては、APIリファレンスにMethodsの説明があり、それを参照することによりJavaScriptで操作できます。

チャート・リージョンはOracle JETを使用しているため、Oracle APEXの開発チームにオーナーシップがありません。そのため、チャート・リージョンについてはページ・デザイナによる宣言的な設定がサポート範囲で、コードによる操作はサポートされません。そもそも、Oracle JETはOracle Corporationが保守しているオープンソース・プロジェクトであり、Oracle JET自体に一般的な製品サポートは提供されていません。

そういう意味ではコードで操作する場合、チャート・コンポーネントは他のオープンソースのフロントエンドのコンポーネントと同じ扱いになります。メンテナンス性を優先する場合は、使用は避けた方が良い、という点でも同じです。

以下より、今回作成したアプリケーションの実装を紹介します。

アプリケーションはすべてホーム・ページに実装しています。

チャートの表示条件となるページ・アイテムP1_JOB選択リストとして作成しています。LOVタイプSQL問合せを選択し、SQL問合せとして以下を記述しています。LOV表示値戻り値ともに表EMPの列JOBに含まれる個別値となります。

select job d, job r from emp group by job

P1_JOBで選択された戻り値をチャートのタイトルとして設定します。

ページ・アイテムが変更されたときに、チャートをリフレッシュする動的アクションを作成します。


チャート・リージョン識別名前給与として作成しています。

ソース表名EMPを指定し、WHERE句:P1_JOB is null or JOB = :P1_JOBを記述しています。送信するページ・アイテムP1_JOBを設定します。この設定により、リージョンのリフレッシュを実行した際に、P1_JOBが空であれば全従業員の給与がバーチャートに表示され、P1_JOBに値があれば、そのJOBを持つ従業員のみがバー・チャートに表示されます。

チャートをJavaScriptから操作するために、詳細静的IDmyChartを設定します。


チャートの属性タイトルとして&P1_JOB.を設定します。これはチャート、つまりOracle JETのチャート・コンポーネントが表示するタイトルになります。


基本的な設定は以上になります。

これから、チャートのタイトルを描画する処理について考えていきます。

最初にページがロードされると、ページに含まれる置換文字列&P1_JOB.が、ページ・アイテムP1_JOBの値で置き換えられます。

ページ・アイテムP1_JOBセッション・ステートストレージセッションごと(永続)としているため、ページ・ロード時にセッション・ステートに保存されている値が反映されます。これがリクエストごと(メモリーのみ)であれば、(デフォルト計算が未設定であれば)つねにページ・アイテムの値は空白になります。

ページ・アイテムP1_JOBの選択を変更したときに、動的アクションでチャートをリフレッシュしています。リージョンの送信するページ・アイテムP1_JOBが設定されていて、そしてセッション・ステートストレージセッションごと(永続)であるため、送信された値がセッション・ステートに保存されます。結果として、ページ・ロード時のP1_JOBの値は、直近のチャートのリフレッシュ時に送信されたP1_JOBの値になります。


置換文字列&P1_JOB.の置き換えはページ・ロード時にのみ行われます。チャートの属性タイトルに設定した&P1_JOB.は、ページ・ロード後はページ・アイテムP1_JOBの値が変わっても、その値が反映されることはありません。


次にチャート・リージョンの属性詳細初期化JavaScriptファンクションが実行されます。初期化JavaScriptファンクションでは、属性に設定項目が存在しない設定もできます。

今回のアプリケーションでは以下のように記述しています。ページ・デザイナで設定した値が引数optionsとして渡され、必要な変更をoptionsに適用して戻します。
function( options ) {
    apex.debug.info(options);
    const job = apex.items.P1_JOB.value ? apex.items.P1_JOB.value : "すべてのJOB";
    // const job = apex.items.P1_JOB.value;
    if ( options.title ) {
        // titleが初期化済みであれば、textのみを更新する。
        options.title.text = job;
        apex.debug.info("INIT: title.text is replaced, ", job);
    }
    else
    {
        // そうでない場合は中央揃えも含めてtitleを初期化する
        options.title = {
            "halign": "center",
            "text": job
        };
        apex.debug.info("INIT: title.text is created, ", job);
    };
    return options;
}
optionsにどのような値が設定されているか、または、どのような値が設定可能かについては、ドキュメント化されていないため、JavaScriptコンソールにoptionsを印刷するか、または、チャート・ウィジェットからoptionを取り出して確認します。

apex.region("myChart").widget().ojChart("option")

例えば、JavaScriptコンソールなどから実行します。


初期化JavaScriptファンクションに渡されるoptionsは、ページ・デザイナで設定している内容に限定されます。リージョンの属性タイトルに値がない場合は、title自体がnullになるため、options.title.textを設定することはできません。そのため初期化JavaScriptファンクションでは、options.titleに設定がない場合は、水平アラインメント(halign)の設定も含めてoptions.titleを設定しています。

初期化JavaScriptファンクションはページ・ロード時に実行されます。リージョンのリフレッシュ時には実行されません。そのため、ページ・アイテムP1_JOBの値が変更されたときは、動的アクションとして同等の処理を実行する必要があります。動的アクションには引数optionsが渡されないため、apex.region("myChart").widget().ojChart()を呼び出して設定を更新します。

チャート・リージョンに必ずタイトルが設定されている場合は、以下のコードでタイトルだけを変更できます。
const job = this.triggeringElement.value ? this.triggeringElement.value : "すべてのJOB";
// const job = this.triggeringElement.value;
apex.region("myChart").widget().ojChart(
    "option",
    "title.text",
    job
);
タイトルが未設定のときがあれば、以下のコードでタイトルを設定できます。
const job = this.triggeringElement.value ? this.triggeringElement.value : "すべてのJOB";
// const job = this.triggeringElement.value;
apex.region("myChart").widget().ojChart(
    "option",
    "title",
    {
        "halign": "center",
        "text": job
    }
);
同じ変更ですが、引数optionを除いて、以下のように呼び出せるようです。
const job = this.triggeringElement.value ? this.triggeringElement.value : "すべてのJOB";
// const job = this.triggeringElement.value;
apex.region("myChart").widget().ojChart(
    { 
        "title": {
            "halign": "center",
            "text": job
        }
    }
);
今回の記事は以上になります。

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

2022年8月31日水曜日

都道府県別年齢3区部分別人口を円グラフで表示する

 総務省統計局より都道府県、年齢3区分別人口の統計データを入手し、カード・リージョンのそれぞれのカードに、都道府県ごとの年齢3区分別の円グラフを表示するAPEXアプリケーションを作成してみます。


グラフの元となるデータとして、総務省統計局日本の統計第2章 人口・世帯にある、2-6 都道府県、年齢区分別人口(エクセル:15KB)を使用します。Excelファイルはn220200600.xlsxというファイル名でダウンロードされました。

SQLワークショップユーティリティクイックSQLを使って、Excelファイルの内容をインポートする表を作成します。以下のモデルを使用します。
# prefix: ccb
populations
    prefecture_name vc50 /nn
    total     num
    age00to14 num
    age15to64 num
    age65     num
    age75    num
SQLの生成SQLスクリプトを保存レビューおよび実行を順番にクリックし、表CCB_POPULATIONSを作成します。アプリケーションの作成は行いません。


Excelファイルの内容を表CCB_POPULATIONSにインポートします。

SQLワークショップユーティリティデータ・ワークショップを開きます。

データのロードを実行します。


ダウンロードしたファイルn220200600.xlsxを選択します。


ロード先既存の表を選択し、として先ほど作成したCCB_POPULATIONSを選びます。設定列見出し最初の行にヘッダーが含まれるチェックを外します。Excelの列と表CCB_POPULATIONSの列をマッピングするため、構成を開きます。


ソース列のCOL001には列をマップしません。それ以外はソース列とマップ先を以下のように指定します。

COL002 = PREFECTURE_NAME
COL003 = TOTAL
COL004 = AGE00TO14
COL005 = AGE15TO64
COL006 = AGE65
COL007 = AGE75

以上を設定し、変更の保存をクリックします。


データのロードを実行します。


表にロードできなかった行が一覧されます。これらの行は表CCB_POPULATIONS_ERR$に保存されています。エラーで取り込めなかった行に、列PREFECTURE_NAMEに値がある行は含まれていないことより、必要なデータはすべてロードできています。

取消をクリックし、データのロードを終了します。


アプリケーション作成ウィザードを起動します。

アプリケーションの名前都道府県別年齢3区分人口とします。予め作成されているホーム・ページ削除し、カード・リージョンのページを追加します。


カードのページは、以下の設定とします。

ページ名を都道府県別年齢3区分人口表またはビューとしてCCB_POPULATIONSを選択します。表示形式はグリッドタイトル列PREFECTURE_NAME本体列TOTALを指定します。

カードのページを追加したのち、アプリケーションの作成を実行します。


アプリケーションが作成されます。

都道府県別年齢3区分人口として作成されたページに含まれるカード・リージョンに、円グラフを表示させます


今回の実装は、ギャラリサンプル・アプリケーションSample Cardsに含まれるページ11Gauge Meter Chart Cardsを参考にしています。


都道府県別年齢3区分人口のページを開き、ページ・プロパティにSample Cardsと同等の設定を加えます。

JavaScriptファイルURLとして、以下を設定します。

[require jet]

JavaScriptページ・ロード時に実行として、以下を設定します。

require(["ojs/ojchart"], function() {});

CSSファイルURLとして、以下を設定します。

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

上記はSample Cardsを確認して初めて分かる設定ではないかと思います。


この時点でアプリケーションを実行すると、ページの表示は以下のようになります。


カードの表示を改善します。

Bodyにあるカード・リージョン都道府県別年齢3区分人口を選択し、プロパティ・エディタの属性タブを開きます。

本体の拡張フォーマットをONにし、HTML式として以下を記述します。

<b>総数:</b> &TOTAL.

メディアの拡張フォーマットをONにし、HTML式として以下を記述します。オプションの詳細はOracle JETのoj-chartのAPI Docを確認します。



以上で円グラフが表示されるようになりました。

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

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