Creating a Mashup with a FusionChart and Ajax Data using the Client Side API

The screen shot above of a Company Summary screen shows a graph displaying the count of opportunities and cases belonging to the company in the TopContent area.

This has been created using the following code added to the Custom Content box of the CompanyBoxLong screen.

var myResults = {};
var OppoData;
var CaseData;

crm.ready(function () {
var contextInfo = crm.getArgs();
//Set up Company Screen
if (contextInfo.Act == "200") {

//Add the chart
var myOutPut = "

";

FusionWidgets XT will load here!


var x = $("#EWARE_TOP").children();
var y = $(x).children();
var z = $(y).children();
var a = $(z).children("td:last");
a.after(myOutPut);

//First do the Ajax Count of Oppos and Cases
//Ajax requests have to be sequenced as chart can only be added after Ajax requests returned
var companyID = crm.getArg("key1")
var strOppoWhereClause = "oppo_primarycompanyid eq " + companyID;
var strCaseWhereClause = "case_primarycompanyid eq " + companyID;

//Function to format returned Case data.
var successCase = function (crmRecord) {
myResults.CaseCount = crmRecord.totalResults;
//CaseData is variable used in Chart setup
CaseData = {
"label": "Cases",
"value": myResults.CaseCount,
"tooltext": "Cases in Progress: " + myResults.CaseCount
}
}

//Function to format returned Opportunity data.
var successOppo = function (crmRecord) {
myResults.OppoCount = crmRecord.totalResults;
//OppoData used in Chart Setup
OppoData = {
"label": "Oppos",
"value": myResults.OppoCount,
"tooltext": "Opportunities in Progress: " + myResults.OppoCount
}
}

//Sequence the Ajax fetches and then draw the chart.
$.when(crm.sdata({
entity: "cases",
where: strCaseWhereClause,
success: successCase
}), crm.sdata({
entity: "opportunity",
where: strOppoWhereClause,
success: successOppo
})
).done(callScripts());

//Fetch FusionChart scripts and run the setup in the same function to allow variables to be used
function callScripts() {
/////Function starts
var strThemePath = crm.installUrl() + "FusionCharts/themes/fusioncharts.theme.fint.js";
$.getScript(strThemePath);
var strScriptPath = crm.installUrl() + "FusionCharts/fusioncharts.js";
//get a javascript file from the server and execute it.
$.getScript(strScriptPath, function (data, textStatus, jqxhr) {
//define chart
FusionCharts.ready(function () {
var myChart = new FusionCharts({
"type": "bar2d",
"renderAt": "chartContainer",
"width": "200",
"height": "75",
"dataFormat": "json",
"dataSource": {
"chart": {
"theme": "fint",
"canvasborderthickness": "1"
},
"data": [
OppoData,
CaseData
]
}
})
myChart.render("chartContainer");
});
})
////Function ends
};
};
});

Notes

Although the code above looks quite complicated it can be broken down and understood pretty easily. However, before I start explaining this code I would recommend that you first read a couple of older articles that deal with using Ajax, FusionWidgets and editing the TopContent area in the Client Side API.

We have to work with a few constraints.

  1. We are including FusionCharts.js script in our own code using the jQuery.getScript() method so our program needs to be within this in order to reference the FusionChart objects.
  2. We will also be passing values returned by the Ajax queries so we will need to use a global object accessible by all functions. I have used the object myResults to store the data to be used in the chart.
  3. The data for the chart elements (OppoCount and CaseCount) are the results of two separate Ajax requests.
  4. Ajax is by nature 'asynchronous' but we need to chain the fetches as we can not draw the chart until the data in returned.
  5. We need to add a 'placeholder' in the TopContent so that the FusionChart code can render the Chart in the correct location.
  6. The basic outline of the script can be seen as
  • Create global results object
  • Include FusionCharts script and write code in context of the jQuery.getScript() function.
    • 'Get Context' - create out the restrictions to be used by the Ajax requests.
    • Define the successCase function. (This is the function that will be run when the Case Ajax request is made. It will create the object holding the Case data to be used in the chart and will also add the place holder into the TopContent and then write out the Chart). At this point the function is only defined.
    • Define the successOppo function. (This is the function that will be run when the Opportunity Ajax request is made. It will create the object holding the Opportunity data to be used in the chart. It also calls the Case Ajax request. This is the 'chain'.
    • Finally invoke the Opportunity Ajax request.

Anonymous
  • This is my criteria

    var strPersonWhereClause = "pers_companyid eq " + companyID;

    //Function to format returned Case data.

    var successPerson = function (crmRecord) {

    myResults.PersonCount = crmRecord.totalResults;

    //PersonData is variable used in Chart setup

    PersonData = {

    "label": "Persons",

    "value": myResults.PersonCount,

    "tooltext": "Active Contacts: " + myResults.PersonCount

    }

    }

  • I added an additional criteria to this script, there are no errors and it loads the canvas but without the graph, am i missing something ?

  • Jeff,

    Great article as usual! The last line also appended a .css file ( which is sometimes needed with canned js libraries) using the html link tag, but it got changed when posting here. Anyways, the new 7.2 clientside api, combined with the ability to add custom js libraries is really providing a powerful to extend this system even further than before!

    Keep the great content coming!

  • Fair point, although I think I ended up not using than when I was evolving this script.

  • As far as #1 is concerned you can load a script src into the page head by using the jquery append() method:

    [code]

    var script = document.createElement("script");

    script.type = "text/javascript";

    script.src = "../js/custom/mylibraries/myfunc.jquery.js"; // use this for linked script

    $('head').append(script);

    $('head').append('') ;

    [/code]