source: code/Website/open-flash-chart/charts/Line.as@ 7937

Last change on this file since 7937 was 7849, checked in by dennisw, 16 years ago
File size: 8.2 KB
Line 
1package charts {
2
3 import flash.events.Event;
4 import flash.events.MouseEvent;
5 import charts.series.Element;
6 import flash.display.BlendMode;
7 import flash.display.Sprite;
8
9 import charts.series.dots.DefaultDotProperties;
10 import charts.series.dots.dot_factory;
11
12 import flash.utils.Timer;
13 import flash.events.TimerEvent;
14 import charts.series.dots.PointDotBase;
15
16 public class Line extends Base
17 {
18 // JSON style:
19 protected var props:Properties;
20 private var dot_style:Properties;
21 private var on_show:Properties;
22 private var line_style:LineStyle;
23
24 private var on_show_timer:Timer;
25 private var on_show_start:Boolean;
26
27 public function Line( json:Object ) {
28
29 var root:Properties = new Properties({
30 values: [],
31 width: 2,
32 colour: '#3030d0',
33 text: '', // <-- default not display a key
34 'font-size': 12,
35 tip: '#val#',
36 loop: false,
37 axis: 'left'
38 });
39 this.props = new Properties(json, root);
40
41 this.line_style = new LineStyle(json['line-style']);
42 this.dot_style = new DefaultDotProperties(json['dot-style'], this.props.get('colour'), this.props.get('axis'));
43
44 //
45 // see scatter base
46 //
47 var on_show_root:Properties = new Properties( {
48 type: "none", // "pop-up",
49 cascade: 0.5,
50 delay: 0
51 });
52 this.on_show = new Properties(json['on-show'], on_show_root);
53 this.on_show_start = true;// this.on_show.get('type');
54 //
55 //
56
57 this.key = this.props.get('text');
58 this.font_size = this.props.get('font-size');
59
60 this.values = this.props.get('values');
61 this.add_values();
62
63 //
64 // this allows the dots to erase part of the line
65 //
66 this.blendMode = BlendMode.LAYER;
67 }
68
69 //
70 // called from the Base object
71 //
72 protected override function get_element( index:Number, value:Object ): Element {
73
74 if ( value is Number )
75 value = { value:value };
76
77 var tmp:Properties = new Properties(value, this.dot_style);
78
79 // Minor hack, replace all #key# with this key text,
80 // we do this *after* the merge.
81 tmp.set( 'tip', tmp.get('tip').replace('#key#', this.key) );
82
83 // attach the animation bits:
84 tmp.set('on-show', this.on_show);
85
86 return dot_factory.make( index, tmp );
87 }
88
89
90 // Draw lines...
91 public override function resize( sc:ScreenCoordsBase ): void {
92 this.x = this.y = 0;
93
94 this.move_dots(sc);
95
96 if ( this.on_show_start )
97 this.start_on_show_timer();
98 else
99 this.draw();
100
101 }
102
103 //
104 // this is a bit dirty, as the dots animate we draw the line 60 times a second
105 //
106 private function start_on_show_timer(): void {
107 this.on_show_start = false;
108 this.on_show_timer = new Timer(1000 / 60); // <-- 60 frames a second = 1000ms / 60
109 this.on_show_timer.addEventListener("timer", animationManager);
110 // Start the timer
111 this.on_show_timer.start();
112 }
113
114 protected function animationManager(eventArgs:TimerEvent): void {
115
116 this.draw();
117
118 if( !this.still_animating() ) {
119 tr.ace( 'Line.as : on show animation stop' );
120 this.on_show_timer.stop();
121 }
122 }
123
124 private function still_animating(): Boolean {
125 var i:Number;
126 var tmp:Sprite;
127
128 for ( i=0; i < this.numChildren; i++ ) {
129
130 tmp = this.getChildAt(i) as Sprite;
131
132 // filter out the line masks
133 if( tmp is PointDotBase )
134 {
135 var e:PointDotBase = tmp as PointDotBase;
136 if ( e.is_tweening() )
137 return true;
138 }
139 }
140 return false;
141 }
142
143 //
144 // this is called from both resize and the animation manager
145 //
146 protected function draw(): void {
147 this.graphics.clear();
148 this.draw_line();
149 }
150
151 // this is also called from area
152 protected function draw_line(): void {
153
154
155 this.graphics.lineStyle( this.props.get_colour('width'), this.props.get_colour('colour') );
156
157 if( this.line_style.style != 'solid' )
158 this.dash_line();
159 else
160 this.solid_line();
161
162 }
163
164 public function move_dots( sc:ScreenCoordsBase ): void {
165
166 var i:Number;
167 var tmp:Sprite;
168
169 for ( i=0; i < this.numChildren; i++ ) {
170
171 tmp = this.getChildAt(i) as Sprite;
172
173 // filter out the line masks
174 if( tmp is Element )
175 {
176 var e:Element = tmp as Element;
177
178 // tell the point where it is on the screen
179 // we will use this info to place the tooltip
180 e.resize( sc );
181 }
182 }
183 }
184
185 public function solid_line(): void {
186
187 var first:Boolean = true;
188 var i:Number;
189 var tmp:Sprite;
190 var x:Number;
191 var y:Number;
192
193 for ( i=0; i < this.numChildren; i++ ) {
194
195 tmp = this.getChildAt(i) as Sprite;
196
197 // filter out the line masks
198 if( tmp is Element )
199 {
200 var e:Element = tmp as Element;
201
202 if( first )
203 {
204 this.graphics.moveTo(e.x, e.y);
205 x = e.x;
206 y = e.y;
207 first = false;
208 }
209 else
210 this.graphics.lineTo(e.x, e.y);
211 }
212 }
213
214 if ( this.props.get('loop') ) {
215 // close the line loop (radar charts)
216 this.graphics.lineTo(x, y);
217 }
218 }
219
220 // Dashed lines by Arseni
221 public function dash_line(): void {
222
223 var first:Boolean = true;
224
225 var prev_x:int = 0;
226 var prev_y:int = 0;
227 var on_len_left:Number = 0;
228 var off_len_left:Number = 0;
229 var on_len:Number = this.line_style.on; //Stroke Length
230 var off_len:Number = this.line_style.off; //Space Length
231 var now_on:Boolean = true;
232
233 for ( var i:Number = 0; i < this.numChildren; i++ ) {
234 var tmp:Sprite = this.getChildAt(i) as Sprite;
235 //
236 // filter out the line masks
237 //
238 if( tmp is Element )
239 {
240 var e:Element = tmp as Element;
241
242 if( first )
243 {
244 this.graphics.moveTo(e.x, e.y);
245 on_len_left = on_len;
246 off_len_left = off_len;
247 now_on = true;
248 first = false;
249 prev_x = e.x;
250 prev_y = e.y;
251 var x_tmp_1:Number = prev_x;
252 var x_tmp_2:Number;
253 var y_tmp_1:Number = prev_y;
254 var y_tmp_2:Number;
255 }
256 else {
257 var part_len:Number = Math.sqrt((e.x - prev_x) * (e.x - prev_x) + (e.y - prev_y) * (e.y - prev_y) );
258 var sinus:Number = ((e.y - prev_y) / part_len);
259 var cosinus:Number = ((e.x - prev_x) / part_len);
260 var part_len_left:Number = part_len;
261 var inside_part:Boolean = true;
262
263 while (inside_part) {
264 //Draw Lines And spaces one by one in loop
265 if ( now_on ) {
266 //Draw line
267 //If whole stroke fits
268 if ( on_len_left < part_len_left ) {
269 //Fits - draw whole stroke
270 x_tmp_2 = x_tmp_1 + on_len_left * cosinus;
271 y_tmp_2 = y_tmp_1 + on_len_left * sinus;
272 x_tmp_1 = x_tmp_2;
273 y_tmp_1 = y_tmp_2;
274 part_len_left = part_len_left - on_len_left;
275 now_on = false;
276 off_len_left = off_len;
277 } else {
278 //Does not fit - draw part of the stroke
279 x_tmp_2 = e.x;
280 y_tmp_2 = e.y;
281 x_tmp_1 = x_tmp_2;
282 y_tmp_1 = y_tmp_2;
283 on_len_left = on_len_left - part_len_left;
284 inside_part = false;
285 }
286 this.graphics.lineTo(x_tmp_2, y_tmp_2);
287 } else {
288 //Draw space
289 //If whole space fits
290 if ( off_len_left < part_len_left ) {
291 //Fits - draw whole space
292 x_tmp_2 = x_tmp_1 + off_len_left * cosinus;
293 y_tmp_2 = y_tmp_1 + off_len_left * sinus;
294 x_tmp_1 = x_tmp_2;
295 y_tmp_1 = y_tmp_2;
296 part_len_left = part_len_left - off_len_left;
297 now_on = true;
298 on_len_left = on_len;
299 } else {
300 //Does not fit - draw part of the space
301 x_tmp_2 = e.x;
302 y_tmp_2 = e.y;
303 x_tmp_1 = x_tmp_2;
304 y_tmp_1 = y_tmp_2;
305 off_len_left = off_len_left - part_len_left;
306 inside_part = false;
307 }
308 this.graphics.moveTo(x_tmp_2, y_tmp_2);
309 }
310 }
311 }
312 prev_x = e.x;
313 prev_y = e.y;
314 }
315 }
316 }
317
318 public override function get_colour(): Number {
319 return this.props.get_colour('colour');
320 }
321 }
322}
Note: See TracBrowser for help on using the repository browser.