2024年12月11日水曜日

クラシック・レポートを使ってヒートマップを実装する

Oracle JETのData Gridを使ってヒートマップを実装する(こちらの記事)のは難しいときのために、クラシック・レポートを使ってヒートマップを実装してみました。Oracle JETでの表示に合わせています。

作成したアプリケーションは以下のように動作します。


データはJETの記事で作成している表EBAJ_DEMO_HOUSE_PRICEを流用します。

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

以下よりアプリケーションの作成手順を紹介します。

アプリケーション作成ウィザードを起動し、空のアプリケーションを作成します。名前Classic Report Heat Mapとします。


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

ページ・デザイナホーム・ページを開き、クラシック・レポートのリージョンを作成します。

識別名前Heat Mapタイプクラシック・レポートです。ソースタイプSQL問合せを返すファンクション本体を選択し、SQL問合せを戻すPL/SQLファンクション本体として、以下を記述します。

このファンクションは以下のSELECT文を返します。PIVOT列は列PERIODの値から決まるため、動的にSQLを作成しています。また、列名は開発時では不明なため、汎用列名の使用オンにしています。汎用列数20を指定しているため、Region列を除いた19列がピボット列の上限になります。
select 
  * 
from 
  (
    select 
      region, 
      period, 
      price 
    from 
      ebaj_demo_house_price
  ) pivot (
    sum(price) for period in (
      'January2013' as January2013, 'February2013' as February2013, 
      'March2013' as March2013, 'April2013' as April2013, 
      'May2013' as May2013, 'June2013' as June2013, 
      'July2013' as July2013, 'August2013' as August2013, 
      'September2013' as September2013, 
      'October2013' as October2013, 'November2013' as November2013, 
      'December2013' as December2013, 'January2014' as January2014, 
      'February2014' as February2014, 'March2014' as March2014, 
      'April2014' as April2014, 'May2014' as May2014
    )
  )
不要な修飾を無くすために、外観テンプレートBlack with Attributes (No Grid)を選択しています。また、JavaScriptとCSSの中でレポート・リージョンを指定するために、静的IDとしてHEATMAPを設定します。


汎用列の列名を保持するページ・アイテムを作成します。汎用列は20個あるため、ページ・アイテムとしてP1_COL01からP1_COL20の20個のページ・アイテムを作成します。タイプ非表示です。

クラシック・レポートのソースであるPL/SQLファンクション内で、これらのページ・アイテムに列名を設定しています。


汎用列のヘッダーにページ・アイテムに設定した値が反映されるように、それぞれの列のヘッダーに置換文字列&P1_COL01.(列名に合わせて&P1_COL01.から&P1_COL20.まで)を設定します。


ページを実行して、これまでの作業を確認します。

表EBAJ_DEMO_HOUSE_PRICEの内容がピボットされてレポートに表示されていることが確認できます。


数値が表示されているセルを、ヒートマップとして正方形にしたり色付けできるようにします。

列COL01はリージョンを表示しているため除外し、列COL02からCOL20までの列の書式HTML式に以下を記述します。
<div class="ht-cell">
 <div class="ht-text">
   #COL02#
  </div>
</div>
また、これらの列でソートすることは無いので、ソートソート可能オフにします。HTML式に含まれる置換文字列#COL02#は、列名に合わせて変更します。


今回のソート可能のように、複数のアイテムのプロパティを同じ値にする場合、対象をすべて選択した上で値を変更すると設定漏れを防げます。


ページ・プロパティCSSインラインに以下を記述します。年月の列名を縦方向に印字する、数値のセルを正方形にする、数値の色を白にしてセルの中央に配置するようにしています。それ以外に、CSS変数の値を変更し、セルのパディングを除いています。


これまでの変更で、レポートは以下のように表示されます。


セルの色付けは、クラシック・レポートのリフレッシュ後動的アクションで行います。

クラシック・レポートに動的アクションを作成します。タイミングイベントリフレッシュ後です。


TRUEアクションとしてJavaScriptコードの実行を選択し、設定コードに以下を記述します。JETの実装と同じ色味になるように、色付けのクラスとしてOracle JETで定義されているクラスを設定しています。



JETの色に関するクラス定義を参照するため、ページ・プロパティCSSファイルURLに以下を設定します。

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


この時点でページを実行しレポートを表示させてみると、以下のようにセルが色付けされません。


ページ・ロード時はリフレッシュ後のイベントが発生しないため、動的アクションが実行されません。

ページ・ロード時にリフレッシュ後のイベントが発生するようにします。

クラシック・レポートの属性を開き、パフォーマンス遅延ロードオンにします。遅延ロードをオンにすると、ページ・ロードとレポート表示が非同期で実行されるようになり、レポート表示が完了した時点でリフレッシュ後イベントが発生します。


クラシック・レポートでは行ごとに背景色を変えたり、ポインタが行に乗ったときに行をハイライトさせるといった機能があります。これらの機能はセルの色に影響を与える可能性があるため、無効化します。

クラシック・レポートの属性に含まれる外観テンプレート・オプションを開き、Alternating RowsおよびRow Highlightingの双方をDisableにします。


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

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

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