package { import com.adobe.serialization.json.JSON; import flash.events.MouseEvent; import flare.animate.*; import flare.display.TextSprite; import flare.util.palette.ColorPalette; import flare.data.DataSet; import flare.data.DataSource; import flare.scale.ScaleType; import flare.vis.Visualization; import flare.vis.data.*; import flare.vis.operator.encoder.ColorEncoder; import flare.vis.operator.encoder.ShapeEncoder; import flare.vis.operator.encoder.PropertyEncoder; import flare.vis.operator.layout.AxisLayout; import flare.vis.legend.*; import flare.vis.events.SelectionEvent; import flare.vis.controls.ClickControl; import flare.vis.controls.HoverControl; import flare.vis.controls.TooltipControl; import flare.vis.events.TooltipEvent; import flare.vis.operator.distortion.*; import flare.vis.data.NodeSprite; import flare.vis.controls.AnchorControl; import flare.vis.operator.layout.Layout; import flare.vis.operator.filter.*; import flare.util.Shapes; import flare.vis.controls.PanZoomControl; import flash.text.TextField; import flash.text.TextFormat; import flash.utils.Dictionary; import flash.display.Sprite; import flash.events.Event; import flash.geom.Rectangle; import flash.net.URLLoader; import flash.external.*; import flash.display.Shape; import flare.util.*; import flash.filters.DropShadowFilter; import com.blitzagency.xray.inspector.Xray; import com.blitzagency.xray.logger.XrayLog; [SWF(width="1100", height="450", backgroundColor="#ffffff", frameRate="30")] public class WordTrends extends Sprite{ [Embed(source="verdana.TTF", fontName="Verdana")] private static var _font:Class; private var vis:Visualization; private var words:Array = new Array(); private var _detail:TextSprite; private var _shown:Array = new Array(); private var axisLayout:AxisLayout; private var labelMask:Shape = new Shape(); private var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; public var xray:Xray = new Xray(); public var log:XrayLog = new XrayLog(); public function WordTrends(){ //addChild(xray); var data = getTimeline(); visualize(data); } private function visualize(data:Data):void{ vis = new Visualization(data); vis.bounds = new Rectangle(0, 0, 850, 300); var offsetX = 150; var offsetY = 10; vis.x = offsetX; vis.y = offsetY; addChild(vis); var fmt:TextFormat = new TextFormat("Verdana", 12, 0x000000); vis.operators.add(new AxisLayout("data.date", "data.count")); var colPal = ColorPalette.category(); vis.operators.add(new ColorEncoder("data.series", Data.NODES, "fillColor", ScaleType.CATEGORIES, colPal)); vis.operators.add(new ColorEncoder("data.series", Data.EDGES, "lineColor", ScaleType.CATEGORIES, colPal)); vis.operators.add(new PropertyEncoder({lineWidth:2}, Data.EDGES)); vis.operators.add(new PropertyEncoder({lineColor: 0xffffffff, lineWidth:1, size:0.5}, Data.NODES)); var distort = new FisheyeDistortion(3,3,0); //var distort = new BifocalDistortion(0.1, 3, 0.1, 3); distort.distortSize = false; distort.enabled = false; vis.operators.add(distort); vis.controls.add(new AnchorControl(distort as Layout)); var show:Link = new Link("Toggle Magnifier"); show.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void{ vis.operators[5].enabled = (vis.operators[5].enabled == false); update(new Transitioner(1)); }); show.x = 20; show.y = 420; addChild(show); with (vis.xyAxes.xAxis) { horizontalAnchor = TextSprite.LEFT; verticalAnchor = TextSprite.MIDDLE; labelAngle = Math.PI / 2; labelTextFormat = fmt; } var legendVals = new Array(); var i = 0; for each (var name:String in words){ legendVals.push({color:colPal.getColorByIndex(i), size: 0.75, label: name}); i++; } var _legend = Legend.fromValues(null, legendVals); _legend.labelTextFormat = fmt; _legend.labelTextMode = TextSprite.EMBED; _legend.update(); addChild(_legend); new ClickControl(LegendItem, 1, function(e:SelectionEvent):void { if(_shown.length == 0) _legend.setItemProperties({alpha:0.5}); var word_num = words.indexOf(LegendItem(e.object).text); if(_shown.indexOf(word_num) == -1){ _shown.push(word_num); e.object.alpha = 1; }else{ _shown = _shown.filter(function(element:*, index:int, arr:Array){ return (element != word_num); }); e.object.alpha = 0.5; } var t:Transitioner = new Transitioner(0.5); vis.data.nodes.visit(function(d:DataSprite):void { t.$(d).visible = _shown.indexOf(d.data.series) != -1; }); vis.data.edges.visit(function(d:DataSprite):void { t.$(d).visible = _shown.indexOf(d.data.series) != -1; }); var max:Number = 0; for each(var d:DataSprite in vis.data.nodes){ if(d.data.count > max && _shown.indexOf(d.data.series) != -1) max = d.data.count; } vis.operators[0].yScale.preferredMax = max; update(t); }).attach(_legend); vis.controls.add(new TooltipControl(Sprite, null, updateTooltip, updateTooltip, null, 50)); vis.update(); } private function updateTooltip(e:TooltipEvent):void{ var date = new Date(int(vis.xyAxes.xAxis.value(vis.mouseX, vis.mouseY))); var count = Math.round(vis.xyAxes.yAxis.value(vis.mouseX, vis.mouseY)); var strDate = String(date.date) + " " + months[date.month]; TextSprite(e.tooltip).htmlText = Strings.format("Count: {0}
Date: {1}", count, strDate); } private function update(t:Transitioner):void{ // toggle screen quality during animation to boost frame rate t.addEventListener(TransitionEvent.START, function(e:Event):void{ }); t.addEventListener(TransitionEvent.END, function(e:Event):void{ //vis.operators[0] = new AxisLayout("data.date", "data.count"); }); vis.update(t).play(); } private function filter(d:DataSprite):Boolean{ if(d.data.count != 0) return true; return false; } public function getTimeline():Data{ var jsonString:String = String(ExternalInterface.call("getPlotData")); var json:Array = JSON.decode(jsonString as String) as Array; var jsonData:Array = new Array(); for each (var item:Array in json){ var tmpObj:Object = new Object(); var tmp:Array = item[1]; tmpObj.name = item[0]; tmp = tmp.map(function(element:*, index:int, arr:Array){ element[0] = Dates.roundTime(new Date(element[0]), Dates.WEEKS); return element; }); var summed:Array = new Array(); for each (var el:Array in tmp){ var x = el[0].time; if(summed[x] == null) summed[x] = el; else summed[x][1] += el[1]; } tmpObj.data = summed; jsonData.push(tmpObj); } var data:Data = new Data(); var j:uint = 0; for each (var dat:Object in jsonData){ words.push(dat.name); for each (var itm:Array in dat.data) data.addNode({series: int(j), name:dat.name, date: itm[0], count: int(itm[1])}); j++; } data.createEdges("data.date", "data.series"); return data; } } }