Tuesday, December 20, 2011

Refresh-able Charts

The Issue

APEX has come a very long way in helping to declaratively tackle JavaScript interactions with page components. One feature that has saved me countless hours of work is the AJAX refresh-able reports. This feature is leveraged by triggering a "refresh" event that APEX has bound to a report region, and the result is an updated report that reflects the current values of the page items. This behavior is used in almost every application I have created and is also desirable for other region types such as flash charts. Unfortunately, in 4.1, flash chart regions cannot be refreshed in the same way out of the box, but it is possible.

What can be done to make refreshing a chart as simple as refreshing a report?

For those of you who are not familiar with how to refresh a report with a dynamic action have a look at the APEX 4.0 new features application

The Solution

In order to make flash charts refresh-able you will have to perform the following actions:
  1. Modify the chart region template.
  2. Trigger the "Refresh" with a dynamic action.
It should be noted that this only works for flash charts and applications that do not require localization.

1. Modify the Chart Region Template

Add the following snippet of code to the bottom of the chart region template. Then, optionally add a "refreshable-chart" class to the main chart div. This allows you to select all charts on a page with a simple selector. Change the third parameter of apex_RefreshFlashChart to be whichever language you are supporting. Since my application only needs to support English, 'en' works just fine.

<script type="text/javascript"> $('##REGION_STATIC_ID#').bind('apexrefresh',function(){ var region_id = '#REGION_ID#'; $(this).trigger('apexbeforerefresh'); try{ apex_RefreshFlashChart(&APP_PAGE_ID., region_id.substr(1), 'en'); }catch(e){} $(this).trigger('apexafterrefresh'); }); </script>



2. Create the Dynamic Action

Name: refresh_chart
Event: Change
Type: Item(s)
Item(s): P2_DEPTNO

Create two true actions. One to update the session state of your page items and another to refresh the chart. Make sure to include all page items used in your chart region in the Page Items to Submit attribute.

Sequence: 10
Action: Execute PL/SQL Code
PL/SQL Code: null;
Page Items to Submit: P2_DEPTNO

Sequence: 20
Action: Refresh
Selection Type: Region
Region: <your chart region>

The result is a chart that can be refreshed declaratively. One modification to this example could be to change the second true action selection type to jQuery Selector and using the selector .refreshable-chart. This will cause all charts on the page to refresh and could be useful for dashboard type interfaces.

Have a look at my demo application to see how it looks in action.

4 comments:

  1. Hi Tyson,

    This is a nice, elegant solution that should help those that need to do this before native support is added in the future.

    Good post!

    Regards,
    Dan

    ReplyDelete
  2. and how can I refresh a HTML Chart (not a flash chart)? Thank you for your help.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. I am getting a js error: document["c" + d].SetXMLText is not a function with this solution. apex_RefreshFlashChart causing this error. My apex version is 4.1 could you help me out?

    ReplyDelete