Ask a Jedi: Adding additional text to a CFCHART

This post is more than 2 years old.

Alison asks:

Have you ever had to include a "Source: the name of a company" within a ColdFusion chart, at the bottom of the chart? I would like it to be part of the chart image so that when someone copies the chart, the Source is there.

Nope, I haven't, but that won't stop me from trying! So the first thing I did was check the built in chart editor. I thought perhaps they may have some kind of arbitrary way to add text to an image. While there is a title, a legend, and marks, there doesn't seem to be support for additional blocks of text. I could be wrong, but from what I see, there is no XML way to do this. So I then switched to ColdFusion's image functions. I figured we could simply treat the chart as an image and then edit it to add the text. This is what I came up with.

First, begin with a simple chart. Notice that I use the name attribute. This stores the binary data into a ColdFusion variable.

<cfchart chartheight="500" chartwidth="500" title="Test Chart" format="png" name="mychart">

&lt;cfchartseries type="bar"&gt;
	&lt;cfchartdata item="Apples" value="50"&gt;
	&lt;cfchartdata item="Bananas" value="40"&gt;
	&lt;cfchartdata item="Cherries" value="72"&gt;
	&lt;cfchartdata item="Donuts" value="59"&gt;
&lt;/cfchartseries&gt;

</cfchart>

Now that we have the binary data, we need to re-"cast" it as a native ColdFusion Image object:

<!--- rewrap as an image ---> <cfset myChart = imageNew(mychart)>

I confirmed that everything was kosher with a quick cfdump. It confirmed I now had an image object. So the next step may not be so obvious. While you can resize an image, doing so may reduce the quality of the image. I decided instead to create a new, blank canvas. I then pasted the chart into it. I added 35 to the height of the new canvas to create room for our text. You can skip this step and try resizing, but be sure to keep the width the same and just increase the height.

<!-- create new image with more space on the bottom ---> <cfset newCanvas = imageNew("", mychart.width, mychart.height + 35, "rgb", "white")>

<!--- paste in the old one ---> <cfset imagePaste(newCanvas, myChart, 0, 0)>

Ok, so the final step is to just write the text to the image. I picked a random font, color, and size. Change to your liking:

<cfset textProps = {font="Arial-Black", size="20"}> <cfset imageSetDrawingColor(newCanvas, "black")> <cfset imageDrawText(newCanvas, "Charts generated by monkeys #chr(169)##year(now())#", 1, newCanvas.height-20, textProps)>

Notice I place the text at "height of canvas - 20". This was purely arbitrary. You may want to tweak these values a bit to place the text differently. ColdFusion does not provide a simple way to handle centering text, or to even get the size of the text. Luckily, there's a CFC for that: ImageUtils. But for now, the simple, hard coded placement works well:

Here is the entire test script. Enjoy!

<cfchart chartheight="500" chartwidth="500" title="Test Chart" format="png" name="mychart">

&lt;cfchartseries type="bar"&gt;
	&lt;cfchartdata item="Apples" value="50"&gt;
	&lt;cfchartdata item="Bananas" value="40"&gt;
	&lt;cfchartdata item="Cherries" value="72"&gt;
	&lt;cfchartdata item="Donuts" value="59"&gt;
&lt;/cfchartseries&gt;

</cfchart>

<!--- rewrap as an image ---> <cfset myChart = imageNew(mychart)>

<!-- create new image with more space on the bottom ---> <cfset newCanvas = imageNew("", mychart.width, mychart.height + 35, "rgb", "white")>

<!--- paste in the old one ---> <cfset imagePaste(newCanvas, myChart, 0, 0)>

<cfset textProps = {font="Arial-Black", size="20"}> <cfset imageSetDrawingColor(newCanvas, "black")> <cfset imageDrawText(newCanvas, "Charts generated by monkeys #chr(169)##year(now())#", 1, newCanvas.height-20, textProps)>

<cfimage action="writeToBrowser" source="#newCanvas#"> <p>

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Ben Nadel posted on 1/26/2010 at 9:33 AM

@Ray,

That's pretty slick; I never thought of using charts as images with the image functions. That could be *super* handy!

Also, I see you used mychart.width / height instead of imageGetWidth() and imageGetHeight().... welcome to the dark side of undocumented features :)

Comment 2 by Raymond Camden posted on 1/26/2010 at 10:25 PM

Hah, I'll be anal and say it is a ColdFusion Image Variable, and therefore it is documented behavior. ;)

Comment 3 by Ben Nadel posted on 1/26/2010 at 10:29 PM

Hey, I'm with you :) ... though, I have to admit that STRING.replaceAll() still makes me feel nervous.

Comment 4 by Raymond Camden posted on 1/26/2010 at 10:34 PM

To be anal, I just checked the CF Dev Guide, and it isn't listed in the variable types, but the section on images does talk about it ... although vaguely.

Comment 5 by Ben Nadel posted on 1/26/2010 at 10:39 PM

With something like an image, where it's not so "typeless", I think it makes sense. But while most things in CF are strings, I guess you can't always depend on a simple value being a string underneath.

Comment 6 by Ben Nadel posted on 1/28/2010 at 6:09 PM

@Ray,

I am fooling around with images and did a CFDump with an image and I see that it has the width / height properties right there (in the CFDump). That's good enough documentation for me ;)

Comment 7 by Lina Haddad posted on 8/23/2011 at 10:23 PM

does any body know how to make the title attribute for cfchart as text/html , which means to accept <img > or styling ?

Comment 8 by Raymond Camden posted on 8/23/2011 at 10:25 PM

Why not just skip the title and put your own html above cfchart?

Comment 9 by Lina Haddad posted on 8/24/2011 at 12:24 AM

i have multiple charts on one page, and i need to show excel icon next to each title , i don't like to add even addtional frame to the chart if i dont have to .
thanks a lot for your help.

Comment 10 by Raymond Camden posted on 8/24/2011 at 12:27 AM

I think you are out of luck then. You can certainly _try_ including HTML in the title (did you try?), but it will probably strip it out.

Comment 11 by Lina Haddad posted on 8/24/2011 at 12:40 AM

well ,i tried but it doesn't recognize the html .so let's say ,if i have <h3> it will leave it as is.thanks again