Creating Flex Charts Easily

S-Controls

Note: S-controls have been superseded by Visualforce pages. For more information, please visit S-Control_Deprecation


Overview

Flash charts are very, very cool to show. However, programming Flash charts can be time consuming and requires a fair amount of programming skills. Several companies have recognized this fact and have created very nice “wrappers” around flash-based charts that make it easy to create flash-based charts without much programming. Once such company is called InfoSoft Global. InfoSoft Global offers a set of Flash-based charts that use simple XML formats to feed data to the graphs. Their product is called FusionCharts.

FusionCharts provide 36 different types of charts that you can use in your demos. The way FusionCharts works is that you create a chart specific XML string that contains the attributes and the data you wanted graphed and then the proper chart object is called with this data.

Example XML:

<chart palette='3' numberPrefix='$' is3D='1' animation='1' clipBubbles='1' xAxisMaxValue='100' showPlotBorder='0' xAxisName='Stickiness' yAxisName='Cost Per Service' chartRightMargin='30'>
<categories>
<category label='0%' x='0' />
<category label='20%' x='20' showVerticalLine='1'/>
<category label='40%' x='40' showVerticalLine='1'/>
<category label='60%' x='60' showVerticalLine='1'/>
<category label='80%' x='80' showVerticalLine='1'/>
<category label='100%' x='100' showVerticalLine='1'/>
</categories>
<dataSet showValues='0'>
<set x='30' y='1.3' z='116'  name='Traders'/>
<set x='32' y='3.5' z='99' name='Farmers'/>
<set x='8' y='2.1' z='33' name='Individuals'/>
<set x='62' y='2.5' z='72' name='Medium Business Houses'/>
<set x='78' y='2.3' z='55' name='Corporate Group A'/>
<set x='75' y='1.4' z='58' name='Corporate Group C'/>
<set x='68' y='3.7' z='80' name='HNW Individuals'/>
<set x='50' y='2.1' z='105' name='Small Business Houses'/>
</dataSet>
<trendlines>
	<line startValue='2.5' isTrendZone='0' displayValue='Median Cost' color='0372AB'/>
</trendlines>
<vTrendlines>
	<line startValue='0' endValue='60' isTrendZone='1' displayValue='Potential Wins' color='663333' alpha='10'/>
<line startValue='60' endValue='100' isTrendZone='1' displayValue='Cash Cows' color='990099' alpha='5'/>
</vTrendlines>
</chart>

Feeding this XML to the Bubble chart will result in:

Image:bubble.jpg

Using Salesforce.com's AJAX toolkit, you can read the data, create the XML with JavaScript and then feed it into the chosen chart. This is all done using S-controls and is completely stored in SFDC. So now you can create all types of Flash-based graphs using S-controls, JavaScript and the SFDC AJAX toolkit.

Getting Started

  • Download an evaluation copy of the Fusion Charts Toolkit. It can be found here.
  • Unzip the FusionCharts zip file into a separate folder. The folder should contain a directory structure like the one below:

image:chartdir.png

  • The file “index.html” in the main page for all the documentation. The part you will most interested in is the “Chart XML Reference”. This lists all the chart types and their associated XML attributes.
  • The folder “Gallery” has great examples of all the charts with some sample data.
  • The folder “Charts” contains all the flash chart files and this is the directory from where you will get the chart files to upload to the S-control.

FusionCharts comes with some JavaScript functions to make life a bit easier. These JavaScript functions can be installed into SFDC as an S-Control Snippet. In the folder “JSClass”, there is a file named “FusionChart.js”. The file contains the code we need. To create the snippet:

  • Go to “Setup->Build->Custom S-controls->New Custom S-control
  • Name the S-control “FusionCharts”
  • Click the button that says ”Snippet”.
  • Now open the “FusionChart.js” file with an editor such as notepad and then copy and paste all of the JavaScript from the FusionChart.js file to the box labeled “Content” on the S-control Snippet.
  • Click “Save’.

Now you can create you s-control. The idea is that you use the AJAX toolkit to gather the data you need, and then use JavaScript to create the chart XML and then call the chart with the data. For our example, we will create an S-Control that will display the total dollar amount of opportunities based on stage. This S-control will reside on the account detail:

Creating the S-Control

Here's the code for the S-Control:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
      <script src="/soap/ajax/10.0/connection.js"></script>
      
<script>
{!INCLUDE($SControl.FusionCharts)} 
accountId="{!Account.Id}";

function gatherData()
{
  var result = sforce.connection.query("Select StageName, Amount from Opportunity where IsClosed=false and AccountId='"+accountId+"'");
  records = result.getArray("records"); 
 
  var Stages=new Array();
  for (var i=0; i< records.length; i++) {
     var record = records[i];
   
     if (typeof(Stages[record.StageName])=="undefined")
      {
        Stages[record.StageName]=0.0;
      }
  
      Stages[record.StageName]=parseFloat(Stages[record.StageName])+parseFloat(record.Amount);
   
    }
  
  
    var chart="<chart caption='Open Opportunities by Stage' numberPrefix='$' bgColor='#f3f3ec'>";
     
    for (i in Stages)
     { 
        chart+="<set label='"+i+"' value='"+Stages[i]+"'/>";
     }
     
    chart+="</chart>";
     
        
    var myChart = new FusionCharts("{!Scontrol.JavaArchive}" , "myChartId", "500", "250", "0", "0"); 
    myChart.setDataXML(chart); 
    myChart.render("chartdiv"); 
     
}


</script>      
</head>

<body onload="gatherData()" bgcolor="#f3f3ec">

<div id="chartdiv" align="center">The chart will appear within this DIV. This text will be replaced by the chart.</div> 

</body>
</html>

Lets assume you know how to use the AJAX tool kit to get the data, so this tutorial will focus on getting the chart created. If you look at the source code, the first important line that you will need:

{!INCLUDE($SControl.FusionCharts)} 

This is the line that includes the FusionChart library (snippet) that we created in the step above. It should be added within your <script></script> tags.

Once you get the data, you then can create the XML. For the basic 3D Doughnut graph, you just need:

  • A chart header; this is the place where you set the attributes of the chart.
<chart caption='Open Opportunities by Stage' numberPrefix='$' bgColor='#f3f3ec'>
  • Most charts require or more “set” tags which describe the data. The label is the name of each of the data points in the graph and the value is the data value you want to graph. In this case, the labels are opportunities stages and the values are the total amount of opportunities for each stage. The tags will utimately look like this:
<set label='Confirming’ value='100000.00'/>
<set label='Negotiation’ value='15677.00'/>
  • And then a final “chart” tag to close it out.
</chart>

Note that there are many options for the chart header as well as the data tag. For example, you can hyperlinks to each of the labels. See the documentation as mentioned above for the all the options detail.

Once you have the XML string created, you can create the chart by:

var myChart = new FusionCharts("{!Scontrol.JavaArchive}" , "myChartId", "500", "250", "0", "0"); 
myChart.setDataXML(chart); 
myChart.render("chartdiv"); 

The first line creates the new chart and describes in size:

var myChart = new FusionCharts("{!Scontrol.JavaArchive}" , "myChartId", "500", "250", "0", "0"); 

The parameters as follows:

  • Parameter 1 – Points to the chart file that contains the code. This will be uploaded into the S-control . This field should be “{!Scontrol.JavaArchive}” for the first chart.
  • Parameter 2 – The chart ID. This can be any text you want but needs to be unique for each chart you render in the S-Control.
  • Parameter 3 - Width of the chart in pixels or percentage.
  • Parameter 4 – Height of the chart in pixels or percentage.
  • Parameters 5 and 6 – These are use for debugging and are explained in the documentation.

The second line points the chart to the XML data:

myChart.setDataXML(chart);

In this case, “chart” is a string variable that contains all of the data. Lastly, you need to tell FusionCharts where to render the chart. The chart uses a “DIV” to render the chart. So

myChart.render("chartdiv"); 

tells FusionCharts to render the chart wherever the “chartdiv” DIV is in the HTML. This means that you need to have a DIV with the same name defined elsewhere in the HTML of the S-control. In our example, you’ll find it towards the bottom:

<div id="chartdiv" align="center">The chart will appear within this DIV. This text will be replaced by the chart.</div>

One last piece of the puzzle, we need to upload the chart file we are going to use. The chart files are stored in the folder “Charts” (see section above). Each chart ends in “.swf”. You need to upload the appropriate file to the S-control. To do this, when editing the S-control, click the browse button to select the file:

image:upload.png

Choose the appropriate SWF file. The names are pretty self explanatory.


And then save the S-Control. This will upload the chart file to the S-control.

That’s it. It’s pretty easy to create quick eye-catching flash charts without a lot of programming.

Tips

  • Since you processing data in an S-control (really inside the browser), you will into limits on how much data you can process and how long you can make XML data string. For most demos, it should work fine. For other times, it might be necessary to use Apex code to handle large amounts of data.
  • If you get errors about “”Invalid Data” or other types of errors, you can turn on debug mode which will give you details on how the chart is being rendered. To turn on debug mode, set parameter 5 to “1”.
var myChart = new FusionCharts("{!Scontrol.JavaArchive}" , "myChartId", "500", "250", "1", "0"); 

More Chart Fun!

Now what’s better then one chart? Two charts! If you want two of the same type chart (pie, bar, etc.), then it’s pretty easy. You just create another instance of the chart and another DIV. But want if you want to different charts side by side like this?

Since you can only upload one chart file at a time to an S-Control, you need to resort to some trickery! There easiest way to do this is to use the documents tab to store the second chart file. We create another instance of a chart in the same S-control that creates the first chart. We then upload the second chart file (.swf) to the documents tab and then use the URL of that document in the second chart instance. We put all of that into a small HTML table so they are side by side. So

  • Create the first chart as described above.
  • Upload the second chart .swf to a folder in the documents tab.
  • Create the second chart by adding another instance of the chart using JavaScript:
var myChart2 = new FusionCharts("/servlet/servlet.FileDownload?file=01550000000DIq7" , "myChartId2", "450", "200", "0", "0"); 

myChart2.setDataXML(chart); 

myChart2.render("chartdiv2");

In the example above “myChart2”, creates the instance of the second chart. Make sure the chart tag (parameter 2) is unique. Also notice the URL in parameter 1, this needs to point to the .swf file uploaded into the documents tab. In the URL, "/servlet/servlet.FileDownload?file=<docId>" replace <docId> with the unique ID of the uploaded chart.

  • Now wrap this up with an HTML table command to put them side by side:
<table><tr><td>
<div id="chartdiv" align="center">The chart will appear within this DIV. This text will be replaced by the chart.</div> 
</td><td>
<div id="chartdiv2" align="center">The chart will appear within this DIV. This text will be replaced by the chart.</div> 
</td>
</tr></table>

The HTML will create a two column, one row table with the first graph in the first column and the second chart in the second column. This is how we get them side by side. You may to adjust the height and width of the charts and the S-Control to get the right look. The end result should look like:

Summary

By using a product like FusionCharts, you will be able to create Flash-based charts easily and be the envy of your staff.