ColumnChartで、選択されたColumnの色を変えるサンプル
デフォルトのままだと、ColumnChartのColumnはデータ系列毎に一色にするしかなく、PieChartのように、選択された箇所だけ動きを変えることができません。ColumnChartで、選択されたColumnの色を変えたくなることがあると思いますが、そのサンプルを紹介します。
このサンプルでは、Sample_Chart.mxml、ColumnChartRenderer.as、EventManager.asの3つのクラスを用意しています。Columnの動きを変えるために、まずはColumnSeriesにItemRendererを指定します。
問題はRendererクラスと、Chartをどう連動させるかなんですが、EventManagerというシングルトンクラスを用意しました。ChartのItemClickイベントをEventManagerを踏み台にしてdispatchさせます。Rendererクラスでは、このEventManagerにListenerをセットしておき、イベントが渡ってきたら、自身が持つColumnSeriesItemオブジェクトと、イベントに格納されているhitData.chartItemと一致確認を行い、挙動を変えます。
この別クラス経由でのやりとりというのが微妙なんですが、一番スマートなやり方じゃないかな・・・と。他にいい案があったら是非ご教示ください。
以下サンプルソースです。
Sample_Chart.mxml
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" applicationComplete="initApp();" pageTitle="ColumnChart"> <mx:Script> <![CDATA[ import managers.EventManager; import mx.collections.ArrayCollection; [Bindable] private var peakData:ArrayCollection = new ArrayCollection(); private function initApp():void { for(var i:int=0; i<30; i++) { var obj:Object = new Object(); obj.yyyymmdd = 20000000 + i; obj.count = i; peakData.addItem(obj); } } ]]> </mx:Script> <mx:ColumnChart id="peakChart" width="100%" height="100%" dataProvider="{peakData}" showDataTips="true" itemClick="EventManager.getInstance().dispatchEvent(event)"> <mx:horizontalAxis> <mx:CategoryAxis id="ca" categoryField="yyyymmdd" dataProvider="{peakData}" /> </mx:horizontalAxis> <mx:series> <mx:ColumnSeries id="peakColumnSeries" xField="yyyymmdd" yField="count" displayName="count" showDataEffect="rearrangeData" itemRenderer="renderer.ColumnChartRenderer" > <mx:fill> <mx:SolidColor color="#ffff99"/> </mx:fill> </mx:ColumnSeries> </mx:series> </mx:ColumnChart> </mx:Application>
ColumnChartRenderer.as
package renderer { import flash.display.Graphics; import managers.EventManager; import mx.charts.events.ChartItemEvent; import mx.charts.series.items.ColumnSeriesItem; import mx.core.IDataRenderer; import mx.skins.ProgrammaticSkin; public class ColumnChartRenderer extends ProgrammaticSkin implements IDataRenderer { private var color:uint = 0xffff99; private var _chartItem:ColumnSeriesItem; public function ColumnChartRenderer() { EventManager.getInstance().addEventListener(ChartItemEvent.ITEM_CLICK,chartItemClickHandler); } private function chartItemClickHandler(e:ChartItemEvent):void { if(this._chartItem == e.hitData.chartItem) { color = 0xFFAE00; invalidateDisplayList(); } else { color = 0xffff99; invalidateDisplayList(); } } public function get data():Object { return _chartItem; } public function set data(value:Object):void { _chartItem = value as ColumnSeriesItem; } override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { super.updateDisplayList(unscaledWidth, unscaledHeight); var g:Graphics = graphics; g.clear(); g.beginFill(color); g.drawRect(0,0,unscaledWidth,unscaledHeight); g.endFill(); } }//end of class }//end of package
EventManager.as
package managers { import flash.events.EventDispatcher; public class EventManager extends EventDispatcher { /** * インスタンス生成判定フラグ **/ private static var inside:Boolean = false; /** * GyomuManagerオブジェクト **/ private static var instance:EventManager = null; public function EventManager() { if(inside) { inside=false; } else { throw new Error("UseSingleton.geInstance() to get the instance"); } } public static function getInstance():EventManager { if(instance==null) { inside = true; instance = new EventManager(); } return instance; } }//end of class }//end of package