Following up on my previous post about customizing CFCHART, I bring news of hidden charts that are not available via the standard ColdFusion CFCHART tag.
Note: The following example will only work with ColdFusion 8.
Fire up the WebCharts Java application (see my previous post on how to do this) and you’ll notice that some charts types available are not supported via the CFCHART tag:
- Gauge Charts
- Gantt Charts
- Heatmaps
I spent some time looking at how I could use ColdFusion to generate one of these chart types. The following example shows how to create a simple gauge chart. So without further ado, I introduce the gaugeChart custom tag:
WebCharts expects XML descriptions of the chart styles and the chart data models in order for the chart engine to output the chart image, swf etc…
<!--- Create the xml chart style structure --->
<cfsavecontent variable="style">
<cfoutput><gauge font="#attributes.font#-#attributes.fontSize#-bold">
<knobStyle clipKnob="false" clipHand="false" size="#attributes.knobSize#">
<paint shadowColor="##FFDDAA" minColor="#attributes.knobColor#"/>
</knobStyle>
<handStyle type="#attributes.dialType#" placement="Text" width="3">
<paint shadowOffsetX="0" shadowOffsetY="0" outlineColor="#attributes.dialOutlineColor#" minColor="##AA0000" maxColor="red" angle="90"/>
</handStyle>
<dialStyle startAngle="#attributes.dialStartAngle#">
<paint minColor="white" maxColor="##333333" isRadial="true"/>
</dialStyle>
<axisStyle scaleMax="#attributes.dialMaxScale#" angleMargin="40" outerMargin="5" limitPlacement="#attributes.dialLimitPlacement#" limitMargin="0" minorTickPlacement="Outer"> <labelStyle isMultiline="false" color="##E2FFFF"/>
<majorTick width="4" length="12"> <paint shadowColor="black"/></majorTick>
<minorTick width="2" length="6"/>
<title angle="-90" ratio="90">#attributes.dialTitle#</title>
<limits index="0" minValue="#attributes.dialLimitStart#" maxValue="#attributes.dialLimitEnd#" minWidth="12" maxWidth="12">
<paint minColor="##AA0000" maxColor="##AA0000"/>
</limits>
</axisStyle>
<edgeStyle outerSide="1" innerSize="2" innerSide="10">
<outer minColor="##666666" angle="-135"/>
<inner minColor="##333333" maxColor="##CCCCC" angle="45"/>
</edgeStyle>
</gauge></cfoutput>
</cfsavecontent>
I didn’t manually hack out all of that styling markup. I cheated and used WebCharts to generate it for me. It is then a simple case of replacing the styles that we need control over, with ColdFusion variables.
The next step is to define the data model. Again I used WebCharts to generate the outline for me:
<!--- Create the chart data model --->
<cfsavecontent variable="model">
<cfoutput><?xml version="1.0" encoding="UTF-8"?>
<XML type="default">
<COL>1000</COL>
<ROW col0="#attributes.dialValue#">Sample 0:</ROW>
</XML></cfoutput>
</cfsavecontent>
Now we are ready to output the chart to our web page:
<!--- Output the chart --->
<cfscript>
context = getPageContext();
chart = createObject("java","com.gp.api.jsp.MxServerComponent");
svr = chart.getDefaultInstance(context.getServletContext());
myChart = svr.newImageSpec();
myChart.width = attributes.chartWidth;
myChart.height = attributes.chartHeight;
myChart.type = attributes.chartFormat;
myChart.style = style;
myChart.model = model;
chartTag = svr.getImageTag(myChart,"/CFIDE/GraphData.cfm?graphCache=wc50&graphID=");
</cfscript>
<cfoutput>#chartTag#</cfoutput>
As ColdFusion uses the WebCharts Java API via the CFCHART tag, this API is naturally available to any ColdFusion template. We take advantage of this and instantiate an MxServerComponent object.
As you can see, the next stage builds up our chart definition via the myChart variable. You can see that the chart dimensions are being defined and we are assigning our style and data models.
To create the chart we call:
svr.getImageTag(myChart,”/CFIDE/GraphData.cfm?graphCache=wc50&graphID=”);
When we do this, the chart image is written to the default chart cache directory, as defined within the ColdFusion administrator.
Finally we write out the HTML markup needed to view the chart:
<cfoutput>#chartTag#</cfoutput>
What’s with the “/CFIDE/GraphData.cfm?graphCache=wc50&graphID=” path specified on the getImageTag method invocation , I hear you cry!
Again, I have cheated here to make life easier. If you view the HTML source on a web page that a CFCHART image has been embedded into, you will see that the chart image links to /CFIDE/GraphData.cfm. This URL pulls the appropriate chart data into the calling web page.
As a matter of interest, you won’t find any template named GraphData.cfm within the CFIDE directory. /CFIDE/GraphData.cfm is simply a mapping to the ColdFusion charting servlet.
Now for an example of the custom tag calling code. I’m going to use the new ColdFusion 8 server monitoring API to get the amount of used JVM memory:
<cfset adminObj = createObject("component","cfide.adminapi.administrator")/>
<cfset adminObj.login("password")/>
<cfset serverMonitor = createObject("component","cfide.adminapi.servermonitoring")/>
<cfset memstats = serverMonitor.getJvmMemoryStats()/>
<cfset megabyte = 1024 * 1024/>
<cfset used = memstats.usedmemory / megabyte>
<cf_gaugeChart chartFormat="png"
chartWidth=200
chartHeight=200
dialLimitStart=450
dialLimitEnd=500
dialMaxScale=500
dialTitle="JVM Memory Used"
dialValue=#getToken(used,'1','.')#>
I won’t explain all of the tag attributes here as they’re all documented within the tag template file. Hopefully the tag call above is fairly self explanatory in terms of how everything works. You set the chart dimensions, some values for the chart upper and lower readout boundaries, a chart title and the format that the chart should be output in. I pipe in the amount of memory used via the dialValue attribute.
Acceptable chart formats are: PNG, SWF, SVG, PDF, EPS, JPG, GIF and TIF.
Here’s an example of what the resulting chart looks like:

I’ll try and get some examples of creating Gantt, heatmap and treemap charts shortly. Until then, here’s the custom tag.
gaugeChart.zip