1package com.yahoo.astra.fl.charts.axes 2{ 3 import com.yahoo.astra.display.BitmapText; 4 import com.yahoo.astra.utils.DynamicRegistration; 5 import flash.geom.Point; 6 7 /** 8 * The default vertical axis renderer for a cartesian chart. 9 * 10 * @see com.yahoo.astra.fl.charts.CartesianChart 11 * @author Tripp Bridges 12 */ 13 public class VerticalAxisRenderer extends DefaultAxisRenderer implements ICartesianAxisRenderer 14 { 15 16 //-------------------------------------- 17 // Constructor 18 //-------------------------------------- 19 public function VerticalAxisRenderer() 20 { 21 super(); 22 this.orientation = AxisOrientation.VERTICAL; 23 } 24 25 //-------------------------------------- 26 // Protected Methods 27 //-------------------------------------- 28 29 /** 30 * @private 31 * Positions the title along the axis. 32 */ 33 override protected function positionTitle():void 34 { 35 var showTitle:Boolean = this.getStyleValue("showTitle") as Boolean; 36 this.titleTextField.visible = showTitle; 37 if(showTitle) 38 { 39 var titleRotation:Number = this.getStyleValue("titleRotation") as Number; 40 titleRotation = Math.max(-90, Math.min(titleRotation, 90)); 41 42 this.titleTextField.rotation = titleRotation; 43 if(this.position == "right") 44 { 45 this.titleTextField.y = this.contentBounds.y + (this.contentBounds.height) / 2; 46 this.titleTextField.x = this.width - this.titleTextField.width; 47 } 48 else 49 { 50 this.titleTextField.y = this.contentBounds.y + (this.contentBounds.height) / 2; 51 this.titleTextField.x = 0; 52 } 53 if(titleRotation > 0) 54 { 55 this.titleTextField.x += this.titleTextField.contentHeight * Math.sin(titleRotation * Math.PI/180); 56 this.titleTextField.y -= this.titleTextField.height/2; 57 } 58 else if(titleRotation < 0) 59 { 60 this.titleTextField.y += this.titleTextField.height/2; 61 } 62 else 63 { 64 this.titleTextField.y -= this.titleTextField.height/2; 65 } 66 } 67 } 68 69 /** 70 * @private 71 * Draws the axis origin line. 72 */ 73 override protected function drawAxis():void 74 { 75 super.drawAxis(); 76 var verticalX:Number = this.contentBounds.x; 77 if(this.position == "right") 78 { 79 verticalX = this.contentBounds.x + this.contentBounds.width; 80 } 81 var verticalStart:Number = this.contentBounds.y; 82 var verticalEnd:Number = this.contentBounds.y + this.contentBounds.height; 83 this.graphics.moveTo(verticalX, verticalStart); 84 this.graphics.lineTo(verticalX, verticalEnd); 85 } 86 87 /** 88 * @private 89 * Draws a set of ticks on the axis. 90 */ 91 override protected function drawTicks(data:Array, showTicks:Boolean, tickPosition:String, 92 tickLength:Number, tickWeight:Number, tickColor:uint):void 93 { 94 if(!showTicks) 95 { 96 return; 97 } 98 99 this.graphics.lineStyle(tickWeight, tickColor); 100 101 var axisPosition:Number = this.position == "right" ? this.contentBounds.x + this.contentBounds.width : this.contentBounds.x; 102 if(this.position == "right") tickLength *= -1; 103 var dataCount:int = data.length; 104 for(var i:int = 0; i < dataCount; i++) 105 { 106 var axisData:AxisData = AxisData(data[i]); 107 if(isNaN(axisData.position)) 108 { 109 //skip bad positions 110 continue; 111 } 112 113 var position:Number = axisData.position; 114 position += this.contentBounds.y; 115 116 switch(tickPosition) 117 { 118 case TickPosition.OUTSIDE: 119 this.graphics.moveTo(axisPosition - tickLength, position); 120 this.graphics.lineTo(axisPosition, position); 121 break; 122 123 case TickPosition.INSIDE: 124 this.graphics.moveTo(axisPosition, position); 125 this.graphics.lineTo(axisPosition + tickLength, position); 126 break; 127 128 default: //CROSS 129 this.graphics.moveTo(axisPosition - tickLength / 2, position); 130 this.graphics.lineTo(axisPosition + tickLength / 2, position); 131 break; 132 } 133 } 134 } 135 136 /** 137 * @private 138 * Positions a set of labels on the axis. 139 */ 140 override protected function positionLabels(labels:Array, showLabels:Boolean, labelDistance:Number, labelRotation:Number, embedFonts:Boolean):void 141 { 142 if(!showLabels) return; 143 var labelCount:int = this.labelTextFields.length; 144 for(var i:int = 0; i < labelCount; i++) 145 { 146 var label:BitmapText = BitmapText(this.labelTextFields[i]); 147 label.rotation = 0; 148 var axisData:AxisData = AxisData(this.ticks[i]); 149 var position:Number = axisData.position; 150 position += this.contentBounds.y; 151 var absRotation:Number = Math.abs(labelRotation); 152 var xRegistration:Number; 153 label.y = position; 154 155 if(this.position == "left") 156 { 157 label.x = this.contentBounds.x - labelDistance - this.outerTickOffset; 158 xRegistration = label.width - Math.min(label.height/2, Math.sin(absRotation * Math.PI/180) * label.height/4); 159 if(absRotation > 0 && absRotation < 90) 160 { 161 label.y -= label.height/2; 162 label.x -= label.width; 163 DynamicRegistration.rotate(label, new Point(xRegistration, label.height / 2), labelRotation); 164 } 165 else if(labelRotation == 90) 166 { 167 label.rotation = labelRotation; 168 label.y -= label.height/2; 169 } 170 else if(labelRotation == -90) 171 { 172 label.rotation = labelRotation; 173 label.x -= label.width; 174 label.y += label.height/2; 175 } 176 else 177 { 178 label.x -= label.width; 179 label.y -= label.height/2; 180 } 181 } 182 else 183 { 184 label.x = this.contentBounds.x + this.contentBounds.width + labelDistance + this.outerTickOffset; 185 xRegistration = Math.min(label.height/2, Math.sin(absRotation * Math.PI/180) * label.height/4); 186 if(absRotation > 0 && absRotation < 90) 187 { 188 label.y -= label.height/2; 189 DynamicRegistration.rotate(label, new Point(xRegistration, label.height / 2), labelRotation); 190 } 191 else if(labelRotation == 90) 192 { 193 label.rotation = labelRotation; 194 label.y -= label.height/2; 195 label.x += label.width; 196 } 197 else if(labelRotation == -90) 198 { 199 DynamicRegistration.rotate(label, new Point(xRegistration, label.height / 2), labelRotation); 200 label.y += label.height/2; 201 } 202 else 203 { 204 label.y -= label.height/2; 205 } 206 } 207 208 label.x = Math.round(label.x); 209 label.y = Math.round(label.y); 210 this.handleOverlappingLabels(); 211 } 212 } 213 214 /** 215 * @private 216 * If labels overlap, some may need to be hidden. 217 */ 218 override protected function handleOverlappingLabels():void 219 { 220 var showLabels:Boolean = this.getStyleValue("showLabels"); 221 var hideOverlappingLabels:Boolean = this.getStyleValue("hideOverlappingLabels"); 222 if(!showLabels || !hideOverlappingLabels) 223 { 224 return; 225 } 226 var labelRotation:Number = this.getStyleValue("labelRotation") as Number; 227 var lastVisibleLabel:BitmapText; 228 var labelCount:int = this.labelTextFields.length; 229 for(var i:int = 0; i < labelCount; i++) 230 { 231 var idealDistance:Number; 232 var index:int = labelRotation >= 0 ? i : (labelCount - i - 1); 233 var label:BitmapText = BitmapText(this.labelTextFields[index]); 234 label.visible = true; 235 if(lastVisibleLabel) 236 { 237 var diff:Number; 238 var offset:Point; 239 offset = new Point(0, 0); 240 var radians:Number = Math.abs(labelRotation) * Math.PI/180; 241 if(lastVisibleLabel.y > label.y) 242 { 243 if(Math.abs(labelRotation) == 90) 244 { 245 idealDistance = label.textField.textWidth; 246 } 247 else if(labelRotation == 0) 248 { 249 idealDistance = label.textField.textHeight; 250 } 251 else 252 { 253 idealDistance = (label.textField.textHeight / (Math.cos((Math.abs(labelRotation))*Math.PI/180))); 254 idealDistance = Math.min(idealDistance, label.height); 255 } 256 if((label.y + label.height + idealDistance) > (lastVisibleLabel.y + lastVisibleLabel.height)) 257 { 258 label.visible = false; 259 } 260 } 261 else 262 { 263 if(Math.abs(labelRotation) == 90) 264 { 265 idealDistance = lastVisibleLabel.textField.textWidth; 266 } 267 else if(labelRotation == 0) 268 { 269 idealDistance = lastVisibleLabel.textField.textHeight; 270 } 271 else 272 { 273 idealDistance = (lastVisibleLabel.textField.textHeight / (Math.cos((Math.abs(labelRotation))*Math.PI/180))); 274 idealDistance = Math.min(idealDistance, lastVisibleLabel.height); 275 } 276 if((lastVisibleLabel.y + lastVisibleLabel.height + idealDistance) > (label.y + label.height)) 277 { 278 label.visible = false; 279 } 280 } 281 } 282 if(label.visible) 283 { 284 lastVisibleLabel = label; 285 } 286 } 287 } 288 289 290 } 291}