// forked from clockmaker's Generation Cluster with Twitter /*===================================================*//** * Generation Cluster with Twitter * ツイッターの世代をグループわけして表示するよ! * * [参加方法] * ボタンをクリックして[]の中に自分の年齢を入れてつぶやくだけ * しばらくすると画面に表示されるよ! * * @author Yasu * @see http://clockmaker.jp/blog/ * @since 2009.09.17 *//*===================================================*/ package { import com.bit101.components.*; import flash.system.LoaderContext; import flash.text.TextField; import flash.utils.Dictionary; import flash.net.*; import flash.ui.*; import flash.display.*; import flash.events.*; import flash.geom.*; import flash.utils.escapeMultiByte; import org.libspark.betweenas3.BetweenAS3; import org.libspark.betweenas3.tweens.ITween; import caurina.transitions.Tweener; [SWF(width="465", height="465", frameRate="60", backgroundColor="0x0")] public class AgeDistribution extends Sprite { // array of objs private var _data:Dictionary = new Dictionary(); /** * Constructor */ public function AgeDistribution() { //stage.align = StageAlign.TOP_LEFT; //stage.scaleMode = StageScaleMode.NO_SCALE; // stage.quality = StageQuality.LOW; var loading:Label = new Label(this, 465 / 2 - 40, 465 / 2, "NOW LOADING"); var tw:ITween = BetweenAS3.tween(loading, { alpha:1 }, { alpha:0.25 }, 0.05); tw = BetweenAS3.serial(tw, BetweenAS3.reverse(tw)); tw.stopOnComplete = false; tw.play(); var textLoader:URLLoader = new URLLoader(); textLoader.addEventListener(Event.COMPLETE, function(e:Event):void { removeChild(loading); tw.stop(); tw = null; default xml namespace = new Namespace("http://www.w3.org/2005/Atom"); var xml:XML = XML(e.target.data); var names:Array = []; trace(xml.entry.length()); myLabel : for (var i:int = 0; i < xml.entry.length(); i++) { var age:int = int(scan(xml.entry[i].title,/\[(.+)\]/)); var name:String = xml.entry[i].author.name; if ( xml.entry[i].title.indexOf("RT") > -1 || //RTを除外 age <= 0 || age >= 99 || //範囲外年齢を除外 names.indexOf(name) != -1 //同一IDは二回目以降を除外 ) continue; names.push(name); if (_data[age] == null) _data[age] = []; var l:int = _data[age].length; while (l--) { if (_data[age][l].name == xml.entry[i].author.name) break myLabel; } _data[age].push({ img : xml.entry[i].link.(@type == "image/png").@href, name : xml.entry[i].author.name, uri : xml.entry[i].author.uri }); } initView(); }); textLoader.load(new URLRequest("http://search.twitter.com/search.atom?q=%23MyAge&rpp=" + 300)); var tweetButton:PushButton = new PushButton(this); tweetButton.label = "Tweet Age!"; tweetButton.x = 465 - tweetButton.width - 10; tweetButton.y = 10 tweetButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void { navigateToURL(new URLRequest("http://twitter.com/home/?status=" + escapeMultiByte("#MyAge [] http://bit.ly/MyAgeFriend") )); }); var title:Label = new Label(this, 8, 0, "Age Distribution with Twitter"); title.scaleX = title.scaleY = 2; var des:Label = new Label(this, 10, 25, "Please click right button. And input your age in []."); } private function initView():void { var ages:Array = []; var maxNum:int = 0; var totalNum:int = 0; var totalAge:int = 0; var num:int; for (var s:String in _data) { ages.push(int(s)); num = _data[s].length; if (maxNum < num) maxNum = num; totalNum += num; totalAge += num * int(s); } ages.sort(); var rect:Rectangle = new Rectangle(40, 100, 360, 320); var minAge:int = ages[0]; var maxAge:int = ages[ages.length - 1]; var agesSpan:int = maxAge - minAge + 1; var ave:Number = totalAge / totalNum; var sp:Shape; var w:Number = rect.width / agesSpan; var h:Number; var g:Graphics; for (var age:int = minAge; age <= maxAge; age++) { var o:Object = _data[age.toString()]; if (o == null) continue; num = o.length; sp = new Shape(); g = sp.graphics; g.beginFill(0xffffff); h = rect.height * 0.9 * num / maxNum; g.drawRect(w*0.1, -h, w*0.8, h); sp.scaleY = 0; sp.x = w * (age - minAge) + rect.left; sp.y = rect.bottom; addChild(sp); var l:Label = new Label(this, sp.x, sp.y, age.toString()); Tweener.addTween(sp, { scaleY:1, time:0.5, transition: "easeOutBack", delay: 0.5 * (age - minAge) / agesSpan }); } sp = new Shape(); g = sp.graphics; g.beginFill(0xff0000); h = rect.height; g.drawRect(-1, -h, 2, h); var angle:Number = Math.PI * 0.3; var destPt:Point = new Point(w * (ave - minAge) + rect.left, rect.bottom); var startPt:Point = Point.polar(700, Math.PI * 2 - angle).add(destPt); sp.x = startPt.x; sp.y = startPt.y; //stage.stageHeight + sp.height; sp.rotation = 90 - angle * 180 / Math.PI; sp.scaleX = sp.scaleY = 20; addChild(sp); Tweener.addTween(sp, { scaleX : 1, scaleY : 1, x : destPt.x, y : destPt.y, time:0.8, delay: 0.8, transition: "easeInQuint", onCompleteScope:this, onComplete : function ():void { sp.scaleX = 4; Tweener.addTween(sp, { scaleX : 1, rotation : 0, time : 0.7, transition: "easeOutBounce", onCompleteScope:this, onComplete : function ():void { var l:Label = new Label(this, sp.x - 40, sp.y - sp.height - 20, "average:" + ave.toFixed(2).toString() + " (total " + totalAge.toString() + " age / " + totalNum.toString() + " person)" ); l.alpha = 0.5; Tweener.addTween(l, { x : sp.x-10, alpha : 1, time : 1 }); } }); } }); } /** * @see http://takumakei.blogspot.com/2009/05/actionscriptrubystringscan.html */ //package com.blogspot.takumakei.utils //{ //public public function scan(str:String, re:RegExp):Array { if(!re.global){ var flags:String = 'g'; if(re.dotall) flags += 's'; if(re.multiline) flags += 'm'; if(re.ignoreCase) flags += 'i'; if(re.extended) flags += 'x'; re = new RegExp(re.source, flags); } var r:Array = []; var m:Array = re.exec(str); while(null != m){ if(1 == m.length) r.push(m[0]); else r.push(m.slice(1, m.length)); m = re.exec(str); } return r; } //} } } AgeDistribution with Twitter