Ok, maybe not ever, but interesting nonetheless. A few days ago a reader pinged me to ask about gauge charts. Those are charts that act like speedometers. I knew it wasn't supported by ColdFusion out of the box, but I recommended he take a look at the WebCharts design tool that ships with ColdFusion. When I did so - I saw right off the bat that it was supported, and there were quite a few of them.
I generated my style xml, passed it to the CFCHART, and promptly got an error about gauge charts not being supported. Darn. I was as frustrated as Britney Spears in a library.
Yesterday the topic of CFCHART came up again, this time on the CFAUSSIE mail list. When I made the same point there, a user named Simon Haddan shared an interesting fact. You can actually use Java to speak directly to the WebCharts engine embedded in ColdFusion. (Christopher Wigginton blogged on this as well back in 2005.)
Essentially, you can use the WebChart's designed to create a WCP file, which is just an XML file. You can then grab the relevant bits out and speak directly to WebCharts. And guess what?
No limits.
Not as far as I can tell. I made this lovely PNG gauge below. (And yes, SWF is supported too.)

The code is a bit complex, and involves some string manipulation, but could be made easier if someone felt like creating a nice CFC for it. Here is the code, and remember credit goes to Simon and Christopher:
<!--- Read the WCP file --->
<cfset sChartStyle = fileRead(expandPath("./raygauge.wcp"))>
<!--- Get the frameChart component --->
<cfset iStart = findNoCase("<gauge",sChartStyle)>
<cfset iEnd = findNoCase("</gauge>",sChartStyle)>
<cfsavecontent variable="chartStyle">
<cfoutput><?xml version="1.0" encoding="UTF-8"?>
#mid(sChartStyle,iStart,iEnd-iStart+13)#
</cfoutput>
</cfsavecontent>
<cfsavecontent variable="chartModel"><?xml version="1.0" encoding="UTF-8"?>
<XML type="default">
<COL>2000</COL>
<ROW col0="88.0">Sample 0:</ROW>
</XML></cfsavecontent>
<cfscript>
oMyWebChart = createObject("Java","com.gp.api.jsp.MxServerComponent");
oMyApp = getPageContext().getServletContext();
oSvr = oMyWebChart.getDefaultInstance(oMyApp);
oMyChart2 = oSvr.newImageSpec();
oMyChart2.width = 375;
oMyChart2.height= 375;
oMyChart2.type = "png";
oMyChart2.style = "#chartStyle#";
oMyChart2.model = "#chartModel#";
</cfscript>
<!--- Create html tag set --->
<cfsavecontent variable="chartImgTag">
<cfoutput>#oSvr.getImageTag(oMyChart2,"http://192.168.1.108/CFIDE/GraphData.cfm?graphCache=wc50&graphID=")#</cfoutput>
</cfsavecontent>
<!--- Good old Webcharts loves to add an extra /Images/ to the URL --->
<cfset chartImgTag = replace(chartImgTag,"http://192.168.1.108/Images/","http://localhost/","All")>
<cfoutput>
#htmlEditFormat(chartimgtag)#
<p>
#chartimgtag#
</cfoutput>
The first part of the file grabs the style portion from the WCP file. I believe this is the same XML you would normally grab from the style tab. The chartModel section is the data. For a gauge it is rather simple - one value. I'm not sure where "Sample 0:" is even used, but the value, 88, is.
Next up we do the Java magic. Note the getImageTag portion expects a URL. This URL represents the same "magic" URL ColdFusion uses to display images/SWF stuff. You probably wouldn't want to hard code an IP like I did. WebCharts also wants to add /Images to this so it has to be stripped out.
The last thing I do is output the HTML in a form I can read, and as is, which works just fine.
Pretty cool, eh? In theory, one could build a custom tag that lets you paste in a MCP and it would run form that, but the data would be hard coded.
Archived Comments
In this entry you speak of both a WCP file and a MCP file. Is this a typo or are these two different files?
I meant WCP. Edited - and thanks.
Yeah, Matt and I talked about this way back in ColdFusion Weekly Podcast version 1.2b in April of 2006.
We use custom CFC API (that we built) for charting on GreatBizTools.com to create all the charts that WebCharts3D supports. There are a bunch of helper java classes for data manipulation and style changes. However I won't get into that here as it's mess to work with directly.
An example chart which is similar to yours is here:
http://coldfusionweekly.com...
Ray waves hand:
These are not the Droids you are looking for....
BTW, the sample: 0 is the label for the row. Since the gauge chart isn't using the label -- it's not shown.
You can also have CF talk to Batik (which comes installed with CF7+8). Batik renders SVG files, which are just XML, into PNG or JPEG. I did exactly that to generate speedometer-type graphs (among many other things) for nowrists.com.
Quite slick. I bet this is one of those tricks that doesn't work with CF7, though. I made a guage-style .wcp file, and set up the example here, and ran it. With CF7, I get "Invalid style type: gauge".
Got to get our copies of CF8 installed...
I've most definitely done the "gauge" style charts on CF7, however I never used the .wcp files instead using the java classes that represent data and charting styles.
Dont forget the designer that is included with CF7, so you have a GUI you can design your chart with, then save it off and use it. =)
http://www.cfcode.net/index...
@Justice: Errr - isn't that I mentioned in the article? ;) I said that I used that - but it still failed when I passed the XML to cfchart.
@Peter: Sorry I missed your earlier posts!
Ray
Sorry bud, thats what I get for reading too quick =)
Anyone have this issue:
When we (three of us now) open webcharts.bat in CF8, all the text is binary zero characters. Totally unreadable.
Hello,
When I try to run this example, with my own (non modified) gauge .wcp file I get the following text and no graph. What am I doing wrong, or missing?
<!-- WebCharts3D v5.1(2077) --> <IMG SRC="http://192.168.1.108/CFIDE/GraphData.cfm?graphCache=wc50&graphID=Images/3607960040100155.png" id="Images_3607960040100155_png" name="Images_3607960040100155_png" usemap="#Images_3607960040100155_png_map" border="0"/> <table cellpadding='0' cellspacing='1' style='visibility: hidden;display: none; position:absolute;font-family: Arial;font-size: 13px; font-weight:700;background:#FFFF00;foreground:#0000FF;color:#0000FF;-moz-opacity:.50;-opacity:.50;filter:alpha(opacity=50);border:1px solid #0000FF;' name='GP1215621759443AAAB' id='GP1215621759443AAAB'><tr><td width='8'> </td></table> <MAP name='Images_3607960040100155_png_map'> <AREA shape='rect' coords='0,0,1,1'/> <AREA shape="poly" coords="293,133,191,194,183,180,289,126"/> </MAP> <script language="javascript" src="http://192.168.1.108/CFIDE/GraphData.cfm?graphCache=wc50&graphID=script.js"></script>
Thanks so much!
-Lyle
I spoke with J off line - the issue was forgetting to update the URL in the code.
To randy:
I had a similar (the same?) issue. Most of the text visible was showing a square instead of the character. Numbers showed up ok. Called up Gpoint and was told to reload the java virtual machine. This did not work. Found out by accident that if instead of running webcharts.bat you find and doubleclick C:\ColdFusion8\lib\wc50.jar all appears to work ok.
Am I correct in assuming the 'Adobe ColdFusion 8 Developer Edition' water mark will show up regardless of your Coldfusion server license?
Thanks,
Adam
You can develop charts on the Developer Edition, you will see the watermark there. When you move the same code to a licensed version of CF you will no longer see the watermark.
Hope that helps.
-Lyle
I understand that in general. I'm asking because I'm on a server that should be legitimately licensed, and doesn't show the watermark for normal graphs, but still shows it for any of the graphs that directly address webcharts3d classes.
But maybe there's something wrong in the server settings. I just thought since I haven't seen the behavior in any other charts it might be related to this specifically. So I was wondering if anyone knew for sure that the watermark shouldn't be there.
Thanks again,
Adam
I haven't tested this yet on production. It may be that it does indeed show the watermark. Has anyone else tried it?
"You can develop charts on the Developer Edition, you will see the watermark there. When you move the same code to a licensed version of CF you will no longer see the watermark.
Hope that helps.
-Lyle
# Posted By J. Lyle Martin | 7/25/08 4:18 PM "
have you tried editing the watermark.png under \lib ?
i removed the text in the png and saved and overwrited the file without the Watermark text
Be careful about doing this! I did it and it caused the Webcharts engine to put "Developer Edition" watermarks on all charts, including those that are created with <CFCHART> - waht a mess!
Where does the GraphData.cfm come from in the reference? I don't believe we have that on our system.
It's a purely virtual file.
Ray,
We have a Load Balancing situation though and if we create the chart, the page just shows an area that says that the chart expired. So typically, we have been writing charts to a file and then calling them back out immediately from a place where we wrote the chart to. Is it possible to write this chart to a file so that we can call it back out that way? Rather than serving it up live from the CF Server and the cache that it creates.
Not sure. You could maybe look at the Java API and see about setting it to a binary type, and see if the Java API lets you get the bits.
My co-worker continued working on it and did save the file out as a binary to a local directory. Then we went back and recalled the saved SWF. We saved the SWF in a folder we named "charts". Here's the last half of the script:
<!--- initialize chart settings --->
<cfscript>
oMyWebChart = createObject("Java","com.gp.api.jsp.MxServerComponent"); oMyApp = getPageContext().getServletContext(); oSvr = oMyWebChart.getDefaultInstance(oMyApp); oMyChart2 = oSvr.newImageSpec();
oMyChart2.width = 400; oMyChart2.height= 300; oMyChart2.type = "swf"; oMyChart2.style = "#chartStyle#"; oMyChart2.model = "#chartModel#";
</cfscript><!--- Create html tag set --->
<cfsavecontent variable="chartImgTag">
<cfoutput>#oSvr.getImageTag(oMyChart2,"http://ourwebsite.com/CFIDE...")#</cfoutput>
</cfsavecontent><!--- Good old Webcharts loves to add an extra /Images/ to the URL --->
<cfset chartImgTag = replace(chartImgTag,"http://ourwebsite.com/Images/","http://ourwebsite.com/","All")>
<cfoutput>
<p>
#chartimgtag#
</cfoutput>
<cfset listpos=listcontains(chartImgTag, "graphID", "=")><cfset listpos=listpos+1>
<cfset chartID=listgetat(chartImgTag,listpos,"=")>
<cfset chartID=listgetat(chartID,2,"/")><cfset chartID=replace(chartID, '"', '')>
<br>
<cfhttp url="http://ourwebsite.com/CFIDE..." getasbinary="yes">
<cffile action="write" file="#local_path#charts\untitled11.swf" output="#cfhttp.filecontent#">
Since the chart is created in the CF cache directory, is there a way to determine the image attributes after it has been drawn? I currently have the chart style set as flash but I have no objection to using PNG or JPG instead. What I’m doing is plotting 22 points on the chart, and then below the chart, I'm outputing the some additional details about the point displayed on the graph. I can hard code the width of the table columns to align directly underneath the respective point on the chart and it looks great, almost as if it is all one image. This is when my monitor resolution is at 1200×800. If I move the web page to my other monitor and view it at 1600x1200, the charts is small when compared to the available screen real estate. LIkewise, if the report is viewed with a resoltuion of 800x600, scrolling is required. I’m trying to take it a step further and make the chart width dynamic for larger/higher resolutons but still keep the tabular data inline with the points on the chart.
I hope this make sense and is clear…
Red
Look at the NAME attribute for CFCHART. It stores the result in binary. So if you use a PNG/JPG chart and NAME, you can then make an image object out of it. See:
http://www.coldfusionjedi.c...
for an example.
@Ray
That'd be too easy. :) I'm not using the cfchart tag though. I'm using the java api to create the chart for me. My code is very similar to yours except for a guage graph, I'm using the line graph (actually, four lines graphs on chart).
The image you have for the guage is named, dial.png. I'm assuming for the purpose of the post, you hard coded the image name to be dial.png. But if you didnt' hard code that and left it with the temp name CF would have created. Is there a way to find out that name?
Actually, I think dial.png is just the _background_, not the final image. (Not 100% sure though.)
Hello,
I am having the same problem as J Lyle, so I'm wondering, as a relative novice to this, where should that URL be pointing? What do you mean by "magic" URL? Is this something that should stay the same, or should it point to my current webpage in development?
Thanks,
Dean
The URL is a servlet set up by CF to help render the images. It isnt a real file. It would not stay the same between different machines, but be unique to each install. Make sense?
It does make sense. So I assume I need to point to wherever the CFIDE folder is? As for that, I'm working off a development server that I don't actually administer; so I'll have to contact the person who administers the server. Am I correct in my assumption above?
Thanks,
Dean
Well it should be just be the same host as what you are on now. You can get that via a CGI variable.
I'm creating a gauge in flash format using this example. Now when the code is on an secure server (HTTPS) in IE I get the not secure content warning. Due to the <OBJECT tag that gets auto created by the server, the CODEBASE url is HTTP only. Is there a way to change the CODEBASE url to HTTPS for the Flash <OBJECT tag? Or switch the format to PNG?
Maybe wrap the output in cfsavecontent and do a regex replace on it?
i need to change the title style in <cfchart > for example make the font bigger and bold but only for the title, but how can we do that through the xml in the style?
Did you try the chart editor? It's right there in the settings - Title. Click on it and you get a box of various options.
what is chart editor ?i only have .cfm file i opened it as text file ;-)
I talked about it in this blog post. It's a program you run (you will find it in the charting subdirectory of your cf install) that allows you to design a chart and spit out an xml file.
@Ray, can I modify the dial chart range ie from 100-200. Default is 0-100. Please let me know.
Thanks in Advance.
Varun Reddy Teeleru.
So... did you try the Chart Editor? :) If you dig into the settings for the dial chart, you will find it under Axis Style: scaleMin and scaleMax.
I would like to get the image file for further manipulations such as watermarking etc.
Is it possible to obtain the image file from the applet ?
I would retrieve the file from the cache and then use the file for my other purposes.
Thanks for any help.
cfchart supports a PNG format. You can use that and then use cfimage functions on it.
You may have heard about the CFIDE hack going around. Well, we had to lock down CFIDE since we are using MX7 and that shut down our cfchart function. I've tried workarounds but no luck. Upgrading Coldfusion is not economically possible so it is what it is.
I did find that the graphic for the chart is saved to cfusionmx7/charting/cache, but the graphic doesn't resolve on the chart page.
Any suggestions on how to use cfsavecontent to make it work while the main CFIDE files are locked down?
This may be a silly question, but why not try one of the _many_ JavaScript-based charting solutions out there? There are a heck of a lot of them - many free.
Raymond, thanks.
That was the next step. The charting queries an Access database so the search is on. Any suggestions?
I've played with a bunch, but none that strike me "THE BEST EVER." I'd recommend what I'd do - Google. :)
Err, I should clarify. Google actually has a charting solution too. ;) I'd _search_ Google. ;)
problem with cfchart is that at any time, the cache will expire and the chart in your page will output an error. i have been playing with cfchart since 2011 but i would not recommend it very much. if you are looking for free charts, there's a lot of jquery chart implementations which uses javascript . try jflot.
I've just moved from CF8, where this trick worked like a charm, to CF11. I've verified that code will work up through CF10. In CF11, when I get to the line that creates the object, I'm getting an error:
Object Instantiation Exception. Class not found: com.gp.api.jsp.MxServerComponent
The error occurred on line 395.
I'm not heavily skilled with this type of sorcery and wondered if anyone else may have run across this error after upgrading, and what might be a solution I can apply.
Thanks,
Myron