Ask a Jedi: Hack for percentage based CFCHART

This post is more than 2 years old.

Mike asked:

Do you know if there is a way to set an auto width to cfchart? Setting a pixel width doesn't work well when coding for touch screens with the different widths for portrait and landscape views. Thanks for any help you can provide.

Interesting question. You may notice that cfchart's height and width attributes only accept real numbers, not percentages. I first tried a hack where I modified the output HTML containing the SWF:

<cfset d = []> <cfset d[1] = {date="1/1/2011 03:22", value=99}> <cfset d[2] = {date="1/2/2011 04:22", value=80}> <cfset d[3] = {date="1/3/2011 09:22", value=79}>

<cfsavecontent variable="html"> <cfchart chartheight="500" chartwidth="500" title="Test Chart" backgroundcolor="red">

   &lt;cfchartseries type="bar"&gt;
           &lt;cfloop index="item" array="#d#"&gt;
                   &lt;cfchartdata item="#item.date#" value="#item.value#"&gt;
           &lt;/cfloop&gt;
   &lt;/cfchartseries&gt;

</cfchart> </cfsavecontent>

<cfset html=replace(html, "WIDTH=""500""", "WIDTH=""100%""","all")> <cfoutput>#html#</cfoutput>

Technically that works - the resultant object/embed tags are updated and the SWF takes 100% of the available width, but the actual chart inside the SWF doesn't size with the change. I then tried the non-interactive version with an image. Because an image map is used normally, I had to store the bits of the image to the file system and then output it.

<cfset d = []> <cfset d[1] = {date="1/1/2011 03:22", value=99}> <cfset d[2] = {date="1/2/2011 04:22", value=80}> <cfset d[3] = {date="1/3/2011 09:22", value=79}>

<cfchart chartheight="500" chartwidth="500" title="Test Chart" backgroundcolor="red" format="png" name="img">

   &lt;cfchartseries type="bar"&gt;
           &lt;cfloop index="item" array="#d#"&gt;
                   &lt;cfchartdata item="#item.date#" value="#item.value#"&gt;
           &lt;/cfloop&gt;
   &lt;/cfchartseries&gt;

</cfchart>

<cfset fileWrite(expandPath("./mychart.png"),img)>

<style> .chartimage { width: 100%; } </style> <img src="mychart.png" class="chartimage">

If you do use this code (and it does actually work), you would want to modify it to not generate and write on every request. It should intelligently determine if it needs to generate a new file first. I'll also remind people that while cfchart is pretty powerful, it's also a bit old. It is not the only way to do charting in ColdFusion. There are numerous other solutions as well.

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 Dan G. Switzer, II posted on 6/27/2011 at 11:47 PM

One thing that can be done is to use AJAX to load the chart fragment into the DOM. This allows you to pass in width/height based dynamic natures of your HTML, so that you can render the image to the specific width/height you've reserved on your page.

Comment 2 by Raymond Camden posted on 6/27/2011 at 11:50 PM

But even with a fragment, the chart will be X wide. Increasing the size of the fragment won't make the chart wider. I don't believe this will work - but if you try it and see otherwise, let me know.

Comment 3 by John Jarrard posted on 11/13/2012 at 2:04 AM

In case this ever comes up again, for the CFChart image output, to scale it, just wrap it in a div and use CSS to scale the internal image.

Example:

<div id="imageDiv">
<cfchart yaddy yaddy format="png">
</div>

Then:
<style>
#imageDiv img {width: 100%}
</style>

Comment 4 by Raymond Camden posted on 11/13/2012 at 2:28 AM

Slick. Thanks John!

Comment 5 by Mike posted on 2/27/2014 at 10:19 PM

You don't even have to mess with the generated image at all if the chart format is "png". Simply wrap the chart in the div with the style (class or id).

Example:
<div class="imageDiv">
<cfchart format="png"...>
<cfchartseries
type="bar"...>
<cfchartdata items...>
</cfchartseries>
</cfchart>
</div>

<style>
.imageDiv img {width: 100%}
</style>