In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Treemap

/**
 * Copyright 7to3 ( http://wonderfl.net/user/7to3 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/qZyx
 */

package
{
    import flash.display.*;
    import flash.filters.*;
    import flash.utils.*;
    import flash.text.*;
    import flash.net.*;
    import flash.system.*;
    
    [SWF(backgroundColor="0xFFFFFF")]
    public class Treemap extends Sprite
    {
        private var _source:Vector.<Data>;
        private var _maxAlpha:Number;
        private const LINE_COLOR:uint = 0x000000;
        private const RECT_COLOR:uint = 0xFF3344;
        private const LETTER_COLOR:uint = 0xFFFFFF;
        private const LETTER_BG_COLOR:uint = 0x000000;
                
        public function Treemap() {
            _createDataSource();
            
            // 色決定用に、最大値を取得しておく。
            _maxAlpha = 0;
            for each (var data:Data in _source)
            {
                if (data.price > _maxAlpha)
                {
                    _maxAlpha = data.price;
                }
            }
            
            // 分割、描画開始。
            _splitMap(_source, 20, 20, stage.stageWidth - 40, stage.stageHeight - 40);
        }
        
        // データソースを作成。
        private function _createDataSource():void
        {
            _source = Vector.<Data>([
                new Data("ラーメン", 120, 1000),
                new Data("カレー", 89, 1200),
                new Data("餅", 70, 800),
                new Data("お好み焼き", 45, 600),
                new Data("白米", 32, 700),
                new Data("そば", 24, 100),
                new Data("ハヤシライス", 16, 700),
                new Data("もやし", 800, 240)
            ]);
            
            // データソースをソート。
            _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 = 1):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);
                    temp += targetH * innerRate;
                }
                else
                {
                    // 横方向に描画。
                    _drawMap(drawing, x + temp, y, targetW * innerRate, targetH);
                    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):void
        {
            var rect:Sprite = new Sprite();
            var g:Graphics = rect.graphics;
            g.lineStyle(1, LINE_COLOR);
            g.beginFill(RECT_COLOR, 0.8 * data.price / _maxAlpha);
            g.drawRect(x, y, w, h);
            g.endFill();
            
            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)];
            
            g.lineStyle();
            g.beginFill(0x000000, 0.5);
            g.drawRect(field.x, field.y - 1, field.textWidth + 4, field.textHeight + 3);
            g.endFill();
            
            addChild(rect);
            addChild(field);
        }
    }
}

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;
    }
}