I have a bubble chart with a custom renderer which is a pie chart. I bind the chart to data which is an array of complex objects which themselves contain references to other data objects in my application.
The data displayed on the chart does not come from the bound object but from the object that it contains. So the main chart looks like this <mx:BubbleChart xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:graphs="pmco.graphs.*"> ....<mx:series> ........<graphs:LinearAreaBubbleSeries ............dataProvider="{fBubbles.bubbles}" ............xField="x" ............yField="y" ............radiusField="radius" ............itemRenderer="pmco.tv.tv_RSPPiePoint" ............minRadius="5" ............maxRadius="100" ............ showDataEffect="rearrangeData" ............id="bubbleSeries"/> ....</mx:series> </mx:BubbleChart> LinearAreaBubbleSeries is just an overloaded BubbleSeries which scales areas rather than radii with bubble value. The item renderer is a canvas with a pie chart on it (I have omitted script code for brevity). <mx:Canvas ....xmlns:mx="http://www.adobe.com/2006/mxml" ....width="400" height="300" ....horizontalScrollPolicy="off" verticalScrollPolicy="off" ....implements="pmco.graphs.IPiePoint"> ....<mx:PieChart id="chart" height="100%" width="100%" paddingRight="0" paddingLeft="0" showDataTips="false" added="init_Pie()" left="0" top="0"> ........<mx:series> ............<mx:PieSeries ................dataProvider="{RSPBubble(data.item).Slices}" ................nameField="name" field="size" ................labelPosition="none" ................id="pieSeries" ................fills="{data.item.fillColours}"> ............</mx:PieSeries> ........</mx:series> ....</mx:PieChart> </mx:Canvas> the data items are complex objects (RSPBubble) which refer to an underlying object which contains the real data (Competitor) (silly is there because I can't figure out how to make the bubble chart show a single series, it only shows anything when there are two bubbles, so I add a silly one by default, a hack for another message...) package pmco.graphs { ....import pmco.pojos.Competitor; ....import mx.collections.ArrayCollection; ....import pmco.utils.PieSegment; ....import pmco.pojos.States; ....import mx.graphics.SolidColor; ....import pmco.pojos.User; .... ....[Bindable] ....public class RSPBubble ....{ ........public var competitor:Competitor; ........public var silly:Boolean; ........public function toString():String ........{ ............return competitor.name; ........} ........public function get y():Number ........{ ............if (silly) return -99.99; ............return competitor.market_attractiveness; ........} ........public function set y(_y:Number):void ........{ ............if (!silly) competitor.market_attractiveness = _y; ........} ........public function get x():Number ........{ ............if (silly) return -99.99; ............return competitor.competitive_position; ........} ........public function set x(_x:Number):void ........{ ............if (!silly) competitor.competitive_position = _x; ........} ........public function get total():Number ........{ ............if (silly) return 0; ............return competitor.potential; ........} ........ ........public function get fillColours():Array ........{ ............if (silly) return null; ............return competitor.fillColours ........} ........ ........// Artificially create pie slices ........public function get Slices():ArrayCollection ........{ ............if (silly) return pieSegments; ............return competitor.Slices; ........} ....} } The point of the RSPBubble object is to abstract the chart rendering from the underlying data and to be able to switch which data gets displayed by adjusting the properties of the bubble, not the underlying value object. I haven't quite managed to do this cleanly so the value object still has some remnants of chart knowledge (again, snipped for brevity): package pmco.pojos { ....import mx.collections.ArrayCollection; ....import mx.graphics.SolidColor; ....import mx.formatters.CurrencyFormatter; ....import pmco.utils.PieSegment; ....import pmco.interfaces.IAssumptionOwner; ....import pmco.interfaces.INotesOwner; ....import pmco.interfaces.IPojo; .... ....[Managed] ....[RemoteClass(alias="pmco.pojos.Competitor")] ....public class Competitor implements IPojo ....{........ ........private var arrFillColours:Array; ........public function get fillColours():Array ........{ ............if (arrFillColours == null) ............{ ................arrFillColours = new Array(); ................arrFillColours.push(new SolidColor(States.STATUS_COLOUR[state],States.ALPHA_VALUE)); ................if (isus) ................{ ....................arrFillColours.push(new SolidColor(States.COLOUR_BUBBLE_BACKGROUND,States.ALPHA_VALUE)); ................} ................else ................{ ....................arrFillColours.push(new SolidColor(States.COLOUR_BUBBLE_BACKGROUND_C,States.ALPHA_VALUE)); ................} ............} ............return arrFillColours; ........} ........private var pieSegments:ArrayCollection; ........public function get Slices():ArrayCollection ........{ ............if (pieSegments == null) ............{ ................//var c:int = States.STATUS_COLOUR[state]; ................pieSegments = new ArrayCollection(); ................// take care of the case when the target and potential are 0 ................if (target == 0 && potential == 0) ................{ ....................pieSegments.addItem(new PieSegment(target, name, state)); ....................pieSegments.addItem(new PieSegment(1, "Remaining Potential", -1)); ................} ................else ................{ ....................pieSegments.addItem(new PieSegment(target, name, state)); ....................pieSegments.addItem(new PieSegment(potential - target, "Remaining Potential", -1)); ................} ............} ............return pieSegments; ........} ....} } and to complete the picture the pieSegment object is as follows: package pmco.utils { ....import mx.graphics.SolidColor; ....import pmco.pojos.Competitor; ....import pmco.pojos.States; ....import mx.charts.series.items.BubbleSeriesItem; .... ....public class PieSegment extends BubbleSeriesItem ....{ ........public var size:Number; ........public var name:String; ........public var state:int; ........public function PieSegment(sz:Number, nm:String, st:int) ........{ ............size = sz; ............name = nm; ............state = st; ............ ........} ....} } The real issue is with fillColours which controls which colour my pie slices are, and Slices which controls how big the slices are. When I run this code I get trace messages as follows: warning: unable to bind to property 'item' on class 'mx.charts.series.items::BubbleSeriesItem' warning: unable to bind to property 'fillColours' on class 'pmco.graphs::RSPBubble' warning: unable to bind to property 'Slices' on class 'pmco.graphs::RSPBubble' Perhaps predictably when I adjust the underlying value object (competitor on a RSPBubble instance) nothing happens to the chart, but I can force the chart to re-bind and thereby get the data again, so one way or another I can get some interactivity. Specifically I want to be able to change the colours and sizes of the slices dynamically on a user interaction. So I have a couple of questions: 1) what is causing the trace messages? 2) can I bind to a getter? 3) is there a better/nicer/cleaner way to do this? Any clues? SP P.S. I know I spell colour properly.