Skip to content

May 19, 2010

4

Using Ajax.PeriodicalUpdater to update Flotr graph in both Ajax Window (pop-in) and child browser window (pop-out) simultaneously on IE8

by Joe Kuan

This article describes how to use Ajax.PeriodicalUpdater and Flotr to plot a graph inside Ajax Windows and browser windows (IE8). The same continuous graph that can do ‘pop in’ as an Ajax Window and ‘pop out’ as inside a browser window. Throughout the article, I am using Prototype-UI for creating Ajax Windows, ie all the tools used in here are based on Prototype.

Plotting graphs within Ajax windows is easy. However, drawing graphs between Ajax windows and standalone browser windows requires a bit more understanding on both Flotr and IE8. I will show you and explain what went wrong in the first approach that has only worked on Safari and Firefox but failed on IE8 and came up with a second approach which worked in all browsers.

PeriodicalUpdater and Flotr graphs

First of all, let me describe what I am trying to achieve here. Part of the user interface I am developing is to plot multiple continuous graphs, therefore I need Ajax.PeriodicalUpdater to extract graph data and use Flotr to draw the graphs. I can have two approaches:

  1. Create a principle Ajax.PeriodicalUpdater to retrieve all the displayed graphs data and update each graph in either Ajax window or standalone browser.
  2. Let each displayed graph has it’s own PeriodicalUpdater to extract the graph data.

For me, the choice is pretty clear to approach 1 mainly because

  • A single PeriodicalUpdater reduces the communication load comparing to multiple PeriodicalUpdaters.
  • Better synchronisation between graphs, users may need to see the characteristic of graph data by putting two graphs side by side
  • Less overhead on client side Javascript.

Pop-in and Pop-out feature

When I first developed plotting these graphs inside Ajax windows, I noticed users will soon running out of space inside the page and this will certainly become frustration. So the requirement for making a graph window appearing as an Ajax window (pop-in) and browser window (pop-out) interchangeably becomes a no brainer. If you still not sure what I am talking about, try Google mail where I first noticed this feature.

The only difference between the pop-in and pop-out windows:

  • Pop-out window requires all the includes of HTML, BODY, Javascript files and CSS files.
  • Any Javascript functions requires update to the parent window has to go through window.opener.

As long as you are aware which Javascript function is running in the child or parent window space, it shouldn’t be difficult at all.

First browser window update approach – Flotr.draw on child window DOM

The first approach is pretty simple. First, I have a main list keeping all the graph instances (window objects created either from UI.Window from Prototype-UI or window.open routine) along with it’s configurations such as graph id, pop-in or pop-out, etc. With PeriodicalUpdater‘s onSuccess callback handler, every second I process and convert the data into series for each graph id and do the following steps:

  1. If the graph is in an Ajax window, then do Flotr.draw($(graph_win_id_container), series, opt) where graph_win_id_container is the DIV element in the Ajax window for the graph. See Flotr documentation.
  2. If the graph is in a browser window, then do Flotr.draw(child_win.document.container, series, opt) where child_win is the returned window object from window.open call and container is the DIV element for the graph inside the browser window.

This method works fine on both Safari and Firefox fine. However, in IE8 there was no graph update at all in the browser window (Step 2) and no errors displayed.

While I tried to catch an exception like below, then the error message appears.

try {
  Flotr(child_win.document.container, series, opt);
} catch (error) {
  alert(error.name + ":" + error.message);
}

And the error was displayed as follow:

This error message, TypeError: Object doesn’t support this property or method, is not clear or helpful what was the problem. After some investigation, I realised that the IE8 was complaining a document object is not allowed to modify an element which is owned by another document object for security reason.

So I turned my attention into Flotr source code and acknowledged the program does try to create and insert “<canvas>” tag with CSS class and style properties (See Flotr:constructCanvas method) inside the ‘container’ DIV element. As soon as Flotr calls Element.create(‘canvas’, size), it assumes the element is created from the caller’s document object which violates the IE8 rule. A different approach has to be taken.

Second approach – Javascript wrapper function

The bottom line is I need to get this working across all the different browsers and the main Ajax page cannot fiddle any elements owned by another document object. In other words, I cannot call Flotr within the parent window space.

I could have start modifying Flotr source code to make sure creating the element from the given’s container document instead of caller’s one but this will lock me into a further chain of changes in Flotr code, very cumbersome and messy.

A simple and clean alternative would be having a Javascript wrapper function flotr_draw inside the browser window, then the function calls the Flotr.draw on the it’s own container. So the whole Flotr is running in the child window space and the wrapper function acts on behalf of the browser window.

<script language="Javascript" type="text/javascript">
function flotr_draw(series, opts) {
   Flotr.draw($('container'), series, opt);
}
</script>

So on the parent window side, it can call the above function to update the graph in the child window. Effectively, parent window is just passing the series data and option object to the child window.

   win.flotr_draw(series, opts);

where win is the window object returned from window.open.

Here is a screenshot of IE8 with one Ajax window and browser window.

I work for iTrinegy. Here are my other Prototype-UI and Prototype blogs

4 Comments Post a comment
  1. tom
    Jan 25 2013

    I like this approach…do you have sample code?

    Reply
    • Joe Kuan
      Jan 26 2013

      Sorry, the article was long time ago and I didn’t have the habit of putting online demo at that time. However, I recommend you to go for Highcharts instead of Flotr and other Javascript framework (Dojo or ExtJs) which can still achieve the same goal.

      Reply

Trackbacks & Pingbacks

  1. Using Ajax.PeriodicalUpdater to update Flotr graph in both Ajax … | Programming Blog Imagik.org

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments

%d bloggers like this: