views:

571

answers:

2

Hey All,

I have some issues in updating the legends created using action script.

Please read the following steps to understand the issue.

  1. Created a line chart with two data Series.
  2. Created a legend.
  3. Appended chart and legend to a container.

  4. There is an update button. Clicked on the button.

  5. Now the line chart was updated with three data Series.
  6. When i tried to update the legend , it was still pointing to the initial values with two labels instead of three.

  7. The code I used to achieve (6)

option (1)

this["containerId"].getChildByName("legendName").dataProvider = LineChart(this["containerId"].getChildByName("chartName"));

option (2)

this["containerId"].getChildByName("legendName").dataProvider = this["containerId"].getChildByName("chartName") as LineChart;

Any comments?

Thanks Jay

A: 

this is a major problem with flex: it is very hard to use with AS3 ... better go with MXML and create bindings ... the problem should probably go away ...

a thing i don't fully understand is, why one child is the dataprovider to another, but maybe the layout of your app makes that clear ... usually, dataproviders come from the app's data model ...


edit: i think, bindings are the best approach ... you should create a class as follows:

class Data {
    [Bindable(event="legendChanged")]
    public function get legend():LegendType {/*implementation*/}
    [Bindable(event="chartChanged")]
    public function get chart():ChartType {/*implementation*/}
    public function choseGraph(index:uint):void {
         //update state so the getters for chart and legend will return the right values
         this.dispatchEvent(new Event("legendChanged"));
         this.dispatchEvent(new Event("chartChanged"));
    }    
}

and then bind your view to it.


greetz

back2dos

back2dos
Hi,The bindable dataproviders won't help much here,Since I' have to handle around 50-60 charts in one single page and have to generate them dynamically.Following is the structure I maintain<container> <chart1></chart1> <legend1></legend1> <chart2></chart2> <legend2></legend2> <chartN></chartN> <legendN></legendN> </container>Whenever there is some change in the input, i retrieve the relevant chart and update the data series and the legends.Hope, I've given you a clear explanation.-Jay
Jay
A: 

About 1 year ago I did some heavy lifting with Flex charts and they can be a constant source of frustration. The fact is they are very clever inside which leads to very difficult to reason about behaviours.

One thing I noticed was that sometimes when you change data, it can actually take a few frames for it to trickle through the hierarchy. That is even if you update the dataProvider on the legend on the same frame as when you update the series information you may not be binding to the correct version of the instance since it will change in a few frames. (i.e. the change to the Series is asynchronous and the change to the dataProvider is synchronous).

One quick test to see if this is your problem is just to put a hack timer in place. Set it for 100ms or so and then set your dataProvider later -- hopefully when the changes to the Series have worked their way to the necessary property. Another idea is to use a second button and once you visually see the new Series use that button to trigger the assignment of the legends dataProvider. That isn't a production ready solution but it will at least determine the nature of the problem.

If it is your problem (which I suspect but am not certain of) then start looking for events that come from all of the chart components. The event that signals the new Series has been drawn may come from anywhere but you'll find it eventually. Good luck.


Also, the difference between:

var foo:Bar = Bar(obj); // if !(obj is Bar) throw Error

and

var foo:Bar = obj as Bar; // if !(obj is Bar) return null

is the first is best if you are certain obj will cast to a Bar and it will throw an exception if it isn't (in fact it would be an error if it didn't cast to a Bar). The second (as) is for when there is a reasonable chance obj won't be a Bar and it won't throw an error and will instead return null.

Because of this behaviour Adobe recommends that the first form be used whenever possible.

James Fassett
No Luck in tryinga) setTimeout function call to set the Legend's data provider.b) adding a new button assigned an eventHandler which takes care of assigning the data provider to the Legend's Instance.In both the above cases I noticed that the dataProvider (chartInstance) points to the intial value instead of the updated instance.Will update you once i fix this issue.ThanksJay
Jay