Thanks Ely... I was hoping to catch your attention ;-)
The (complete) code for the itemRenderer is below in my original
posting. Was there some other sample code that would be useful? I
can't imagine that the MXML would be all that helpful... as all that
would show is that I'm assigning the custom itemRenderer to the
PlotSeries of the chart. But... let me know.
Basically my app consists of two panes, one contains the chart, and
one contains a datagrid, both bound to the same object for their
dataProviders. The object is actually being populated via a DB query
using Flexcubed's FlexSQL SWC (since the backend is ASP and I can't
use CF on this project). But I don't think that plays into it since
I've checked a number of times that the array is created as expected
and is valid.
The query loads up a bindable object (localData). I have a button to
save the data back to the DB, but until the user elects to do so, I
just want to operate with the local version of the object. So I can't
go back to the DB for a full refresh. But I tried something like:
{
var origDataProvider = chart.dataProvider;
chart.dataProvider = new Object();
chart.dataProvider = origDataProvider;
}
and even that didn't refresh the chart appropriately.
Can you give me some pointers to "have my dataprovider items dispatch
change events"?
Thanks much!
-Carl
--- In [email protected], "Ely Greenfield" <[EMAIL PROTECTED]> wrote:
>
> Carl -
>
> Can you share some sample code? The simpler the better.
>
>
> My short answer is...the chart will only set the data property on your
> renderer if the chart knows things have changed. Since the chart knows
> nothing about the size or color fields, it won't trigger an update.
> You'll need to have your dataprovider items dispatch change events, and
> have your renderers listen to the data object (the item) for those
> change events yourself.
>
>
>
> Or, re-assign the dataProvider to the chart, to slam a full update.
>
>
>
> Ely.
>
>
>
>
>
> From: [email protected] [mailto:[EMAIL PROTECTED] On
> Behalf Of carl_steinhilber
> Sent: Tuesday, May 08, 2007 10:00 AM
> To: [email protected]
> Subject: [flexcoders] Absolutely forcing chart to redraw
>
>
>
> I asked this earlier and didn't get any response... but I think maybe
> I hijacked another thread, so I'll ask again as it's own topic.
>
> I have a PlotChart that uses a custom itemRenderer. The dataProvider
> bound to the chart has objects with the keys:
> - xAxis:Number, which translates to the position on the xAxis of
> the chart (-10 to 10), as the value moves to negative, the items color
> changes from green to orange to red
> - yAxis:Number, which translates to the position on the yAxis of
> the chart (-10 to 10), as the value moves to negative, the items color
> changes from green to orange to red
> - size:Number, which translates to the size of the item (diameter
> of circle)
> - visible:Boolean, which determines whether the item is actually
> plotted on the chart or not
>
> At runtime, the chart initially loads exactly as expected (items the
> correct size, color and position). Then if I update the values for
> xAxis and/or yAxis, the item moves on the chart as expected (though if
> it moves from a positive value to negative value on either axis, the
> color remains green).
> But if I update the value for size it doesn't update the item on the
> chart, and if I update visible to false the item remains visible.
>
> Obviously the data setter function in my itemRenderer class is not
> called when I expect.
>
> Also, if I completely replace the dataProvider with a new object, item
> 1 retains the color and size of item 1 in the old data, and so on.
>
> I've tried explicitly calling invalidateDisplayList() and
> validateNow() on the chart, but it seems to just run the
> updateDisplayList(). This makes some sense... I guess set data is only
> run when the chart is first initialized. Seems like I really want the
> bulk of the logic that's currently in the data setter to be in the
> updateDisplayList() function... but I don't seem to have access to the
> dataProvider data in that function.
>
> How do I force the chart to rerun the renderer for the item(s) with
> updated data? Or, conversely, how do I get at dataProvider values from
> the updateDisplayList() function in the class?
>
> Any help would be appreciated.
>
> Thanks in advance!
> -Carl
>
> Here's the class
> ==================================================
> package
> {
> import mx.skins.ProgrammaticSkin;
> import flash.geom.Rectangle;
> import mx.graphics.*;
> import flash.display.Graphics;
> import mx.core.IDataRenderer;
>
> import mx.charts.ChartItem;
> import flash.events.MouseEvent;
> import mx.core.UIComponent;
> import mx.controls.Label;
> import mx.charts.PlotChart;
> import mx.charts.series.items.PlotSeriesItem;
>
> public class ClientItemRenderer extends UIComponent implements
> IDataRenderer
> {
> private var _label:Label;
> private var _status:Label;
> private var _itemFill:uint;
> private var _itemVisible:Boolean;
> private var _itemSize:int;
> private var _itemXAxis:int;
> private var _itemYAxis:int;
>
> public function ClientItemRenderer()
> {
> super();
> _label = new Label();
> addChild(_label);
> _label.setStyle("color",0x000000);
> _status = new Label();
> addChild(_status);
> _status.setStyle("color",0x000000);
> }
> private var _chartItem:ChartItem;
>
> public function get data():Object
> {
> return _chartItem;
> }
>
> public function set data(value:Object):void
> {
> if (_chartItem == value)
> return;
> _chartItem = ChartItem(value);
> _itemVisible = false;
>
> if(_chartItem != null){
> _itemXAxis = _chartItem.item.xAxis;
> _itemYAxis = _chartItem.item.yAxis;
>
> var size = _chartItem.item.size;
> _itemSize = 1;
> if (int(size) > 250000)
> _itemSize = 2;
> if (int(size) > 500000)
> _itemSize = 3;
> if (int(size) > 750000)
> _itemSize = 4;
> if (int(size) > 999999)
> _itemSize = 5;
>
> if (String(_chartItem.item.visible)=="True")
> _itemVisible = true;
>
> _label.text = _chartItem.item.clientname;
> _status.text = String(_itemSize);
>
> _itemFill = 0xFFA023;
> if (_itemXAxis < 0 && _itemYAxis < 0)
> _itemFill = 0xFF0000;
> if (_itemXAxis >= 0 && _itemYAxis >= 0)
> _itemFill = 0x26B417;
> }
>
> }
>
> private var _over:Boolean = false;
>
> private static var rcFill:Rectangle = new Rectangle();
>
> private function rollOver(e:MouseEvent):void
> {
> _over = true;
> invalidateDisplayList();
> }
> private function rollOut(e:MouseEvent):void
> {
> _over = false;
> invalidateDisplayList();
> }
>
> override protected function updateDisplayList(unscaledWidth:Number,
> unscaledHeight:Number):void
> {
> super.updateDisplayList(unscaledWidth, unscaledHeight);
> if (_itemVisible){
> var fill:* = (_over)? 0x0000FF:_itemFill;
> var stroke:IStroke = getStyle("stroke");
> var w:Number = (_itemSize - 1) * 4;
> rcFill.right = unscaledWidth;
> rcFill.bottom = unscaledHeight;
>
> var g:Graphics = graphics;
> g.clear();
> if (stroke)
> stroke.apply(g);
> if (fill is IFill)
> fill.begin(g, rcFill);
> else if (fill is Number)
> g.beginFill(fill);
> g.drawCircle( unscaledWidth / 2,
> unscaledHeight / 2,
> unscaledWidth / 2 + w);
> if (fill is IFill)
> fill.end(g);
> else if (fill is Number)
> g.endFill();
>
>
> _label.setActualSize(_label.getExplicitOrMeasuredWidth(),_label.getExpli
> citOrMeasuredHeight());
> _label.move(unscaledWidth/2 -
> _label.getExplicitOrMeasuredWidth()/2,- (15 + w));
> }
> }
> }
> }
>