思路分爲以下:三步:
1:創建SolidChart組件,像製作二維圖表一樣正常顯示數據部分。
2:自定義ColumnChart的ItemRenderer項呈示器,並指定ColumnSeries的itemRenderer屬性爲剛自定義的項項呈示器。
3:創建MXML應用程序,將剛製作好的ColumnChart組件放入顯示。
這樣自定義組件,也是爲了以後可以複用的考慮。
項目目錄結構如下:前面點紅色部分是本例所能使用到的。
第一步:創建SolidChart.組件,代碼如下:commponent.chart/SolidChart.MXML
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fx="http://ns.adobe.com/mxml/2009"
width="100%"
height="100%"
title="{Title}"
layout="absolute"
>
<fx:Script>
<![CDATA[
import itemRender.histogramSkin;
import mx.charts.chartClasses.CartesianCanvasValue;
import mx.charts.events.ChartItemEvent;
import mx.charts.events.LegendMouseEvent;
import mx.charts.renderers.BoxItemRenderer;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import mx.graphics.codec.JPEGEncoder;
[Bindable]
public var expenses:ArrayCollection; //數據集合
[Bindable]
private var Title:String; //Panel頭部信息
public function init(datas:ArrayCollection,title:String):void{
expenses = new ArrayCollection();
Title = title; //初始化Panel頭部信息
expenses = datas; //初始化表的數據集合
}
protected function legend1_itemMouseDownHandler(event:LegendMouseEvent):void
{
var index:int=-1;
for(var i:int=0;i<myChart.series.length;i++){
if(event.item.label==myChart.series[i].displayName){
index=i;
}
myChart.series[i].visible=false;
}
myChart.series[index].visible=true;
}
]]>
</fx:Script>
<fx:Declarations>
<fx:Array id="fillcolor">
<s:SolidColor color="#EF7651" alpha="0.5"/>
<s:SolidColor color="#E9C836" alpha="0.6" />
<s:SolidColor color="#6FB35F" alpha="0.7" />
<s:SolidColor color="#A1AECF" alpha="0.8" />
<s:SolidColor color="green" alpha="0.9" />
</fx:Array>
<mx:SeriesSlide id="SlideIn" direction="up" duration="3000"/>
<mx:SeriesSlide id="SlideOut" direction="down" duration="1000"/>
</fx:Declarations>
<mx:ColumnChart id="myChart"
horizontalCenter="true"
fontSize="13.5"
dataProvider="{expenses}"
showDataTips="true"
textAlign="center"
width="95%"
height="100%"
>
<mx:horizontalAxis>
<mx:CategoryAxis categoryField="name"
displayName="動畫名稱"
title="動畫名稱"/>
</mx:horizontalAxis>
<mx:verticalAxis>
<mx:LinearAxis title="數量"
autoAdjust="true"
alignLabelsToInterval="true"
computedMaximum="800"
displayName="數量"
interval="100"
maximum="800"
/>
</mx:verticalAxis>
<mx:series>
<mx:ColumnSeries displayName="人氣指數" yField="hot" itemRenderer="itemRender.solidSkin"
showDataEffect="{SlideIn}" showEffect="{SlideIn}"
/>
<mx:ColumnSeries displayName="劇場版數" yField="theatre" itemRenderer="itemRender.solidSkin"
showDataEffect="{SlideIn}" showEffect="{SlideIn}"
/>
<mx:ColumnSeries displayName="已出集數" yField="blues" itemRenderer="itemRender.solidSkin"
showDataEffect="{SlideIn}" showEffect="{SlideIn}"
/>
<mx:ColumnSeries displayName="好評度" yField="rating" itemRenderer="itemRender.solidSkin"
showDataEffect="{SlideIn}" showEffect="{SlideIn}"
/>
<mx:ColumnSeries displayName="發展趨勢" yField="trends" itemRenderer="itemRender.solidSkin"
showDataEffect="{SlideIn}" showEffect="{SlideIn}"
/>
</mx:series>
</mx:ColumnChart>
<mx:Legend id="legend1"
right="40" top="30" height="151"
dataProvider="{myChart}"
toolTip="點擊圖例名稱可只顯示
一個相應欄目"
itemClick="legend1_itemMouseDownHandler(event)"
/>
</mx:Panel>
第二部,因爲柱狀圖ColumnChart組件的默認呈示器BoxItemRenderer是二維畫圖的,所以在此需要自定義項呈示器solidSkin。itemRender/solidSkin.MXML。代碼如下:
//自定義柱狀圖的外觀類——實現立方效果
package itemRender
{
import flash.display.Graphics;
import flash.geom.Point;
import flash.geom.Rectangle;
import mx.charts.ChartItem;
import mx.charts.chartClasses.GraphicsUtilities;
import mx.charts.series.ColumnSeries;
import mx.charts.series.items.ColumnSeriesItem;
import mx.collections.ArrayCollection;
import mx.controls.Text;
import mx.core.IDataRenderer;
import mx.graphics.IFill;
import mx.graphics.IStroke;
import mx.graphics.SolidColor;
import mx.skins.ProgrammaticSkin;
import mx.utils.ColorUtil;
import spark.primitives.Graphic;
//ProgrammaticSkin是外觀元素的基類,他們通過編程方式繪製自身。
public class solidSkin extends ProgrammaticSkin implements IDataRenderer
{
//data屬性表示要呈示或編輯的數據,在這裏指chartItem,柱狀圖的一列
private var _data:Object;
//創建柱狀圖的一列
private var _chartItem:ColumnSeriesItem;
//構造函數
public function solidSkin()
{
super();
}
public function get data():Object
{
return Object(_chartItem);
}
public function set data(value:Object):void
{
_chartItem = value as ColumnSeriesItem;
//標記組件,以便在稍後屏幕更新期間調用該組件的 updateDisplayList() 方法。
invalidateDisplayList();
}
//從ProgramaticSkin繼承的方法,通過編程方式繪製自身
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth,unscaledHeight);
//清除畫布
this.graphics.clear();
//得到立方圖的8個點座標
var points:Array = getPoints(unscaledWidth*0.65,unscaledHeight);
//柱狀圖展示,只需要3面就可,畫3個矩形即可。
drawFill(points[4],points[7],points[6],points[5]);
drawFill(points[6],points[2],points[3],points[7]);
drawFill(points[7],points[4],points[0],points[3]);
this.graphics.endFill();
}
//根據長寬計算8點座標信息
protected function getPoints(w:Number,h:Number):Array
{
var points:Array = new Array(8);
points[0] = new Point(0,h);
points[1] = new Point(w,h);
points[2] = new Point(w,0);
points[3] = new Point(0,0);
points[4] = new Point(0+w/2.0,h+w/2.0);
points[5] = new Point(w+w/2.0,h+w/2.0);
points[6] = new Point(w+w/2.0,0+w/2.0);
points[7] = new Point(0+w/2.0,0+w/2.0);
return points;
}
//根據傳入的座標信息,繪製線條及填充繪製區域
protected function drawFill(...args):void
{
var fill:IFill;//定義執行填充的類必須實現的接口。
var state:String = "";//定義當前組件的視圖狀態
//以下代碼爲默認項呈示器的內容,用來判斷每個系列的顏色,
if (_data is ChartItem && _data.hasOwnProperty('fill'))
{
state = _data.currentState;
fill = _data.fill;
}
else{
fill = GraphicsUtilities.fillFromStyle(getStyle('fill'));
}
var color:uint;
var adjustedRadius:Number = 0;
switch (state)
{
case ChartItem.FOCUSED:
case ChartItem.ROLLOVER:
if (styleManager.isValidStyleValue(getStyle('itemRollOverColor')))
color = getStyle('itemRollOverColor');
else
color = ColorUtil.adjustBrightness2(GraphicsUtilities.colorFromFill(fill),-20);
fill = new SolidColor(color);
adjustedRadius = getStyle('adjustedRadius');
if (!adjustedRadius)
adjustedRadius = 0;
break;
case ChartItem.DISABLED:
if (styleManager.isValidStyleValue(getStyle('itemDisabledColor')))
color = getStyle('itemDisabledColor');
else
color = ColorUtil.adjustBrightness2(GraphicsUtilities.colorFromFill(fill),20);
fill = new SolidColor(GraphicsUtilities.colorFromFill(color));
break;
case ChartItem.FOCUSEDSELECTED:
case ChartItem.SELECTED:
if (styleManager.isValidStyleValue(getStyle('itemSelectionColor')))
color = getStyle('itemSelectionColor');
else
color = ColorUtil.adjustBrightness2(GraphicsUtilities.colorFromFill(fill),-30);
fill = new SolidColor(color);
adjustedRadius = getStyle('adjustedRadius');
if (!adjustedRadius)
adjustedRadius = 0;
break;
}
var stroke:IStroke = getStyle("stroke");
var w:Number = stroke ? stroke.weight / 2 : 0;
var rc:Rectangle = new Rectangle(w - adjustedRadius, w - adjustedRadius, width - 2 * w + adjustedRadius * 2, height - 2 * w + adjustedRadius * 2);
var g:Graphics = graphics;
if (stroke)
stroke.apply(g,null,null);
if (fill)
fill.begin(g,rc,null);
g.moveTo(args[0].x,args[0].y);
for(var i:int=1;i<args.length;i++)
{
g.lineTo(args[i].x,args[i].y);
}
}
}
}
第三步,創建應用程序,顯示第一步自定義的組件SolidChart.代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:chart="component.chart.*"
creationComplete="init()">
<fx:Style source="css/Chart3D.css"/>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
[Bindable]
public var funs:ArrayCollection=new ArrayCollection([//創建數據集合
{name:"海賊王",hot:90,theatre:110,blues:482,rating:90,trends:100},
{name:"死神",hot:60,theatre:120,blues:230,rating:460,trends:570},
{name:"火影忍者",hot:80,theatre:413,blues:520,rating:80,trends:340},
{name:"柯南",hot:250,theatre:340,blues:600,rating:370,trends:430}
]);//傳入數據源,顯示柱狀圖
protected function init():void {
chart1.init(funs,"柱狀圖——立方圖");
}
]]>
</fx:Script>
<chart:SolidChart id="chart1" x="-4" y="3"/>
</s:Application>
最終效果如圖: