Editable charts with Adobe Flex
One of the cool things about Flex is its ability to snapshot just about anything in the application. It's usually as simple as:
var snapshot:String = ImageSnapshot.encodeImageAsBase64( ImageSnapshot.captureImage("your view component here", 0, new PNGEncoder));
This is particularly handy when you've got a dynamically generated resource, such as a chart, that you'd like to have customized by the user and then exported as an image. One thing that is handy to customize in a chart is its axis titles. That's exactly what we are going to do.
This demo application has view source enabled, so just right click to see how it was put together.
Chart axis titles are typically just strings of text that you specify when you create a chart. However you can use your own TitleRenderer to produce just about anything you want instead of the Flex default. We are going to use the excellent IPE controls by Ely Greenfield available here: http://demo.quietlyscheming.com/IPE/index.html
Much of the code in editablecharts.mxml is standard chart boiler plate, with the exception of horizontal and vertical AxisRenderer properties called titleRenderer. These are set to our custom implementation that hooks up an editable IPE control instead of the default flex TextField.
Following is the code for EditableTitleRenderer:
package editablecharts { import mx.charts.AxisRenderer; import mx.core.IDataRenderer; import mx.core.UIComponent; import qs.ipeControls.IPETextInput; public class EditableTitleRenderer extends UIComponent implements IDataRenderer { public function EditableTitleRenderer() { super(); } private var editableTitle:IPETextInput; public function get data():Object { return editableTitle; } public function set data(value:Object):void { editableTitle.text = String(value); invalidateSize(); invalidateDisplayList(); } override protected function createChildren():void { super.createChildren(); editableTitle = new IPETextInput; editableTitle.editOnClick = true; editableTitle.commitOnEnter = true; editableTitle.commitOnBlur = true; editableTitle.styleName = "editableAxisTitle"; addChild(editableTitle); } override protected function measure():void { var oldRotation:Number = rotation; if (parent && parent.rotation == 90) { rotation = -90; } editableTitle.validateNow(); measuredWidth = editableTitle.measuredWidth; measuredHeight = editableTitle.measuredHeight; rotation = oldRotation; } override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { if (parent && parent is AxisRenderer && parent.rotation == 90) { var p:AxisRenderer = AxisRenderer(parent); if(p.getStyle('verticalAxisTitleAlignment') == 'vertical') { editableTitle.rotation = 180; editableTitle.y = editableTitle.y + editableTitle.height; editableTitle.x = editableTitle.x + editableTitle.width; } } editableTitle.validateNow(); editableTitle.setActualSize(unscaledWidth, unscaledHeight); } } }
One thing to keep in mind is that you need embedded fonts to pull off rotation. If you sent rotation to anything other than 0 on a normal TextField control it'll just disappear. To work around that use an embedded font.
That's pretty much all there's to editable chart axis titles in Flex.