1//////////////////////////////////////////////////////////////////////////////// 2// 3// ADOBE SYSTEMS INCORPORATED 4// Copyright 2009 Adobe Systems Incorporated 5// All Rights Reserved. 6// 7// NOTICE: Adobe permits you to use, modify, and distribute this file 8// in accordance with the terms of the license agreement accompanying it. 9// 10//////////////////////////////////////////////////////////////////////////////// 11 12package mx.charts.effects.effectClasses 13{ 14 15import flash.geom.Point; 16import flash.geom.Rectangle; 17 18/** 19 * The SeriesZoomInstance class implements the instance class 20 * for the SeriesZoom effect. 21 * Flex creates an instance of this class when it plays a SeriesZoom effect; 22 * you do not create one yourself. 23 * 24 * @see mx.charts.effects.SeriesZoom 25 * 26 * @langversion 3.0 27 * @playerversion Flash 9 28 * @playerversion AIR 1.1 29 * @productversion Flex 3 30 */ 31public class SeriesZoomInstance extends SeriesEffectInstance 32{ 33 include "../../../core/Version.as"; 34 35 //-------------------------------------------------------------------------- 36 // 37 // Class constants 38 // 39 //-------------------------------------------------------------------------- 40 41 /** 42 * @private 43 */ 44 private static var BOTH:uint = 0; 45 46 /** 47 * @private 48 */ 49 private static var HORIZONTAL:uint = 1; 50 51 /** 52 * @private 53 */ 54 private static var VERTICAL:uint = 2; 55 56 //-------------------------------------------------------------------------- 57 // 58 // Constructor 59 // 60 //-------------------------------------------------------------------------- 61 62 /** 63 * Constructor. 64 * 65 * @param target The target of the effect. 66 * 67 * @langversion 3.0 68 * @playerversion Flash 9 69 * @playerversion AIR 1.1 70 * @productversion Flex 3 71 */ 72 public function SeriesZoomInstance(target:Object) 73 { 74 super(target); 75 } 76 77 //-------------------------------------------------------------------------- 78 // 79 // Variables 80 // 81 //-------------------------------------------------------------------------- 82 83 /** 84 * @private 85 */ 86 private var _direction:uint; 87 88 /** 89 * @private 90 */ 91 private var _elementBounds:Array /* of Rectangle */; 92 93 /** 94 * @private 95 */ 96 private var _slideDistance:Number; 97 98 /** 99 * @private 100 */ 101 private var _zoomPoints:Array /* of Point */; 102 103 /** 104 * @private 105 */ 106 private var seriesRenderData:Object; 107 108 109 //-------------------------------------------------------------------------- 110 // 111 // Properties 112 // 113 //-------------------------------------------------------------------------- 114 115 //---------------------------------- 116 // horizontalFocus 117 //---------------------------------- 118 119 [Inspectable(category="General", enumeration="left,center,right")] 120 121 /** 122 * Defines the location of the focul point of the zoom. 123 * 124 * <p>Valid values of <code>horizontalFocus</code> are 125 * <code>"left"</code>, <code>"center"</code>, <code>"right"</code>, 126 * and <code>null</code>.</p> 127 * The default value is <code>"center"</code>. 128 * 129 * <p>You combine the <code>horizontalFocus</code> and 130 * <code>verticalFocus</code> properties to define where the data series 131 * zooms in and out from. 132 * For example, set <code>horizontalFocus</code> to <code>"left"</code> 133 * and <code>verticalFocus</code> to <code>"top"</code> to zoom 134 * the series data to and from the top left corner of either the element 135 * or the chart (depending on the setting of the 136 * <code>relativeTo</code> property).</p> 137 * 138 * <p>If you specify only one of these two properties, then the focus 139 * is a horizontal or vertical line rather than a point. 140 * For example, when you set <code>horizontalFocus</code> to 141 * <code>"left"</code> but <code>verticalFocus</code> to 142 * <code>null</code>, the element zooms to and from a vertical line 143 * along the left edge of its bounding box. 144 * Set <code>verticalFocus</code> to <code>"center"</code> to zoom 145 * chart elements to and from a horizontal line along the middle 146 * of the chart's bounding box.</p> 147 * 148 * @langversion 3.0 149 * @playerversion Flash 9 150 * @playerversion AIR 1.1 151 * @productversion Flex 3 152 */ 153 public var horizontalFocus:String; 154 155 //---------------------------------- 156 // relativeTo 157 //---------------------------------- 158 159 [Inspectable(category="General", enumeration="series,chart", defaultValue="series")] 160 161 /** 162 * Controls the bounding box that Flex uses to calculate 163 * the focal point of the zooms. 164 * 165 * <p>Valid values for <code>relativeTo</code> are 166 * <code>"series"</code> and <code>"chart"</code>. 167 * The default value is <code>"series"</code>.</p> 168 * 169 * <p>Set to <code>"series"</code> to zoom each element 170 * relative to itself. 171 * For example, each column of a ColumnChart zooms from the top left 172 * of the column, the center of the column, and so on.</p> 173 * 174 * <p>Set to <code>"chart"</code> to zoom each element 175 * relative to the chart area. 176 * For example, each column zooms from the top left of the axes, 177 * the center of the axes, and so on.</p> 178 * 179 * @langversion 3.0 180 * @playerversion Flash 9 181 * @playerversion AIR 1.1 182 * @productversion Flex 3 183 */ 184 public var relativeTo:String = "series"; 185 186 //---------------------------------- 187 // verticalFocus 188 //---------------------------------- 189 190 [Inspectable(category="General", enumeration="top,center,bottom")] 191 192 /** 193 * Defines the location of the focul point of the zoom. 194 * 195 * <p>Valid values of <code>verticalFocus</code> are 196 * <code>"top"</code>, <code>"center"</code>, <code>"bottom"</code>, 197 * and <code>null</code>. 198 * The default value is <code>"center"</code>.</p> 199 * 200 * <p>For more information, see the description of the 201 * <code>horizontalFocus</code> property.</p> 202 * 203 * @langversion 3.0 204 * @playerversion Flash 9 205 * @playerversion AIR 1.1 206 * @productversion Flex 3 207 */ 208 public var verticalFocus:String; 209 210 //-------------------------------------------------------------------------- 211 // 212 // Overridden methods 213 // 214 //-------------------------------------------------------------------------- 215 216 /** 217 * @private 218 */ 219 override public function play():void 220 { 221 seriesRenderData = targetSeries.getRenderDataForTransition(type); 222 223 targetSeries.getElementBounds(seriesRenderData); 224 var elementBounds:Array /* of Rectangle */ = _elementBounds = 225 seriesRenderData.elementBounds; 226 227 var activeBounds:Array /* of Rectangle */ = []; 228 var zoomPoints:Array /* of Point */ = []; 229 230 var n:int = elementBounds.length; 231 var i:int; 232 var pt:Point; 233 var v:Rectangle; 234 235 if (relativeTo == "series") 236 { 237 loadSeriesRelativePoints(zoomPoints, elementBounds); 238 } 239 else 240 { 241 loadChartRelativePoints(zoomPoints, elementBounds, 242 seriesRenderData.visibleRegion); 243 } 244 245 if (type == "show") 246 { 247 switch (_direction) 248 { 249 case BOTH: 250 { 251 for (i = 0; i < n; i++) 252 { 253 pt = zoomPoints[i]; 254 activeBounds[i] = new Rectangle(pt.x, pt.y, 0, 0); 255 } 256 break; 257 } 258 259 case HORIZONTAL: 260 { 261 for (i = 0; i < n; i++) 262 { 263 pt = zoomPoints[i]; 264 v = elementBounds[i]; 265 activeBounds[i] = 266 new Rectangle(pt.x, v.top, 0, v.height); 267 } 268 break; 269 } 270 271 case VERTICAL: 272 { 273 for (i = 0; i < n; i++) 274 { 275 pt = zoomPoints[i]; 276 v = elementBounds[i]; 277 activeBounds[i] = 278 new Rectangle(v.left, pt.y, v.width, 0); 279 } 280 break; 281 } 282 } 283 } 284 else 285 { 286 for (i = 0; i < n; i++) 287 { 288 v = elementBounds[i]; 289 activeBounds[i] = elementBounds[i].clone(); 290 } 291 } 292 293 seriesRenderData.elementBounds = activeBounds; 294 targetSeries.transitionRenderData = seriesRenderData; 295 _zoomPoints = zoomPoints; 296 297 beginTween(n); 298 } 299 300 /** 301 * @private 302 */ 303 override public function onTweenUpdate(value:Object):void 304 { 305 super.onTweenUpdate(value); 306 307 var elementBounds:Array /* of Rectangle */ = _elementBounds; 308 var activeBounds:Array /* of Rectangle */ = seriesRenderData.elementBounds; 309 var zoomPoints:Array /* of Point */ = _zoomPoints; 310 311 var n:int = elementBounds.length; 312 var base:Number = 0; 313 var scale:Number = 1; 314 var i:int; 315 var v:Rectangle; 316 var pt:Point; 317 var interpolation:Number; 318 319 if (type == "hide") 320 { 321 base = 1; 322 scale = -1; 323 } 324 { 325 switch (_direction) 326 { 327 case BOTH: 328 { 329 for (i = 0; i < n; i++) 330 { 331 interpolation = base + scale * interpolationValues[i]; 332 v = elementBounds[i]; 333 334 pt = zoomPoints[i]; 335 activeBounds[i] = new Rectangle( 336 pt.x + (v.left - pt.x) * interpolation, 337 pt.y + (v.top - pt.y) * interpolation, 338 v.width * interpolation, 339 v.height * interpolation); 340 } 341 break; 342 } 343 344 case HORIZONTAL: 345 { 346 for (i = 0; i < n; i++) 347 { 348 interpolation = base + scale * interpolationValues[i]; 349 v = elementBounds[i]; 350 351 pt = zoomPoints[i]; 352 activeBounds[i] = new Rectangle( 353 pt.x + (v.left - pt.x) * interpolation, v.top, 354 v.width *interpolation, v.height); 355 } 356 break; 357 } 358 359 case VERTICAL: 360 { 361 for (i = 0; i < n; i++) 362 { 363 interpolation = base + scale * interpolationValues[i]; 364 v = elementBounds[i]; 365 366 pt = zoomPoints[i]; 367 activeBounds[i] = new Rectangle( 368 v.left, pt.y + (v.top - pt.y) * interpolation, 369 v.width, v.height * interpolation); 370 } 371 break; 372 } 373 } 374 } 375 376 targetSeries.invalidateDisplayList(); 377 } 378 379 /** 380 * @private 381 */ 382 override public function onTweenEnd(value:Object):void 383 { 384 super.onTweenEnd(value); 385 386 targetSeries.transitionRenderData = null; 387 } 388 389 //-------------------------------------------------------------------------- 390 // 391 // Methods 392 // 393 //-------------------------------------------------------------------------- 394 395 /** 396 * @private 397 */ 398 private function loadChartRelativePoints(zoomPoints:Array /* of Point */, 399 elementBounds:Array /* of Rectangle */, 400 visibleRegion:Rectangle):void 401 { 402 var n:int = elementBounds.length; 403 var i:int; 404 var pt:Point; 405 406 if (!visibleRegion) 407 visibleRegion = new Rectangle(0, 0, 408 targetSeries.width / Math.abs(targetSeries.scaleX), 409 targetSeries.height / Math.abs(targetSeries.scaleY)); 410 411 switch (horizontalFocus) 412 { 413 case "left": 414 { 415 switch (verticalFocus) 416 { 417 case "top": 418 { 419 _direction = BOTH; 420 pt = visibleRegion.topLeft; 421 for (i = 0; i < n; i++) 422 { 423 zoomPoints[i] = pt; 424 } 425 break; 426 } 427 428 case "center": 429 { 430 _direction = BOTH; 431 pt = new Point(visibleRegion.left, 432 visibleRegion.top + 433 visibleRegion.height / 2); 434 for (i = 0; i < n; i++) 435 { 436 zoomPoints[i] = pt; 437 } 438 break; 439 } 440 441 case "bottom": 442 { 443 _direction = BOTH; 444 pt = new Point(visibleRegion.left, 445 visibleRegion.bottom); 446 for (i = 0; i < n; i++) 447 { 448 zoomPoints[i] = pt; 449 } 450 break; 451 } 452 453 default: 454 { 455 _direction = HORIZONTAL; 456 pt = new Point(visibleRegion.left, NaN); 457 for (i = 0; i < n; i++) 458 { 459 zoomPoints[i] = pt; 460 } 461 break; 462 } 463 } 464 break; 465 } 466 467 case "right": 468 { 469 switch (verticalFocus) 470 { 471 case "top": 472 { 473 _direction = BOTH; 474 pt = new Point(visibleRegion.right, 475 visibleRegion.top); 476 for (i = 0; i < n; i++) 477 { 478 zoomPoints[i] = pt; 479 } 480 break; 481 } 482 483 case "center": 484 { 485 _direction = BOTH; 486 pt = new Point(visibleRegion.right, 487 visibleRegion.top + 488 visibleRegion.height / 2); 489 for (i = 0; i < n; i++) 490 { 491 zoomPoints[i] = pt; 492 } 493 break; 494 } 495 496 case "bottom": 497 { 498 _direction = BOTH; 499 pt = visibleRegion.bottomRight; 500 for (i = 0; i < n; i++) 501 { 502 zoomPoints[i] = pt; 503 } 504 break; 505 } 506 507 default: 508 { 509 _direction = HORIZONTAL; 510 pt = new Point(visibleRegion.right, NaN); 511 for (i = 0; i < n; i++) 512 { 513 zoomPoints[i] = pt; 514 } 515 break; 516 } 517 } 518 break; 519 } 520 521 case "center": 522 { 523 switch (verticalFocus) 524 { 525 case "top": 526 { 527 _direction = BOTH; 528 pt = new Point(visibleRegion.left + 529 visibleRegion.width / 2, 530 visibleRegion.top); 531 for (i = 0; i < n; i++) 532 { 533 zoomPoints[i] = pt; 534 } 535 break; 536 } 537 538 case "center": 539 { 540 _direction = BOTH; 541 pt = new Point(visibleRegion.left + 542 visibleRegion.width / 2, 543 visibleRegion.top + 544 visibleRegion.height / 2); 545 for (i = 0; i < n; i++) 546 { 547 zoomPoints[i] = pt; 548 } 549 break; 550 } 551 552 case "bottom": 553 { 554 _direction = BOTH; 555 pt = new Point(visibleRegion.left + 556 visibleRegion.width / 2, 557 visibleRegion.bottom); 558 for (i = 0; i < n; i++) 559 { 560 zoomPoints[i] = pt; 561 } 562 break; 563 } 564 565 default: 566 { 567 _direction = HORIZONTAL; 568 pt = new Point(visibleRegion.left + 569 visibleRegion.width / 2, 570 NaN); 571 for (i = 0; i < n; i++) 572 { 573 zoomPoints[i] = pt; 574 } 575 break; 576 } 577 } 578 break; 579 } 580 581 default: 582 { 583 switch (verticalFocus) 584 { 585 case "top": 586 { 587 _direction = VERTICAL; 588 pt = new Point(NaN, visibleRegion.top); 589 for (i = 0; i < n; i++) 590 { 591 zoomPoints[i] = pt; 592 } 593 break; 594 } 595 596 case "center": 597 { 598 _direction = VERTICAL; 599 pt = new Point(NaN, 600 visibleRegion.top + 601 visibleRegion.height / 2); 602 for (i = 0; i < n; i++) 603 { 604 zoomPoints[i] = pt; 605 } 606 break; 607 } 608 609 case "bottom": 610 { 611 _direction = VERTICAL; 612 pt = new Point(NaN, visibleRegion.bottom); 613 for (i = 0; i < n; i++) 614 { 615 zoomPoints[i] = pt; 616 } 617 break; 618 } 619 620 default: 621 { 622 _direction = BOTH; 623 pt = new Point(visibleRegion.left + 624 visibleRegion.width / 2, 625 visibleRegion.top + 626 visibleRegion.height / 2); 627 for (i = 0; i < n; i++) 628 { 629 zoomPoints[i] = pt; 630 } 631 break; 632 } 633 } 634 break; 635 } 636 } 637 } 638 639 /** 640 * @private 641 */ 642 private function loadSeriesRelativePoints(zoomPoints:Array /* of Point */, 643 elementBounds:Array /* of Rectangle */):void 644 { 645 var n:int = elementBounds.length; 646 var i:int; 647 var v:Rectangle; 648 var pt:Point; 649 650 switch (horizontalFocus) 651 { 652 case "left": 653 { 654 switch (verticalFocus) 655 { 656 case "top": 657 { 658 _direction= BOTH; 659 for (i = 0; i < n; i++) 660 { 661 v = elementBounds[i]; 662 zoomPoints[i] = new Point(v.left, v.top); 663 } 664 break; 665 } 666 667 case "center": 668 { 669 _direction = BOTH; 670 for (i = 0; i < n; i++) 671 { 672 v = elementBounds[i]; 673 zoomPoints[i] = new Point(v.left, 674 (v.top + v.bottom) / 2); 675 } 676 break; 677 } 678 679 case "bottom": 680 { 681 _direction = BOTH; 682 for (i = 0; i < n; i++) 683 { 684 v = elementBounds[i]; 685 zoomPoints[i] = new Point(v.left, v.bottom); 686 } 687 break; 688 } 689 690 default: 691 { 692 _direction = HORIZONTAL; 693 for (i = 0; i < n; i++) 694 { 695 v = elementBounds[i]; 696 zoomPoints[i] = new Point(v.left,NaN); 697 } 698 break; 699 } 700 } 701 break; 702 } 703 704 case "right": 705 { 706 switch (verticalFocus) 707 { 708 case "top": 709 { 710 _direction = BOTH; 711 for (i = 0; i < n; i++) 712 { 713 v = elementBounds[i]; 714 zoomPoints[i] = new Point(v.right, v.top); 715 } 716 break; 717 } 718 719 case "center": 720 { 721 _direction = BOTH; 722 for (i = 0; i < n; i++) 723 { 724 v = elementBounds[i]; 725 zoomPoints[i] = new Point(v.right, 726 (v.top + v.bottom) / 2); 727 } 728 break; 729 } 730 731 case "bottom": 732 { 733 _direction = BOTH; 734 for (i = 0; i < n; i++) 735 { 736 v = elementBounds[i]; 737 zoomPoints[i] = new Point(v.right, v.bottom); 738 } 739 break; 740 } 741 742 default: 743 { 744 _direction = HORIZONTAL; 745 for (i = 0; i < n; i++) 746 { 747 v = elementBounds[i]; 748 zoomPoints[i] = new Point(v.right,NaN); 749 } 750 break; 751 } 752 } 753 break; 754 } 755 756 case "center": 757 { 758 switch (verticalFocus) 759 { 760 case "top": 761 { 762 _direction = BOTH; 763 for (i = 0; i < n; i++) 764 { 765 v = elementBounds[i]; 766 zoomPoints[i] = new Point((v.left + v.right) / 2, 767 v.top); 768 } 769 break; 770 } 771 772 case "center": 773 { 774 _direction = BOTH; 775 for (i = 0; i < n; i++) 776 { 777 v = elementBounds[i]; 778 zoomPoints[i] = new Point((v.left + v.right) / 2, 779 (v.top + v.bottom) / 2); 780 } 781 break; 782 } 783 784 case "bottom": 785 { 786 _direction = BOTH; 787 for (i = 0; i < n; i++) 788 { 789 v = elementBounds[i]; 790 zoomPoints[i] = new Point((v.left + v.right) / 2, 791 v.bottom); 792 } 793 break; 794 } 795 796 default: 797 { 798 _direction = HORIZONTAL; 799 for (i = 0; i < n; i++) 800 { 801 v = elementBounds[i]; 802 zoomPoints[i] = new Point((v.right + v.left) / 2, 803 NaN); 804 } 805 break; 806 } 807 } 808 break; 809 } 810 811 default: 812 { 813 switch (verticalFocus) 814 { 815 case "top": 816 { 817 _direction = VERTICAL; 818 for (i = 0; i < n; i++) 819 { 820 v = elementBounds[i]; 821 zoomPoints[i] = new Point(NaN, v.top); 822 } 823 break; 824 } 825 826 case "center": 827 { 828 _direction = VERTICAL; 829 for (i = 0; i < n; i++) 830 { 831 v = elementBounds[i]; 832 zoomPoints[i] = new Point(NaN, 833 (v.top + v.bottom) / 2); 834 } 835 break; 836 } 837 838 case "bottom": 839 { 840 _direction = VERTICAL; 841 for (i = 0; i < n; i++) 842 { 843 v = elementBounds[i]; 844 zoomPoints[i] = new Point(NaN, v.bottom); 845 } 846 break; 847 } 848 849 default: 850 { 851 _direction = BOTH; 852 for (i = 0; i < n; i++) 853 { 854 v = elementBounds[i]; 855 zoomPoints[i] = new Point((v.left + v.right) / 2, 856 (v.top + v.bottom) / 2); 857 } 858 break; 859 } 860 } 861 break; 862 } 863 } 864 } 865} 866 867} 868