Book Image

ActionScript Graphing Cookbook

Book Image

ActionScript Graphing Cookbook

Overview of this book

"A picture is worth a thousand words" has never been more true than when representing large sets of data. Bar charts, heat maps, cartograms, and many more have become important tools in applications and presentations to quickly give insight into complicated issues.The "ActionScript Graphing Cookbook" shows you how to add your own charts to any ActionScript program. The recipes give step-by-step instructions on how to process the input data, how to create various types of charts and how to make them interactive for even more user engagement.Starting with basic ActionScript knowledge, you will learn how to develop many different types of charts.First learn how to import your data, from Excel, web services and more. Next process the data and make it ready for graphical display. Pick one of the many graph options available as the book guides you through ActionScript's drawing functions. And when you're ready for it, branch out into 3D display.The recipes in the "ActionScript Graphing Cookbook" will gradually introduce you into the world of visualization.
Table of Contents (17 chapters)
ActionScript Graphing Cookbook
Credits
About the Authors
About the Reviewers
www.PacktPub.com
Preface
Index

Adding labels and axes


Before diving into some more graph types, it's about time we started adding axes and scales. If we don't have those, there really is no way to properly interpret our nice charts.

In this recipe we will add a horizontal and vertical axis to the sine graph we created in the previous recipe. We will also add markers and labels.

Getting ready

This recipe continues to expand the Graph class presented in the previous recipe. So if you haven't written that yet, copy it from the provided sources.

Next, create a Recipe4 class, just as we did in the previous recipes.

How to do it...

To create axes, we will add two methods to the Graph class. They are as follows:

  • public function drawVerticalAxis(x:Number, y1:Number, y2:Number)

  • public function drawHorizontalAxis(y: Number, x1:Number, x2:Number)

Calling the methods will draw a straight line from (x,y1) to (x,y2) and (x1,y) to (x2,y), respectively.

  1. For our first implementation we can simply reuse the drawLine method.

    Add the following methods to the Graph class:

        public function drawVerticalAxis(x:Number, y1:Number, y2:Number)
        {
          drawLine(x, y1, x, y2);
        }
    
        public function drawHorizontalAxis(y: Number, x1:Number, x2:Number)
        {
          drawLine(x1, y, x2, y);
        }
  2. Now you can try them out in the Recipe4 class:

    package  
    {
      import flash.display.Sprite;
      import flash.geom.Point;
    
      public class Recipe4 extends Sprite
      {
        private var graph:Graph;
    
        public function Recipe4() 
        {
          graph = new Graph( -Math.PI/2, 1, Math.PI/2, -1);
          addChild(graph);
    
          graph.drawVerticalAxis(0, 1, -1);
          graph.drawHorizontalAxis(0, -Math.PI / 2, Math.PI /2);
    
          var i:Number = -Math.PI/2;
          var step:Number = 0.1;
          var previousPoint:Point = new Point(i,Math.sin(i));
          for (i += step; i <= Math.PI/2; i += step)
          {
            var point:Point = new Point(i, Math.sin(i));
            graph.drawLine(previousPoint.x, previousPoint.y ,point.x, point.y);
            previousPoint = point;
          }
        }
    
      }
    }

    The result should be the same graph as before, but now with two lines forming an axis.

    A typical axis has at least two features that make it actually useful:

    i. Regularly spaced tick marks.

    ii. Labels associated with those marks.

  3. We will first draw the marks. In order to do this, we first create a separate drawAxisLine method. This will also allow you to style the axes differently than the actual graph.

    A first revision of the drawHorizontalAxis method looks like the following code:

    public function drawHorizontalAxis(y: Number, x1:Number, x2:Number):void
    {
      var transformedLocation1:Point = matrix.transformPoint(new Point(x1, y));
      var transformedLocation2:Point = matrix.transformPoint(new Point(x2, y));
      drawAxisLine(transformedLocation1, transformedLocation2);
    }
    
    private function drawAxisLine(p1: Point, p2: Point):void
    {
      var line:Shape = new Shape();
      line.graphics.lineStyle(1, 0x000000);
      line.graphics.moveTo(p1.x, p1.y);
      line.graphics.lineTo(p2.x, p2.y);
      addChild(line);
    }
  4. Now we add marks. This uses a stepping algorithm very similar to the one we used for drawing a function. First we calculate the mark position on the axis and next a short line is drawn, perpendicular to the axis:

    public function drawHorizontalAxis(y: Number, x1:Number, x2:Number):void
    {
      var transformedLocation1:Point = matrix.transformPoint(new Point(x1, y));
      var transformedLocation2:Point = matrix.transformPoint(new Point(x2, y));
      drawAxisLine(transformedLocation1, transformedLocation2);
    
      var step:Number    = 50;
      for (var markX:Number = transformedLocation1.x; 
        markX <= transformedLocation2.x; 
        markX += step) 
      {
        var markPoint1:Point = new Point(markX, transformedLocation1.y);
        var markPoint2:Point = new Point(markX, transformedLocation1.y + 10);
        drawAxisLine(markPoint1, markPoint2);
    }
    }
  5. And finally we add labels. To display a label we use the ActionScript TextField class. This class has a tremendous amount of parameters that allow you to customize how the text is displayed. We will look at a few parameters in the later recipes, but for now, we use the standard formatting.

    We don't want to clutter the display too much, so we only add a text label every four markers:

    public function drawHorizontalAxis(y: Number, x1:Number, x2:Number):void
    {
      var transformedLocation1:Point = matrix.transformPoint(new Point(x1, y));
      var transformedLocation2:Point = matrix.transformPoint(new Point(x2, y));
      drawAxisLine(transformedLocation1, transformedLocation2);
    
      var labels:Array   = ["-PI/2","-PI/4","0","PI/4","PI/2"];
      var step:Number = 50;
      var labelCount:int = 0;
      for (var markX:Number = transformedLocation1.x; 
        markX <= transformedLocation2.x; 
        markX += step) 
      {
        var markPoint1:Point = new Point(markX, transformedLocation1.y);
        var markPoint2:Point = new Point(markX, transformedLocation1.y + 10);
        drawAxisLine(markPoint1, markPoint2);
    
        if (int(markX) % 200 == 0)
        {
          //place a label every 4 markers
          var textField:TextField = new TextField();
          textField.text = labels[labelCount++];
          textField.x = markX;
          textField.y = transformedLocation1.y + 12;
          addChild(textField);
        }
      }
    }
  6. Run the program again, and you'll see a horizontal axis with values.

How it works...

This recipe is probably one of the least spectacular ones. It just builds on top of ActionScript methods for drawing lines and displaying text. There's a lot of mechanical work involved in getting everything in the right location, but nothing complicated.

The best way to understand the recipe is to play with the various parameters:

  • Increase and decrease the marker step size

  • Change the size of the markers

  • Change the number of labels (make sure you have enough label values in the labels array; if not, you'll end up receiving error messages)

There's more...

Now let's talk about some other options, or possibly some pieces of general information that are relevant to this task.

Vertical axis

Only the code for the horizontal axis was shown. The code for the vertical axis is, of course, very similar and a great exercise.

Screen versus graph coordinates

All the axes drawing code was written in screen coordinates. This simplified a few things, but it could also make it more complex to correctly place the marks. A good exercise is to rewrite the code using graph coordinates.

Error checking and adding parameters

We haven't really bothered ourselves with adding error checking to the parameters (what if the first value of the axis coordinate is larger than the second?). We also haven't yet made the code more generic. You can add parameters for the number of marks you want to be shown on the labels.