Coloring CFCHART Dynamically

This post is more than 2 years old.

Here is a question that came up earlier this morning on a mailing list. How can we specify colors for CFCHART based on some particular business rule? So for example, imagine we have a set of average temperatures. You want to chart them and specifically call out values that are below, or above, certain notes. This is rather simple if you make use of the colorList attribute of cfchartseries. Normally this is used to provide a static list of colors, but you can certainly make it dynamic as well. Here is a simple example.

Let's start off with some simple, static data, and no, this isn't real temperatures for Louisiana.

<cfset data = arrayNew(2)> <cfset data[1][1] = "Jan"> <cfset data[1][2] = 30> <cfset data[2][1] = "Feb"> <cfset data[2][2] = 60> <cfset data[3][1] = "Mar"> <cfset data[3][2] = 70> <cfset data[4][1] = "Ap"> <cfset data[4][2] = 80> <cfset data[5][1] = "May"> <cfset data[5][2] = 85> <cfset data[6][1] = "Jun"> <cfset data[6][2] = 95> <cfset data[7][1] = "Jul"> <cfset data[7][2] = 105> <cfset data[8][1] = "Aug"> <cfset data[8][2] = 104> <cfset data[9][1] = "Sep"> <cfset data[9][2] = 95> <cfset data[10][1] = "Oct"> <cfset data[10][2] = 80> <cfset data[11][1] = "Nov"> <cfset data[11][2] = 75> <cfset data[12][1] = "Dec"> <cfset data[12][2] = 60>

Next, let's supply this to a cfchart just to see how it looks without any modification:

<cfchart chartheight="500" chartwidth="600" title="Average Temperature" show3d="false" > <cfchartseries type="bar" paintstyle="shade"> <cfloop index="datum" array="#data#"> <cfchartdata item="#datum[1]#" value="#datum[2]#"> </cfloop> </cfchartseries> </cfchart>

This results in the rather lovely chart you see here:

Ok, so it works. I'm not exactly sure where the Halloween Orange theme came from, but it works. So now let's make it dynamic. I'm going to use the following rules for my colors:

  • If the temperature was less than 40, use blue (get it?).
  • If the temperature was greater than 90, use red (clever, I know).
  • Otherwise just use green.

I whipped up the following to generate a color list:

<cfset cList = ""> <cfloop index="datum" array="#data#"> <cfif datum[2] lt 40> <cfset cList = listAppend(cList, "##0000FF")> <cfelseif datum[2] gt 90> <cfset cList = listAppend(cList, "##FF0000")> <cfelse> <cfset cList = listAppend(cList, "##00FF00")> </cfif> </cfloop>

Next I passed in cList:

<cfchartseries type="bar" colorlist="#cList#" paintstyle="shade">

And voila:

Not exactly a work of art, but better. You can quickly see which items are at the extreme of my data set. I've pasted the complete template below.

<cfset data = arrayNew(2)> <cfset data[1][1] = "Jan"> <cfset data[1][2] = 30> <cfset data[2][1] = "Feb"> <cfset data[2][2] = 60> <cfset data[3][1] = "Mar"> <cfset data[3][2] = 70> <cfset data[4][1] = "Ap"> <cfset data[4][2] = 80> <cfset data[5][1] = "May"> <cfset data[5][2] = 85> <cfset data[6][1] = "Jun"> <cfset data[6][2] = 95> <cfset data[7][1] = "Jul"> <cfset data[7][2] = 105> <cfset data[8][1] = "Aug"> <cfset data[8][2] = 104> <cfset data[9][1] = "Sep"> <cfset data[9][2] = 95> <cfset data[10][1] = "Oct"> <cfset data[10][2] = 80> <cfset data[11][1] = "Nov"> <cfset data[11][2] = 75> <cfset data[12][1] = "Dec"> <cfset data[12][2] = 60>

<cfset cList = ""> <cfloop index="datum" array="#data#"> <cfif datum[2] lt 40> <cfset cList = listAppend(cList, "##0000FF")> <cfelseif datum[2] gt 90> <cfset cList = listAppend(cList, "##FF0000")> <cfelse> <cfset cList = listAppend(cList, "##00FF00")> </cfif> </cfloop>

<cfchart chartheight="500" chartwidth="600" title="Average Temperature" show3d="false" > <cfchartseries type="bar" colorlist="#cList#" paintstyle="shade"> <cfloop index="datum" array="#data#"> <cfchartdata item="#datum[1]#" value="#datum[2]#"> </cfloop> </cfchartseries> </cfchart>

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 Jody Fitzpatrick posted on 3/13/2010 at 5:49 PM

I don't use CFCHART anymore. I have found out that it slows down my application quite considerably I switched to jQuery to render my charts.

But great post... I have always wondered how to do this. I was also wondering if coldfusion could have to sets of data points on the same chart data point a on the left defined by a bar ( or whatever ) and datapoint b defined on the right side with a line chart. I'm sure you have seen something similar to what I'm referring to Ray, well at least I hope so.

Comment 2 by Raymond Camden posted on 3/14/2010 at 3:50 AM

All you need is two cfchartseries tags. One for the bar chart, one for the line chart.

Comment 3 by Larry C. Lyons posted on 3/18/2010 at 9:21 PM

Thanks Ray, that cfchart suggestion you gave me a couple of days ago worked out very well. Looks like it turned into a nice blog post as well.

larry

Comment 4 by Thrifte posted on 7/28/2010 at 7:17 PM

This was very useful. Couldn't figure out how to apply dynamic colors to CFChart... this is probably why you are famous :)

Comment 5 by Raymond Camden posted on 7/28/2010 at 10:08 PM

Actually it's my singing ability.... not. :)

Comment 6 by Dan Murphy posted on 5/14/2013 at 8:07 PM

I know this is old, but google (thankfully) lead me here. I love this tip, but any idea on why it doesn't work with multiple cfchartseries tags on the same chart? It seems like no matter what I do, the colorlist attribute gets ignored once there are multiple series. As an easy test, you could just use the example above but copy the cfchartseries to create the second one. Colorlist gets ignored. Seriescolor still works, but not colorlist. Any ideas?

Comment 7 by Raymond Camden posted on 5/14/2013 at 8:14 PM

Confirmed. I'm guessing it is a bug. You could try to work around it using the chart editor.

However.

I no longer recommend using the older cfchart engine. There are a multitude of charting options available today that would work well with CF. Some free, some not, some open source, some not. But the point is - you have options. The old cfchart is near 10 years old I think. I suggest moving on from it.

Comment 8 by Misty posted on 5/20/2013 at 12:55 PM

Hi ray, How to dynamically change the type of the chartseries from pie, to cone, to area using jquery

Any Idea

Comment 9 by Raymond Camden posted on 5/20/2013 at 2:35 PM

Well, if you are using the new charting in CF10, it is trivial. You get a chart handle and reset the settings. In CF9 (or CF10 STD), you would use an iframe that calls the CFM. Make the CFM accept URL params for the type. jQuery can then 'drive' that iframe.

Comment 10 by Misty posted on 5/20/2013 at 5:09 PM

Hi ray, Actually Solved with iframe, Few issues i cam across IN IE 7 or 8, due to jquery permission denied. I am not sure what was causing it, then i reverted the code to iframe and loaded contents inside that and now it is working flawlessly

btw i am using cf10, you said "Well, if you are using the new charting in CF10, it is trivial.", can you show how?

Comment 11 by Raymond Camden posted on 5/20/2013 at 6:12 PM

Um, ok, maybe not *trivial*. ;) Zingchart has an API that allows you to completely change the model/UI of a chart on the fly. CF gives you a handle to the chart object. You would then do what I would do - go to the Zingchart docs. :)

Comment 12 by Lakshmi posted on 7/22/2014 at 9:42 AM

I am creating a bar graph in CF11 .i tried this in cf7 ad it worked but CF11 it didnt.

Comment 13 by Raymond Camden posted on 7/22/2014 at 6:53 PM

CF11 has a new charting engine, so my code here isn't guaranteed to work anymore.