source: code/Website/open-flash-chart/main.as@ 7849

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