天天看點

Flex ColumnChart verticalAxis 中的title在變換皮膚時的異常

  在ColumnChart 中添加了title的顯示,但在更新皮膚時,發現title 的位置會向左下方移動(僅在verticalAxisTitleAlignment="vertical"時)。 AxisRenderer 中的verticalAxisTitleAlignment有兩值可供先用:flippedVertical 将title從上往下渲染; vertical 将title從下往上渲染。 部分代碼如下: Solution: 調式跟蹤發現在ChartLabel 這個類中的updateDisplayList()方法中 if (parent && parent is AxisRenderer && parent.rotation == 90 && _label.embedFonts == true) { var p:AxisRenderer = AxisRenderer(parent); if ((p.getStyle('verticalAxisTitleAlignment') == 'vertical' && p.layoutDirection == LayoutDirection.LTR) || (p.getStyle('verticalAxisTitleAlignment') == 'flippedVertical' && p.layoutDirection == LayoutDirection.RTL)) { _label.rotation = 180; _label.y = _label.y + _label.height; _label.x = _label.x + _label.width; } } 注:因為項目中用到了嵌入字型,是以label.embedFonts = true。

  title會旋轉180度,然後将x,y坐标相應的增加width和height。這樣以來,每次調到該方法,title就會向左下方

  移動了。

  本想擴充ChartLabel時,發現該類中都是私有屬性。隻好使用titleRenderer來處理了。 ChartTitleRenderer.as 如下: package com.onestart.example.controls { import flash.display.*; import flash.geom.*; import mx.charts.AxisLabel; import mx.charts.AxisRenderer; import mx.core.FlexBitmap; import mx.core.IDataRenderer; import mx.core.IUITextField; import mx.core.LayoutDirection; import mx.core.UIComponent; import mx.core.UITextField; import mx.core.mx_internal; use namespace mx_internal; public class ChartTitleRenderer extends UIComponent implements IDataRenderer { //------------------------------------------------ -------------------------- // // Class constants // //------------------------------------------------ -------------------------- private static var ORIGIN:Point = new Point(0, 0); private static var X_UNIT:Point = new Point(1, 0); //------------------------------------------------ -------------------------- // // Constructor // //------------------------------------------------ -------------------------- public function ChartTitleRenderer() { super(); this.includeInLayout = false; this.layoutDirection = LayoutDirection.LTR; } //------------------------------------------------ -------------------------- // // Variables // //------------------------------------------------ -------------------------- private var _label:IUITextField; private var _bitmap:Bitmap; private var _capturedText:BitmapData; private var _text:String; //------------------------------------------------ -------------------------- // // Properties // //------------------------------------------------ -------------------------- //---------------------------------- // data //---------------------------------- private var _data:Object; [Inspectable(environment="none")] public function get data():Object { return _data; } public function set data(value:Object):void { if (value == _data) return; _data = value; if (value is AxisLabel) _text = AxisLabel(value).text; else if (value is String) _text = String(value); _label.text = _text == null ? "":_text; invalidateSize(); invalidateDisplayList(); } //------------------------------------------------ -------------------------- // // Overridden methods: UIComponent // //------------------------------------------------ -------------------------- override public function invalidateSize():void { super.invalidateSize(); } override protected function createChildren():void { super.createChildren(); _label = IUITextField(createInFontContext(UITextField)); _label.multiline = true; _label.selectable = false; _label.autoSize = "left"; _label.styleName = this; addChild(DisplayObject(_label)); } override protected function measure():void { var oldRotation:Number = rotation; if (parent && parent.rotation == 90) rotation = -90; _label.validateNow(); if (_label.embedFonts) { measuredWidth = _label.measuredWidth + 6; measuredHeight = _label.measuredHeight + UITextField.TEXT_HEIGHT_PADDING; } else { measuredWidth = _label.textWidth + 6; measuredHeight = _label.textHeight + UITextField.TEXT_HEIGHT_PADDING; } rotation = oldRotation; } override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { if (parent && parent is AxisRenderer && parent.rotation == 90 && _label.embedFonts == true) { var p:AxisRenderer = AxisRenderer(parent); if ((p.getStyle('verticalAxisTitleAlignment') == 'vertical' && p.layoutDirection == LayoutDirection.LTR) || (p.getStyle('verticalAxisTitleAlignment') == 'flippedVertical' && p.layoutDirection == LayoutDirection.RTL)) { _label.rotation = 180; _label.y = _label.height ; _label.x = _label.width; } } _label.validateNow(); _label.setActualSize(unscaledWidth, unscaledHeight); var localX:Point; var localO:Point; var useLabel:Boolean = true; if (_label.embedFonts == false && unscaledWidth > 0 && unscaledHeight > 0) { localX = globalToLocal(X_UNIT); localO = globalToLocal(ORIGIN); useLabel = localX.x - localO.x == 1 && localX.y - localO.y == 0; } if (useLabel) { if (_bitmap) { removeChild(_bitmap); _bitmap = null; } _label.visible = true; } else { _label.visible = false; if (!_capturedText || _capturedText.width != unscaledWidth || _capturedText.height != unscaledHeight) { _capturedText = new BitmapData(unscaledWidth, unscaledHeight); if (_bitmap) { removeChild(_bitmap); _bitmap = null; } } if (!_bitmap) { _bitmap = new FlexBitmap(_capturedText); _bitmap.smoothing = true; addChild(_bitmap); } _capturedText.fillRect( new Rectangle(0, 0, unscaledWidth, unscaledHeight), 0); _capturedText.draw(_label); if (parent && parent.rotation == 90 && parent is AxisRenderer) { p = AxisRenderer(parent); if((p.getStyle('verticalAxisTitleAlignment')=="ver tical" && p.layoutDirection == LayoutDirection.LTR) || (p.getStyle('verticalAxisTitleAlignment') == 'flippedVertical' && p.layoutDirection == LayoutDirection.RTL)) { _bitmap.rotation = 180; _bitmap.y = _label.x + _bitmap.height; _bitmap.x = _label.y + _bitmap.width; } } } } } } 其實ChartTitleRenderer.as 是copy了官方的ChartLabel.as ,将其中的代碼改了一點。