Tuesday, July 15, 2008

Editable chart with custom axis from Flexosaurus

Nearly one month ago I was needed to create a custom axis which contains controls. We have little time and we decided to round this problem and chose another approach. On previous weekend I decided to find out how it is possible to insert controls into axis and found it very easy. Following example is adding one image and one button with every label, it is also providing a way of editing chart run-time.




<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="{init()}"
width="460" height="450">


<mx:ColumnChart id="championsChart" dataProvider="{champions}">
<mx:horizontalAxis>
<mx:CategoryAxis id="horAxis" dataProvider="{champions}"
categoryField="Team"/>
</mx:horizontalAxis>
<mx:series>
<mx:ColumnSeries xField="Team" yField="Count"
displayName="Team">
<mx:fill>
<mx:SolidColor color="0xc02314"/>
</mx:fill>
</mx:ColumnSeries>
</mx:series>
<mx:horizontalAxisRenderers>
<mx:AxisRenderer axis="{horAxis}">
<mx:labelRenderer>
<mx:Component>
<mx:VBox horizontalAlign="center">
<mx:HBox>
<mx:Image source="@Embed('../assets/f1logo.png')"/>
<mx:Label id="newLabel"/>
</mx:HBox>
<mx:Button label="EDIT" click="{outerDocument.onClick(event)}"/>
<mx:Script><![CDATA[
override public function set data(value:Object):void
{
if(value == null)
{
return;
}

newLabel.text = value.text;
}
]]></mx:Script>
</mx:VBox>
</mx:Component>
</mx:labelRenderer>
</mx:AxisRenderer>
</mx:horizontalAxisRenderers>
</mx:ColumnChart>

<mx:Script><![CDATA[

import mx.containers.*;
import mx.controls.Button;
import mx.controls.TextInput;
import mx.collections.ArrayCollection;
import mx.managers.PopUpManager;

private var titleWindow:TitleWindow;
private var countTextInput:TextInput;
private var saveButton:Button;
private var cancelButton:Button;
private var index:int;

[Bindable]

public var champions:ArrayCollection = new ArrayCollection
([
{Team:"Ferrari", Count:15},
{Team:"Williams", Count:9},
{Team:"McLaren", Count:8}
]);

public function onClick(e:Event):void
{
index = searchName(e.target.parent.newLabel.text);
titleWindow.title = e.target.parent.newLabel.text + " championships number";
PopUpManager.addPopUp(titleWindow,this,true);
PopUpManager.centerPopUp(titleWindow);
}

private function init():void
{
var vbox:VBox = new VBox();
var hbox:HBox = new HBox();

titleWindow = new TitleWindow();
countTextInput = new TextInput();
saveButton = new Button();
cancelButton = new Button()

cancelButton.addEventListener(MouseEvent.CLICK, onCancel);
saveButton.addEventListener(MouseEvent.CLICK, onSave);

saveButton.label = "SAVE";
cancelButton.label = "CANCEL";

hbox.addChild(saveButton);
hbox.addChild(cancelButton);

vbox.addChild(countTextInput);
vbox.addChild(hbox);

titleWindow.addChild(vbox);
}

private function onCancel(e:Event):void
{
PopUpManager.removePopUp(titleWindow);
countTextInput.text = "";
}

private function onSave(e:Event):void
{
champions.getItemAt(index).Count = (countTextInput.text == "") ? 10 : int(countTextInput.text);

PopUpManager.removePopUp(titleWindow);
countTextInput.text = "";

championsChart.dataProvider = champions;
}

private function searchName(name:String):int
{
for(var i:int = 0; i < champions.length; i++)
{
if(champions.getItemAt(i).Team == name)
{
return i;
}
}
return -1;
}

]]></mx:Script>
</mx:Application>

No comments: