PageRenderTime 3662ms CodeModel.GetById 37ms RepoModel.GetById 15ms app.codeStats 0ms

/tags/0.1/open-flash-chart/main.as

http://ofc-etw.googlecode.com/
ActionScript | 911 lines | 497 code | 189 blank | 225 comment | 69 complexity | bf9791fcbe4f4f27782ef2d5fceac7dc MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. package {
  2. import charts.series.Element;
  3. import charts.Factory;
  4. import charts.ObjectCollection;
  5. import elements.menu.Menu;
  6. import charts.series.has_tooltip;
  7. import flash.events.Event;
  8. import flash.events.MouseEvent;
  9. // for image upload:
  10. import flash.events.ProgressEvent;
  11. import flash.net.URLVariables;
  12. import flash.display.Sprite;
  13. import flash.net.URLLoader;
  14. import flash.net.URLRequest;
  15. import flash.display.StageAlign;
  16. import flash.display.StageScaleMode;
  17. import string.Utils;
  18. import global.Global;
  19. import com.serialization.json.JSON;
  20. import flash.external.ExternalInterface;
  21. import flash.ui.ContextMenu;
  22. import flash.ui.ContextMenuItem;
  23. import flash.events.IOErrorEvent;
  24. import flash.events.ContextMenuEvent;
  25. import flash.system.System;
  26. import flash.display.LoaderInfo;
  27. // export the chart as an image
  28. import com.adobe.images.PNGEncoder;
  29. import com.adobe.images.JPGEncoder;
  30. import mx.utils.Base64Encoder;
  31. // import com.dynamicflash.util.Base64;
  32. import flash.display.BitmapData;
  33. import flash.utils.ByteArray;
  34. import flash.net.URLRequestHeader;
  35. import flash.net.URLRequestMethod;
  36. import flash.net.URLLoaderDataFormat;
  37. import elements.axis.XAxis;
  38. import elements.axis.XAxisLabels;
  39. import elements.axis.YAxisBase;
  40. import elements.axis.YAxisLeft;
  41. import elements.axis.YAxisRight;
  42. import elements.axis.RadarAxis;
  43. import elements.Background;
  44. import elements.labels.XLegend;
  45. import elements.labels.Title;
  46. import elements.labels.Keys;
  47. import elements.labels.YLegendBase;
  48. import elements.labels.YLegendLeft;
  49. import elements.labels.YLegendRight;
  50. public class main extends Sprite {
  51. public var VERSION:String = "2-Etw 0.1";
  52. private var title:Title = null;
  53. //private var x_labels:XAxisLabels;
  54. private var x_axis:XAxis;
  55. private var radar_axis:RadarAxis;
  56. private var x_legend:XLegend;
  57. private var y_axis:YAxisBase;
  58. private var y_axis_right:YAxisBase;
  59. private var y_legend:YLegendBase;
  60. private var y_legend_2:YLegendBase;
  61. private var keys:Keys;
  62. private var obs:ObjectCollection;
  63. public var tool_tip_wrapper:String;
  64. private var sc:ScreenCoords;
  65. private var tooltip:Tooltip;
  66. private var background:Background;
  67. private var menu:Menu;
  68. private var ok:Boolean;
  69. private var URL:String; // ugh, vile. The IOError doesn't report the URL
  70. private var id:String; // chart id passed inf from user
  71. private var chart_parameters:Object;
  72. private var json:String;
  73. public function main() {
  74. this.chart_parameters = LoaderInfo(this.loaderInfo).parameters;
  75. if( this.chart_parameters['loading'] == null )
  76. this.chart_parameters['loading'] = 'Loading data...';
  77. var l:Loading = new Loading(this.chart_parameters['loading']);
  78. this.addChild( l );
  79. this.build_right_click_menu();
  80. this.ok = false;
  81. if( !this.find_data() )
  82. {
  83. // no data found -- debug mode?
  84. try {
  85. var file:String = "../../data-files/y-axis-auto-steps.txt";
  86. this.load_external_file( file );
  87. /*
  88. // test AJAX calls like this:
  89. var file:String = "../data-files/bar-2.txt";
  90. this.load_external_file( file );
  91. file = "../data-files/radar-area.txt";
  92. this.load_external_file( file );
  93. */
  94. }
  95. catch (e:Error) {
  96. this.show_error( 'Loading test data\n'+file+'\n'+e.message );
  97. }
  98. }
  99. // inform javascript that it can call our reload method
  100. this.addCallback("reload", reload); // mf 18nov08, line 110 of original 'main.as'
  101. // inform javascript that it can call our load method
  102. this.addCallback("load", load);
  103. // inform javascript that it can call our post_image method
  104. this.addCallback("post_image", post_image);
  105. //
  106. this.addCallback("get_img_binary", getImgBinary);
  107. // more interface
  108. this.addCallback("get_version", getVersion);
  109. // TODO: chanf all external to use this:
  110. //
  111. // tell our external interface manager to pass out the chart ID
  112. // with every external call.
  113. //
  114. if ( this.chart_parameters['id'] )
  115. {
  116. var ex:ExternalInterfaceManager = ExternalInterfaceManager.getInstance();
  117. ex.setUp(this.chart_parameters['id']);
  118. }
  119. //
  120. // TODO: move this so it is called after set_the_stage is ready.
  121. //
  122. // tell the web page that we are ready
  123. if( this.chart_parameters['id'] )
  124. this.callExternalCallback("ofc_ready", this.chart_parameters['id']);
  125. else
  126. this.callExternalCallback("ofc_ready");
  127. //
  128. //
  129. //
  130. this.set_the_stage();
  131. }
  132. private function addCallback(functionName:String, closure:Function): void {
  133. // the debug player does not have an external interface
  134. // because it is NOT embedded in a browser
  135. if (ExternalInterface.available)
  136. ExternalInterface.addCallback(functionName, closure);
  137. }
  138. private function callExternalCallback(functionName:String, ... optionalArgs ): * {
  139. // the debug player does not have an external interface
  140. // because it is NOT embedded in a browser
  141. if (ExternalInterface.available)
  142. return ExternalInterface.call(functionName, optionalArgs);
  143. }
  144. public function getVersion():String {return VERSION;}
  145. // public function getImgBinary():String { return Base64.encodeByteArray(image_binary()); }
  146. public function getImgBinary():String {
  147. tr.ace('Saving image :: image_binary()');
  148. var bmp:BitmapData = new BitmapData(this.stage.stageWidth, this.stage.stageHeight);
  149. bmp.draw(this);
  150. var b64:Base64Encoder = new Base64Encoder();
  151. var b:ByteArray = PNGEncoder.encode(bmp);
  152. // var encoder:JPGEncoder = new JPGEncoder(80);
  153. // var q:ByteArray = encoder.encode(bmp);
  154. // b64.encodeBytes(q);
  155. //
  156. //
  157. //
  158. b64.encodeBytes(b);
  159. return b64.toString();
  160. //
  161. // commented out by J vander? why?
  162. // return b64.flush();
  163. //
  164. //
  165. /*
  166. var b64:Base64Encoder = new Base64Encoder();
  167. b64.encodeBytes(image_binary());
  168. tr.ace( b64 as String );
  169. return b64 as String;
  170. */
  171. }
  172. /**
  173. * Called from the context menu:
  174. */
  175. public function saveImage(e:ContextMenuEvent):void {
  176. // ExternalInterface.call("save_image", this.chart_parameters['id']);// , getImgBinary());
  177. // ExternalInterface.call("save_image", getImgBinary());
  178. // this just calls the javascript function which will grab an image from use
  179. // an do something with it.
  180. this.callExternalCallback("save_image", this.chart_parameters['id']);
  181. }
  182. private function image_binary() : ByteArray {
  183. tr.ace('Saving image :: image_binary()');
  184. var pngSource:BitmapData = new BitmapData(this.width, this.height);
  185. pngSource.draw(this);
  186. return PNGEncoder.encode(pngSource);
  187. }
  188. //
  189. // External interface called by Javascript to
  190. // save the flash as an image, then POST it to a URL
  191. //
  192. //public function post_image(url:String, post_params:Object, callback:String, debug:Boolean):void {
  193. public function post_image(url:String, callback:String, debug:Boolean):void {
  194. var header:URLRequestHeader = new URLRequestHeader("Content-type", "application/octet-stream");
  195. //Make sure to use the correct path to jpg_encoder_download.php
  196. var request:URLRequest = new URLRequest(url);
  197. request.requestHeaders.push(header);
  198. request.method = URLRequestMethod.POST;
  199. //
  200. request.data = image_binary();
  201. var loader:URLLoader = new URLLoader();
  202. loader.dataFormat = URLLoaderDataFormat.VARIABLES;
  203. /*
  204. * i can't figure out how to make these work
  205. *
  206. var urlVars:URLVariables = new URLVariables();
  207. for (var key:String in post_params) {
  208. urlVars[key] = post_params[key];
  209. }
  210. */
  211. // base64:
  212. // urlVars.b64_image_data = getImgBinary();
  213. // RAW:
  214. // urlVars.b64_image_data = image_binary();
  215. // request.data = urlVars;
  216. var id:String = '';
  217. if ( this.chart_parameters['id'] )
  218. id = this.chart_parameters['id'];
  219. if( debug )
  220. {
  221. // debug the PHP:
  222. flash.net.navigateToURL(request, "_blank");
  223. }
  224. else
  225. {
  226. //we have to use the PROGRESS event instead of the COMPLETE event due to a bug in flash
  227. loader.addEventListener(ProgressEvent.PROGRESS, function (e:ProgressEvent):void {
  228. tr.ace("progress:" + e.bytesLoaded + ", total: " + e.bytesTotal);
  229. if ((e.bytesLoaded == e.bytesTotal) && (callback != null)) {
  230. tr.aces('Calling: ', callback + '(' + id + ')');
  231. this.call(callback, id);
  232. }
  233. });
  234. try {
  235. loader.load( request );
  236. } catch (error:Error) {
  237. tr.ace("unable to load:" + error);
  238. }
  239. /*
  240. var loader:URLLoader = new URLLoader();
  241. loader.dataFormat = URLLoaderDataFormat.BINARY;
  242. loader.addEventListener(Event.COMPLETE, function(e:Event):void {
  243. tr.ace('Saved image to:');
  244. tr.ace( url );
  245. //
  246. // when the upload has finished call the user
  247. // defined javascript function/method
  248. //
  249. ExternalInterface.call(callback);
  250. });
  251. loader.load( jpgURLRequest );
  252. */
  253. }
  254. }
  255. private function onContextMenuHandler(event:ContextMenuEvent):void
  256. {
  257. }
  258. //
  259. // try to find some data to load,
  260. // check the URL for a file name,
  261. //
  262. //
  263. public function find_data(): Boolean {
  264. // var all:String = ExternalInterface.call("window.location.href.toString");
  265. var vars:String = this.callExternalCallback("window.location.search.substring", 1);
  266. if( vars != null )
  267. {
  268. var p:Array = vars.split( '&' );
  269. for each ( var v:String in p )
  270. {
  271. if( v.indexOf( 'ofc=' ) > -1 )
  272. {
  273. var tmp:Array = v.split('=');
  274. tr.ace( 'Found external file:' + tmp[1] );
  275. this.load_external_file( tmp[1] );
  276. //
  277. // LOOK:
  278. //
  279. return true;
  280. }
  281. }
  282. }
  283. if( this.chart_parameters['data-file'] )
  284. {
  285. // tr.ace( 'Found parameter:' + parameters['data-file'] );
  286. this.load_external_file( this.chart_parameters['data-file'] );
  287. //
  288. // LOOK:
  289. //
  290. return true;
  291. }
  292. var get_data:String = 'open_flash_chart_data';
  293. if( this.chart_parameters['get-data'] )
  294. get_data = this.chart_parameters['get-data'];
  295. var json_string:*;
  296. if( this.chart_parameters['id'] )
  297. json_string = this.callExternalCallback( get_data , this.chart_parameters['id']);
  298. else
  299. json_string = this.callExternalCallback( get_data );
  300. if( json_string != null )
  301. {
  302. if( json_string is String )
  303. {
  304. this.parse_json( json_string );
  305. //
  306. // We have loaded the data, so this.ok = true
  307. //
  308. this.ok = true;
  309. //
  310. // LOOK:
  311. //
  312. return true;
  313. }
  314. }
  315. return false;
  316. }
  317. //
  318. // an external interface, used by javascript to
  319. // reload JSON from a URL :: mf 18nov08
  320. //
  321. public function reload( url:String ):void {
  322. var l:Loading = new Loading(this.chart_parameters['loading']);
  323. this.addChild( l );
  324. this.load_external_file( url );
  325. }
  326. private function load_external_file( file:String ):void {
  327. this.URL = file;
  328. //
  329. // LOAD THE DATA
  330. //
  331. var loader:URLLoader = new URLLoader();
  332. loader.addEventListener( IOErrorEvent.IO_ERROR, this.ioError );
  333. loader.addEventListener( Event.COMPLETE, xmlLoaded );
  334. var request:URLRequest = new URLRequest(file);
  335. loader.load(request);
  336. }
  337. private function ioError( e:IOErrorEvent ):void {
  338. // remove the 'loading data...' msg:
  339. this.removeChildAt(0);
  340. var msg:ErrorMsg = new ErrorMsg( 'Open Flash Chart\nIO ERROR\nLoading test data\n' + e.text );
  341. msg.add_html( 'This is the URL that I tried to open:<br><a href="'+this.URL+'">'+this.URL+'</a>' );
  342. this.addChild( msg );
  343. }
  344. private function show_error( msg:String ):void {
  345. // remove the 'loading data...' msg:
  346. this.removeChildAt(0);
  347. var m:ErrorMsg = new ErrorMsg( msg );
  348. //m.add_html( 'Click here to open your JSON file: <a href="http://a.com">asd</a>' );
  349. this.addChild(m);
  350. }
  351. public function get_x_legend() : XLegend {
  352. return this.x_legend;
  353. }
  354. private function set_the_stage():void {
  355. // tell flash to align top left, and not to scale
  356. // anything (we do that in the code)
  357. this.stage.align = StageAlign.TOP_LEFT;
  358. //
  359. // ----- RESIZE ----
  360. //
  361. // noScale: now we can pick up resize events
  362. this.stage.scaleMode = StageScaleMode.NO_SCALE;
  363. this.stage.addEventListener(Event.ACTIVATE, this.activateHandler);
  364. this.stage.addEventListener(Event.RESIZE, this.resizeHandler);
  365. this.stage.addEventListener(Event.MOUSE_LEAVE, this.mouseOut);
  366. this.addEventListener( MouseEvent.MOUSE_OVER, this.mouseMove );
  367. }
  368. private function mouseMove( event:Event ):void {
  369. // tr.ace( 'over ' + event.target );
  370. // tr.ace('move ' + Math.random().toString());
  371. // tr.ace( this.tooltip.get_tip_style() );
  372. if ( !this.tooltip )
  373. return; // <- an error and the JSON was not loaded
  374. switch( this.tooltip.get_tip_style() ) {
  375. case Tooltip.CLOSEST:
  376. this.mouse_move_closest( event );
  377. break;
  378. case Tooltip.PROXIMITY:
  379. this.mouse_move_proximity( event as MouseEvent );
  380. break;
  381. case Tooltip.NORMAL:
  382. this.mouse_move_follow( event as MouseEvent );
  383. break;
  384. }
  385. }
  386. private function mouse_move_follow( event:MouseEvent ):void {
  387. // tr.ace( event.currentTarget );
  388. // tr.ace( event.target );
  389. if ( event.target is has_tooltip )
  390. this.tooltip.draw( event.target as has_tooltip );
  391. else
  392. this.tooltip.hide();
  393. }
  394. private function mouse_move_proximity( event:MouseEvent ):void {
  395. //tr.ace( event.currentTarget );
  396. //tr.ace( event.target );
  397. var elements:Array = this.obs.mouse_move_proximity( this.mouseX, this.mouseY );
  398. this.tooltip.closest( elements );
  399. }
  400. private function mouse_move_closest( event:Event ):void {
  401. var elements:Array = this.obs.closest_2( this.mouseX, this.mouseY );
  402. this.tooltip.closest( elements );
  403. }
  404. private function activateHandler(event:Event):void {
  405. tr.aces("activateHandler:", event);
  406. tr.aces("stage", this.stage);
  407. }
  408. private function resizeHandler(event:Event):void {
  409. // tr.ace("resizeHandler: " + event);
  410. this.resize();
  411. }
  412. //
  413. // pie charts are simpler to resize, they don't
  414. // have all the extras (X,Y axis, legends etc..)
  415. //
  416. private function resize_pie(): ScreenCoordsBase {
  417. // should this be here?
  418. this.addEventListener(MouseEvent.MOUSE_MOVE, this.mouseMove);
  419. this.background.resize();
  420. this.title.resize();
  421. // this object is used in the mouseMove method
  422. this.sc = new ScreenCoords(
  423. this.title.get_height(), 0, this.stage.stageWidth, this.stage.stageHeight,
  424. null, null, null, 0, 0, false );
  425. this.obs.resize( sc );
  426. return sc;
  427. }
  428. //
  429. //
  430. private function resize_radar(): ScreenCoordsBase {
  431. this.addEventListener(MouseEvent.MOUSE_MOVE, this.mouseMove);
  432. this.background.resize();
  433. this.title.resize();
  434. this.keys.resize( 0, this.title.get_height() );
  435. var top:Number = this.title.get_height() + this.keys.get_height();
  436. // this object is used in the mouseMove method
  437. var sc:ScreenCoordsRadar = new ScreenCoordsRadar(top, 0, this.stage.stageWidth, this.stage.stageHeight);
  438. sc.set_range( this.radar_axis.get_range() );
  439. // 0-4 = 5 spokes
  440. sc.set_angles( this.obs.get_max_x()-this.obs.get_min_x()+1 );
  441. // resize the axis first because they may
  442. // change the radius (to fit the labels on screen)
  443. this.radar_axis.resize( sc );
  444. this.obs.resize( sc );
  445. return sc;
  446. }
  447. private function resize():void {
  448. //
  449. // the chart is async, so we may get this
  450. // event before the chart has loaded, or has
  451. // partly loaded
  452. //
  453. if ( !this.ok )
  454. return; // <-- something is wrong
  455. var sc:ScreenCoordsBase;
  456. if ( this.radar_axis != null )
  457. sc = this.resize_radar();
  458. else if ( this.obs.has_pie() )
  459. sc = this.resize_pie();
  460. else
  461. sc = this.resize_chart();
  462. if( this.menu )
  463. this.menu.resize();
  464. // tell the web page that we have resized our content
  465. if( this.chart_parameters['id'] )
  466. this.callExternalCallback("ofc_resize", sc.left, sc.width, sc.top, sc.height, this.chart_parameters['id']);
  467. else
  468. this.callExternalCallback("ofc_resize", sc.left, sc.width, sc.top, sc.height);
  469. sc = null;
  470. }
  471. private function resize_chart(): ScreenCoordsBase {
  472. //
  473. // we want to show the tooltip closest to
  474. // items near the mouse, so hook into the
  475. // mouse move event:
  476. //
  477. this.addEventListener(MouseEvent.MOUSE_MOVE, this.mouseMove);
  478. // FlashConnect.trace("stageWidth: " + stage.stageWidth + " stageHeight: " + stage.stageHeight);
  479. this.background.resize();
  480. this.title.resize();
  481. var left:Number = this.y_legend.get_width() /*+ this.y_labels.get_width()*/ + this.y_axis.get_width();
  482. this.keys.resize( left, this.title.get_height() );
  483. var top:Number = this.title.get_height() + this.keys.get_height();
  484. var bottom:Number = this.stage.stageHeight;
  485. bottom -= (this.x_legend.get_height() + this.x_axis.get_height());
  486. var right:Number = this.stage.stageWidth;
  487. right -= this.y_legend_2.get_width();
  488. //right -= this.y_labels_right.get_width();
  489. right -= this.y_axis_right.get_width();
  490. // this object is used in the mouseMove method
  491. this.sc = new ScreenCoords(
  492. top, left, right, bottom,
  493. this.y_axis.get_range(),
  494. this.y_axis_right.get_range(),
  495. this.x_axis.get_range(),
  496. this.x_axis.first_label_width(),
  497. this.x_axis.last_label_width(),
  498. false );
  499. this.sc.set_bar_groups(this.obs.groups);
  500. this.x_axis.resize( sc,
  501. // can we remove this:
  502. this.stage.stageHeight-(this.x_legend.get_height()+this.x_axis.labels.get_height()) // <-- up from the bottom
  503. );
  504. this.y_axis.resize( this.y_legend.get_width(), sc );
  505. this.y_axis_right.resize( 0, sc );
  506. this.x_legend.resize( sc );
  507. this.y_legend.resize();
  508. this.y_legend_2.resize();
  509. this.obs.resize( sc );
  510. // Test code:
  511. this.dispatchEvent(new Event("on-show"));
  512. return sc;
  513. }
  514. private function mouseOut(event:Event):void {
  515. if( this.tooltip != null )
  516. this.tooltip.hide();
  517. if( this.obs != null )
  518. this.obs.mouse_out();
  519. }
  520. //
  521. // an external interface, used by javascript to
  522. // pass in a JSON string
  523. //
  524. public function load( s:String ):void {
  525. this.parse_json( s );
  526. }
  527. //
  528. // JSON is loaded from an external URL
  529. //
  530. private function xmlLoaded(event:Event):void {
  531. var loader:URLLoader = URLLoader(event.target);
  532. this.parse_json( loader.data );
  533. }
  534. //
  535. // we have data! parse it and make the chart
  536. //
  537. private function parse_json( json_string:String ):void {
  538. // tr.ace(json_string);
  539. var ok:Boolean = false;
  540. try {
  541. var json:Object = JSON.deserialize( json_string );
  542. ok = true;
  543. }
  544. catch (e:Error) {
  545. // remove the 'loading data...' msg:
  546. this.removeChildAt(0);
  547. this.addChild( new JsonErrorMsg( json_string as String, e ) );
  548. }
  549. //
  550. // don't catch these errors:
  551. //
  552. if( ok )
  553. {
  554. // remove 'loading data...' msg:
  555. this.removeChildAt(0);
  556. this.build_chart( json );
  557. // force this to be garbage collected
  558. json = null;
  559. }
  560. json_string = '';
  561. }
  562. private function build_chart( json:Object ):void {
  563. tr.ace('----');
  564. tr.ace(JSON.serialize(json));
  565. tr.ace('----');
  566. if ( this.obs != null )
  567. this.die();
  568. // init singletons:
  569. NumberFormat.getInstance( json );
  570. NumberFormat.getInstanceY2( json );
  571. this.tooltip = new Tooltip( json.tooltip )
  572. var g:Global = Global.getInstance();
  573. g.set_tooltip_string( this.tooltip.tip_text );
  574. //
  575. // these are common to both X Y charts and PIE charts:
  576. this.background = new Background( json );
  577. this.title = new Title( json.title );
  578. //
  579. this.addChild( this.background );
  580. //
  581. if ( JsonInspector.is_radar( json ) ) {
  582. this.obs = Factory.MakeChart( json );
  583. this.radar_axis = new RadarAxis( json.radar_axis );
  584. this.keys = new Keys( this.obs );
  585. this.addChild( this.radar_axis );
  586. this.addChild( this.keys );
  587. }
  588. else if ( !JsonInspector.has_pie_chart( json ) )
  589. {
  590. this.build_chart_background( json );
  591. }
  592. else
  593. {
  594. // this is a PIE chart
  595. this.obs = Factory.MakeChart( json );
  596. // PIE charts default to FOLLOW tooltips
  597. this.tooltip.set_tip_style( Tooltip.NORMAL );
  598. }
  599. // these are added in the Flash Z Axis order
  600. this.addChild( this.title );
  601. for each( var set:Sprite in this.obs.sets )
  602. this.addChild( set );
  603. this.addChild( this.tooltip );
  604. if (json['menu'] != null) {
  605. this.menu = new Menu(this.chart_parameters['id'], json['menu']);
  606. this.addChild(this.menu);
  607. }
  608. this.ok = true;
  609. this.resize();
  610. }
  611. //
  612. // PIE charts don't have this.
  613. // build grid, axis, legends and key
  614. //
  615. private function build_chart_background( json:Object ):void {
  616. //
  617. // This reads all the 'elements' of the chart
  618. // e.g. bars and lines, then creates them as sprites
  619. //
  620. this.obs = Factory.MakeChart( json );
  621. //
  622. this.x_legend = new XLegend( json.x_legend );
  623. this.y_legend = new YLegendLeft( json );
  624. this.y_legend_2 = new YLegendRight( json );
  625. this.x_axis = new XAxis( json, this.obs.get_min_x(), this.obs.get_max_x() );
  626. this.y_axis = new YAxisLeft();
  627. this.y_axis_right = new YAxisRight();
  628. // access all our globals through this:
  629. var g:Global = Global.getInstance();
  630. // this is needed by all the elements tooltip
  631. g.x_labels = this.x_axis.labels;
  632. g.x_legend = this.x_legend;
  633. //
  634. // pick up X Axis labels for the tooltips
  635. //
  636. this.obs.tooltip_replace_labels( this.x_axis.labels );
  637. //
  638. //
  639. //
  640. this.keys = new Keys( this.obs );
  641. this.addChild( this.x_legend );
  642. this.addChild( this.y_legend );
  643. this.addChild( this.y_legend_2 );
  644. this.addChild( this.y_axis );
  645. this.addChild( this.y_axis_right );
  646. this.addChild( this.x_axis );
  647. this.addChild( this.keys );
  648. // now these children have access to the stage,
  649. // tell them to init
  650. this.y_axis.init(json);
  651. this.y_axis_right.init(json);
  652. }
  653. /**
  654. * Remove all our referenced objects
  655. */
  656. private function die():void {
  657. this.obs.die();
  658. this.obs = null;
  659. if ( this.tooltip != null ) this.tooltip.die();
  660. if ( this.x_legend != null ) this.x_legend.die();
  661. if ( this.y_legend != null ) this.y_legend.die();
  662. if ( this.y_legend_2 != null ) this.y_legend_2.die();
  663. if ( this.y_axis != null ) this.y_axis.die();
  664. if ( this.y_axis_right != null ) this.y_axis_right.die();
  665. if ( this.x_axis != null ) this.x_axis.die();
  666. if ( this.keys != null ) this.keys.die();
  667. if ( this.title != null ) this.title.die();
  668. if ( this.radar_axis != null ) this.radar_axis.die();
  669. if ( this.background != null ) this.background.die();
  670. this.tooltip = null;
  671. this.x_legend = null;
  672. this.y_legend = null;
  673. this.y_legend_2 = null;
  674. this.y_axis = null;
  675. this.y_axis_right = null;
  676. this.x_axis = null;
  677. this.keys = null;
  678. this.title = null;
  679. this.radar_axis = null;
  680. this.background = null;
  681. while ( this.numChildren > 0 )
  682. this.removeChildAt(0);
  683. if ( this.hasEventListener(MouseEvent.MOUSE_MOVE))
  684. this.removeEventListener(MouseEvent.MOUSE_MOVE, this.mouseMove);
  685. // do not force a garbage collection, it is not supported:
  686. // http://stackoverflow.com/questions/192373/force-garbage-collection-in-as3
  687. }
  688. private function build_right_click_menu(): void {
  689. var cm:ContextMenu = new ContextMenu();
  690. cm.addEventListener(ContextMenuEvent.MENU_SELECT, onContextMenuHandler);
  691. cm.hideBuiltInItems();
  692. // OFC CREDITS
  693. var fs:ContextMenuItem = new ContextMenuItem("Charts by Open Flash Chart [Version "+VERSION+"]" );
  694. fs.addEventListener(
  695. ContextMenuEvent.MENU_ITEM_SELECT,
  696. function doSomething(e:ContextMenuEvent):void {
  697. var url:String = "http://teethgrinder.co.uk/open-flash-chart-2/";
  698. var request:URLRequest = new URLRequest(url);
  699. flash.net.navigateToURL(request, '_blank');
  700. });
  701. cm.customItems.push( fs );
  702. var save_image_message:String = ( this.chart_parameters['save_image_message'] ) ? this.chart_parameters['save_image_message'] : 'Save Image Locally';
  703. var dl:ContextMenuItem = new ContextMenuItem(save_image_message);
  704. dl.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, this.saveImage);
  705. cm.customItems.push( dl );
  706. this.contextMenu = cm;
  707. }
  708. public function format_y_axis_label( val:Number ): String {
  709. // if( this._y_format != undefined )
  710. // {
  711. // var tmp:String = _root._y_format.replace('#val#',_root.format(val));
  712. // tmp = tmp.replace('#val:time#',_root.formatTime(val));
  713. // tmp = tmp.replace('#val:none#',String(val));
  714. // tmp = tmp.replace('#val:number#', NumberUtils.formatNumber (Number(val)));
  715. // return tmp;
  716. // }
  717. // else
  718. return NumberUtils.format(val,2,true,true,false);
  719. }
  720. }
  721. }