To read the article online, visit http://www.4GuysFromRolla.com/webtech/111302-1.3.shtml

Real-time Animated Graphing using Flash MX, Part 3

By Pallav Nadhani


  • Read Part 1
  • Read Part 2

  • In Part 2 we looked at the XML data structure and examined the first few stages in preparing our Flash movie. In this part we'll look at the code needed for actually rendering the graph through Flash.

    Setting the Canvas and other Graph Elements
    Create a new layer named Canvas and on the frames of this layer draw a graph canvas as you would like it to be. As for me, I have drawn a 3d canvas of size 250x200 px. It's always a better idea to draw this canvas inside a separate movie clip and then place an instance of that movie clip on the stage - as it gives added flexibility.

    Now, we need to set up the textboxes which would contain the graph caption, x-axis and y-axis names and the y-axis upper and lower limits. For all these textboxes, create a new layer named Textboxes and place five dynamic textboxes (with HTML support on) on the stage (as shown below) with their variable names as: tbGraphCaption, tbyaxisname, tbxaxisname, tbyaxisminvalue, and tbyaxismaxvalue. Also, add another keyframe to the Actions and Labels layer with its name as SetProperties.

    Now, bring up the actions Panel for the SetProperties frame and enter the following ActionScript:

    tbGraphCaption = "<P align='left'><B>"+ String(caption) +"</B></P>";
    
    tbxaxisname = "<P Align='center'><B>" + String(xaxisname) + "</B></P>";
    tbyaxisname = "<P Align='center'><B>" + String(yaxisname) + "</B></P>";
    tbyaxisminvalue = "<P Align='right'>" + String(yaxisminvalue) + "</P>";
    tbyaxismaxvalue = "<P Align='right'>" + String(yaxismaxvalue) + "</P>";
    
    setcolor = new Color("MCIBg");
    setcolor.setRGB(parseInt(bgcolor, 16));
    
    play();
    

    As you can see from the ActionScript above, the SetProperties frame specifies the HTML for the various textboxes.

    At this point we've examined how to read the contents of the XML data file into an array, how to add the textboxes, and how to specify aesthetic properties. At this point let's turn our attention to the final piece of the puzzle - actually rendering the graph!

    Rendering the Graph
    Since, we are going to create an animated graph, our whole graph ActionScript and objects will be spanned across three keyframes. The first frame will be responsible for calculating and initializing the graph properties. The second will be responsible for drawing the lines in an animated way. And, the third will be responsible for setting the name and value textboxes and checking whether all of the lines have been drawn.

    So, create three new frames on the layers Actions and Labels and name them as Graph, MakeLines and Finalize.

    The Initialization Process
    Open up the Actions panel for the Graph keyframe and enter the following ActionScript:

    // specify constants
    constmaxheight = 200;
    constbasebypos = 255;
    constbasebxpos = 74.7;
    animspeed=1;
    constlinethickness = 2;
    
    intperunitpixels = constmaxheight/(Number(_root.yaxismaxvalue)
                    -Number(_root.yaxisminvalue));
    spacing = Math.round(235/(num-1));
    
    posy = new Array();
    for (i=1; i<=_root.num; i++) {
    	posy[i] = constbasebypos-(Number(_root.datavalue[i])-
    	                _root.yaxisminvalue)*intperunitpixels;
    }
    
    posx = new Array();
    for (i=1; i<=_root.num; i++) {
    	posx[i] = (constbasebxpos+5)+((i-1)*spacing);
    }
    
    curr = 1;
    
    currx = posx[curr];
    curry = posy[curr];
    
    _root.createEmptyMovieClip("lines", 1000);
    
    with (_root.lines) {
    	moveTo(currx, curry);
    }
    
    gotoAndPlay("MakeLines");
    

    The ActionScript for the Graph frame starts by first determining constant values for the height and bottom x and y positions of the canvas, since all the points calculations have to be done with the canvas (plot) area in mind. In addition to these constants we also specify a constant animation speed and line thickness.

    Next we determine the per-unit-pixel factor, that is, what unit does one pixel represent. For example, if the max value is 100 and min value is 0, each pixel represents 0.5 units (since our canvas height is 200 pixels). Based on this per-unit-pixel factor, we calculate the x and y co-ordinates of each data set. In addition, we calculate the spacing that's going be in between two data points (x,y) and (x1,y1).

    Two new arrays are created to store values multiplied by a factor. The first array stores the actual y points represented on the canvas by the data values. The second array stores the x position of each point. We then set the initialization values. curr is the variable that indicates the index of the dataset that is currently being plotted. The first dataset is indexed as 1 and therefore we start the rendering process with the first dataset.

    The createEmptyMovieClip function call creates a placeholder for the line chart. We then move our drawing pointer to the initialization point i.e., currx, curry. Finally, we shift the control to the frame MakeLines to draw the lines.

    Making the Lines
    The ActionScript contained in the frame MakeLines is responsible for increasing the size of the line by the number of pixels specified by animspeed (to give the animation effect).

    _root.lines.lineStyle(constlinethickness, 
                      "0x"+_root.datacolor[curr],100);
    _root.lines.lineTo(currx, curry);
    play();
    

    This ActionScript code first sets the line style using the lineStyle method of the Flash drawing API. This method takes in three parameters, namely line thickness, line color and the line alpha. We now draw a line to the position currx, curry. We keep on playing, which moves the pointer to Finalize Frame.

    The Finalize Frame
    The following ActionScript contained in the Finalize frame helps us to recurse between the MakeLines frame and Finalize frame to create the animated lines for all the datasets. Essentially we keep toggling back between these two frames until the lines are completely drawn. The ActionScript to accomplish this is given below:

    if (curr<=_root.num) {
      if (currx<posx[curr]) {
        if (currx+Number(animspeed)<=posx[curr]) {
          currx = currx+Number(animspeed);
        } else {
          currx++;
        }
        //calculating curry using formula y-y' = m(x-x')
        m = (posy[curr]-posy[curr-1])/(posx[curr]-posx[curr-1]);
        curry = m*(currx-posx[curr-1])+posy[curr-1];
        gotoAndPlay("MakeLines");
      } else {
        setValue(curr, posx[curr], posy[curr]);
        setName(curr, posx[curr], 280);
        _root.lines.moveTo(posx[curr], posy[curr]);
        currx = posx[curr];
        curry = posy[curr];
        curr++;
        gotoAndPlay("MakeLines");
      }
    } else {
      stop();
    }
    

    We first check if lines have been drawn for all the data sets. To do this, we match the value of curr with that of _root.num. If all the datasets haven't been drawn, we check if the complete line for the current dataset has been drawn. If the line for the current dataset is still incomplete, we keep on increasing the currx and curry position by animspeed pixels (to render an animating effect) and send the control back to MakeLines. (Some simple two-dimensional geometry equations are used to calculate the next point on the graph based upon the previous position and the slope.)

    If the line for the current dataset is complete, we set its name and value textbox to display the required figures. To set the value, we invoke the function setValue (which we'll look at shortly) and we pass the current dataset index, the x position and the y position, to this function as its parameters. Similarly, we display the name by calling the setName function in the same manner.

    If all the lines have been successfully drawn, we come to a halt by calling stop().

    Let's now shift our focus to the two functions setName and setValues. The function setName is invoked to set the name textbox for a particular dataset. In this function, we simply duplicate a movie clip MCITb (this is a movie clip placed in the layer textboxes, which contains a textbox with its variable name as text and registration point in the center). Thereafter, we set it's x and y co-ordinates and finally set it's text (which is _root.dataname[curr] where curr is the current dataset index). The code for this function is as follows:

    function setName(curr, posx, posy) {
      duplicateMovieClip("MCITb","Name"+curr,curr+100);
      set("Name"+curr+".text","<p align='center'>" +
                     _root.dataname[curr] + "</p>");
      setProperty("Name"+curr,_x,posx);
      setProperty("Name"+curr,_y,posy);
    }
    

    The same is done within the function setValue:

    function setValue(curr,posx,posy)
    {
      duplicateMovieClip("MCITb","Value"+curr,curr+1000);
      set("Value"+curr+".text","<p align='center'>" + 
                _root.datavalue[curr] + "</p>");
      setProperty("Value"+curr,_x,posx);
      setProperty("Value"+curr,_y,posy);
    }
    

    And, with this, the graph component is virtually ready for use. All that's left is the XMLError keyframe, which contains an error message to be displayed to the user when the XML document received by the Flash movie is malformed. To do this, simply create another frame on Actions and Labels layer and name it as XMLError. Specify the stop(); action in this keyframe and render the message that you want your users to see in case of XML error.

    Exporting the Movie
    To export the movie, go to File > Export Movie. Select the target file name and click Save. You'll next be presented with a Export Flash Player configuration dialog box. Here, place a check next to Omit Trace Actions and Compress Movie - enter JPEG quality as 100 and finally click on Ok. You are now ready to use FunkyCharts.swf in your Web site! In Part 4 we'll look at a couple examples of using FunkyCharts.

  • Read Part 4!


  • Article Information
    Article Title: Real-time Animated Graphing using Flash MX, Part 3
    Article Author: Pallav Nadhani
    Published Date: Wednesday, November 13, 2002
    Article URL: http://www.4GuysFromRolla.com/webtech/111302-1.3.shtml


    Copyright 2017 QuinStreet Inc. All Rights Reserved.
    Legal Notices, Licensing, Permissions, Privacy Policy.
    Advertise | Newsletters | E-mail Offers