Visualforce charting is one of the most popular features added to Visualforce while I’ve been writing documentation for the product, and JavaScript Remoting is one of the most powerful. Perhaps you’ve wondered how to combine the two.

Visualforce Pie Chart This sample shows how to load and update a chart using two different methods, highlighting how to use JavaScript Remoting to smoothly load new data and update the chart. The example chart is a simple pie chart, and updates happen when the user selects a new year to display from a menu.

“Traditional” Visualforce loads the chart data using an expression to call a controller method, and updates the data using an <apex:actionSupport> component to re-render the chart’s section of the page in response to choosing a different year. The technique is well explained in the Visualforce Developer’s Guide.

The JavaScript Remoting version relies on some JavaScript code that I’ve written myself, instead of the automatic behaviors built into Visualforce. It’s a bit more code, but it’s also more flexible, with a smoother transition when the chart is updated. The following sample is more comprehensive than any currently in the Visualforce documentation.

To start with, here’s the controller code, a straightforward expansion of a pie chart controller from the Visualforce Developer’s Guide:

The code is pretty ordinary, except perhaps in that it supports getting chart data via two different methods. getPieData() is intended to be used in a Visualforce expression as {! pieData }, while getRemotePieData() is, as you might guess by the @RemoteAction annotation, intended to be called directly using JavaScript Remoting.

Here’s the Visualforce page, with the two different charts in separate <apex:pageBlockSection>s:

The “normal” Visualforce chart is on lines 4-23, and the Remoting-based chart (well, most of it) is on lines 25-46. You can see that they have similar forms: both <apex:pageBlockSection>s have two blocks of their own, the chart block and the year selection menu form. The two chart blocks are nearly identical, the only meaningful difference is the data attribute for the <apex:chart> tag. The Visualforce chart uses an expression to call a controller method that provides the data. The Remoting chart data attribute is…well, it looks like just a string. I’ll get right back to that. The year selection form for the Visualforce chart uses the expected Visualforce tags, including <apex:actionSupport> to provide the refreshing and <apex:actionStatus> to display a simple “loading” message during a refresh. In contrast, the Remoting version uses static HTML, more to show that you can than because it’s required, and has no apparent way to trigger a refresh.

In the above code sample, the two charts appear to have roughly the same number of lines of code. The thing is, I left off part of the Remoting chart’s code. The JavaScript part of JavaScript Remoting. This part goes between the opening <apex:page> and the <apex:pageBlock> tags:

This is the most interesting part of the page, at least for understanding how to combine Visualforce charting and JavaScript Remoting. These two JavaScript functions are the glue between the Visualforce chart and the @RemoteAction controller method that provides the data. There are three links between the functions and the chart component you should notice:

  1. The chart component’s data attribute is the string “retrieveChartData”, which is the name of the first JavaScript function. This tells the chart component to use the JavaScript function to load its data. retrieveChartData() is only invoked once by the chart component directly, when the chart is first created and the data is initially loaded.
  2. Reloading happens when the second JavaScript function, refreshRemoteChart(), is called. This is the second link, and it’s actually from the year menu item, a static HTML element, which has an onChange attribute of refreshRemoteChart();. When you make a change to the menu, refreshRemoteChart() is invoked, and it re-invokes the retrieveChartData() function to load a new set of data.
  3. When refreshRemoteChart() invokes retrieveChartData() it provides an anonymous function as a callback, which handles the result of the @RemoteAction call when it returns. This callback is what actually updates the chart, by calling RemotingPieChart.reload(data). RemotingPieChart is the name I gave to the chart component, on line 29 of the first sample, and reload() is a JavaScript function available on it that accepts new data and then redraws the chart.

Here’s a more visual way to see these links between the different components of the page:

Updating Visualforce Charts with JavaScript Remoting

The sequence for the initial loading of the chart is simple: the <apex:chart> named RemotePieChart calls retrieveChartData() to get its initial data, and retrieveChartData() calls when it has the data. And, the chart appears.

Updates are more complicated. When a new year is chosen from the theYear menu, the menu’s onChange event fires, which calls refreshRemoteChart(). refreshRemoteChart() in turn calls retrieveChartData(), and when that returns new data, it (via the callback it created) calls RemotePieChart.reload(). And, the chart updates.

The structure of this code sample may seem complicated at first, but it provides a great deal of flexibility in what to display or change at various points in the update cycle. Once you study it a bit, and spend some time writing JavaScript user interface code, you’ll find that it’s perfectly natural.

Here are a couple of other items to note.

  • The <apex:chart> uses the hidden="true" attribute to prevent the chart from displaying before there’s data to display. The retrieveChartData() function calls to display the chart once the chart data is loaded. This and RemotingPieChart.reload() provide for much smoother chart animations than what is achieved using <apex:actionSupport>. Add this code into your own org and compare the two.
  • The refreshRemoteData() function sets the statusElement HTML <span> to a “loading…” message before it attempts to update the data by calling retrieveChartData(), and then the anonymous callback function sets it to an empty string to hide the message once the data is returned and the chart updated. It’s a bit more work than using <apex:actionStatus> for basically the same effect. You could easily show a “busy” animation or graphic using the same technique.

This article was inspired by a recent post in the Visualforce discussion forum, which asked about using JavaScript Remoting to load and update chart data, and how to get the chart to draw with that data. We answered the question in the discussion, but I wanted to also expand the existing documentation on the topic. The code sample in this article, and the explanation (in substantially different form), will appear in a future edition of the Visualforce Developer’s Guide. I hope it’s useful, and interesting, to get a preview of that documentation a little early.

Get the latest Salesforce Developer blog posts and podcast episodes via Slack or RSS.

Add to Slack Subscribe to RSS