A Quick Look at Visualforce Charting

It's been almost two weeks since the end of Dreamforce, but if anything, the excitement level here is going up. Winter '12 is just around the corner, and we're getting amped to see what you can do with it. Today I want to give a quick tour of one of the features I documented---charting in Visualforce. Visualforce charting is a way for you to create custom "business style" charts on your Visualforce pages---pie, bar, and line charts. It simplifies the process of connecting a data source (generally a custom controller method) to JavaScript charting libraries that render groovy charts in the browser. If you want to, you can work exclusively in Visualforce and Apex, and let the charting components take care of all the JavaScript for you.

It’s been almost two weeks since the end of Dreamforce, but if anything, the excitement level here is going up. Winter ’12 is just around the corner, and we’re getting amped to see what you can do with it. Today I want to give a quick tour of one of the features I documented—charting in Visualforce.

Note: Visualforce charting components are currently available through a pilot program. For information on enabling this feature for your organization, contact salesforce.com. At this time it is not recommended that this feature be used in production code or managed packages.

Visualforce charting is a way for you to create custom “business style” charts on your Visualforce pages—pie, bar, and line charts. It simplifies the process of connecting a data source (generally a custom controller method) to JavaScript charting libraries that render groovy charts in the browser. If you want to, you can work exclusively in Visualforce and Apex, and let the charting components take care of all the JavaScript for you.

But enough with the description—let’s look at some code! Here’s what a simple pie chart looks like in a Visualforce page:

<apex:page controller="PieChartController" title="Pie Chart">
    <apex:chart height="350" width="450" data="{!pieData}">
        <apex:pieSeries dataField="data" labelField="name"/>
        <apex:legend position="right"/>
    </apex:chart>
</apex:page>

This needs to be paired with a controller that can supply the pie chart data. Normally you would perform a SOQL query or otherwise calculate the pie wedge data from your live business data, but to keep this simple (and to give you something to copy and paste once you have Winter ’12 yourself), here’s an example that uses dummy data:

public class PieChartController {
    public List<PieWedgeData> getPieData() {
        List<PieWedgeData> data = new List<PieWedgeData>();
        data.add(new PieWedgeData('Jan', 30));
        data.add(new PieWedgeData('Feb', 15));
        data.add(new PieWedgeData('Mar', 10));
        data.add(new PieWedgeData('Apr', 20));
        data.add(new PieWedgeData('May', 20));
        data.add(new PieWedgeData('Jun', 5));
        return data;
    }

    // Wrapper class
    public class PieWedgeData {

        public String name { get; set; }
        public Integer data { get; set; }

        public PieWedgeData(String name, Integer data) {
            this.name = name;
            this.data = data;
        }
    }
}

But here’s what you really want to see—the chart itself:

Deliberately Spartan, but it’s awfully easy to create! Before we look at a more interesting chart, here’s a few things to note in this simple example.

  • The chart itself is defined using four new components, on lines 2-5. The structure is simple: an overall chart component creates a context and wraps various child components that define how to construct the chart.
  • You should have no difficulty identifying how the getPieData() controller method that supplies the data is linked to the chart component, using the {!pieData} expression that calls it.
  • What’s interesting here is the format in which the data is supplied. The controller defines an inner class that “wraps” the data for each pie wedge. The properties of the inner class—name and data—create a simple name/value pair for accessing the elements for each data point in the chart. I’ll expand on this in the second example.

Pie charts are pretty simple, with only one data series per chart. Bar and line charts can layer multiple data series, combining lines and bars to tell a compelling story. Here’s a chart that combines three different sets of data to show the relationship between them:

Pretty snazzy, huh? Here’s the Visualforce markup to display that chart:

<apex:page controller="ChartController">
    <apex:chart height="400" width="700" data="{!data}">
        <apex:legend position="right"/>
        <apex:axis type="Numeric" position="left" fields="data1"
            title="Opportunities Closed" grid="true"/>
        <apex:axis type="Numeric" position="right" fields="data3"
            title="Revenue (millions)"/>
        <apex:axis type="Category" position="bottom" fields="name"
            title="Month of the Year">
            <apex:chartLabel rotate="315"/>
        </apex:axis>
        <apex:barSeries title="Monthly Sales" orientation="vertical" axis="right"
            xField="name" yField="data3">
            <apex:chartTips height="20" width="120"/>
        </apex:barSeries>
        <apex:lineSeries title="Closed-Won" axis="left" xField="name" yField="data1"
            fill="true" markerType="cross" markerSize="4" markerFill="#FF0000"/>
        <apex:lineSeries title="Closed-Lost" axis="left" xField="name" yField="data2"
            markerType="circle" markerSize="4" markerFill="#8E35EF"/>
    </apex:chart>
</apex:page>

The preview documentation has extensive details for these charting components, but here are two differences to highlight compared to the pie chart:

  • Notice the three <apex:axis> components, lines 4-11, which define the units and labels for the three chart axes that are in use here. An axis automatically calculates its minimum, maximum, and tick mark increments based on the data found in the data series defined in the fields attribute. You can also set the start and end of the axis manually.
  • After the axes definitions are three data series—one <apex:barSeries> and two <apex:lineSeries> components, on lines 12-19. Each series represents a set of points plotted on the chart. The points are defined by the xField and yField attributes in the series, which define the properties (the name part of the name/value pair) in the {!data} collection that represents each data point. So, for the <apex:barSeries>, the X value of the point is the name property, representing a month of the year, and the Y value of the point is the data3 property, representing dollars (in millions).

Finally, here’s the controller that supplies the data:

public class ChartController {
    // Return a list of data points for a chart
    public List<Data> getData() {
        List<Data> data = new List<Data>();
        data.add(new Data('Jan', 30, 90, 55));
        data.add(new Data('Feb', 44, 15, 65));
        data.add(new Data('Mar', 25, 32, 75));
        data.add(new Data('Apr', 74, 28, 85));
        data.add(new Data('May', 65, 51, 95));
        data.add(new Data('Jun', 33, 45, 99));
        data.add(new Data('Jul', 92, 82, 60));
        data.add(new Data('Aug', 87, 73, 45));
        data.add(new Data('Sep', 34, 65, 55));
        data.add(new Data('Oct', 78, 66, 56));
        data.add(new Data('Nov', 80, 67, 53));
        data.add(new Data('Dec', 17, 70, 70));
        return data;
    }

    // Wrapper class
    public class Data {
        public String name { get; set; }
        public Integer data1 { get; set; }
        public Integer data2 { get; set; }
        public Integer data3 { get; set; }
        public Data(String name, Integer data1, Integer data2, Integer data3) {
            this.name = name;
            this.data1 = data1;
            this.data2 = data2;
            this.data3 = data3;
        }
    }
}

Really, this isn’t meaningfully different from the PieChartController in the first example. All I’ve done is added additional properties to the wrapper class, one per data series. If I wanted to be a little more semantic, I could name those properties to be related to their underlying data—for example, dataClosedWon instead of data1. I’ll leave that as an exercise for you when you create your first chart. 😉

That’s all for this week. You can read more about Visualforce charting in the preview release notes and documentation we published last week. The whole Visualforce team is looking forward to seeing what you do with Winter ’12!

Leave your comments...

A Quick Look at Visualforce Charting