APEXを使用して動的マトリックスレポートを実装するための最良の方法は何ですか?

ZZa

Oracle ApplicationExpressフレームワークを使用してこのタスクを完了する必要があります。

そのようなクエリがあるとしましょう:

select   
  col1,  
  col2,  
  val1,  
  val2,  
  val3,  
  val4,  
  val5,  
  val6,  
  val7,  
  val8,  
  val9,  
  val10,  
  val11  
from table(mega_function(city => ?, format => ?, percent => ?, days => ?));

そして、このクエリは次のようなものを返します(CSV形式で表示):

col1;col2;val1;val2;val3;val4;val5;val6;val7;val8;val9;val10;val11
S2;C1;32000;120;"15:38:28";1450;120;1500;1200;31000;120;32600;300
S1;C1;28700;120;"15:35:01";150;120;1500;1800;2700;60;28900;120
S1;C2;27000;240;"14:44:23";0;1500;240;1200;25500;60;null;null

簡単に言うと、クエリは、いくつかのパラメーターを受け取り、最初の2列の値の異なるペアに対していくつかの値のセットを返すパイプライン関数に基づいていますcol1;col2

実装する必要があるのは、の値がcol1レポートの行として使用され、の値が列として使用されるマトリックスレポートcol2です。交差点には、いくつかの書式設定とスタイルが適用されたペアの値のセットを含むセルがあります。また必要なのは、行で並べ替えることです(これは、列 'val1'の値で列を並べ替える必要があります)。

または、モックアップで上記のニーズを示した場合: モックアップ

したがって、問題は、相互作用とカスタムスタイルを使用してこのようなマトリックスレポートを実装するためのベストプラクティスは何ですか?

私がすでに調べようとしたこと:

  • インタラクティブレポートピボット機能(https://docs.oracle.com/cd/E71588_01/AEEUG/managing-pivot-reports.htm#AEEUG29137)-カスタマイズが不足しており、特に数値でない場合、多くの値でうまく機能しません。
  • Classic report based on Function - I have implemented PL/SQL function which returns dynamic PIVOT SQL query, in the properties of the report Use Generic Column Names set to Yes (in order to parse the query only in runtime) and for headings of the report I used another PL/SQL function, which generates a string in the format heading1:headning2:...:headingN. The solution works (you can check it here - https://apex.oracle.com/pls/apex/f?p=132832:2), but I need to refresh the report dynamically every, let's say, 5 seconds, and it will suck in terms of performance (dynamic SQL is always bad and not managable way if we talk about execution plans). Also this solution doesn't fit, because headings are not concerted with the data (actually I used order by col1 in the queries in both PL/SQL functions to make headings be in their places) and I don't know how to make rows sortable here.
  • PL/SQL Dynamic Content Region - I haven't tried to code something here, but I realise that it's possible to do anything here just using HTP package and APEX API. The tricky thing is this solution is quite complex, I'll need to implement all the logic of the report 'from scratch' and I believe there's a better and easier way to succeed in the task, which I don't know.
ZZa

Unfortunately, none of the options I mentioned in the question met all the requirements because of the conditions in which report will live:

  • Data should be dynamically updated every, let's say, 5 seconds.
  • State of the report should be saved over data updates.
  • Number of columns of the report is variable (definition of columns is provided with data), number of rows is variable as well. Report should have sorting, pagination and scrolling (by X and Y) options. All the stuff (sorting, etc.) should be done on client-side.
  • Styles and custom cell rendering should be applied to cells of the table.
  • Cells should be clickable (click should generate an event, which is interceptable).

I realized that for such a task it's better to manipulate DOM on-the-fly on client-side instead of using some out-of-the-box APEX solutions like classic reports, interactive reports or grids.

I used DataTables.js jQuery plugin for this approach. After a week of estimating the technology and learning some basic JavaScript (which is not my primary skill), I had the following:

In the APEX application I implemented an Ajax Callback process (called TEST_AJAX), it runs PL/SQL code, which returns JSON-object to SYS.HTP output (using APEX_JSON or HTP packages). Its source:

declare 
    l_temp sys_refcursor;
begin  
    open l_temp for go_pivot;
    APEX_JSON.open_object;
    APEX_JSON.open_array('columns');
    APEX_JSON.open_object;
    APEX_JSON.write('data', 'COL2');
    APEX_JSON.write('title', '/');
    APEX_JSON.close_object;
    for x in (select distinct col1 from test order by 1) loop
        APEX_JSON.open_object;
        APEX_JSON.write('data', upper(x.col1));
        APEX_JSON.write('title', x.col1);
        APEX_JSON.close_object;
    end loop;
    APEX_JSON.close_array;
    APEX_JSON.write('data', l_temp); 
    APEX_JSON.close_object;
end;

The go_pivot function source:

create or replace function go_pivot return varchar2
  is
      l_query long := 'select col2';
  begin
      for x in (select distinct col1 from test order by col1)
      loop
          l_query := l_query ||
             replace(', min(decode(col1,''$X$'',v)) $X$',
                      '$X$',
                     x.col1);
     end loop;
     l_query := l_query || ' from test group by col2';
    return l_query;
 end;

Then I created a Static Content region on the page, the source of which is following:

<div id="datatable_test_container"></div>

I uploaded CSS and JS files of DataTables.js to application static files and included them in the page properties. In the JavaScript section of the page for Function and Global Variable Declaration I added this javascript code:

var $ = apex.jQuery;
var table;
var columns;
var rows;

//table initialization function
function table_init(json_data) {
    return $('#datatable_test').DataTable({
        //column defaults options
        columnDefs: [{
            "data": null,
            "defaultContent": "-",
            "targets": "_all"
        }],
        columns: json_data.columns,
        data: json_data.data,
        stateSave: true
    });
}
//function to asynchronously get data from APEX AJAX CALLBACK
//process and then to draw a table based on this data
function worker() {
    //run the process called TEST_JSON
    apex.server.process(
        "TEST_JSON", {}, {
            success: function(pData) {
                //on first run we need to initialize the table
                if (typeof table == 'undefined') {
                    //save current data for future use
                    columns = $.extend(true, [], pData.columns);
                    rows = $.extend(true, [], pData.data);
                    //generate empty html-table in the container
                    $('#datatable_test_container').append('<table id = "datatable_test" class = "display" cellspacing = "0" width = "100%" > < /table>');
                    //init the table
                    table = table_init(pData);
                    //when columns of the table changes we need to 
                    //reinitialize the table (DataTables require it due to architecture)
                } else if (JSON.stringify(columns) !=
                    JSON.stringify(pData.columns)) {
                    //save current data for future use
                    columns = $.extend(true, [], pData.columns);
                    rows = $.extend(true, [], pData.data);
                    //delete the table from DOM
                    table.destroy(true);
                    //generate empty html-table in the container
                    $('#datatable_test_container').append('<table id = "datatable_test" class = "display" cellspacing = "0" width = "100%" > < /table>');
                    //reinit the table
                    table = table_init(pData);
                }
                //if data changes, clear and re-draw the table
                else if (JSON.stringify(rows) != JSON.stringify(pData.data)) {
                    //save current data for future use
                    //we don't need to save the columns, they didn't change
                    rows = $.extend(true, [], pData.data);
                    //clear table, add rows from recieved JSON-object, re-
                    draw the table with new data
                    table.clear().rows.add(pData.data).draw(false);
                }
                //if nothing changes, we do nothing
            }
        }
    );
    //repeat the procedure in a second
    setTimeout(worker, 1000);
};

For Execute when Page Loads I added:

$(document).ready(function() {
    worker();
});

What all this does:

  1. Static <div> in the static content region recieves an empty table where DataTables constructor is applied.
  2. JavaScript code starts its work by triggering the Ajax Callback server process, and on success uses the result this process returned.
  3. DataTables constructor supports different types of data sources, for example it can parse an html-table or make an ajax-call, but I preferred to use an APEX process and then base the table on the JSON-object, which this process returns.
  4. Then the script watches changes. If columns changes, the table is deleted from the document and re-initialized using new data, if only rows changes, then the table is just re-drawn with this data. If nothing changes in data then the script does nothing.
  5. This process is repeated every second.

その結果、ソート、ページング、検索、イベント処理などのオプションを備えた、完全にインタラクティブで動的に更新されるレポートがあります。そして、これらはすべて、サーバーへの追加のクエリなしでクライアント側で実行されます。

このライブデモを使用して結果を確認できます(上部の領域はDataTablesレポートで、その下にはソーステーブルに編集可能なインタラクティブグリッドがあり、変更を確認するには、インタラクティブグリッドを使用してデータを変更できます)。

これが最善のアプローチかどうかはわかりませんが、私の要件を満たしています。

2017年9月5日更新:APEX_JSON Ajaxコールバックプロセスとgo_pivotPL / SQL関数のリストを追加しました

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Spring BootとJPAを使用してlikeステートメントを使用してデータベースにクエリを実行するRESTサービスを実装するための最良の方法は何ですか?

分類Dev

PowerShellスクリプトの翻訳を実装するための最良の方法は何ですか?

分類Dev

PowerShellスクリプトの翻訳を実装するための最良の方法は何ですか?

分類Dev

ネットワークを介して多くのRaspPis間で完全な通信を実装するための最良の方法は何ですか?

分類Dev

プレロリポップデバイスにマテリアルデザインを実装するための最良の方法は何ですか?

分類Dev

RestKitを使用してアプリのキャッシュ動作を実装するための最良の方法は何ですか

分類Dev

Jenkinsを介してリモートでスクリプトを実行するための最良の方法は何ですか

分類Dev

APIを使用してすべてのNestuiteデータをエクスポートするための最良の方法は何ですか

分類Dev

Spring Data RESTを使用して深くネストされたJSON構造の更新を実装するための最良の方法は何ですか?

分類Dev

Androidで垂直フローテキストを実装するための最良の方法は何ですか?

分類Dev

自己類似性マトリックスを視覚化するための最良の方法は何ですか

分類Dev

中断信号でサーバーのストップアクションを実装するための最良の方法は何ですか?

分類Dev

RSpecリクエストスペックを使用してJSONAPIをテストするための最良のアプローチは何ですか

分類Dev

他のレイアウトのリストを使用してコーディングするための最良の方法は何ですか?

分類Dev

グーグルクラウドストレージを実装するための最良の方法は何ですか?

分類Dev

各プレイリストのHTMLマークアップを生成するための最良の方法は何ですか?

分類Dev

NOLIOを使用して、SQLスクリプトを実行するための最良の方法は何でしょうか?

分類Dev

流星または角度流星でテーマ/テンプレートを実装するための最良の方法は何ですか

分類Dev

ビットマップリスト内の画像を比較するための最良の方法は何ですか

分類Dev

反応として、Render()の前にAPI呼び出しを実行してリダイレクトするための最良の方法は何ですか?

分類Dev

コンポーネントスコープのシングルトンを実装するための最良の方法は何ですか?

分類Dev

同じソースディレクトリを使用して複数のプラットフォーム用にCargoを使用してビルドするための最良の方法は何ですか?

分類Dev

データを渡してオブジェクトをエクスポートするための最良の方法は何ですか?

分類Dev

PythonからPowerShellスクリプトを実行するための最良の方法は何ですか

分類Dev

Makefileインストールでディレクトリを適切な場所に移動するための最良の方法は何ですか?

分類Dev

私のコントロールを実装するための最良の方法は何ですか

分類Dev

Pythonスクリプトを毎日実行するための最良の方法は何ですか?

分類Dev

スクリプトをもう一度実行するための最良の方法は何ですか?

分類Dev

OSxで仮想環境を使用してJupyterノートブックをセットアップするための最良の方法は何ですか

Related 関連記事

  1. 1

    Spring BootとJPAを使用してlikeステートメントを使用してデータベースにクエリを実行するRESTサービスを実装するための最良の方法は何ですか?

  2. 2

    PowerShellスクリプトの翻訳を実装するための最良の方法は何ですか?

  3. 3

    PowerShellスクリプトの翻訳を実装するための最良の方法は何ですか?

  4. 4

    ネットワークを介して多くのRaspPis間で完全な通信を実装するための最良の方法は何ですか?

  5. 5

    プレロリポップデバイスにマテリアルデザインを実装するための最良の方法は何ですか?

  6. 6

    RestKitを使用してアプリのキャッシュ動作を実装するための最良の方法は何ですか

  7. 7

    Jenkinsを介してリモートでスクリプトを実行するための最良の方法は何ですか

  8. 8

    APIを使用してすべてのNestuiteデータをエクスポートするための最良の方法は何ですか

  9. 9

    Spring Data RESTを使用して深くネストされたJSON構造の更新を実装するための最良の方法は何ですか?

  10. 10

    Androidで垂直フローテキストを実装するための最良の方法は何ですか?

  11. 11

    自己類似性マトリックスを視覚化するための最良の方法は何ですか

  12. 12

    中断信号でサーバーのストップアクションを実装するための最良の方法は何ですか?

  13. 13

    RSpecリクエストスペックを使用してJSONAPIをテストするための最良のアプローチは何ですか

  14. 14

    他のレイアウトのリストを使用してコーディングするための最良の方法は何ですか?

  15. 15

    グーグルクラウドストレージを実装するための最良の方法は何ですか?

  16. 16

    各プレイリストのHTMLマークアップを生成するための最良の方法は何ですか?

  17. 17

    NOLIOを使用して、SQLスクリプトを実行するための最良の方法は何でしょうか?

  18. 18

    流星または角度流星でテーマ/テンプレートを実装するための最良の方法は何ですか

  19. 19

    ビットマップリスト内の画像を比較するための最良の方法は何ですか

  20. 20

    反応として、Render()の前にAPI呼び出しを実行してリダイレクトするための最良の方法は何ですか?

  21. 21

    コンポーネントスコープのシングルトンを実装するための最良の方法は何ですか?

  22. 22

    同じソースディレクトリを使用して複数のプラットフォーム用にCargoを使用してビルドするための最良の方法は何ですか?

  23. 23

    データを渡してオブジェクトをエクスポートするための最良の方法は何ですか?

  24. 24

    PythonからPowerShellスクリプトを実行するための最良の方法は何ですか

  25. 25

    Makefileインストールでディレクトリを適切な場所に移動するための最良の方法は何ですか?

  26. 26

    私のコントロールを実装するための最良の方法は何ですか

  27. 27

    Pythonスクリプトを毎日実行するための最良の方法は何ですか?

  28. 28

    スクリプトをもう一度実行するための最良の方法は何ですか?

  29. 29

    OSxで仮想環境を使用してJupyterノートブックをセットアップするための最良の方法は何ですか

ホットタグ

アーカイブ