Using ChartDirector with ColdFusion

There are several methods to use ChartDirector with ColdFusion. For ColdFusion MX (version 6 or above), it is recommended using ChartDirector for JSP/Java with ColdFusion. For old versions of ColdFusion (eg. Ver 5.x), one may use ChartDirector for ASP/COM/VB.
ColdFusion MX with ChartDirector for JSP/Java

Installation

To allow ColdFusion CFM scripts to access the ChartDirector for JSP/Java library, one needs to inform ColdFusion where is the "ChartDirector.jar". The steps are:
  • Extract the ChartDirector for JSP/Java distribution to an empty directory. The ChartDirector for JSP/Java is distributed as a WAR file (Web Archive - a Java standard), which can be extracted using WinZip or the Java "jar" utility. Copy the "WEB-INF/lib/ChartDirector.jar" to any directory you want.

  • In ColdFusion Administrator, under Java and JVM settings, add the full path to the "ChartDirector.jar" file to the classpath field.

  • Restart the ColdFusion server.
Alternatively, you may also copy "ChartDirector.jar" to the "WEB-INF/lib" subdirectory of your ColdFusion server (eg. "C:\cfusionmx\wwwroot\WEB-INF\lib" or "\JRun4\servers\cfusion\cfusion-ear\cfusion-war\WEB-INF\lib"), and then restart the ColdFusion server.

Using ChartDirector in CFM

ChartDirector for JSP/Java comes with plenty of sample code in JSP. It is easy to translate them to ColdFusion scripts. The following is an example based on the "Simple Bar Chart" (simplebar.jsp) sample code that comes with ChartDirector for JSP/Java.

<html>
<body topmargin="5" leftmargin="5" rightmargin="0">
<div style="font-size:18pt; font-family:verdana; font-weight:bold">
    My First ColdFusion ChartDirector Chart
</div>
<hr color="#000080">
<cfscript>

//The data for the bar chart
data = arrayNew(1);
data[1] = 85;
data[2] = 156;
data[3] = 179.5;
data[4] = 211;
data[5] = 123;

//The labels for the bar chart
labels = arrayNew(1);
labels[1] = "Mon";
labels[2] = "Tue";
labels[3] = "Wed";
labels[4] = "Thu";
labels[5] = "Fri";

//Create a XYChart object of size 250 x 250 pixels
c = createObject("java", "ChartDirector.XYChart");
c.init(250, 250);

//Set the plotarea at (30, 20) and of size 200 x 200 pixels
c.setPlotArea(30, 20, 200, 200);

//Add a bar chart layer using the given data
c.addBarLayer(data);

//Set the labels on the x axis.
c.xAxis().setLabels(labels);

//output the chart
chart1URL = c.makeSession(getPageContext().getRequest(), "chart1");

//include tool tip for the chart
imageMap1 = c.getHTMLImageMap("", "", "title='{xLabel}: US${value}K'");

</cfscript>

<cfoutput>
<img src="getchart.jsp?#chart1URL#" usemap="##map1" border="0">
<map name="map1">#imageMap1#</map>
</cfoutput>

</body>
</html>
The key points to note for translating the sample code are:
  • The Java constructor

    XYChart c = new XYChart(250, 250);

    should be translated to using the ColdFusion createObject method:

    c = createObject("java", "ChartDirector.XYChart"); c.init(250, 250);

  • The JSP variable "request" is translated to "getPageContext().getRequest()".

  • The HTML tags for inserting the chart and image map in the web document are translated to:

    <cfoutput>
    <img src="getchart.cfm?#chart1URL#" usemap="##map1" border="0">
    <map name="map1">#imageMap1#</map>
    </cfoutput>

  • The "getchart.cfm" file is a utility file translated from the equivalent JSP file "getchart.jsp". You may download a copy of "getchart.cfm" here. The above code assumes you have put "getchart.cfm" to the same directory as the charting CFM script. If you put it in a different directory, you would need to modify the src attribute of the <img> tag to specify the path of "getchart.cfm".

  • The chart data should be read into ColdFusion arrays. The arrays may then be passed to ChartDirector for chart creation.

ColdFusion with ChartDirector for ASP/COM/VB

On Windows, ColdFusion supports COM components by using the CFOBJECT tag. So one way to use ChartDirector with ColdFusion is to use ChartDirector for ASP/COM/VB as a COM component.

However, ColdFusion only provides basic COM support. Special considerations are needed to use CFOBJECT to access the ChartDirector API through COM. For this reason, if you are using ColdFusion MX (version 6 or above), it is recommended that you use ChartDirector for JSP/Java instead.

The followings are the key points when ColdFusion is used to access the ChartDirector API through COM:

  • Cold Fusion COM does not support passing arrays as arguments. To solve this problem, since ChartDirector for ASP/COM/VB Ver 3.02, a new feature is introduced that allows an array to be encoded as a text string. The encoding method is as follows.

    The text string must start with the six characters header - "Array" & Chr(31) - to indicate that it is an encoded array. The content of the array are converted into a list delimited by the ASCII character Chr(31) and appended to the header. (Chr(31) is the ASCII "Unit Separator" control code.)

    See the code sample below for an example.

  • Cold Fusion Ver 5.0 or before does not support optional parameters. So when calling the ChartDirector API, all parameters must be provided. (Note: Cold Fusion MX does not have this limitation.)

    For example, the code:

    <CFSET c = cd.XYChart(250, 250)>

    must be written as the following in Cold Fusion 5.0 or before:

    <CFSET c = cd.XYChart(250, 250, "&Hffffff", "&Hffffff", 0)>

  • The original Cold Fusion MX has many COM support problems. If you are using Cold Fusion MX, please apply the Cold Fusion MX updater from Macromedia if you have not already done so.

  • Cold Fusion MX can only pass standard positive integers and text strings to ChartDirector correctly. Passing other data types of ChartDirector will result in Java type cast exceptions.

    For example, Cold Fusion MX cannot pass -1 to ChartDirector, and it cannot pass cd.PNG (a ChartDirector constant) to ChartDirector.

    The get around is to pass numbers as text strings to ChartDirector. If ChartDirector expects a number but a text string is received, it will automatically convert it to a number.

    For example, the number -1 should be passed to ChartDirector as "-1". The ChartDirector constant cd.PNG should be passed to ChartDirector as ToString(cd.PNG).

  • Cold Fusion does not have a syntax to create hexadecimal numbers. On the other hand, the ChartDirector API often accepts colors as inputs, and it is most convenient to represent colors as hex numbers.

    For example. the red color is FF0000. This is hard to represent in Cold Fusion. To solve this problem, you can use a text string to encode the hex number as "&HFF00000". The "&H" means hexadecimal numbers in COM. When ChartDirector receives the text string, it will automatically convert it to a number.

  • Cold Fusion does not support binary output. It can only output text. So you cannot stream a chart image directly from Cold Fusion to a browser. Instead, you must create the chart in a temporary image file, and use an <IMG> tag to tell the browser to load the chart from the temporary file.

    ChartDirector has a special API "makeTmpChart" that create charts in temporary files and automatically remove old temporary files. For it to work, you would need to create a temporary directory in your web server, and configure it to allow the web server anonymous user to be able to write to it. (By default, web servers cannot write to the hard disk.)

Cold Fusion MX Sample Code

The following is the "Simple Bar Chart" example in the ChartDirector documentation, translated to Cold Fusion MX.
<HTML>
<BODY>
<H1>Hello World - My First Chart</H1>

<CFOBJECT action = "Create"
  type = "COM"
  class = ChartDirector.API
  name = "cd"> 

<!--- The data for the bar chart --->
<CFSET data = ListToArray("85, 156, 179.5, 211, 123")>

<!--- The labels for the bar chart --->
<CFSET labels = ListToArray("Mon, Tue, Wed, Thu, Fri")>

<!--- Create a XYChart object of size 250 x 250 pixels --->
<CFSET c = cd.XYChart(250, 250)>

<!--- Set the plotarea at (30, 20) and of size 200 x 200 pixels --->
<CFSET c.setPlotArea(30, 20, 200, 200)>

<!--- Add a bar chart layer using the given data --->
<CFSET c.addBarLayer("Array" & Chr(31) & ArrayToList(data, Chr(31)))>

<!--- Set the x axis labels using the given labels --->
<CFSET c.xAxis().setLabels("Array" & Chr(31) & ArrayToList(labels, Chr(31)))>

<!--- output the chart --->
<CFSET filename = c.makeTmpFile(ExpandPath("tmpcharts"))>

<CFOUTPUT>
<IMG SRC="tmpcharts/#filename#">
</CFOUTPUT>

</BODY>
</HTML>

Cold Fusion 5.0 Sample Code

The following is the "Simple Bar Chart" example in the ChartDirector documentation, translated to Cold Fusion 5.0.
<HTML>
<BODY>
<H1>Hello World - My First Chart</H1>

<CFOBJECT action = "Create"
  type = "COM"
  class = ChartDirector.API
  name = "cd"> 
  
<!--- The data for the bar chart --->
<CFSET data = ListToArray("85, 156, 179.5, 211, 123")>

<!--- The labels for the bar chart --->
<CFSET labels = ListToArray("Mon, Tue, Wed, Thu, Fri")>

<!--- Create a XYChart object of size 250 x 250 pixels --->
<CFSET c = cd.XYChart(250, 250, "&Hffffff", "&Hffffff", 0)>

<!--- Set the plotarea at (30, 20) and of size 200 x 200 pixels --->
<CFSET c.setPlotArea(30, 20, 200, 200, cd.Transparent, -1, cd.LineColor, "&Hc0c0c0", 
      cd.Transparent)>

<!--- Add a bar chart layer using the given data --->
<CFSET c.addBarLayer("Array" & Chr(31) & ArrayToList(data, Chr(31)), -1, "", 0)>

<!--- Set the x axis labels using the given labels --->
<CFSET xAxis = c.xAxis()>
<CFSET xAxis.setLabels("Array" & Chr(31) & ArrayToList(labels, Chr(31)))>

<!--- output the chart --->
<CFSET filename = c.makeTmpFile(ExpandPath("tmpcharts"), cd.PNG, 600)>

<CFOUTPUT>
<IMG SRC="tmpcharts/#filename#">
</CFOUTPUT>

</BODY>
</HTML>