How to exclude series in legend (Flex)
In flex charting, I want to draw开发者_StackOverflow中文版 something like "reference lines" which are related to specific series, therefore these lines are not independent series and should not be shown in legend. Is it possible to exclude some series from chart legend? Thanks!
I elaborated on Luis B's answer to make this dynamically reflect on the linechart's data provider. This way the legend only shows what fields are available in the chart. Kinda nifty.
Here is what I came up with, and it works well:
protected function onUpdateLinechartComplete(e:FlexEvent):void
{
//empty legend for fresh display
var legendArray:Array = new Array();
legend1.dataProvider = legendArray;
//filter Legend data so that only LineSeries with data can be shown
for(var i:int=0; i< linechart1.legendData.length; i++) {
//if data is found in the line series, let's add it to the chart legend data provider, so it can be displayed in the legend
if (linechart1.legendData[i].element.items.length != 0) {
legendArray.push(linechart1.legendData[i]);
}
}
legend1.dataProvider = legendArray;
legend1.direction = "vertical";
}
//in the page Initialize function, I add a listener event to the linechart component for when the legend update completes so it can filter lineseries on the legend's dataprovider in [onUpdateLegendComplete]
linechart1.addEventListener(FlexEvent.UPDATE_COMPLETE, onUpdateLinechartComplete);
I ended up having to use an EventHandler and attaching an event Listener to the linechart itself. This is because I was experiencing "race conditions" with the legend's data provider. Sometmes it would work, sometimes it would not. Using the event Listener eliminated that problem, and only filters the legend when the linechart has completed loading it's data.
FEEL FREE TO UPVOTE THIS ANSWER, FLEX FOLKS!!
It is possible to exclude some series from the chart legend.
Every chart class (extending ChartBase) has a legendData Array property. This legendData has a list of LegendItem's. If you create a newArray based on the legendData, but with only the LegendItem's that you want; then you can set that array as the dataProvider for your legend.
Also, you can create your own array of LegendItem's based on LegendItems that you create from scratch. And use that array as the dataProvider for the Legend.
For example, here I only display the first and third series in my legend:
<mx:Script>
<![CDATA[
private function cc(event:Event):void
{
var newArray:Array = new Array();
newArray.push(myChart.legendData[0]);
newArray.push(myChart.legendData[2]);
myActionScriptLegend.dataProvider = newArray;
}
]]>
</mx:Script>
<mx:ColumnChart id="myChart">
<mx:series>
<mx:ColumnSeries id="series0"/>
<mx:ColumnSeries id="series1"/>
<mx:ColumnSeries id="series2"/>
</mx:series>
</mx:ColumnChart>
<mx:Legend dataProvider="{[myChart.legendData[0],myChart.legendData[2]]}" />
<mx:Legend id="myActionScriptLegend" creationComplete="cc(event)" />
http://livedocs.adobe.com/flex/3/langref/mx/charts/chartClasses/ChartBase.html#legendData
http://livedocs.adobe.com/flex/3/langref/mx/charts/LegendItem.html
http://livedocs.adobe.com/flex/3/html/charts_displayingdata_12.html#330954
OK another version of devtron's answer, if you already have a custom linechart class anyway like I have, then put this in:
[Bindable] public var activeLegendData:Array;
// this goes in an initialize handler
addEventListener(FlexEvent.UPDATE_COMPLETE, onUpdateChartComplete);
protected function onUpdateChartComplete(e:FlexEvent):void {
activeLegendData = new Array();
for(var i:int=0; i < legendData.length; i++) {
if (legendData[i].element.items.length != 0) {
activeLegendData.push(legendData[i]);
}
}
}
Then you bind your legend dataprovider to linechart.activeLegendData instead of linechart.
The advantage of this solution over Devtron's is that you don't have to rewrite the code every time you put another linechart in your app.
Another alternative ...
Derive a new class from one of the chart series classes, then override the getter for legendData()
and return an empty array. Here's an example for PlotSeries:
public class PlotSeriesNoLegend extends PlotSeries
{
public function PlotSeriesNoLegend()
{
super();
}
override public function get legendData():Array /* of LegendData */
{
return [ ];
}
}
Some comments on previous answers. When referring to create a new array to use it as legend, take care because it's not as described. For me it works this way:
When you try to access a value in the existing pie.legendData you should do it this way: pie.legendData[0][0] or pie.legendData[0][1]
Besides that, in order to get these data into a new array and use it for creating the new legend, you should wait for the pie to be already created.
For that I simply use the render event of the pie.
Hope it helps you.
精彩评论