Ask a Jedi: Adding additional text to a CFCHART

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"> <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>

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"> <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>

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate. He focuses on JavaScript, serverless 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

Comments