Building Dynamic Stacking Bar Charts in Visualforce

November 13, 2015 Appirio

By Pankaj Mehra


Salesforce’s Stacked Bar Charts visualizes grouped data, segmented proportionally by a key metric. These Stacked Bar and Stacked Column charts are standard Salesforce charts that you can add to your reports through the normal report builder.

Sometimes, though, you need to include your charts in a custom Visualforce page

As part of last year’s Spring ’14 release, Salesforce made it significantly easier to including existing reports directly within a Visualforce page.

For example, here’s how you might bring in a report with the ID 00Oxxxxxxxxxxxx.


<analytics:reportChart reportId=”00Oxxxxxxxxxxxx”></analytics:reportChart>



However, in cases where embedding existing reports will not meet your requirements, Salesforce offers the <apex:chart> component, which allows you to dynamically query what data you would like to display, and construct at runtime the attributes of the visualization.
An “out-of-the-box” Stacked Bar Chart implementation in Visualforce would dynamically extract the data from the backend and leverage the settings defined in the Visualforce code to generate displaying the data — for instance what type of chart (Bar, Pie, Funnel, etc), the labels for the axises, and the existence of a legend based on your returned data.


In the above example we generated a Stacked Bar Chart in a Visualforce page by constructing a new wrapper class definition in the controller for the data that we intend to display (“public class Data”), and create a property within the controller to build a list of “Data” records to return for display.

In the Visualforce settings, we identify which fields of our known Data wrapper class that we intend to display (yField=”data1,data2,data3″), as well as set the legend to identify the titles of all the fields displayed (title=”MacDonald,Promas,Worle“, which will then render our legend with the title of the first field “data1” listed as “MacDonald” matched to the color value used to render data1’s values.

The dataset we hardcoded into our controller’s get property can easily be replaced with one that queries against our unique Salesforce instance and then builds the data intended to be displayed with the wrapper class.
The full copy and pastable example using static data is as follows:


<apex:page controller=”ChartController”>

   <apex:chart data=”{!data}” height=”400″ width=”500″>

       <apex:legend position=”left”/>

       <apex:axis type=”Numeric” position=”left” title=”Closed Won” grid=”true”

           fields=”data1,data2,data3″ dashSize=”2″>



       <apex:axis type=”Category” position=”bottom” fields=”name” title=”Stacked Bars”>

           <apex:chartLabel rotate=”315″/>


       <apex:barSeries orientation=”vertical” axis=”left” stacked=”true”



title=”MacDonald,Promas,Worle” />



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) {

  = name;

           this.data1 = data1;

           this.data2 = data2;

           this.data3 = data3;






In cases where it will always be the same fields displayed, with the same headings, this type of static configuration of the Visualforce chart is easy to implement and maintain.

But how would you approach rendering a chart where both the number of group values and the description of the types of data displayed changes?
For instance, in the example screenshot below, querying Opportunity amounts, grouped by Quarter and then by Currency Codes, the number of Currency Code Values will change over time.




Previously we saw how easy it was to stack static fields in a bar chart.

The following approach will allow you to dynamically stack fields in a bar chart. This approach will use both Apex code and Javascript to create the desired results.

Standard stacked bar charts accept input from an Apex class or javascript. In the case of an apex class, we cannot add fields to the apex class on the basis of the fields to be stacked.

To build our solution, we enlisted the aid of JavaScript to help organize and prepare the data that we intend to display.  The bar chart will then be able to display stacked values based on currency codes (USD,JMD,KRW etc) for each Quarter.

Step 1. Within Apex, Create a Map that will include data for the x-axis (Quarter), y-axis (Amount) and the field to be stacked (Currency):

This Map, which we’ll call “dataMap”, will contain x-axis data which has been mapped to another map of stacked data and stacked data value. The Map will be of below format:

public static Map<String, Map<String, Integer>> dataMap{get;set;}

where the primary map key value, highlighted in red, will point to the data on x-axis , in the above screenshot it represents a quarter of year.

The inner map will represent a pair of Amount in a specific currency, so the entry of map will look like:

dataMap = <’2014 Q1’ , <[’USD’,900.00],[’INR’,200.00]>>

Step 2. Create a way of providing a list all the values that will be included with the “y-axis” of your chart

Your chart will need a way of iterating over your named mapped pairs of data. To do this we provide a list of fields – or, in our case, quarters – which will be used to further retrieve our data.

Your primary key will contain all the data that you intend to display across the y-axis of your stacked report. If you previously build the list of values in order to help construct your dataMap variable, simply expose that collection in a property.

If you have not build that value yet, consider exposing the dataMap’s primary key values via an Apex property.

In the static sample, we set our “yField” values with “data1,data2,data3”

If an Apex Property exists for the yField, this value can be set dynamically following the pattern of:  yField=”{!yfield}”

Step 3. Add javascript to map data from apex map to javascript array that will populate the chart data.

We will then populate a javascript array of object using this map on page load:

We begin by initializing a new JavaScript variable “data”

var data = new Array();

And then iterate over the Apex variable “dataMap” we defined in our class to populate our JavaScript variable with organized grouping of data.

We can do this through the use of nested repeaters.

First we iterate over the Quarters, the primary key in our dataMap multidimensional array.

Within each iteration we create a new Array called “product”.

For each quarter there is a product that contains a list of currency code and the total amount for that code for that quarter.


<script type=”text/javascript”>

<apex:repeat value=”{!dataMap}” var=”aQuarter”>

var product = {};

product[‘name’] = ‘{!aQuarter}’;

<apex:repeat value=”{!dataMap[aQuarter]}” var=”currencyCode”>

product[‘{!currencyCode}’] =








Step 4. Add the dynamic stacked bar chart to the Visualforce page

Set the apex:chart data attribute to our JavaScript data variable (“data”) to then render the grouped currency coded data.


<apex:chart data=”data height=”250″ width=”320″>

<apex:legend position=”right” />

<apex:axis type=”Numeric” position=”left” title=”” grid=”true”

fields=”{!yfield}” dashSize=”2″>

<apex:chartLabel />


<apex:axis type=”Category” position=”bottom” fields=”name”>

<apex:chartLabel rotate=”315″/>


<apex:barSeries orientation=”vertical” axis=”left”  stacked=”true”

xField=”name” yField=”{!yfield}” colorSet=”#FFB100,#F15D15,#359A2C,#009BBD,#17C3B5,#9E62B7,#A2D760,#8DD7E8″>

<apex:chartTips height=”20″ width=”120″ rendererFn=”renderTooltipStacked”/>




Finally, set the “yfield” values to the data source for the dataMap primary key. For example: yField=”{!yfield}”

Step 5. For added usability, include an additional Javascript function to update the tooltip text to show the Stacked field name with stacked field value:


function renderTooltipStacked(data , item) {

           this.setTitle(item.yField+ ‘ : ‘ + item.value[1]);



Previous Article
Appirio is Making Big Changes to the Topcoder Community and Improving the Member Experience
Appirio is Making Big Changes to the Topcoder Community and Improving the Member Experience

Exciting changes are coming to Topcoder™, Appirio’s crowdsourcing community. In a recent press release, Ale...

Next Article
Is Full Regression Testing Required in Agile Development?
Is Full Regression Testing Required in Agile Development?

By Neerav Patel One of the most important features of Agile Development methodology is the client review/de...