Salesforce Reporting API and NVD3

I’ve read a few posts about how to query Salesforce’s reporting API in order to generate charts. However, none of those explained how to set custom filters or groupings on that data. One of our clients required a chart making but not using the default groupings/filters that existed in the actual report. Here’s how it was done…

Constructing the request


We used jQuery to make ajax calls to the Salesforce reporting API, then render the chart data. So, you create an object that will return a promise. Once the promise resolves, away you go!

xhr = $.ajax(this.endPoint,
  type: 'POST', 
  beforeSend: function(xhr) {
    xhr.setRequestHeader('Authorization', 'Bearer 1234567');   // 1
    xhr.setRequestHeader('Content-Type', 'application/json');   
  data: postData === null ? null : JSON.stringify(postData),  // 2

  .done (function (response) {
    self.cacheData(cacheKey, response);  // 3
  .fail (function (jqXHR, textStatus) {
  1. An authorisation request header must be sent with each request to Salesforce. In our case, the authKey is set from the VisualForce page, which can then be accessed by our javascript.
  2. A data object can be sent with the request, which contains a JSON stringified object containing groupings and filters. In our code, either the data or null is passed in. This means that if null is passed, the default groupings and filters for the report will be returned.
  3. Not really required to make the request, but once the promise resolves, the data can be cached reducing the number of requests to the API.

The postData object

This is what the postData object looks like…

  "reportFilters":[{"column":"ACCOUNT.TYPE","isRunPageEditable":false,"operator":"equals","value":"Customer,Support Location Only"},{"column":"RECORDTYPE","isRunPageEditable":false,"operator":"equals","value":"Almonde,Bankmaster"},{"column":"CREATED_DATEONLY","isRunPageEditable":false,"operator":"greaterOrEqual","value":"N_MONTHS_AGO:12"}]}

By passing this as the data object in the ajax request, custom filtered and grouped data is passed back. Depending of the type of chart you’re trying to render, you can just loop through the ‘groupingsDown’ object of the returned data, optionally loop through the ‘groupingsAcross’ object and look up the actual values in the ‘factMap’ object (Here’s a link to the salesforce reporting api).

Displaying the chart

We’ve used version 3 of the NVD3 charting engine, which has some nice features. Here’s how a multibar chart is created.

var chart = nv.models.multiBarChart()
    .margin({ left: 80 })



  var chartData = [];
  $.each(response.groupingsDown.groupings, function(di, de) {
    var values = [];
    chartData.push({"key":de.label, "values": values});
    $.each(response.groupingsAcross.groupings, function(ai, ae) {
      values.push({"x": ae.label, "y": response.factMap[de.key+"!"+ae.key].aggregates[0].value});
  }); + ' svg')

As well as actually outputting the chart, this bit of code also shows x and y axis labels based on the metadata coming out of the report JSON.

Leave a Reply