source: code/Website/open-flash-chart/elements/axis/XAxis.as@ 7937

Last change on this file since 7937 was 7849, checked in by dennisw, 15 years ago
File size: 11.4 KB
Line 
1package elements.axis {
2 import flash.display.Sprite;
3 import flash.geom.Matrix;
4 import string.Utils;
5 import charts.series.bars.Bar3D;
6 import com.serialization.json.JSON;
7 import Range;
8
9
10 public class XAxis extends Sprite {
11
12 private var steps:Number;
13 private var alt_axis_colour:Number;
14 private var alt_axis_step:Number;
15 private var three_d:Boolean;
16 private var three_d_height:Number;
17
18 private var stroke:Number;
19 private var tick_height:Number;
20 private var colour:Number;
21 public var offset:Boolean;
22 private var grid_colour:Number;
23 private var grid_visible:Boolean;
24 private var user_ticks:Boolean;
25 private var user_labels:Array;
26
27 // make this private
28 public var labels:XAxisLabels;
29
30 private var style:Object;
31
32 function XAxis( json:Object, min:Number, max:Number )
33 {
34 // default values
35 this.style = {
36 stroke: 2,
37 'tick-height': 3,
38 colour: '#784016',
39 offset: true,
40 'grid-colour': '#F5E1AA',
41 'grid-visible': true,
42 '3d': 0,
43 steps: 1,
44 min: 0,
45 max: null
46 };
47
48 if( json != null )
49 object_helper.merge_2( json.x_axis, this.style );
50
51 this.calcSteps();
52
53 this.stroke = this.style.stroke;
54 this.tick_height = this.style['tick-height'];
55 this.colour = this.style.colour;
56 // is the axis offset (see ScreenCoords)
57 this.offset = this.style.offset;
58 this.grid_visible = this.style['grid-visible'];
59
60 this.colour = Utils.get_colour( this.style.colour );
61 this.grid_colour = Utils.get_colour( this.style['grid-colour'] );
62
63
64 if( style['3d'] > 0 )
65 {
66 this.three_d = true;
67 this.three_d_height = int( this.style['3d'] );
68 }
69 else
70 this.three_d = false;
71
72 // Patch from Will Henry
73 if( json )
74 {
75 if( json.x_label_style != undefined ) {
76 if( json.x_label_style.alt_axis_step != undefined )
77 this.alt_axis_step = json.x_label_style.alt_axis_step;
78
79 if( json.x_label_style.alt_axis_colour != undefined )
80 this.alt_axis_colour = Utils.get_colour(json.x_label_style.alt_axis_colour);
81 }
82 }
83
84 this.labels = new XAxisLabels( json );
85 this.addChild( this.labels );
86
87 // the X Axis labels *may* require info from
88 // this.obs
89 if( !this.range_set() )
90 {
91 //
92 // the user has not told us how long the X axis
93 // is, so we figure it out:
94 //
95 if( this.labels.need_labels ) {
96 //
97 // No X Axis labels set:
98 //
99
100 // tr.aces( 'max x', this.obs.get_min_x(), this.obs.get_max_x() );
101 this.set_range( min, max );
102 }
103 else
104 {
105 //
106 // X Axis labels used, even so, make the chart
107 // big enough to show all values
108 //
109 // tr.aces('x labels', this.obs.get_min_x(), this.x_axis.labels.count(), this.obs.get_max_x());
110 if ( this.labels.count() > max ) {
111
112 // Data and labesl are OK
113 this.set_range( 0, this.labels.count() );
114 } else {
115
116 // There is more data than labels -- oops
117 this.set_range( min, max );
118 }
119 }
120 }
121 else
122 {
123 //range set, but no labels...
124 this.labels.auto_label( this.get_range(), this.get_steps() );
125 }
126
127 // custom ticks:
128 this.make_user_ticks();
129 }
130
131 //
132 // a little hacky, but we inspect the labels
133 // to see if we need to display user custom ticks
134 //
135 private function make_user_ticks():void {
136
137 if ((this.style.labels != null) &&
138 (this.style.labels.labels != null) &&
139 (this.style.labels.labels is Array) &&
140 (this.style.labels.labels.length > 0))
141 {
142 this.user_labels = new Array();
143 for each( var lbl:Object in this.style.labels.labels )
144 {
145 if (!(lbl is String)) {
146 if (lbl.x != null)
147 {
148 var tmpObj:Object = { x: lbl.x };
149 if (lbl["grid-colour"])
150 {
151 tmpObj["grid-colour"] = Utils.get_colour(lbl["grid-colour"]);
152 }
153 else
154 {
155 tmpObj["grid-colour"] = this.grid_colour;
156 }
157
158 this.user_ticks = true;
159 this.user_labels.push(tmpObj);
160 }
161 }
162 }
163 }
164 }
165
166 private function calcSteps():void {
167 if (this.style.max == null) {
168 this.steps = 1;
169 }
170 else {
171 var xRange:Number = this.style.max - this.style.min;
172 var rev:Boolean = (this.style.min >= this.style.max); // min-max reversed?
173 this.steps = ((this.style.steps != null) &&
174 (this.style.steps != 0)) ? this.style.steps : 1;
175
176 // force max of 250 labels and tick marks
177 if ((Math.abs(xRange) / this.steps) > 250) this.steps = xRange / 250;
178
179 // guarantee lblSteps is the proper sign
180 this.steps = rev ? -Math.abs(this.steps) : Math.abs(this.steps);
181 }
182 }
183
184 //
185 // have we been passed a range? (min and max?)
186 //
187 public function range_set():Boolean {
188 return this.style.max != null;
189 }
190
191 //
192 // We don't have a range, so we need to calculate it.
193 // grid lines, depends on number of values,
194 // the X Axis labels and X min and X max
195 //
196 public function set_range( min:Number, max:Number ):void
197 {
198 this.style.min = min;
199 this.style.max = max;
200 // Calc new steps
201 this.calcSteps();
202
203 this.labels.auto_label( this.get_range(), this.get_steps() );
204 }
205
206 //
207 // how many items in the X axis?
208 //
209 public function get_range():Range {
210 return new Range( this.style.min, this.style.max, this.steps, this.offset );
211 }
212
213 public function get_steps():Number {
214 return this.steps;
215 }
216
217 public function resize( sc:ScreenCoords, yPos:Number ):void
218 {
219 this.graphics.clear();
220
221 //
222 // Grid lines
223 //
224 if (this.user_ticks)
225 {
226 for each( var lbl:Object in this.user_labels )
227 {
228 this.graphics.beginFill(lbl["grid-colour"], 1);
229 var xVal:Number = sc.get_x_from_val(lbl.x);
230 this.graphics.drawRect( xVal, sc.top, 1, sc.height );
231 this.graphics.endFill();
232 }
233 }
234 else if(this.grid_visible)
235 {
236 var rev:Boolean = (this.style.min >= this.style.max); // min-max reversed?
237 var tickMax:Number = /*(rev && this.style.offset) ? this.style.max-2 : */ this.style.max
238
239 for( var i:Number=this.style.min; rev ? i >= tickMax : i <= tickMax; i+=this.steps )
240 {
241 if( ( this.alt_axis_step > 1 ) && ( i % this.alt_axis_step == 0 ) )
242 this.graphics.beginFill(this.alt_axis_colour, 1);
243 else
244 this.graphics.beginFill(this.grid_colour, 1);
245
246 xVal = sc.get_x_from_val(i);
247 this.graphics.drawRect( xVal, sc.top, 1, sc.height );
248 this.graphics.endFill();
249 }
250 }
251
252 if( this.three_d )
253 this.three_d_axis( sc );
254 else
255 this.two_d_axis( sc );
256
257 this.labels.resize( sc, yPos );
258 }
259
260 public function three_d_axis( sc:ScreenCoords ):void
261 {
262
263 // for 3D
264 var h:Number = this.three_d_height;
265 var offset:Number = 12;
266 var x_axis_height:Number = h+offset;
267
268 //
269 // ticks
270 var item_width:Number = sc.width / this.style.max;
271
272 // turn off out lines:
273 this.graphics.lineStyle(0,0,0);
274
275 var w:Number = 1;
276
277 if (this.user_ticks)
278 {
279 for each( var lbl:Object in this.user_labels )
280 {
281 var xVal:Number = sc.get_x_from_val(lbl.x);
282 this.graphics.beginFill(this.colour, 1);
283 this.graphics.drawRect( xVal, sc.bottom + x_axis_height, w, this.tick_height );
284 this.graphics.endFill();
285 }
286 }
287 else
288 {
289 for( var i:Number=0; i < this.style.max; i+=this.steps )
290 {
291 var pos:Number = sc.get_x_tick_pos(i);
292
293 this.graphics.beginFill(this.colour, 1);
294 this.graphics.drawRect( pos, sc.bottom + x_axis_height, w, this.tick_height );
295 this.graphics.endFill();
296 }
297 }
298
299
300 var lighter:Number = Bar3D.Lighten( this.colour );
301
302 // TOP
303 var colors:Array = [this.colour,lighter];
304 var alphas:Array = [100,100];
305 var ratios:Array = [0,255];
306
307 var matrix:Matrix = new Matrix();
308 matrix.createGradientBox(sc.width_(), offset, (270 / 180) * Math.PI, sc.left-offset, sc.bottom );
309 this.graphics.beginGradientFill('linear' /*GradientType.Linear*/, colors, alphas, ratios, matrix, 'pad'/*SpreadMethod.PAD*/ );
310 this.graphics.moveTo(sc.left,sc.bottom);
311 this.graphics.lineTo(sc.right,sc.bottom);
312 this.graphics.lineTo(sc.right-offset,sc.bottom+offset);
313 this.graphics.lineTo(sc.left-offset,sc.bottom+offset);
314 this.graphics.endFill();
315
316 // front
317 colors = [this.colour,lighter];
318 alphas = [100,100];
319 ratios = [0, 255];
320
321 matrix.createGradientBox( sc.width_(), h, (270 / 180) * Math.PI, sc.left - offset, sc.bottom + offset );
322 this.graphics.beginGradientFill("linear", colors, alphas, ratios, matrix);
323 this.graphics.moveTo(sc.left-offset,sc.bottom+offset);
324 this.graphics.lineTo(sc.right-offset,sc.bottom+offset);
325 this.graphics.lineTo(sc.right-offset,sc.bottom+offset+h);
326 this.graphics.lineTo(sc.left-offset,sc.bottom+offset+h);
327 this.graphics.endFill();
328
329 // right side
330 colors = [this.colour,lighter];
331 alphas = [100,100];
332 ratios = [0,255];
333
334 // var matrix:Object = { matrixType:"box", x:box.left - offset, y:box.bottom + offset, w:box.width_(), h:h, r:(225 / 180) * Math.PI };
335 matrix.createGradientBox( sc.width_(), h, (225 / 180) * Math.PI, sc.left - offset, sc.bottom + offset );
336 this.graphics.beginGradientFill("linear", colors, alphas, ratios, matrix);
337 this.graphics.moveTo(sc.right,sc.bottom);
338 this.graphics.lineTo(sc.right,sc.bottom+h);
339 this.graphics.lineTo(sc.right-offset,sc.bottom+offset+h);
340 this.graphics.lineTo(sc.right-offset,sc.bottom+offset);
341 this.graphics.endFill();
342
343 }
344
345 // 2D:
346 public function two_d_axis( sc:ScreenCoords ):void
347 {
348 //
349 // ticks
350 var item_width:Number = sc.width / this.style.max;
351 var left:Number = sc.left+(item_width/2);
352
353 //this.graphics.clear();
354 // Axis line:
355 this.graphics.lineStyle( 0, 0, 0 );
356 this.graphics.beginFill( this.colour );
357 this.graphics.drawRect( sc.left, sc.bottom, sc.width, this.stroke );
358 this.graphics.endFill();
359
360
361 if (this.user_ticks)
362 {
363 for each( var lbl:Object in this.user_labels )
364 {
365 var xVal:Number = sc.get_x_from_val(lbl.x);
366 this.graphics.beginFill(this.colour, 1);
367 this.graphics.drawRect( xVal-(this.stroke/2), sc.bottom + this.stroke, this.stroke, this.tick_height );
368 this.graphics.endFill();
369 }
370 }
371 else
372 {
373 for( var i:Number=this.style.min; i <= this.style.max; i+=this.steps )
374 {
375 xVal = sc.get_x_from_val(i);
376 this.graphics.beginFill(this.colour, 1);
377 this.graphics.drawRect( xVal-(this.stroke/2), sc.bottom + this.stroke, this.stroke, this.tick_height );
378 this.graphics.endFill();
379 }
380 }
381 }
382
383 public function get_height():Number {
384 if( this.three_d )
385 {
386 // 12 is the size of the slanty
387 // 3D part of the X axis
388 return this.three_d_height+12+this.tick_height + this.labels.get_height();
389 }
390 else
391 return this.stroke + this.tick_height + this.labels.get_height();
392 }
393
394 public function first_label_width() : Number
395 {
396 return this.labels.first_label_width();
397 }
398
399 public function last_label_width() : Number
400 {
401 return this.labels.last_label_width();
402 }
403
404 public function die(): void {
405
406 this.style = null;
407
408 this.graphics.clear();
409 while ( this.numChildren > 0 )
410 this.removeChildAt(0);
411
412 if (this.labels != null)
413 this.labels.die();
414 this.labels = null;
415 }
416 }
417}
Note: See TracBrowser for help on using the repository browser.