Creating a Visualforce Bar Chart

Creating a Visualforce Bar Chart in Salesforce

Visualforce charting allows custom charts to be embedded into any Visualforce page using standard components and some server-side coding. A key difference from the standard charting functionality available in reports and dashboards is that the data provided by the Visualforce page controller and can be derived from any number of sObjects, regardless of whether any relationships between the sObjects exists or not.

Bar charts allow easy comparison of groups of data. Typical use in Salesforce is to view performance on a month-by-month basis; for example, to identify the effectiveness of process improvement.

In this example, we will create a Salesforce Visualforce page containing a bar chart that displays the total value of won opportunities per month for the previous 12 months. This allows a sales manager to view at a glance the sales performance, and to identify any problem months that require further analysis.

/******************************************************
Custom controller for the "Creating a Bar Chart" Example. * Manages a list of wrapper classes used to back a chart that * contain the total won opportunity value for a month over the * last year.
*************************************************************/
public with sharing class BarChartCont { 
    // List of month names 
    private static List<String> months=new List<String> { 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' };
    // Getter to retrieve the list to draw the chart.
    public List<Data> getChartData() { 
        Map<Integer, Data> dataByMonth = new Map<Integer, Data>(); 
        List<Data> chartData=new List<Data>(); 
        DateTime startDT=DateTime.newInstance(Date.today().addYears(-1).toStartOfMonth(), Time.newInstance(0, 0, 0, 0)); 
        DateTime endDT=DateTime.newInstance(Date.today(), Time.newInstance(23, 59, 59, 999)); 
        Integer startMonth=startDT.date().month()-1;
        for (Integer idx=0; idx<12; idx++){
            Integer monthNo=Math.mod(startMonth+idx, 12);
            Data theData=new Data(months.get(monthNo));
            dataByMonth.put(monthNo, theData);
            chartData.add(theData);
        } 
        for (Opportunity opp : [select id, CloseDate, Amount from Opportunity where IsClosed = true and IsWon =     true and CloseDate>=:startDT.date() and CloseDate<=:endDT.date()]) {
            Data cand=dataByMonth.get(opp.CloseDate.month()-1); cand.oppTotal+=opp.Amount;
        }
        // Demonstration purposes only - create some random data for empty months
        // between 0 and 750,000 
        for (Integer idx=0; idx<12; idx++) {
            Data cand=dataByMonth.get(idx);
            if (0.0==cand.oppTotal) {
                cand.oppTotal=Math.random()*750000;
            }
        }
        return chartData;
    }
    // Wrapper class 
    public class Data {
        public String name { get; set; } 
        public Decimal oppTotal { get; set; } 
        public Data(String name) {
            this.name = name; this.oppTotal = 0.0; 
        }
    }
}
<apex:page controller=”BarChartCont”>
    <p style=”font-size:18px; font-weight: bold;”>
        Opportunity Value – Last 12 Months – executed on
        <apex:outputText value=”{0,date,dd/MM/yyyy}”>
            <apex:param value=”{!TODAY()}”/>
        </apex:outputText>
    </p>
    <div style=”margin-left: auto; margin-right: auto”>
        <apex:chart height=”400″ width=”650″ data=”{!chartData}”>
            <apex:axis type=”Category” position=”bottom” fields=”name” title=”Month” />
            <apex:axis type=”Numeric” position=”left” fields=”oppTotal” title=”Value” grid=”true”/>
            <apex:barSeries orientation=”vertical” axis=”bottom” xField=”name” yField=”oppTotal” />
        </apex:chart>
    </div>
</apex:page>

How it works…

The Visualforce chart is generated via an <apex:chart/> standard component, which defines the dimensions of the chart and the collection of data that will be plotted. <apex:chart height="300" width="550" data="{!chartData}"> The bar series component defines the values from the chart data that will be used to plot the x and y values.

<apex:barSeries orientation="vertical" axis="bottom" xField="name"yField="oppTotal" />

The axes for the chart are defined by <apex:axis/> components: one for the bottom axis displaying the month name and another for the left-hand axis displaying the total opportunity value.

<apex:axis type="Category" position="bottom" fields="name" title="Month" />
<apex:axis type="Numeric" position="left" fields="oppTotal"title="Value" grid="true"/>

The chart data is a collection of inner classes defined in the custom controller.

public class Data{    
    public String name { get; set; }   
    public Decimal oppTotal { get; set; }
}

Here, the name property contains the month name, while the oppTotal property contains the total value of opportunities closed in that month. The chart data collection is provided by the getChartData() controller method, which iterates all opportunities closed in the last year and adds the opportunity amount to the wrapper class instance for the month that the opportunity closed in.

DateTimestartDT = DateTime.newInstance(Date.today().addYears(-1).toStartOfMonth(), Time.newInstance(0, 0, 0, 0));
DateTimeendDT = DateTime.newInstance(Date.today(),Time.newInstance(23, 59, 59, 999)); 

for (Opportunity opp : [select id, CloseDate, Amountfrom Opportunity where IsClosed = true and IsWon = true and CloseDate =:startDT.date()and CloseDate =:endDT.date()]) {      
    Data cand = dataByMonth.get(opp.CloseDate.month()-1);   
    cand.oppTotal+=opp.Amount;
}

In order to ensure that a bar is rendered for each month, the controller iterates the months and generates a random value for any month that has an opportunity total value of zero.

for (Integer idx=0; idx&lt;12; idx++) {
    Data cand = dataByMonth.get(idx);
    if (0.0==cand.oppTotal) {
        cand.oppTotal=Math.random()*750000;
    }
}

Page-reference: https://developer.salesforce.com/docs/atlas.../pages_charting_example.htm

Popular Salesforce Blogs