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.
<cfchartseries type="bar">
<cfchartdata item="Apples" value="50">
<cfchartdata item="Bananas" value="40">
<cfchartdata item="Cherries" value="72">
<cfchartdata item="Donuts" value="59">
</cfchartseries> </cfchart>
<cfchart chartheight="500" chartwidth="500" title="Test Chart" format="png" name="mychart">
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.
<!--- paste in the old one --->
<cfset imagePaste(newCanvas, myChart, 0, 0)>
<!-- create new image with more space on the bottom --->
<cfset newCanvas = imageNew("", mychart.width, mychart.height + 35, "rgb", "white")>
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">
<cfchartseries type="bar">
<cfchartdata item="Apples" value="50">
<cfchartdata item="Bananas" value="40">
<cfchartdata item="Cherries" value="72">
<cfchartdata item="Donuts" value="59">
</cfchartseries>
</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>
Archived Comments
@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 :)
Hah, I'll be anal and say it is a ColdFusion Image Variable, and therefore it is documented behavior. ;)
Hey, I'm with you :) ... though, I have to admit that STRING.replaceAll() still makes me feel nervous.
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.
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.
@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 ;)
does any body know how to make the title attribute for cfchart as text/html , which means to accept <img > or styling ?
Why not just skip the title and put your own html above cfchart?
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.
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.
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