【转】flex piechart 钻取的实现 .

   sdk:flex 3.2

    flex piechart钻取的实现,其实钻取的实现本质是:当单击(或双击)的时候,重新加载piechart的数据,并且加点动画效果,这样感觉就像实现了钻取。本文是双击向下钻取,单击向上钻取


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
xmlns:effects="jac.*"
layout="vertical" verticalAlign="top"
horizontalAlign="center" backgroundGradientColors="[0x000000,0x323232]" paddingTop="0" viewSourceURL="srcview/index.html">

<mx:Script>
<![CDATA[

import mx.collections.ArrayCollection;
import mx.charts.events.ChartItemEvent;
import mx.controls.Alert;
import com.adobe.serialization.json.JSON;
import mx.charts.series.items.ColumnSeriesItem; 
[Bindable]
private var medalsAC:ArrayCollection = new ArrayCollection( [
{ Country: "USA", Gold: 35, Silver:39, Bronze: 29 },
{ Country: "China", Gold: 32, Silver:17, Bronze: 14 },
{ Country: "Russia", Gold: 27, Silver:27, Bronze: 38 } ]);

private var downArray:ArrayCollection = new ArrayCollection([
{ Country: "California",Gold:23.3},
{ Country: "Japan",Gold:23.4},
{ Country: "South Korea",Gold:33.3},
{ Country: "England",Gold:20}]);
private function displayGold(data:Object, field:String, index:Number, percentValue:Number):String {
var temp:String= (" " + percentValue).substr(0,6);
return data.Country + ": " + '/n' + "Total Gold: " + data.Gold + '/n' + temp + "%";
}
private function pieItemClick(evt:ChartItemEvent):void{
// Alert.show(""+JSON.encode(evt.hitSet),"tips");
var arr:Array = [];
arr[evt.hitData.chartItem.index] = 0.2;
series.perWedgeExplodeRadius=arr;
// chart.perWedgeExplodeRadius=arr;
}
private function pieItemDBClick(evt:ChartItemEvent):void{//drilldown
// Alert.show("ds","tips");
chart.showDataTips = false;
series.setStyle("showDataEffect", drillDownEffect);
chart.dataProvider=downArray;

chart.removeEventListener(ChartItemEvent.ITEM_DOUBLE_CLICK,pieItemDBClick);
chart.addEventListener(MouseEvent.CLICK, drillUp);
}
private function drillUp(event:MouseEvent):void{
chart.showDataTips = false;
series.setStyle("showDataEffect",drillUpEffect);
chart.dataProvider=medalsAC;

chart.addEventListener(ChartItemEvent.ITEM_DOUBLE_CLICK,pieItemDBClick);
chart.removeEventListener(MouseEvent.CLICK,drillUp);
}
//piechart钻取(drilldown或者drillup,本质是数据的重新加载)
]]>
</mx:Script>








向下钻取效果的实现-  DrillDownEffect.as


package jac
{
import mx.charts.effects.SeriesEffect;
import mx.effects.IEffectInstance;
import mx.effects.TweenEffect;

public class DrillDownEffect extends TweenEffect
{
public function DrillDownEffect(target:Object = null)
{
super(target);
instanceClass = DrillDownEffectInstance;
} 

public var drillFromIndex:Number = 0;
public var splitDirection:String = "vertical";


override protected function initInstance(inst:IEffectInstance):void
{
super.initInstance(inst);

DrillDownEffectInstance(inst).drillFromIndex = drillFromIndex;
DrillDownEffectInstance(inst).splitDirection = splitDirection;
}

}
}

import mx.charts.effects.effectClasses.SeriesEffectInstance;
import mx.charts.chartClasses.RenderData;
import flash.geom.Rectangle;
import mx.effects.effectClasses.TweenEffectInstance;
import mx.charts.chartClasses.Series;


class DrillDownEffectInstance extends TweenEffectInstance
{
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------

/**
* Constructor.
*/
public function DrillDownEffectInstance(target:Object)
{
super(target);
}

public var drillFromIndex:Number;
public var splitDirection:String;
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------

/**
* @private
*/
private var _startingBounds:Rectangle;
private var _state:String = "";

/**
* @private
*/
private var dstRenderData:RenderData;
private var srcRenderData:RenderData;
private var targetBounds:Array;


//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------

/**
* @private
*/
override public function play():void
{
var targetSeries:Series = Series(target);

srcRenderData = RenderData(targetSeries.getRenderDataForTransition("hide")); 
dstRenderData = RenderData(targetSeries.getRenderDataForTransition("show"));

targetSeries.getElementBounds(srcRenderData);
targetSeries.getElementBounds(dstRenderData);



if(drillFromIndex >= srcRenderData.elementBounds.length)
drillFromIndex = 0;

var dstCount:Number= dstRenderData.elementBounds.length;
var srcCount:Number = srcRenderData.elementBounds.length;
if(drillFromIndex < srcRenderData.elementBounds.length)
{
_startingBounds = srcRenderData.elementBounds[drillFromIndex].clone();

targetBounds = []; 
for(var i:int = 0;i<dstCount;i++)
{
targetBounds[i] = dstRenderData.elementBounds[i].clone();
}
for(i= 0;i<srcCount;i++)
{
dstRenderData.elementBounds[i] = srcRenderData.elementBounds[i].clone();
}
}
else
{
_startingBounds = null;
} 

targetSeries.transitionRenderData = srcRenderData;
targetSeries.invalidateDisplayList();
_state = "hiding";

// Create a tween to move the object
tween = createTween(this, [ 0 ],
[ 1 ], duration);
}

/**
* @private
*/
override public function onTweenUpdate(values:Object):void 
{ 
var targetSeries:Series = Series(target);

super.onTweenUpdate(values);

var value:Number = values[0];

if(_startingBounds == null)
return;


var targetBounds:Array = targetBounds;
var n:int;

var i:int;
var interpolation:Number;
var v:Rectangle;


interpolation = Math.min(1,value/.1);

if(_state == "hiding")
{
n = srcRenderData.filteredCache.length;
for (i = 0; i < n; i++)
{
interpolation = value/.1;
if(i != drillFromIndex)
srcRenderData.filteredCache[i].itemRenderer.alpha = (1-interpolation);
}
if(value >= .1)
{
_state = "holding"; 
n = srcRenderData.filteredCache.length;
for (i = 0; i < n; i++)
{
srcRenderData.filteredCache[i].itemRenderer.alpha = 1;
}
targetSeries.transitionRenderData = dstRenderData;
targetSeries.validateNow();
layoutDestination(0);
}
}
if (_state == "holding")
{
if(value >= .5)
{
_state = "splitting";
}
}

if(_state == "splitting")
{
interpolation = Math.max(value-.5,0)/.5;
layoutDestination(interpolation);
}

targetSeries.invalidateDisplayList();
}
private function layoutDestination(interpolation:Number):void
{
var n:Number = dstRenderData.filteredCache.length;
var startWidth:Number;
var startHeight:Number;
var activeBounds:Array = dstRenderData.elementBounds;
var a:Rectangle;
var vInterpolation:Number;
var hInterpolation:Number;
var target:Rectangle;
var startLeft:Number;
var wDelta:Number;
var hDelta:Number;
var lDelta:Number;
var tDelta:Number;
var newWidth:Number;
var newHeight:Number;
var startTop:Number;

var i:int;
if(splitDirection == "vertical")
{
startWidth = _startingBounds.width / n;
startHeight = _startingBounds.height;

vInterpolation = Math.pow(interpolation,4);
hInterpolation = Math.pow(interpolation,2);

for (i = 0; i < n; i++)
{
startLeft = _startingBounds.left + startWidth * i; 

target = targetBounds[i];
a = activeBounds[i];
wDelta = target.width - startWidth;
hDelta = target.height - startHeight;
lDelta = target.left - startLeft;
tDelta = target.top - _startingBounds.top;

newWidth = startWidth + wDelta * hInterpolation;
newHeight = startHeight + hDelta * vInterpolation;

a.left = startLeft + lDelta * hInterpolation;
a.right = a.left + newWidth;
a.top = _startingBounds.top + tDelta * vInterpolation;
a.bottom = a.top + newHeight;
}
}
else
{
startWidth = _startingBounds.width;
startHeight = _startingBounds.height / n;
startLeft = _startingBounds.left;


vInterpolation = Math.pow(interpolation,4);
hInterpolation = Math.pow(interpolation,2/3);

for (i= 0; i < n; i++)
{
startTop = _startingBounds.top + startHeight * i; 

target = targetBounds[i];
a = activeBounds[i];
wDelta = target.width - startWidth;
hDelta = target.height - startHeight;
lDelta = target.left - startLeft;
tDelta = target.top - startTop;

newWidth = startWidth + wDelta * hInterpolation;
newHeight = startHeight + hDelta * vInterpolation;

a.left = startLeft + lDelta * hInterpolation;
a.right = a.left + newWidth;
a.top = startTop + tDelta * vInterpolation;
a.bottom = a.top + newHeight;
}
}
}
}




向上钻取的实现,类似于向下钻取-  DrillUpEffect.as



package jac
{
import mx.charts.effects.SeriesEffect;
import mx.effects.IEffectInstance;
import mx.effects.TweenEffect;

public class DrillUpEffect extends TweenEffect
{
public function DrillUpEffect(target:Object = null)
{
super(target);
instanceClass = DrillUpEffectInstance;
} 
public var drillToIndex:Number = 0;


override protected function initInstance(inst:IEffectInstance):void
{
super.initInstance(inst);

DrillUpEffectInstance(inst).drillToIndex = drillToIndex;
}

}
}

import mx.charts.effects.effectClasses.SeriesEffectInstance;
import mx.charts.chartClasses.RenderData;
import flash.geom.Rectangle;
import mx.effects.effectClasses.TweenEffectInstance;
import mx.charts.chartClasses.Series;


class DrillUpEffectInstance extends TweenEffectInstance
{
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------

/**
* Constructor.
*/
public function DrillUpEffectInstance(target:Object)
{
super(target);
}

public var drillToIndex:Number;
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------

/**
* @private
*/
private var _drillBounds:Rectangle;
private var _state:String = "";

/**
* @private
*/
private var dstRenderData:RenderData;
private var srcRenderData:RenderData;
private var targetBounds:Array;


//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------

/**
* @private
*/
override public function play():void
{
var targetSeries:Series = Series(target);

srcRenderData = RenderData(targetSeries.getRenderDataForTransition("hide")); 
dstRenderData = RenderData(targetSeries.getRenderDataForTransition("show"));

targetSeries.getElementBounds(srcRenderData);
targetSeries.getElementBounds(dstRenderData);



if(drillToIndex >= srcRenderData.elementBounds.length)
drillToIndex = 0;

var dstCount:Number= dstRenderData.elementBounds.length;
var srcCount:Number = srcRenderData.elementBounds.length;
if(drillToIndex < srcRenderData.elementBounds.length)
{
_drillBounds = dstRenderData.elementBounds[drillToIndex].clone();

targetBounds = []; 
for(var i:int = 0;i<srcCount;i++)
{
targetBounds[i] = srcRenderData.elementBounds[i].clone();
}
}
else
{
_drillBounds = null;
} 

targetSeries.transitionRenderData = srcRenderData;
targetSeries.invalidateDisplayList();
_state = "merging";

// Create a tween to move the object
tween = createTween(this, [ 0 ],
[ 1 ], duration);
}

/**
* @private
*/
override public function onTweenUpdate(values:Object):void 
{ 
var targetSeries:Series = Series(target);

super.onTweenUpdate(values);

var value:Number = values[0];

if(_drillBounds == null)
return;


var targetBounds:Array = targetBounds;
var n:int;
var i:int;
var interpolation:Number;
var v:Rectangle;



if(_state == "merging")
{
n = srcRenderData.filteredCache.length;
interpolation = value/.5;
layoutDestination(interpolation);
if(value >= .5)
{
_state = "holding"; 
targetSeries.transitionRenderData = dstRenderData;
targetSeries.invalidateDisplayList();
targetSeries.validateNow();

n = dstRenderData.filteredCache.length;
for (i = 0; i < n; i++)
{
if(i != drillToIndex)
dstRenderData.filteredCache[i].itemRenderer.alpha = 0;
else
dstRenderData.filteredCache[i].itemRenderer.alpha = 1;
}
}
}
if (_state == "holding")
{
if(value >= .9)
{
_state = "showing";
}
}

if(_state == "showing")
{
interpolation = Math.max(value-.9,0)/.1;
n = dstRenderData.filteredCache.length;
for (i = 0; i < n; i++)
{
if(i == drillToIndex)
dstRenderData.filteredCache[i].itemRenderer.alpha = 1;
else
dstRenderData.filteredCache[i].itemRenderer.alpha = interpolation;
}
}

targetSeries.invalidateDisplayList();
}

private function layoutDestination(interpolation:Number):void
{
var n:Number = srcRenderData.filteredCache.length;
var endWidth:Number = _drillBounds.width / n;
var endHeight:Number = _drillBounds.height;
var activeBounds:Array = srcRenderData.elementBounds;
var a:Rectangle;

var verticalInterpolation:Number = Math.pow(interpolation,1/4);

for (var i:int = 0; i < n; i++)
{
var endLeft:Number = _drillBounds.left + endWidth * i; 

var itemBounds:Rectangle = targetBounds[i];
a = activeBounds[i];
var wDelta:Number = endWidth - itemBounds.width;
var hDelta:Number = endHeight - itemBounds.height;
var lDelta:Number = endLeft - itemBounds.left;
var tDelta:Number = _drillBounds.top - itemBounds.top;

var newWidth:Number = itemBounds.width + wDelta * interpolation;
var newHeight:Number = itemBounds.height + hDelta * verticalInterpolation;

a.left = itemBounds.left + lDelta * interpolation;
a.right = a.left + newWidth;
a.top = itemBounds.top + tDelta * verticalInterpolation;
a.bottom = a.top + newHeight;
}
}
}

你可能感兴趣的:(chart)