package { import com.meandmybadself.ui.Slider; import flash.display.*; import flash.text.TextField; import flash.utils.Timer; import org.casaframework.load.DataLoad; import flash.events.*; import DynamicSound; import org.casaframework.math.Percent; import org.casaframework.util.DateUtil; import gs.TweenLite; public class LiveStock extends Sprite { private static const DATA_URL:String = 'http://work.meandmybadself.com/proxy.php?u=http://chartapi.finance.yahoo.com/instrument/1.0/POOP/chartdata;type=quote;range=365d/xml/'; public function LiveStock() { $init(); } public var $cta:MovieClip; public var $symbol:TextField; private var $dl:DataLoad; private var $slider:Slider; private var $stockView:Sprite; private var $start; private var $end; private var $close; private var $high; private var $low; private var $open; private var $volume; private var $playPause:MovieClip; private function $init():void { $showCTA(); } private function $showCTA():void { removeChild($date); stage.addEventListener(KeyboardEvent.KEY_DOWN, $keyboard_HANDLER); stage.focus = $symbol; } private var $symbols:Array; private var $symbolStep:int; private var $quotes:Vector.; private function $keyboard_HANDLER(ke:KeyboardEvent):void { if (ke.keyCode == 13 && $symbol.text.length > 0) { stage.removeEventListener(KeyboardEvent.KEY_DOWN, $keyboard_HANDLER); //split the data. $symbolStep = -1; $lowest = 10000000; $highest = 0; $symbols = $symbol.text.split(","); $quotes = new Vector.(); $dataLoad(); } } private function $dataLoad():void { if (++$symbolStep < $symbols.length) { $loadStockData($symbols[$symbolStep]); } else { $showChart(); } } private function $loadStockData(_symbol:String):void { trace('$loadStockData:' + _symbol); $dl = new DataLoad(DATA_URL.replace('POOP', _symbol)); $dl.addEventListener(Event.COMPLETE, $dl_COMPLETE); $dl.start(); } public var $date:TextField; private var $cursor:Sprite; private function $showChart():void { $removeCTA(); addChild($date) $playPause = new PlayPauseButton(); $playPause.addEventListener(MouseEvent.CLICK, $playPause_HANDLER); $playPause.x = 25; $playPause.y = stage.stageHeight - 25 - $playPause.height; $playPause.buttonMode = true; addChild($playPause); $slider = new Slider(); $slider.setWidth(stage.stageWidth - 70); $slider.x = $playPause.x + $playPause.width + 10; $slider.y = stage.stageHeight - 25 - $slider.height; addChild($slider); $slider.addEventListener(Event.CHANGE, $slider_HANDLER); $stockView = new Sprite(); $stockView.x = $slider.x; $stockView.y = 200; addChild($stockView); $keys = new Sprite(); $keys.x = stage.stageWidth - 70 - 30; $keys.y = 62; addChild($keys); for (var _i:uint = 0; _i < $quotes.length; _i++) { //go through all of the quotes and draw them to the chart. var _q:Quote = $quotes[_i]; var _col:uint = HSBtoRGB(_i / $quotes.length, 1, .9); $stockView.addChild($drawStock(_q.prices, _q.low, _q.high, _col)); var _k:StockKey = new StockKey(); _k.$text.text = _q.symbol.toUpperCase(); _k.graphics.moveTo(0, 10); _k.graphics.lineStyle(1, _col); _k.graphics.lineTo(20, 10); _k.y = 20 * _i; $keys.addChild(_k); var _ds:DynamicSound = new DynamicSound(); _q.sound = _ds; } $cursor = new Sprite(); $cursor.graphics.lineStyle(1, 0xCCCCCC); $cursor.graphics.lineTo(0, -VIS_HEIGHT - 180); $cursor.x = $slider.x; $cursor.y = $slider.y - 20; addChild($cursor); $slider.x -= 2; } public static function HSBtoRGB(hue:Number, saturation:Number, brightness:Number):uint { var r:int = 0; var g:int = 0; var b:int = 0; if (saturation == 0) { r = g = b = brightness * 255.0 + 0.5; } else { var h:Number = (hue - Math.floor(hue)) * 6.0; var f:Number = h - Math.floor(h); var p:Number = brightness * (1.0 - saturation); var q:Number = brightness * (1.0 - saturation * f); var t:Number = brightness * (1.0 - (saturation * (1.0 - f))); switch (int(h)) { case 0: r = brightness * 255.0 + 0.5; g = t * 255.0 + 0.5; b = p * 255.0 + 0.5; break; case 1: r = q * 255.0 + 0.5; g = brightness * 255.0 + 0.5; b = p * 255.0 + 0.5; break; case 2: r = p * 255.0 + 0.5; g = brightness * 255.0 + 0.5; b = t * 255.0 + 0.5; break; case 3: r = p * 255.0 + 0.5; g = q * 255.0 + 0.5; b = brightness * 255.0 + 0.5; break; case 4: r = t * 255.0 + 0.5; g = p * 255.0 + 0.5; b = brightness * 255.0 + 0.5; break; case 5: r = brightness * 255.0 + 0.5; g = p * 255.0 + 0.5; b = q * 255.0 + 0.5; break; } } return (r << 16) | (g << 8) | (b << 0); } private function $dl_COMPLETE(e:Event):void { var _xml:XML = $dl.dataAsXml; var _symbol:String = _xml.meta.feature.(@name == 'ticker').text(); var _start:Date = new Date(uint(_xml['reference-meta'].min.text())); var _end:Date = new Date(uint(_xml['reference-meta'].max.text())); var _close:Number = Number(_xml.series.values.value.(@id == 'close').min.text()) var _high:Number = Number(_xml.series.values.value.(@id == 'high').max.text()) var _low:Number = Number(_xml.series.values.value.(@id == 'low').min.text()) var _open:Number = Number(_xml.series.values.value.(@id == 'open').min.text()) var _volume:Number = Number(_xml.series.values.value.(@id == 'volume').max.text()) $lowest = Math.min($lowest, _low); $highest = Math.max($highest, _high); var _stockVector:Vector. = new Vector.(); for each(var _p:XML in _xml.series..p) { var _ls:StockItem = new StockItem(uint(_p.@ref), Number(_p.v[0].text()), Number(_p.v[1].text()), Number(_p.v[2].text()), Number(_p.v[3].text()), Number(_p.v[4].text())); _stockVector.push(_ls); } var _q:Quote = new Quote(_symbol, _start, _end, _close, _high, _low, _open, _volume, _stockVector); $quotes.push(_q); $dataLoad(); } private function $playPause_HANDLER(me:MouseEvent):void { if ($playPause.currentFrame == 1) { $playPause.gotoAndStop(2); $play(); } else { $playPause.gotoAndStop(1); $pause(); } } private function $pause():void { $timer.stop(); $timer.removeEventListener(TimerEvent.TIMER, $timer_HANDLER); $timer = null; for (var _i:uint = 0; _i < $quotes.length; _i++) { var _q:Quote = $quotes[_i]; var _ds:DynamicSound = _q.sound; _ds.volume = 0; } } private var $timer:Timer; private function $play():void { $timer = new Timer(100); $timer.addEventListener(TimerEvent.TIMER, $timer_HANDLER); $timer.start(); for (var _i:uint = 0; _i < $quotes.length; _i++) { var _q:Quote = $quotes[_i]; var _ds:DynamicSound = _q.sound; _ds.volume = 1; } } private function $timer_HANDLER(te:TimerEvent):void { var _val:Number = $slider.getValue().decimalPercentage; var _step:Number = .005; _val += _step; if (_val > 1) { _val = 0; } trace(_val); $slider.setValue(new Percent(_val)); $slider_HANDLER(new Event(Event.CHANGE)); } private function $removeCTA():void { removeChild($cta); removeChild($symbol); } private static const VIS_HEIGHT:Number = 300; private var $keys:Sprite; private function $drawStock(_v:Vector., _min:Number, _max:Number, _color:uint):Sprite { var _spr:Sprite = new Sprite(); var _w:Number = stage.stageWidth - 70; var _stepX:Number = _w / _v.length; _spr.graphics.lineStyle(1, _color, 1, false, LineScaleMode.NONE); var _s:StockItem = _v[0] as StockItem; var _per:Number = ((_s.high - _min) / (_max - _min)) ; $date.text = DateUtil.formatDate(_v[0].time, "l d F Y h:i:s A"); _spr.graphics.moveTo(0, (VIS_HEIGHT - (VIS_HEIGHT * _per))); for (var _i:uint = 0; _i < _v.length; _i++) { _s = _v[_i] as StockItem; _per = ((_s.high - _min) / (_max - _min)) ; _spr.graphics.lineTo((_i * _stepX), (VIS_HEIGHT - (VIS_HEIGHT * _per))); } _spr.blendMode = BlendMode.MULTIPLY; return _spr; } private function $unlockUI():void { $slider.unlock(); } private var $lowest:Number; private var $highest:Number; private function $slider_HANDLER(e:Event):void { switch(e.type) { case Event.CHANGE: var _per:Number = $slider.getValue().decimalPercentage; var _index:int; var _pitch:Number; var _volume:Number; var _date:String; var _ds:DynamicSound; var _i:uint; for (_i = 0; _i < $quotes.length; _i++) { var _q:Quote = $quotes[_i]; _index = Math.floor(_per * _q.prices.length); // _pitch = (_q.prices[_index].high - $lowest) / ($highest - $lowest); // trace(_pitch); _pitch = (_q.prices[_index].high - _q.low) / (_q.high - _q.low); _date = DateUtil.formatDate(_q.prices[_index].time, "l d F Y h:i:s A"); _ds = _q.sound; if (_ds.lastIndexedPitch != _pitch) { _ds.lastIndexedPitch = _pitch; _ds.pitch = _pitch } // + (_ds.lastIndexedPitch - _pitch) * ; } $cursor.x = $slider.x + ($slider.width * _per); $date.text = _date; break; } } } }