Add and remove lineseries - Flex LineChart
This took me some time to figure out so I thought I would post about it.
Main objective is to toggle on and off lineseries based on user input. Usually this would mean editing the dataprovider, tricky thing here is that I need the color of each line to always be the same based on data, so instead I leave the dataprovider alone and actually add and remove LineSeries to/from the LineChart. This probably isn't the best way to do this, but hey, it works, and it may help someone else out.
Here we go...
First lets start with the MXML:
Here I have a Panel with a LineChart and a Legend inside it, as well as 3 Toggle Buttons. You will notice that there are no series inside the LineChart.
And here is the DataProvider:
For ActionScript, lets start with the UpdateChart method:
This method looks to see if the button you just pressed is selected (toggle on) or not. If the toggle is on that means the user is adding the line, if the toggle is off that means the user is removing the line, and this method calls the appropriate method.
Here is the addToChart method. This method creates a new LineSeries and adds it to the chart. Note that the LineSeries DataProvider is the same of the LineChart and the data you're referring to (yField) should already be present in the DataProvider.
You may have noticed the line newLS.setStyle('lineStroke',newStroke);. This refers to the following method, all it does is assigns a color based on the button selected.
And finally here is the remove method.
The default series gets added with the CreationComplete method:
Anyway, I hope that wasn't too confusing. I should really start hosting these little examples somewhere with the ViewSorce available. If you need more clarification just gimmie a comment here.
Main objective is to toggle on and off lineseries based on user input. Usually this would mean editing the dataprovider, tricky thing here is that I need the color of each line to always be the same based on data, so instead I leave the dataprovider alone and actually add and remove LineSeries to/from the LineChart. This probably isn't the best way to do this, but hey, it works, and it may help someone else out.
Here we go...
First lets start with the MXML:
Here I have a Panel with a LineChart and a Legend inside it, as well as 3 Toggle Buttons. You will notice that there are no series inside the LineChart.
<mx:Panel title="LineChart Example" height="500" width="100%" layout="vertical">
<mx:HBox id="choices" horizontalGap="0">
<mx:Button id="Profit" label="Profit" toggle="true" click="updateChart(event)"/>
<mx:Button id="Expenses" label="Expenses" toggle="true" click="updateChart(event)"/>
<mx:Button id="Amount" label="Amount" toggle="true" click="updateChart(event)"/>
</mx:HBox>
<mx:LineChart id="linechart" height="80%" width="100%" showDataTips="true" dataProvider="{expensesAC}" creationComplete="init()">
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="Month"/>
</mx:horizontalAxis>
</mx:LineChart>
<mx:Legend dataProvider="{linechart}" labelPlacement="right" verticalGap="2" direction="vertical"/>
</mx:Panel>
And here is the DataProvider:
[Bindable]
private var expensesAC:ArrayCollection = new ArrayCollection( [
{ Month: "Jan", Profit: 2000, Expenses: 1500, Amount: 450 },
{ Month: "Feb", Profit: 1000, Expenses: 200, Amount: 600 },
{ Month: "Mar", Profit: 1500, Expenses: 500, Amount: 300 },
{ Month: "Apr", Profit: 1800, Expenses: 1200, Amount: 900 },
{ Month: "May", Profit: 2400, Expenses: 575, Amount: 500 } ]);
For ActionScript, lets start with the UpdateChart method:
This method looks to see if the button you just pressed is selected (toggle on) or not. If the toggle is on that means the user is adding the line, if the toggle is off that means the user is removing the line, and this method calls the appropriate method.
private function updateChart(evt:Event):void
{
if ( evt.currentTarget.selected == true )
{
addToChart(evt.currentTarget.label);
} else {
removeFromChart(evt.currentTarget.label);
}
}
Here is the addToChart method. This method creates a new LineSeries and adds it to the chart. Note that the LineSeries DataProvider is the same of the LineChart and the data you're referring to (yField) should already be present in the DataProvider.
private function addToChart(item:String):void
{
var newLS:LineSeries = new LineSeries();
var newStroke:Stroke = new Stroke();
newStroke.color = strokeColor(item);
newLS.yField = item;
newLS.displayName = item;
newLS.setStyle('form','curve');
newLS.dataProvider = expensesAC;
newLS.setStyle('lineStroke',newStroke);
var tmp:Array = linechart.series;
tmp.push(newLS);
linechart.series = tmp;
linechart.invalidateSeriesStyles();
}
You may have noticed the line newLS.setStyle('lineStroke',newStroke);. This refers to the following method, all it does is assigns a color based on the button selected.
private function strokeColor(item:String):uint
{
switch (item)
{
case 'Amount':
return 0x0000FF;
break;
case 'Profit':
return 0xFF0000;
break;
case 'Expenses':
return 0x00FF00;
break;
default:
return 0x000000;
break;
}
}
And finally here is the remove method.
private function removeFromChart(item:String):void
{
var objToRemoveIndex:int;
for ( var i:int = 0; i < linechart.series.length; i++ )
{
if ( linechart.series[i].yField == item )
{
objToRemoveIndex = i;
}
}
var tmp:Array = linechart.series;
tmp.splice(objToRemoveIndex,1);
linechart.series = tmp;
linechart.invalidateSeriesStyles();
}
The default series gets added with the CreationComplete method:
private function init():void
{
addToChart('Amount');
Amount.selected = true;
}
Anyway, I hope that wasn't too confusing. I should really start hosting these little examples somewhere with the ViewSorce available. If you need more clarification just gimmie a comment here.
Comments
Saludos desde Madrid !!!
One note: for me at least, it gets a bit buggy when I try to deselect 'Amount' (the line that is pre-selected). But if I remove it from the init() method it works fine.
thanks!