For line chart, intersecting and overlapping lines (series) is often a significant issue because topmost displayed line is usually the last one in the list and covered by many others. Users usually are interested to see item better by bringing it to front. Also, items in chart may require custom order. This is actual for bubble charts where bubbles often overlap.
Below code samples show how you can re-order series or items for chart in any required way.
For line chart, series re-ordering can be done initially by defining series in one order and legend items in another. For this, you should define custom data source for legend and custom legend item renderer by using array as dataProvider for legend.
When you have series already defined for chart, and you need to change the order of lines displaying, use below code sample. The sample code is a method for line chart subclass that is called on event when re-ordering is needed. For example, call it in case when need to bring some special (highlighted) line to front. The isSerieAtFront(serie) function call should be implemented to return true if specified serie should be displayed at front. You can use different approaches here to determine if serie is at top (such as custom serie method call, pass top serie index into this method as parameter etc.) The key moment in below code is use of setChildIndex method for parent container of serie. By re-ordering series in the parent container you re-order how series are displayed.
public function reOrderLines() : void {
// re-order series if we get some of them highlighted
var serie:LineSeries;
var i:int;
var len:int = series.length;
// first of all, set order that is opposite to series in array
for (i=len-1; i>=0; i--) {
serie = series[i] as LineSeries;
if (serie && serie.parent) {
serie.parent.setChildIndex(serie, serie.parent.numChildren - len + i);
}
}
// bring requried serie to front
for (i=0; i<len; i++) {
serie = series[i] as LineSeries;
if (serie && serie.parent && isSerieAtFront(serie)) {
serie.parent.setChildIndex(serie, serie.parent.numChildren-1);
}
}
}
As about items re-ordering, series for some charts (column, area and line) have property sortOnXField. However, if need custom re-ordering, you can do this by overriding the updateMapping or describeData methods, call parent class method, and then change order in the renderData.cache array. You will need to do this as part of new class that is override of the series class. Below is example for bubble chart with use of custom series class.This example takes already sorted array, specify zFilter values to change order of items (you will need to define customOrderIndex method to provide order values), then sort. Final step is clear filtering values that are used by chart to sorts items, so chart would not override our custom sorting again.
protected override function updateMapping():void {
// here is where default sorting happens
super.updateMapping();
// re-order items
var dataItems:Array = renderData.cache;
var i:int;
for (i = 0; i<dataItems.length; i++) {
dataItems[i]['zFilter'] = customOrderIndex(i);
}
dataItems.sortOn('zFilter', Array.DESCENDING | Array.NUMERIC);
// to make default code do not sort items back again, set filter values to NaN
for (i = 0; i<dataItems.length; i++) {
dataItems[i]['zFilter'] = NaN;
}
}
The difference in use of updateMapping vs describeData to re-order items is following: with updateMapping we do not need to change data provider data (refresh data) each time we need to bring some bubble to front. To refresh chart when need to bring some bubble to front, we just can call invalidateMapping method of serie instead. invalidateMapping method is protected, so you would need to publish it if call from outside of custom serie class. For example, put following in your cusom series class:
public function invalidateDataMapping() : void {
super.invalidateMapping();
}