forked from: Moving Treemap
Added animation.
/**
* Copyright hacker_ihh94j05 ( http://wonderfl.net/user/hacker_ihh94j05 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/34QJ
*/
// forked from 7to3's Moving Treemap
// forked from 7to3's Treemap
// Added animation.
package
{
import flash.display.*;
import flash.filters.*;
import flash.utils.*;
import flash.text.*;
import flash.net.*;
import flash.system.*;
import caurina.transitions.Tweener;
[SWF(backgroundColor="0xFFFFFF")]
public class Treemap extends Sprite
{
private var _source:Vector.<Data>;
private var _maxAlpha:Number;
private const LINE_COLOR:uint = 0x666666;
private const RECT_COLOR:uint = 0x66FF33;
private const LETTER_COLOR:uint = 0xFFFFFF;
private const LETTER_BG_COLOR:uint = 0x000000;
// For animation
private var _count:uint;
public function Treemap() {
_createDataSource();
// 色決定用に、最大値を取得しておく。
_maxAlpha = 0;
for each (var data:Data in _source)
{
if (data.price > _maxAlpha)
{
_maxAlpha = data.price;
}
}
// 描画コマンドを格納するリストを準備。
_count = 0; // delay 計算用。
// 分割開始。
_splitMap(_source, 20, 20, stage.stageWidth - 40, stage.stageHeight - 40);
}
// データソースを作成。
private function _createDataSource():void
{
_source = Vector.<Data>([
new Data("test1", 20, 1000),
new Data("test2", 20, 1200),
new Data("test3", 70, 800),
new Data("test4", 20, 600),
new Data("test5", 20, 700),
new Data("test6", 20, 100),
new Data("test7", 20, 700),
]);
// データソースをソート。
_source.sort(function(a:Data, b:Data):int
{
if (a.amount > b.amount)
{
return -1;
}
else if (a.amount == b.amount)
{
return 0;
}
else
{
return 1;
}
});
}
// 領域を分割。
private function _splitMap(target:Vector.<Data>, x:Number, y:Number, w:Number, h:Number, drawNum:uint = 2):void
{
if (target.length <= 0)
{
return;
}
if (target.length < drawNum)
{
drawNum = target.length;
}
// 分割の比率を計算。
var drawings:Vector.<Data> = target.splice(0, drawNum);
var drawingAmount:Number = 0;
for each (var drawing:Data in drawings)
{
drawingAmount += drawing.amount;
}
var otherAmount:Number = 0;
for each (var other:Data in target)
{
otherAmount += other.amount;
}
var rate:Number = drawingAmount / (drawingAmount + otherAmount);
// Draw targets
var temp:Number = 0;
var targetW:Number = w, targetH:Number = h;
var otherW:Number = w, otherH:Number = h;
if (w > h)
{
targetW = w * rate;
otherW = w * (1 - rate);
}
else
{
targetH = h * rate;
otherH = h * (1 - rate);
}
// 描画。
for each (drawing in drawings)
{
var innerRate:Number = drawing.amount / drawingAmount;
if (targetW < targetH)
{
// 縦方向に描画。
_drawMap(drawing, x, y + temp, targetW, targetH * innerRate, false);
temp += targetH * innerRate;
}
else
{
// 横方向に描画。
_drawMap(drawing, x + temp, y, targetW * innerRate, targetH, true);
temp += targetW * innerRate;
}
}
// 残りを分割
if (w > h)
{
// 横方向に分割した場合
_splitMap(target, x + w * rate, y, otherW, otherH);
}
else
{
// 縦方向に分割した場合
_splitMap(target, x, y + h * rate, otherW, otherH);
}
}
// 領域と文字を描画。
private function _drawMap(data:Data, x:Number, y:Number, w:Number, h:Number, vertical:Boolean = true):void
{
var rect:Sprite = new Sprite();
rect.graphics.lineStyle(1, LINE_COLOR);
rect.graphics.beginFill(RECT_COLOR, 0.8 * data.price / _maxAlpha);
rect.graphics.drawRect(0, 0, w, h);
rect.graphics.endFill();
rect.x = x;
rect.y = y;
var format:TextFormat = new TextFormat();
format.color = 0xFFFFFF;
var field:TextField = new TextField();
field.defaultTextFormat = format;
field.autoSize = TextFieldAutoSize.LEFT;
field.x = x + 5;
field.y = y + 5;
field.text = data.name;
// field.filters = [new DropShadowFilter(0, 0, 0x000000, 0.5, 5, 5, 3)];
var back:Sprite = new Sprite();
back.graphics.lineStyle();
back.graphics.beginFill(0x000000, 0.5);
back.graphics.drawRect(field.x, field.y - 1, field.textWidth + 4, field.textHeight + 3);
back.graphics.endFill();
addChild(rect);
addChild(back);
addChild(field);
// 分割方向に応じたアニメーションを設定。
if (!vertical)
{
rect.scaleY = 0;
Tweener.addTween(rect, {time:1, delay: 0.5 * _count, scaleY:1, transition:"easeOutBounce"});
}
else
{
rect.scaleX = 0;
Tweener.addTween(rect, {time:1, delay: 0.5 * _count, scaleX:1, transition:"easeOutBounce"});
}
_count ++;
}
}
}
// 描画対象のデータを格納するクラス。
class Data
{
public var name:String;
public var amount:Number;
public var price:Number
public function Data(name:String, amount:Number, price:Number)
{
this.name = name;
this.amount = amount;
this.price = price;
}
}