The charting in Flex is a pretty good tool, but there are a few small features that it would be really nice if it had. One of these would be the ability to have a chart series that changed colors depending on it’s value. Conditionally colored charts are something that a lot of us (and our customers) have grown accustomed to and we shouldn’t have to give it up with Flex. If you are like me you have probably been “googling” every variation of “flex colored charts” that you can think of. I couldn’t find an answer anywhere, but hopefully your search will end right here.
I wanted the ability to color charts based on their value, giving them red/yellow/green colors based on if they were lower/equal to/higher than a given value. The ability to use gradients instead of solid colors was also a requirement. I basically wanted to do something like this:
The columns below the line are red, on the line are yellow, and above the line are green. The need might arise to do more colors than this, so the code should be flexible
But almost as important as the final look of the graph itself was the ability to re-use the code without having to rewrite parts of it for each implementation. And I wanted to be able to use it in a flex application using only mxml, but still be able to use it in ActionScript if needed.
In the end I wanted to be able to define the threshold or goal as part of the data that the graph used and the code would color the columns based on that data (if it was greater than/less than/equal to). So the code to use the “coloring object” would look something like this (where we define High/Mid/Low colors):
<mx:series> <mx:ColumnSeries xField="Month" yField="Income" displayName="Income2"> <mx:itemRenderer> <mx:Component> <utils:ColoredSeriesItemRenderer valueField="Income" thresholdField="Goal"> <utils:thresholdGradients> <mx:Object> <mx:High><mx:Object gradient="[0x55dd55,0x005500]" /></mx:High> <mx:Mid><mx:Object gradient="[0xdddd55,0x555500]" /></mx:Mid> <mx:Low><mx:Object gradient="[0xdd5555,0x550000]" /></mx:Low> </mx:Object> </utils:thresholdGradients> </utils:ColoredSeriesItemRenderer> </mx:Component> </mx:itemRenderer> </mx:ColumnSeries> <mx:LineSeries xField="Month" yField="Goal" displayName="Goal"/> </mx:series>
But to be flexible I also wanted to be able to define the goal in the code, where I could give it as many ranges with associated colors as I wanted. This code would look something like this:
<mx:series> <mx:ColumnSeries xField="Month" yField="Income" displayName="Income1"> <mx:itemRenderer> <mx:Component> <utils:ColoredSeriesItemRenderer valueField="Income"> <utils:ranges> <mx:Array> <mx:Object lowerLimit="280" color="0xFF0000" /> <mx:Object lowerLimit="240" upperLimit="280" gradient="[0xFFFF00,0x55FF55]" /> <mx:Object lowerLimit="220" upperLimit="240" gradient="[0x5555FF,0x000099]" /> <mx:Object lowerLimit="200" upperLimit="220" gradient="[0x0000FF,0x00FF00,0xFF0000]" /> <mx:Object upperLimit="200" color="0xFFFF00" /> </mx:Array> </utils:ranges> </utils:ColoredSeriesItemRenderer> </mx:Component> </mx:itemRenderer> </mx:ColumnSeries> </mx:series>
Creating a custom item renderer allowed me (and now you too) to change the colors of the columns as they were being created. This works so much better than other solutions I saw (laying a filter on top of the columns) because it automatically changes when the column changes.
I created a new object out of it so you can just drop it in the directory where you keep your other library files (and change the package name if needed) and start using it. I have included it along with some sample files in a handy zip file for you… 😉
I hope this saves you all the time it could have saved me (if I would have found something similar).
Download the ColoredSeriesItemRenderer.as object with two full examples that you can compile and try in a handy zip file.
If you are not familiar with including custom made objects into an mxml file then you’ll need to know about packages. In the sample code I used a package name of “utils”, which means that the actionscript object is defined with an “utils” package declaration and is in an “utils” subdirectory. Also, the example files will require you to define the xml namespace in the Application tag. This is done by adding something like this: xmlns:utils=”utils.*”