Until now, we've used the most basic way of drawing points, lines, and areas. However, ActionScript's Graphic
class offers a wealth of different options to make your charts look more attractive.
In this recipe, we will give a short primer of some of the tools at your fingertips. We won't be able to cover them all, but this should help you on your way.
We start by having a graph that shows all three types of charts we've discussed:
package { import flash.display.Sprite; public class Recipe8 extends Sprite { private var graph:Graph; private var data:Array = [[0, 20], [50, 70], [100, 0], [150, 150], [200, 300], [250, 200], [300, 400], [350, 20], [400, 60], [450, 250], [500, 90], [550, 400], [600, 500], [650, 450], [700, 320]]; public function Recipe8() { graph = new Graph( -50, 550, 750, -50); addChild(graph); graph.drawHorizontalAxis(0, 0, 700, 50, ["0", "700"]); graph.drawVerticalAxis(0, 0, 500, 50, ["0", "250", "500"]); graph.drawPoint(data[0][0], data[0][1] + 50); for (var i:Number = 1; i < data.length; i++) { graph.drawArea(data[i - 1][0], data[i - 1][1], data[i][0], data[i][1]); graph.drawLine(data[i - 1][0], data[i - 1][1] + 25, data[i][0], data[i][1] + 25); graph.drawPoint(data[i][0], data[i][1] + 50); } } } }
Notice that we have shifted the y-coordinate of the different charts, so that it's clear which one is which. If you run this program you should see an area chart, 25 pixels higher a line graph, and the another 25 pixels higher a point chart.
For this recipe, we will use the freely available SweetiePlus icons, available at http://sublink.ca/icons/sweetieplus/. Copy any one of the icons you would like to the lib
folder of your project. For instance, the heart icon: heart-16-ns.png
.
If you open the folder in FlashDevelop, you should see the file appear. Place the cursor in the Recipe8
class file, just above the graph's var
definition.
Now right-click on the image and pick generate embed code. This will embed the image into your program and is the easiest and best way to embed small images like this.
If you use some other software, embedding images might be a little different: In Flash Builder you can use the [Embed]
metadata tag directly. Refer to: http://www.adobe.com/devnet/flash/articles/embed_metadata.html.
In Flash Professional, you can also add the resource to the stage and give it an instance name to address it directly without the need for an [Embed]
tag.
Just below the embed code, you now need to connect that embedded image to a class name. It looks like the following code:
… public class Recipe8 extends Sprite { [Embed(source = "../lib/heart-16-ns.png")] private var HeartClass:Class; private var graph:Graph;
We can now add a new drawBitmapPoint
method to the Graph
class:
public function drawBitmapPoint(x:Number, y:Number, BitmapClass:Class):void { var transformedLocation:Point = matrix.transformPoint(new Point(x, y)); var bitmapPoint: Bitmap = new BitmapClass(); bitmapPoint.x = transformedLocation.x - bitmapPoint.width / 2; bitmapPoint.y = transformedLocation.y - bitmapPoint.height / 2; addChild(bitmapPoint); }
However, we will explain one example, the drawing of a gradient-filled area:
public function drawGradientArea(x1:Number, y1:Number, x2:Number, y2:Number, y3:Number = 0, y4:Number = 0):void { var transformedLocation1:Point = matrix.transformPoint(new Point(x1, y1)); var transformedLocation2:Point = matrix.transformPoint(new Point(x2, y2)); var transformedLocation3:Point = matrix.transformPoint(new Point(x1, y3)); var transformedLocation4:Point = matrix.transformPoint(new Point(x2, y4)); var area:Shape = new Shape(); var gradType:String = GradientType.LINEAR; var colors:Array = [0xff9933, 0x9933ff]; var alphas:Array = [1, 1]; var ratios:Array = [100, 255]; var matrix:Matrix = new Matrix(); matrix.createGradientBox(stage.stageWidth, stage.stageHeight, Math.PI / 2); area.graphics.beginGradientFill(gradType, colors, alphas, ratios, matrix); area.graphics.moveTo(transformedLocation1.x, transformedLocation1.y); area.graphics.lineTo(transformedLocation2.x, transformedLocation2.y); area.graphics.lineTo(transformedLocation4.x, transformedLocation4.y); area.graphics.lineTo(transformedLocation3.x, transformedLocation3.y); area.graphics.endFill(); addChild(area); }
public function drawBitmapLine(x1:Number, y1:Number, x2:Number, y2:Number, BitmapClass:Class):void { var transformedLocation1:Point = matrix.transformPoint(new Point(x1, y1)); var transformedLocation2:Point = matrix.transformPoint(new Point(x2, y2)); var line:Shape = new Shape(); line.graphics.lineStyle(16, 0x000000); var bitmap:Bitmap = new BitmapClass(); line.graphics.lineBitmapStyle(bitmap.bitmapData); line.graphics.moveTo(transformedLocation1.x, transformedLocation1.y); line.graphics.lineTo(transformedLocation2.x, transformedLocation2.y); addChild(line); }
ActionScript's Graphic
class offers a rich set of drawing primitives. This allows you to create virtually any vector graphic you like. Some of the concepts will feel natural, while others can take a while to properly grasp. It's worth learning the ins and outs of the Graphics
class because a well-placed gradient or bitmap can really spice up any graph.
As in all other drawing methods we've seen in this chapter, first the coordinates are transformed.
When drawing a bitmap point, the embedded resource class is instantiated into a Bitmap
class. This is the class that will display the image.
Next we use some simple math to place the bitmap at the center of the coordinates. In ActionScript, the bitmap's (x , y) coordinates reflect the upper-left corner. So if we want to place the center of the bitmap at our coordinates, we need to subtract half of the width and height.
As usual, the final step is adding the bitmap to the graph sprite.
Drawing gradients requires extra work. To draw an area that is filled with a gradient, we use the beginGradientFill
method. It takes the following parameters:
GradientType.LINEAR
and GradientType.RADIAL
are supported.Optionally, you can also add a matrix that transforms the gradient. This will allow you to correctly place the gradient. In the case of this example, we stretch the gradient over the full screen and rotate it by 90 degrees.
When drawing bitmap fills for lines, there are a few points worth noting:
lineStyle
and lineBitmapStyle
methods. You can't take out the first one or you would not see anything drawn.lineBitmapStyle
method takes a BitmapData
class as an argument. The difference between this and the Bitmap
class, is that bitmap is the actual representation on the screen, while BitmapData
is just the bits that are needed to draw the bitmap. Hence BitmapData
does not have an x or y coordinate.If you want to change the exact placement of the bitmaps, the lineBitmapStyle
method takes an optional Matrix
as an argument. This works similar to all the other matrix operations we've seen. Getting this exactly right isn't easy, so you may need to do some experimentation.
We've only covered the very tip of the iceberg that is the Graphics
class.
As with most visual elements in ActionScript, bitmaps and gradients can be translated, rotated, made translucent, and much more. It's worth experimenting a little to get to know what's possible.
Most ActionScript books have good coverage of the Graphics
class. But there are also a few that go into much more detail.
Although it can be a bit hard to get into, the live docs also provide a fairly in-depth overview of the features. This is available at: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Graphics.html .
3.137.164.24